Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » scout » Supporting disabled buttons and toggle buttons on the toolbar
Supporting disabled buttons and toggle buttons on the toolbar [message #1063112] Wed, 12 June 2013 11:31 Go to next message
Urs Beeli is currently offline Urs BeeliFriend
Messages: 341
Registered: October 2012
Location: Bern, Switzerland
Senior Member
A while ago, based on the discussion in this thread and various other forum posts I added toolbar button support to my SWT client (I summarised this on this howto page).

This works nicely but I've come across some limitations. I would like to be able to disable the toolbar buttons or make them toggle.

I've tried adding:
    @Override
    protected boolean getConfiguredToggleAction() {
      return true;
    }


To my class extending AbstractOutlineViewButton (which is used for the Coolbar Button) but neither that nor calling setSelected() or setEnabled() have any effect on the toolbar button.

Is there any way to make this work?
Re: Supporting disabled buttons and toggle buttons on the toolbar [message #1064972 is a reply to message #1063112] Sat, 22 June 2013 09:11 Go to previous messageGo to next message
Nataly Mogilka is currently offline Nataly MogilkaFriend
Messages: 11
Registered: August 2010
Location: Kazakhstan, Almaty
Junior Member
Hi, Urs Beeli! Did you find a solution how to use toggle buttons in toolbar? I want to use that kind of buttons too but don't know how
Re: Supporting disabled buttons and toggle buttons on the toolbar [message #1065123 is a reply to message #1064972] Mon, 24 June 2013 12:51 Go to previous messageGo to next message
Urs Beeli is currently offline Urs BeeliFriend
Messages: 341
Registered: October 2012
Location: Bern, Switzerland
Senior Member
No, I haven't had any feedback so far and am out of ideas. I'm still hoping for some input in this thread Wink
Re: Supporting disabled buttons and toggle buttons on the toolbar [message #1072777 is a reply to message #1065123] Tue, 23 July 2013 13:25 Go to previous messageGo to next message
Andreas Hoegger is currently offline Andreas HoeggerFriend
Messages: 174
Registered: February 2010
Senior Member
Thank you all for the input.

The problem here is again the static workbench model of Eclipse 3.x. We have to find somehow a way to propagate dynamic to the static workbench model. With e4 everything will be better or at least different Wink.

So for now you are able to change/add a few classes to get toggle tool buttons.


  1. Change your 'whatEverName'.ui.swt.application.button.CoolbarButton class to:
    package ch.ahoegger.sessiontest.ui.swt.application.button;
    
    import java.beans.PropertyChangeEvent;
    import java.beans.PropertyChangeListener;
    
    import org.eclipse.jface.action.Action;
    import org.eclipse.jface.action.ToolBarManager;
    import org.eclipse.scout.commons.OptimisticLock;
    import org.eclipse.scout.commons.logger.IScoutLogger;
    import org.eclipse.scout.commons.logger.ScoutLogManager;
    import org.eclipse.scout.rt.client.ui.action.IAction;
    import org.eclipse.scout.rt.client.ui.action.keystroke.KeyStroke;
    import org.eclipse.scout.rt.ui.swt.ISwtEnvironment;
    import org.eclipse.scout.rt.ui.swt.util.SwtUtility;
    import org.eclipse.swt.SWT;
    
    public class CoolbarButton extends Action {
      private static final IScoutLogger LOG = ScoutLogManager.getLogger(CoolbarButton.class);
    
      private IAction m_scoutAction;
      private ISwtEnvironment m_swtEnvironment;
      private final OptimisticLock m_updateSwtFromScoutLock;
      private boolean m_updateUi = true;
    
      private P_ScoutPropertyChangeListener m_scoutPropertyListener;
    
      private ToolBarManager m_toolbarMananger;
    
      public CoolbarButton(IAction scoutAction, ToolBarManager manager, ISwtEnvironment environment) {
        super((scoutAction.getText() == null) ? (" ") : scoutAction.getText(), transformScoutStyle(scoutAction));
        m_toolbarMananger = manager;
        m_swtEnvironment = environment;
        m_updateSwtFromScoutLock = new OptimisticLock();
        m_scoutAction = scoutAction;
        setId(getScoutObject().getActionId());
        attachScout();
        m_scoutAction.addPropertyChangeListener(new P_ScoutPropertyChangeListener());
      }
    
      private static int transformScoutStyle(IAction scoutAction) {
        if (scoutAction.isToggleAction()) {
          return SWT.TOGGLE;
        }
        return AS_PUSH_BUTTON;
      }
    
      protected void attachScout() {
        try {
          setUpdateUi(false);
          updateEnabledFromScout();
          updateIconFromScout();
          updateKeystrokeFromScout();
          updateSelectedFromScout();
          updateTextFromScout();
          updateTooltipTextFromScout();
        }
        finally {
          setUpdateUi(true);
        }
      }
    
      /**
       * @return the swtEnvironment
       */
      public ISwtEnvironment getEnvironment() {
        return m_swtEnvironment;
      }
    
      protected IAction getScoutObject() {
        return m_scoutAction;
      }
    
      /**
       * @param updateUi
       *          the updateUi to set
       */
      public void setUpdateUi(boolean updateUi) {
        if (updateUi != m_updateUi) {
          m_updateUi = updateUi;
          if (updateUi) {
            m_toolbarMananger.update(true);
          }
        }
      }
    
      /**
       * @return the updateUi
       */
      public boolean isUpdateUi() {
        return m_updateUi;
      }
    
      protected void updateEnabledFromScout() {
        setEnabled(getScoutObject().isEnabled());
        if (isUpdateUi()) {
          m_toolbarMananger.update(true);
        }
      }
    
      protected void updateIconFromScout() {
        setImageDescriptor(getEnvironment().getImageDescriptor(getScoutObject().getIconId()));
        if (isUpdateUi()) {
          m_toolbarMananger.update(true);
        }
      }
    
      protected void updateKeystrokeFromScout() {
        String keyStroke = getScoutObject().getKeyStroke();
        if (keyStroke != null) {
          int keyCode = SwtUtility.getSwtKeyCode(new KeyStroke(keyStroke));
          int stateMask = SwtUtility.getSwtStateMask(new KeyStroke(keyStroke));
          setAccelerator(stateMask | keyCode);
        }
        else {
          setAccelerator(SWT.NONE);
        }
        if (isUpdateUi()) {
          m_toolbarMananger.update(true);
        }
      }
    
      protected void updateTextFromScout() {
    
        setText(getScoutObject().getText());
        if (isUpdateUi()) {
          m_toolbarMananger.update(true);
        }
      }
    
      protected void updateTooltipTextFromScout() {
        setToolTipText(getScoutObject().getTooltipText());
        if (isUpdateUi()) {
          m_toolbarMananger.update(true);
        }
      }
    
      protected void updateSelectedFromScout() {
        setChecked(getScoutObject().isSelected());
        if (isUpdateUi()) {
          m_toolbarMananger.update(true);
        }
      }
    
      protected void updateVisibleFromScout() {
        LOG.warn("set visible on SWT action is not supported");
      }
    
      @Override
      public void run() {
        handleSwtAction();
      }
    
      protected void handleSwtAction() {
        try {
          if (getUpdateSwtFromScoutLock().acquire()) {
            Runnable t = new Runnable() {
              @Override
              public void run() {
                if (getScoutObject().isToggleAction()) {
                  getScoutObject().getUIFacade().setSelectedFromUI(!getScoutObject().isSelected());
                }
                else {
                  getScoutObject().getUIFacade().fireActionFromUI();
                }
              }
            };
            getEnvironment().invokeScoutLater(t, 0);
          }
        }
        finally {
          getUpdateSwtFromScoutLock().release();
        }
      }
    
      /**
       * @return the lock used in the Swt thread when applying scout changes
       */
      public OptimisticLock getUpdateSwtFromScoutLock() {
        return m_updateSwtFromScoutLock;
      }
    
      protected void handleScoutPropertyChange(String propertyName, Object newValue) {
        if (IAction.PROP_ENABLED.equals(propertyName)) {
          updateEnabledFromScout();
        }
        else if (IAction.PROP_ICON_ID.equals(propertyName)) {
          updateIconFromScout();
        }
        else if (IAction.PROP_KEYSTROKE.equals(propertyName)) {
          updateKeystrokeFromScout();
        }
        else if (IAction.PROP_SELECTED.equals(propertyName)) {
          updateSelectedFromScout();
        }
        else if (IAction.PROP_TEXT.equals(propertyName)) {
          updateTextFromScout();
        }
        else if (IAction.PROP_TOOLTIP_TEXT.equals(propertyName)) {
          updateTooltipTextFromScout();
        }
        else if (IAction.PROP_VISIBLE.equals(propertyName)) {
          updateVisibleFromScout();
        }
    
      }
    
      private class P_ScoutPropertyChangeListener implements PropertyChangeListener {
        @Override
        public void propertyChange(final PropertyChangeEvent evt) {
          Runnable t = new Runnable() {
            @Override
            public void run() {
              try {
                getUpdateSwtFromScoutLock().acquire();
                //
                handleScoutPropertyChange(evt.getPropertyName(), evt.getNewValue());
              }
              finally {
                getUpdateSwtFromScoutLock().release();
              }
            }
    
          };
          getEnvironment().invokeSwtLater(t);
    
        }
      }
    
    }
    

  2. Change your 'whatEverName'.ui.swt.application.ApplicationActionBarAdvisor to:
    package ch.ahoegger.sessiontest.ui.swt.application;
    
    import org.eclipse.jface.action.Action;
    import org.eclipse.jface.action.ActionContributionItem;
    import org.eclipse.jface.action.ICoolBarManager;
    import org.eclipse.jface.action.IMenuManager;
    import org.eclipse.jface.action.MenuManager;
    import org.eclipse.jface.action.ToolBarContributionItem;
    import org.eclipse.jface.action.ToolBarManager;
    import org.eclipse.scout.commons.logger.IScoutLogger;
    import org.eclipse.scout.commons.logger.ScoutLogManager;
    import org.eclipse.scout.rt.client.ui.action.tool.IToolButton;
    import org.eclipse.scout.rt.client.ui.action.view.IViewButton;
    import org.eclipse.scout.rt.client.ui.desktop.IDesktop;
    import org.eclipse.scout.rt.ui.swt.ISwtEnvironment;
    import org.eclipse.swt.SWT;
    import org.eclipse.ui.IWorkbenchActionConstants;
    import org.eclipse.ui.application.ActionBarAdvisor;
    import org.eclipse.ui.application.IActionBarConfigurer;
    
    import ch.ahoegger.sessiontest.ui.swt.Activator;
    import ch.ahoegger.sessiontest.ui.swt.SwtEnvironment;
    import ch.ahoegger.sessiontest.ui.swt.application.button.CoolbarButton;
    
    /**
     * <h3>ApplicationActionBarAdvisor</h3> Used for menu contributions.
     */
    public class ApplicationActionBarAdvisor extends ActionBarAdvisor {
    
      private static IScoutLogger logger = ScoutLogManager.getLogger(ApplicationActionBarAdvisor.class);
    
      private ToolBarManager m_toolbar;
    
      public ApplicationActionBarAdvisor(IActionBarConfigurer configurer) {
        super(configurer);
        ((SwtEnvironment) Activator.getDefault().getEnvironment()).setAdvisor(this);
      }
    
      @Override
      protected void fillMenuBar(IMenuManager menuBar) {
        menuBar.add(new MenuManager("", IWorkbenchActionConstants.M_FILE));
      }
    
      public void initViewButtons(ISwtEnvironment swtEnvironment, IDesktop d) {
        for (IToolButton scoutToolButton : d.getToolButtons()) {
          if (scoutToolButton.isVisible() && scoutToolButton.isVisibleGranted()) {
            CoolbarButton swtAction = new CoolbarButton(scoutToolButton, m_toolbar, swtEnvironment);
            contributeToCoolBar(swtAction);
          }
        }
    
        for (IViewButton scoutViewButton : d.getViewButtons()) {
          if (scoutViewButton.isVisible() && scoutViewButton.isVisibleGranted()) {
            CoolbarButton swtAction = new CoolbarButton(scoutViewButton, m_toolbar, swtEnvironment);
            contributeToCoolBar(swtAction);
          }
        }
      }
    
      protected void contributeToCoolBar(Action swtAction) {
        ActionContributionItem contributionItem = new ActionContributionItem(swtAction);
        contributionItem.setMode(ActionContributionItem.MODE_FORCE_TEXT);
        m_toolbar.add(contributionItem);
      }
    
      @Override
      protected void fillCoolBar(ICoolBarManager coolBar) {
    
        m_toolbar = new ToolBarManager(SWT.FLAT | SWT.RIGHT);
        ToolBarContributionItem item = new ToolBarContributionItem(m_toolbar, "main");
        coolBar.add(item);
      }
    }
    

  3. Ensure in 'whatEverName'.ui.swt.application.ApplicationWorkbenchWindowAdvisor.preWindowOpen() the configurer.setShowCoolBar(true); is set.



The final solution for toolbar button issues is scheduled for 3.10 (Luna) release and hopefully be part of the framework;). I opened Bugzilla 413524.

-andreas
Re: Supporting disabled buttons and toggle buttons on the toolbar [message #1073247 is a reply to message #1072777] Wed, 24 July 2013 11:42 Go to previous messageGo to next message
Urs Beeli is currently offline Urs BeeliFriend
Messages: 341
Registered: October 2012
Location: Bern, Switzerland
Senior Member
Thanks. As far as I can tell, this works well for AbstractToolButton and AbstracFormToolButton. However, I have trouble with AbstractOutlineViewButtons. When I click on them, they change toggle state but the execAction() method is not called, hence the outline is not changed.

Also, in ApplicationWorkbenchAdvisor.initialize we have the following line of code to allow saving of window/view size/position:
configurer.setSaveAndRestore(true);


This leads to the Coolbar being created when the Workbench is set up, long before Scout is ready. In order to make sure the CoolBar is really shown, I've had to add the following code to ApplicationActionBarAdvisor:

A member variable to store the configurer:
private IActionBarConfigurer m_configurer;


In the constructor, I store the configurer:
m_configurer = configurer;


Then at the end of initViewButtons I need the following code:
m_configurer.getCoolBarManager().update(true);


Using the above, the CoolBar is shown even when setSaveAndRestore is active.
Re: Supporting disabled buttons and toggle buttons on the toolbar [message #1073248 is a reply to message #1073247] Wed, 24 July 2013 11:45 Go to previous messageGo to next message
Urs Beeli is currently offline Urs BeeliFriend
Messages: 341
Registered: October 2012
Location: Bern, Switzerland
Senior Member
And as an item on the wishlist Smile

I have also registered ToolBars on some of the views by extending CompoundContributionItem. This comes with a fill(ToolBar parent, int index) method in which I have been adding buttons to the toolbar. If possible, I would also like to make these buttons dynamic. However, as the parameter into this method is a ToolBar instead of a ICoolBarManager, I don't easily see how to use your CoolbarButton to do this. Any ideas on how to solve this would be appreciated.
Re: Supporting disabled buttons and toggle buttons on the toolbar [message #1073258 is a reply to message #1073248] Wed, 24 July 2013 12:14 Go to previous messageGo to next message
Urs Beeli is currently offline Urs BeeliFriend
Messages: 341
Registered: October 2012
Location: Bern, Switzerland
Senior Member
The problem with AbstractOutlineViewButtons seems to stem from the fact that this class defines
  @Override
  protected boolean getConfiguredToggleAction() {
    return true;
  }

but then defines execAction() to take care of the outline switch.

In CoolbarButton.handleSwtAction() the code then tests isToggleAction() to decide whether to to call setSelectedFromUI() or fireActionFromUI().

This seems to be a bug in AbstractOutlineViewButton, rather than the new CoolBar implementation...

By adding the following code to my OutlineViewButtons, I can make them work:
    @Override
    protected void execToggleAction(boolean selected) throws ProcessingException {
      if (selected) {
        execAction();
      }
    }
Re: Supporting disabled buttons and toggle buttons on the toolbar [message #1073629 is a reply to message #1073258] Thu, 25 July 2013 07:51 Go to previous messageGo to next message
Andreas Hoegger is currently offline Andreas HoeggerFriend
Messages: 174
Registered: February 2010
Senior Member
you might probably also change the CoolbarButton.handleSwtAction to :

 protected void handleSwtAction() {
    try {
      if (getUpdateSwtFromScoutLock().acquire()) {
        Runnable t = new Runnable() {
          @Override
          public void run() {
            if (getScoutObject().isToggleAction()) {
              getScoutObject().getUIFacade().setSelectedFromUI(!getScoutObject().isSelected());
            }
            getScoutObject().getUIFacade().fireActionFromUI();
          }
        };
        getEnvironment().invokeScoutLater(t, 0);
      }
    }
    finally {
      getUpdateSwtFromScoutLock().release();
    }
  }


Let me know if that works...

-andreas
Re: Supporting disabled buttons and toggle buttons on the toolbar [message #1075282 is a reply to message #1073629] Mon, 29 July 2013 07:13 Go to previous message
Urs Beeli is currently offline Urs BeeliFriend
Messages: 341
Registered: October 2012
Location: Bern, Switzerland
Senior Member
Andreas Hoegger wrote on Thu, 25 July 2013 09:51
Let me know if that works...


Yes, that seems to work (and it doesn't seem to break any of the other buttons as far as I can see).
Previous Topic:Detect timeout
Next Topic:Using IOUtility from behind an authenticating proxy
Goto Forum:
  


Current Time: Fri Nov 21 18:15:46 GMT 2014

Powered by FUDForum. Page generated in 0.03365 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software