/**
   * Constructor.
   *
   * @param pSelectorCallback called when the selector is clicked. Must <b>not</b> be <code>null
   *     </code>.
   * @param pMoreArrowCallback called when the 'More' arrow is clicked. Must <b>not</b> be <code>
   *     null</code>.
   */
  public CbGenericListItem(
      final CbSelectorCallbackIF<W> pSelectorCallback,
      final CbMoreArrowCallbackIF<W> pMoreArrowCallback) {
    // dummy widget we put on the panel until the display widget is set in setDisplayWidget()
    Label dummy = new Label("<dummy>"); // $NON-NLS-1$

    // image shown when the marker is active
    Image markerActive = new Image(CbConstants.IMG_BUNDLE.markerActive());
    markerActive.setStyleName(CbConstants.CSS.ccColMarker());
    markerActive.setVisible(false);
    Image markerPassive = new Image(CbConstants.IMG_BUNDLE.markerPassive());
    markerPassive.setStyleName(CbConstants.CSS.ccColMarker());

    CbMoreArrow moreArrow = new CbMoreArrow(pMoreArrowCallback.getTooltipText());
    moreArrow.addStyleName(CbConstants.CSS.cbMoreArrowLabelSmaller());

    iDisplayWidgetWrapper = new FlowPanel();
    iDisplayWidgetWrapper.add(dummy);
    iDisplayWidgetWrapper.setStyleName(CbConstants.CSS.cbDisplayWidgetWrapper());

    final FlowPanel fp = new FlowPanel();
    fp.setStyleName(CbConstants.CSS.cbGeneralListItem());
    fp.add(markerActive);
    fp.add(markerPassive);
    fp.add(iDisplayWidgetWrapper);
    fp.add(moreArrow);

    final ClickHandler clickHandler =
        new ClickHandler() {
          @Override
          public void onClick(final ClickEvent pEvent) {
            int pos = COL_SELECTOR;
            if (!fp.getWidget(pos).isVisible()) {
              pos++;
            }
            if (CbUtil.isInside(fp.getWidget(pos), pEvent)) {
              pSelectorCallback.onItemSelected(CbGenericListItem.this);
            } else {
              pMoreArrowCallback.onMoreArrowClicked(CbGenericListItem.this);
            }
          }
        };
    addClickHandler(clickHandler);
    initWidget(fp);
  }
  /**
   * Constructor.
   *
   * @param pMsgs message texts used in this view
   * @param pShowVersion flag indicating whether the version and build numbers should be shown on
   *     the bottom bar
   */
  protected CbAbstractListView(final CbMessages pMsgs, final boolean pShowVersion) {
    CbIconButton btnNewItem =
        new CbIconButton(CbIconButton.CbPosition.left, CbConstants.IMG_BUNDLE.iconAdd());
    btnNewItem.setTitle(pMsgs.iBtnNewTooltip);
    btnNewItem.addClickHandler(
        new ClickHandler() {
          @Override
          public void onClick(final ClickEvent pEvent) {
            iPresenter.onNewClicked();
          }
        });

    iBtnEditItem = null;
    if (pMsgs.iBtnEditTooltip != null) {
      iBtnEditItem =
          new CbIconButton(CbIconButton.CbPosition.center, CbConstants.IMG_BUNDLE.iconEdit());
      iBtnEditItem.setTitle(pMsgs.iBtnEditTooltip);
      iBtnEditItem.setEnabled(false);
      iBtnEditItem.addClickHandler(
          new ClickHandler() {
            @Override
            @SuppressWarnings("unchecked")
            public void onClick(final ClickEvent pEvent) {
              if (iMarkedIdx >= 0 && iMarkedIdx < iGuiList.getWidgetCount()) {
                iPresenter.onChangeClicked(
                    getIdFromWidget(
                        ((CbGenericListItem<W>) iGuiList.getWidget(iMarkedIdx))
                            .getDisplayWidget()));
              } else {
                clearMarker(); // should not happen
              }
            }
          });
    }

    iBtnDeleteItem =
        new CbIconButton(CbIconButton.CbPosition.right, CbConstants.IMG_BUNDLE.iconDelete());
    iBtnDeleteItem.setTitle(pMsgs.iBtnRemoveTooltip);
    iBtnDeleteItem.setEnabled(false);
    iBtnDeleteItem.addClickHandler(
        new ClickHandler() {
          @SuppressWarnings("unchecked")
          @Override
          public void onClick(final ClickEvent pEvent) {
            LOG.enter("onClick"); // $NON-NLS-1$
            if (iMarkedIdx >= 0 && iMarkedIdx < iGuiList.getWidgetCount()) {
              iPresenter.onRemoveClicked(
                  getIdFromWidget(
                      ((CbGenericListItem<W>) iGuiList.getWidget(iMarkedIdx)).getDisplayWidget()));
            } else {
              clearMarker(); // should not happen
            }
            LOG.exit("onClick"); // $NON-NLS-1$
          }
        });

    Panel headPanel = new FlowPanel();
    Label heading = new InlineLabel(pMsgs.iViewTitle);
    final CbAbstractPlace backPlace = getPreviousPlace();
    if (backPlace != null) {
      CbNavigationButton btnBack =
          new CbNavigationButton(
              CbNavigationButton.CbPosition.left, pMsgs.iBtnBackCaption, pMsgs.iBtnBackTooltip);
      btnBack.addClickHandler(
          new ClickHandler() {
            @Override
            public void onClick(final ClickEvent pEvent) {
              iPresenter.goTo(backPlace);
            }
          });
      headPanel.add(btnBack);
    }
    headPanel.add(heading);
    headPanel.setStyleName(CbConstants.CSS.cbTitleBar());
    headPanel.addStyleName(CbConstants.CSS_TITLEBAR_GRADIENT);
    headPanel.addStyleName(CbConstants.CSS.cbTitleBarTextShadow());
    FlowPanel headPanelIeWrapper = new FlowPanel();
    headPanelIeWrapper.setStyleName(CbConstants.CSS.cbTitleBarIeWrapper());
    headPanelIeWrapper.add(headPanel);

    Panel bottomBar = new FlowPanel();
    bottomBar.add(btnNewItem);
    if (iBtnEditItem != null) {
      bottomBar.add(iBtnEditItem);
    }
    bottomBar.add(iBtnDeleteItem);
    bottomBar.setStyleName(CbConstants.CSS.cbBottomBar());
    bottomBar.addStyleName(CbConstants.CSS_TITLEBAR_GRADIENT);
    bottomBar.addStyleName(CbConstants.CSS.cbTitleBarTextShadow());
    if (pShowVersion) {
      // add version info to corner of screen
      final String version =
          'v'
              + CbConstants.VERSION.major()
              + '.'
              + CbConstants.VERSION.minor()
              + '.'
              + CbConstants.VERSION.patch();
      HTML versionInfo = new HTML(version);
      versionInfo.setStyleName(CbConstants.CSS.ccGamesVersionInfo());
      bottomBar.add(versionInfo);
    }
    FlowPanel bottomBarIeWrapper = new FlowPanel();
    bottomBarIeWrapper.setStyleName(CbConstants.CSS.cbBottomBarIeWrapper());
    bottomBarIeWrapper.add(bottomBar);

    iHeaderHint = new Label(pMsgs.iHeaderHint);
    iHeaderHint.setStyleName(CbConstants.CSS.cbBackgroundTitle());
    iHeaderHint.setVisible(false);

    iEmpty = new Label(pMsgs.iEmptyListMessage);
    iEmpty.setStyleName(CbConstants.CSS.cbBackgroundText());

    iGuiList = new FlowPanel();
    iGuiList.setStyleName(CbConstants.CSS.cbPageItem());
    iGuiList.setVisible(false);

    iSelectTooltip = pMsgs.iSelectTooltip;

    FlowPanel viewPanel = new FlowPanel();
    viewPanel.add(headPanelIeWrapper);
    viewPanel.add(bottomBarIeWrapper);
    viewPanel.add(iHeaderHint);
    viewPanel.add(iGuiList);
    viewPanel.add(iEmpty);
    viewPanel.setStyleName(CbConstants.CSS.cbAbstractListViewMargin());
    initWidget(viewPanel);
  }