IconPanel constructor

IconPanel(Element parent, String id, String iconPath, List<String> iconNames, GetIconCallbacks getIconCallbacks, BaseDialogCloseCallback closeCallback, int x, int y, int panelWidth, int iconSize, int ncols, bool preventDefault)

Creates and displays a panel with icons. Each icon may have a callback function executed when the icon is clicked. parent - the panel is added to this element. id - the panel can be identified with this id if unique. iconPath - where the icons are stored reletive to specpad. iconNames - list of the icons to be displayed. getIconCallbacks - a function returning a list of callback functions to be executed when clicking on an icon. Order and length of the list must correspond to iconNames. A list entry may be null. closeCallback - called when the panel gets closed. x, y - position of the panel relative to specpad. panelWidth - panel will get this width. Height is automatic. iconSize - size of the icons in pixels, e.g. 24. ncols - panel will get this many icon columns. preventDefault - if false, finger-scrolling the items is enabled for touch.

Implementation

IconPanel(
    Element parent,
    String id,
    String iconPath,
    List<String> iconNames,
    GetIconCallbacks getIconCallbacks,
    BaseDialogCloseCallback closeCallback,
    int x,
    int y,
    int panelWidth,
    int iconSize,
    int ncols,
    bool preventDefault)
    : super.noModal(closeCallback) {
  int nitems = iconNames.length;
  _iconStyle = """
  alt="" align="top"
    border="none" height="${iconSize - 4}" width="${iconSize - 4}"
  """;

//    baseDia = BaseDialog.noModal(closeCallback);
  dia.id = id;

  // Make sure the popup is always displayed above everything else by giving it a big z-index.
  // Especially over the jsme structure display div.

  setStyle(dia, null);
  Map<String, String> attr = DiaAttr.attr; // use shortcut
  // nodify standad style:
  parent.append(dia);

  diaTable.style
    ..cursor = "pointer"
    ..backgroundColor = attr[DiaAttr.ICONPANEL_BACKGROUND]
    ..background = attr[DiaAttr.ICONPANEL_BACKGROUND]
//      ..borderCollapse = "collapse"
    ..marginTop = "6px"
    ..marginBottom = "0px";

  dia
    ..append(diaTable)
    ..onTouchMove.listen((e) {
      // Needed on iPad: Otherwise moving the finger over the dialog would move
      // the whole browser content up.
      // This feature is very good if a text entry field are present,
      // to be able to enter text if covered by the keyboard. In our popup
      // case that's not necessary, but rather
      // disturbing.
      if (preventDefault) e.preventDefault();
    });

  int nrows = nitems ~/ ncols;
  if (nitems.remainder(ncols) > 0) nrows++;
  List<TableRowElement> rows = List<TableRowElement>(nrows);

  // add table header
  // decode: "iconName||action code"
  int iconcount = 0;
  int iconPadding = 5;
  String iconName;
  IconCallback iconCallback;
  TableCellElement cell;
  for (int i = 0; i < nrows; i++) {
    // NOTE: for any one reason, the type TableRowElement must be specified inside the loop,
    // otherwsie
    rows[i] = TableRowElement();
    TableRowElement row = rows[i];
    row.style
      ..color = attr[DiaAttr.DIALOG_TEXT_COLOR] // initial setting
      ..cursor = "pointer"
      ..backgroundColor = attr[DiaAttr.ICONPANEL_BACKGROUND];

    void handleTouchStart(TouchEvent e) {
      _lastTouchPoints = DiaUtils.getTouchPoints(e);
    }

    void executIconFunction(UIEvent e) {
      TableCellElement eventCell;
      if (e.target is ImageElement) {
        ImageElement icon = e.target; // event fired by icon
        eventCell = icon.parent;
      } else if (e.target is TableCellElement) {
        eventCell = e.target; // event fired by cell
      } else {
        return;
      }

      int touchedIconNo = int.parse(eventCell.id);
      // get callbacks here because the panel may stay open while the dataset
      // and its dimension changes.
      List<IconCallback> iconCallbacks = getIconCallbacks();
      assert(iconNames.length == iconCallbacks.length);
      iconCallback = iconCallbacks[touchedIconNo];
      if (iconCallback != null) iconCallback(e);
    }

    void handleTouchEnd(TouchEvent e) {
      TouchList tl = e.changedTouches;
      if (tl == null || tl.isEmpty) return;
      int lastx = _lastTouchPoints[0].x;
      int lasty = _lastTouchPoints[0].y;
      if ((lastx - tl.first.page.x).abs() > 30 ||
          (lasty - tl.first.page.y).abs() > 20) {
        return;
      }
      executIconFunction(e);
    }

    // these are the icons in the current row
    List<TableCellElement> iconCells = List<TableCellElement>(ncols);
    for (int k = 0; k < ncols; k++) {
      // format is: "icon name||action code"
      iconName = iconNames[iconcount];

      iconCells[k] = TableCellElement();
      cell = iconCells[k];
      cell.id = "$iconcount"; // will indentify iconCallback
      DiaUtils.appendHtml2(
          cell, """<img src="${iconPath}/${iconName}" $_iconStyle>""");
      cell.style
            ..cursor = "pointer"
            ..backgroundColor = attr[DiaAttr.ICONPANEL_BACKGROUND]
//          ..margin = ".5em 1em"
            ..padding = "${iconPadding}px" // 0px 0px 5px" // t r b l
          ;

      cell.onMouseEnter.listen((MouseEvent event) {
        iconCells[k].style
          ..backgroundColor = attr[DiaAttr.POPUP_SELECTION_COLOR];
      });

      cell.onMouseLeave.listen((MouseEvent event) {
        iconCells[k].style
          ..backgroundColor = attr[DiaAttr.ICONPANEL_BACKGROUND];
      });

      if (!DiaUtils.hasMouse()) {
        cell.onTouchStart.listen((TouchEvent e) {
          handleTouchStart(e);
        });

        cell.onTouchEnd.listen((TouchEvent e) {
          handleTouchEnd(e);
        });
      } else {
        cell.onClick.listen((MouseEvent e) {
          executIconFunction(e);
        });
      }

      row.append(cell);

      diaTable.append(row);
      if (iconcount >= iconNames.length - 1) break; // all done
      iconcount++;
    } // for k
  } // for i

  dia.style
    ..position = "fixed"
    ..left = "${x}px"
    ..top = "${y}px"
    ..marginLeft = "0px"
    ..marginTop = "0px"
    ..paddingTop = "0px"
    ..paddingLeft = "0px"
    ..width = "${panelWidth}px"
    ..opacity = "1";
}