/** * Mark the list item with the given ID. * * @param pItemId item ID */ @SuppressWarnings("unchecked") public void setMarked(final String pItemId) { if (LOG.isTraceEnabled()) { LOG.enter( "setMarked", //$NON-NLS-1$ new String[] {"pItemId"}, new Object[] {pItemId}); // $NON-NLS-1$ } boolean clear = pItemId == null || pItemId.equals( getIdFromWidget( ((CbGenericListItem<W>) iGuiList.getWidget(iMarkedIdx)).getDisplayWidget())); clearMarker(); if (pItemId != null && !clear) { int idx = 0; for (Iterator<Widget> iter = iGuiList.iterator(); iter.hasNext(); idx++) { CbGenericListItem<W> gli = (CbGenericListItem<W>) iter.next(); W w = gli.getDisplayWidget(); if (pItemId.equals(getIdFromWidget(w))) { setMarked(idx); break; } } } LOG.exit("setMarked"); // $NON-NLS-1$ }
/** * Setter. * * @param pPresenter the new presenter */ public void setPresenter(final P pPresenter) { if (LOG.isDetailEnabled()) { LOG.detail( "setPresenter", //$NON-NLS-1$ "pPresenter = " + pPresenter); // $NON-NLS-1$ } iPresenter = pPresenter; }
/** * Getter. * * @return the ID of the marked entry */ @SuppressWarnings("unchecked") public String getMarkedID() { LOG.enter("getMarkedID"); // $NON-NLS-1$ if (LOG.isDetailEnabled()) { LOG.detail( "getMarkedID", //$NON-NLS-1$ "iMarkedIdx = " + iMarkedIdx); // $NON-NLS-1$ } String result = null; if (iMarkedIdx >= 0 && iMarkedIdx < iGuiList.getWidgetCount()) { result = getIdFromWidget( ((CbGenericListItem<W>) iGuiList.getWidget(iMarkedIdx)).getDisplayWidget()); } LOG.exit("getMarkedID", result); // $NON-NLS-1$ return result; }
/** * Common superclass of our views which simply shows a list of objects. * * @author Thomas Jensen * @param <W> the type of widget displaying our main view object in the list * @param <P> the presenter type used for the view instance */ public abstract class CbAbstractListView<W extends Widget, P extends CbListPresenterIF> extends Composite { /** Logger for this class */ private static final CbLogAdapter LOG = CbLogAdapter.getLogger(CbAbstractListView.class); /** our current presenter */ private P iPresenter; /** index of the currently marked item (-1 == nothing marked) */ private int iMarkedIdx = -1; /** message shown above the list to tell the user what to do */ private Label iHeaderHint; /** label shown when the list is empty */ private Label iEmpty; /** the list of {@link CbGenericListItem}s, each representing a row in the list */ private FlowPanel iGuiList; /** button 'Edit' */ private CbIconButton iBtnEditItem; /** button 'Delete' */ private CbIconButton iBtnDeleteItem; /** tooltip under the 'more' arrows */ private String iSelectTooltip; /** called when an item is selected */ private CbGenericListItem.CbSelectorCallbackIF<W> iSelectorCallback; /** called when the 'More' arrow or the display widget are clicked */ private CbGenericListItem.CbMoreArrowCallbackIF<W> iMoreArrowCallback; /** * Message texts used in {@link CbAbstractListView}. * * @author Thomas Jensen */ protected static class CbMessages { /** main view heading */ private String iViewTitle = null; /** message shown above the list to tell the user what to do */ private String iHeaderHint = null; /** 'Back' button caption (text on the button itself) */ private String iBtnBackCaption = null; /** 'Back' button tooltip text */ private String iBtnBackTooltip = null; /** 'New' button tooltip text */ private String iBtnNewTooltip = null; /** 'Edit' button tooltip text */ private String iBtnEditTooltip = null; /** 'Remove' button tooltip text */ private String iBtnRemoveTooltip = null; /** message shown when there are no items in the list */ private String iEmptyListMessage = null; /** 'More' arrow tooltip text */ private String iSelectTooltip = null; protected void setViewTitle(final String pViewTitle) { iViewTitle = pViewTitle; } public void setBtnBackCaption(final String pBtnBackCaption) { iBtnBackCaption = pBtnBackCaption; } public void setBtnBackTooltip(final String pBtnBackTooltip) { iBtnBackTooltip = pBtnBackTooltip; } protected void setBtnNewTooltip(final String pBtnNewTooltip) { iBtnNewTooltip = pBtnNewTooltip; } protected void setBtnEditTooltip(final String pBtnEditTooltip) { iBtnEditTooltip = pBtnEditTooltip; } protected void setBtnRemoveTooltip(final String pBtnRemoveTooltip) { iBtnRemoveTooltip = pBtnRemoveTooltip; } protected void setEmptyListMessage(final String pEmptyListMessage) { iEmptyListMessage = pEmptyListMessage; } protected void setSelectTooltip(final String pSelectTooltip) { iSelectTooltip = pSelectTooltip; } protected void setHeaderHint(final String pHeaderHint) { iHeaderHint = pHeaderHint; } } /** * 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); } private CbGenericListItem.CbSelectorCallbackIF<W> getSelectorCallback() { if (iSelectorCallback == null) { iSelectorCallback = new CbGenericListItem.CbSelectorCallbackIF<W>() { @Override public void onItemSelected(final CbGenericListItem<W> pSource) { setMarked(pSource.getRowIdx()); } }; } return iSelectorCallback; } private CbGenericListItem.CbMoreArrowCallbackIF<W> getMoreArrowCallback() { if (iMoreArrowCallback == null) { iMoreArrowCallback = new CbGenericListItem.CbMoreArrowCallbackIF<W>() { @Override public void onMoreArrowClicked(final CbGenericListItem<W> pSource) { String itemId = getIdFromWidget(pSource.getDisplayWidget()); iPresenter.goTo(getNextPlace(itemId)); } @Override public String getTooltipText() { return iSelectTooltip; } }; } return iMoreArrowCallback; } /** * Get the identifying attribute of the item from the display widget. * * @param pWidget the widget * @return the ID String (e.g. game or player name) */ protected abstract String getIdFromWidget(final W pWidget); /** * Create the place object of the previous place in the click chain. * * @return the previous place, or <code>null</code> if no 'back' button should be shown */ protected abstract CbAbstractPlace getPreviousPlace(); /** * Create the place object of the place navigated to upon selection of an item. * * @param pItemId the selected item's ID * @return the next place */ protected abstract CbAbstractPlace getNextPlace(final String pItemId); @SuppressWarnings("unchecked") private void clearMarker() { if (iMarkedIdx >= 0) { if (iMarkedIdx < iGuiList.getWidgetCount()) { // (else the widget is already deleted) ((CbGenericListItem<W>) iGuiList.getWidget(iMarkedIdx)).setMarkerVisible(false); } iMarkedIdx = -1; iBtnDeleteItem.setEnabled(false); if (iBtnEditItem != null) { iBtnEditItem.setEnabled(false); } } } /** * Gets the display widget with the given item ID from {@link #iGuiList}. * * @param pItemId the widget's item ID * @return the widget itself */ protected W getItem(final String pItemId) { W result = null; for (Iterator<Widget> iter = iGuiList.iterator(); iter.hasNext(); ) { @SuppressWarnings("unchecked") CbGenericListItem<W> gli = (CbGenericListItem<W>) iter.next(); W w = gli.getDisplayWidget(); if (pItemId.equals(getIdFromWidget(w))) { result = w; break; } } return result; } /** * Mark the list item with the given ID. * * @param pItemId item ID */ @SuppressWarnings("unchecked") public void setMarked(final String pItemId) { if (LOG.isTraceEnabled()) { LOG.enter( "setMarked", //$NON-NLS-1$ new String[] {"pItemId"}, new Object[] {pItemId}); // $NON-NLS-1$ } boolean clear = pItemId == null || pItemId.equals( getIdFromWidget( ((CbGenericListItem<W>) iGuiList.getWidget(iMarkedIdx)).getDisplayWidget())); clearMarker(); if (pItemId != null && !clear) { int idx = 0; for (Iterator<Widget> iter = iGuiList.iterator(); iter.hasNext(); idx++) { CbGenericListItem<W> gli = (CbGenericListItem<W>) iter.next(); W w = gli.getDisplayWidget(); if (pItemId.equals(getIdFromWidget(w))) { setMarked(idx); break; } } } LOG.exit("setMarked"); // $NON-NLS-1$ } /** * Getter. * * @return the ID of the marked entry */ @SuppressWarnings("unchecked") public String getMarkedID() { LOG.enter("getMarkedID"); // $NON-NLS-1$ if (LOG.isDetailEnabled()) { LOG.detail( "getMarkedID", //$NON-NLS-1$ "iMarkedIdx = " + iMarkedIdx); // $NON-NLS-1$ } String result = null; if (iMarkedIdx >= 0 && iMarkedIdx < iGuiList.getWidgetCount()) { result = getIdFromWidget( ((CbGenericListItem<W>) iGuiList.getWidget(iMarkedIdx)).getDisplayWidget()); } LOG.exit("getMarkedID", result); // $NON-NLS-1$ return result; } /** * Mark the list item at the given position. * * @param pRowIdx item index */ @SuppressWarnings("unchecked") private void setMarked(final int pRowIdx) { boolean clear = pRowIdx < 0 || pRowIdx >= iGuiList.getWidgetCount() || pRowIdx == iMarkedIdx; clearMarker(); if (!clear) { ((CbGenericListItem<W>) iGuiList.getWidget(pRowIdx)).setMarkerVisible(true); iMarkedIdx = pRowIdx; iBtnDeleteItem.setEnabled(true); if (iBtnEditItem != null) { iBtnEditItem.setEnabled(true); } } } protected P getPresenter() { return iPresenter; } /** * Setter. * * @param pPresenter the new presenter */ public void setPresenter(final P pPresenter) { if (LOG.isDetailEnabled()) { LOG.detail( "setPresenter", //$NON-NLS-1$ "pPresenter = " + pPresenter); // $NON-NLS-1$ } iPresenter = pPresenter; } /** * Add an item to the list. * * @param pNewWidget the new display widget */ @SuppressWarnings("unchecked") protected void addDisplayWidget(final W pNewWidget) { final String itemId = getIdFromWidget(pNewWidget); int beforeIdx = -1; for (Widget w : iGuiList) { CbGenericListItem<W> gli = (CbGenericListItem<W>) w; if (itemId.compareToIgnoreCase(getIdFromWidget(gli.getDisplayWidget())) < 0) { beforeIdx = gli.getRowIdx(); break; } } CbGenericListItem<W> newRow = new CbGenericListItem<W>(getSelectorCallback(), getMoreArrowCallback()); newRow.setDisplayWidget(pNewWidget); if (beforeIdx < 0) { newRow.setRowIdx(iGuiList.getWidgetCount()); iGuiList.add(newRow); } else { newRow.setRowIdx(beforeIdx); iGuiList.insert(newRow, beforeIdx); int i = 0; for (Widget w : iGuiList) { ((CbGenericListItem<W>) w).setRowIdx(i++); } } checkEmptyListHint(); } /** * Replace the list displayed with the given one. * * @param pDisplayWidgets the new list of items to display */ protected void setDisplayWidgets(final List<W> pDisplayWidgets) { iGuiList.clear(); int i = 0; for (W w : pDisplayWidgets) { CbGenericListItem<W> newRow = new CbGenericListItem<W>(getSelectorCallback(), getMoreArrowCallback()); newRow.setDisplayWidget(w); newRow.setRowIdx(i++); iGuiList.add(newRow); } checkEmptyListHint(); } /** * Removes the entry with the given item ID. * * @param pItemId the unique item ID */ protected void removeDisplayWidget(final String pItemId) { int i = 0; for (Iterator<Widget> iter = iGuiList.iterator(); iter.hasNext(); i++) { @SuppressWarnings("unchecked") CbGenericListItem<W> gli = (CbGenericListItem<W>) iter.next(); if (pItemId.equals(getIdFromWidget(gli.getDisplayWidget()))) { iter.remove(); i--; } else { gli.setRowIdx(i); } } checkEmptyListHint(); } private void checkEmptyListHint() { boolean empty = iGuiList.getWidgetCount() < 1; iEmpty.setVisible(empty); iHeaderHint.setVisible(!empty); iGuiList.setVisible(!empty); } }