Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    RibbonGroups disappearing when using new api RibbonGroup.reflowControls()

    Hi Isomorphic. I recently updated to 6.0-p20160511 from 6.0-p20160324, and I started experiencing some unexpected behavior (whole RibbonGroups disappearing from the RibbonBar) when I use the api you added in response to this.

    Here is a short video documenting the behavior. When I make the window smaller, the Setup RibbonGroup controls disappear, and when I maximize it again, the Playback and Results controls disappear as well.


    I don't know if this means something, but trying to find the source of the error by watching the developer console, I could see that some elements present in the RibbonGroups before the window resizing:

    Click image for larger version

Name:	RibbonBarComponents(Before).png
Views:	68
Size:	189.4 KB
ID:	237947
    ...are not present there after the resizing is done:

    Click image for larger version

Name:	RibbonBarComponents(After).png
Views:	63
Size:	166.6 KB
ID:	237946

    And this only happens to the groups (RibbonGroup_2 and RibbonGroup3) exhibiting the behavior.

    Chrome version is 50.0.2661.102 m.

    Thanks in advance for any help you can provide on this case.
    Attached Files

    #2
    Well need to see sample-code for this then we can take a look - we've no idea what the code running in your video is doing.

    Comment


      #3
      Hi Isomorphic. Below is a test case that you can run on your side. It has been simplified as much as possible, and it still shows the erratic behavior.

      MyEntryPoint.java
      Code:
      package com.myApp.testcases.client;
      
      import com.smartgwt.client.core.KeyIdentifier;
      import com.smartgwt.client.util.Page;
      import com.smartgwt.client.util.PageKeyHandler;
      import com.smartgwt.client.util.SC;
      import com.google.gwt.core.client.EntryPoint;
        
      public class TestCases implements EntryPoint {  
        
          private static final String CONSOLE_SHORTCUT = "Q";
          
          public void onModuleLoad() {  
              MyRibbon ribbon = new MyRibbon();
              ribbon.show();
              enableAdminConsole();
          }  
          
          private void enableAdminConsole() {
              /** this code enables the Admin Console which provides a graphical interface 
               * to configure database connections, create database tables from DataSource
               * descriptors, and import test data. 
               */
              KeyIdentifier debugKey = new KeyIdentifier();
              debugKey.setCtrlKey(true);
              debugKey.setKeyName(CONSOLE_SHORTCUT);
      
              Page.registerKey(debugKey, new PageKeyHandler() {
                  public void execute(String keyName) {
                      SC.showConsole();
                  }
              });
          }
      }
      MyRibbon.java
      Code:
      package com.myApp.testcases.client;
      
      import java.util.ArrayList;
      
      import com.smartgwt.client.util.Page;
      import com.smartgwt.client.widgets.Canvas;
      import com.smartgwt.client.widgets.IconButton;
      import com.smartgwt.client.widgets.events.ClickEvent;
      import com.smartgwt.client.widgets.events.ClickHandler;
      import com.smartgwt.client.widgets.events.ResizedEvent;
      import com.smartgwt.client.widgets.events.ResizedHandler;
      import com.smartgwt.client.widgets.form.DynamicForm;
      import com.smartgwt.client.widgets.form.fields.SpacerItem;
      import com.smartgwt.client.widgets.toolbar.RibbonBar;
      import com.smartgwt.client.widgets.toolbar.RibbonGroup;
      
      public class MyRibbon extends RibbonBar{
      
          private static final int ICON_SIZE = 22;
          private static final int TEXTBOX_SIZE = 26;
          private static final int RIBBON_WIDTH = 1024;
              
          // constants to hold all RibbonGroups titles/labels and the logout URL
          private static final String RIBBONGROUP_VIEWMODE = "View Mode";
          private static final String RIBBONGROUP_SETUP = "Setup";
          private static final String RIBBONGROUP_PLAYBACK = "Playback";
          private static final String RIBBONGROUP_PADDING = "";
          
          // variables to hold all RibbonGroups and to hold them classified by ViewMode
          private ArrayList<RibbonGroup> setupRibbonGroups = new ArrayList<RibbonGroup>();
          private ArrayList<RibbonGroup> playbackRibbonGroups = new ArrayList<RibbonGroup>();
          private ArrayList<RibbonGroup> allRibbonGroups = new ArrayList<RibbonGroup>();
          
          // variables to control changes in ViewMode and userMode
          private IconButton viewModeButton;
          private ViewMode currentViewMode;
          
          public MyRibbon(){
              addRibbonGroup(RIBBONGROUP_VIEWMODE, ViewMode.BOTH);
              addRibbonGroup(RIBBONGROUP_SETUP, ViewMode.SETUP);
              addRibbonGroup(RIBBONGROUP_PLAYBACK, ViewMode.PLAYBACK);
              // this group is added only for a better appearance, to make the ribbon fill the screen
              addRibbonGroup(RIBBONGROUP_PADDING, ViewMode.BOTH);
              
              this.addResizedHandler(new RibbonResizedHandler());
          }
      
          private void addRibbonGroup(String title, ViewMode mode) {
              RibbonGroup group = new RibbonGroup();
              group.setTitle(title);
              if(group.getTitle().equals(RIBBONGROUP_PADDING)){
                  group.setWidth100();
              }
              setRibbonGroupControls(group);
              this.addGroup(group);
              addRibbonGroupToLists(mode, group);
          }
      
          private void addRibbonGroupToLists(ViewMode mode, RibbonGroup group) {
              allRibbonGroups.add(group);
              switch (mode){
                  case SETUP: 
                      setupRibbonGroups.add(group);
                      break;
                  case PLAYBACK:
                      playbackRibbonGroups.add(group);
                      break;
                  default:
                      setupRibbonGroups.add(group);
                      playbackRibbonGroups.add(group);
              }
          }
          
          private void setRibbonGroupControls(RibbonGroup group){
              
              Canvas[] controls = null;
              String groupName = group.getTitle();
              
              if(groupName.equals(RIBBONGROUP_VIEWMODE)){
                  viewModeButton = newIconButton(ViewMode.SETUP.value);
                  controls = new Canvas[]{
                      viewModeButton
                  }; 
              }else if(groupName.equals(RIBBONGROUP_SETUP)){
                  controls = new Canvas[]{
                      newIconButton("Load SKUs")
                  }; 
              }else if(groupName.equals(RIBBONGROUP_PLAYBACK)){
                  controls = new Canvas[]{
                      newIconButton("No Animation"),
                      newIconButton("With Animation"),
                      newIconButton("Stop Run")
                  };
              }else if(groupName.equals(RIBBONGROUP_PADDING)){
                  controls = new Canvas[]{
                      newPaddingItem()
                  };
              }
              
              group.setControls(controls); 
          }
              
          private IconButton newIconButton(String title) {  
              IconButton button = new IconButton(title);   
              button.setIconSize(ICON_SIZE);
              if(title.equals(ViewMode.SETUP.value)){
                  button.addClickHandler(new ViewModeHandler()); 
              }
              return button;
          }  
          
          private DynamicForm newPaddingItem() {
              DynamicForm form = new DynamicForm();
              SpacerItem padding = new SpacerItem();
              padding.setHeight(TEXTBOX_SIZE);
              form.setItems(padding);
              return form;
          }
      
          private void toggleViewModeButton() {
              currentViewMode = (currentViewMode == ViewMode.PLAYBACK) ? ViewMode.SETUP : ViewMode.PLAYBACK;
              viewModeButton.setTitle(currentViewMode.value);
          }
          
          private void toggleRibbonGroups() {
              // cycle through all RibbonGroups and show/hide them according to the current viewMode
              for(RibbonGroup group: getRibbonGroupsByVisibility("hidden")){
                  group.hide();
              }
              for(RibbonGroup group: getRibbonGroupsByVisibility("visible")){
                  group.show();
              }
          }
      
          private void respondToWindowChanges() {       
              int requiredRows = (Page.getWidth() > RIBBON_WIDTH) ? 1 : 2;
              int currentRows = allRibbonGroups.get(0).getNumRows();
              if(currentRows != requiredRows){
                  for(RibbonGroup group: allRibbonGroups){
                      group.setNumRows(requiredRows);
                      group.setHeight(ICON_SIZE * requiredRows * 2);
                      group.reflowControls();
                  }
              }
          }
          
          private ArrayList<RibbonGroup> getRibbonGroupsByVisibility(String visibility){
              ViewMode currentMode = currentViewMode;
              ArrayList<RibbonGroup> ribbonGroups;
              
              switch(visibility){
                  case "hidden":
                      ribbonGroups = (currentMode == ViewMode.PLAYBACK)? setupRibbonGroups : playbackRibbonGroups;
                      break;
                  case "visible":
                  default: 
                      ribbonGroups = (currentMode == ViewMode.PLAYBACK)? playbackRibbonGroups : setupRibbonGroups;
              }
              
              return ribbonGroups;
          }
          
          private class RibbonResizedHandler implements ResizedHandler{
              @Override
              public void onResized(ResizedEvent event) {
                  respondToWindowChanges();
              }
          }
             
          private class ViewModeHandler implements ClickHandler{
              @Override
              public void onClick(ClickEvent event) {
                  toggleViewModeButton(); 
                  toggleRibbonGroups();
              }
          }
          
          public enum ViewMode {
              SETUP("Setup"),
              PLAYBACK("Playback"),
              BOTH("Both");
      
              private String value;
      
              ViewMode(String value) {
                  this.value = value;
              }
      
              public String getValue() {
                  return this.value;
              }
          }
      }
      Thanks

      Comment


        #4
        Hi Isomorphic. Were you able to reproduce this behavior? Do you need me to provide anything else?
        Thanks in advance!

        Comment


          #5
          We don't see th issue you describe, but the problem is almost certainly that your code is calling reflowControls() on groups when they're hidden, which is having the effect of removing the controls (or, not re-adding them).

          A better approach is probably to remove groups, rather than hiding them - then, when you come to re-add the groups, set numRows on them before you call addGroup() - also, instead of calls to group.setHeight(), you should use the combination of setNumRows() and setRowHeight().

          Comment


            #6
            Thanks Isomorphic. I can confirm that error I was having got solved by removing RibbonGroups instead of hiding them.

            Now, regarding your suggestion on using setNumRows() and setRowHeight() instead of group.setHeight(), the problem is that if I do it like that, I end up with a toolbar that looks like this:

            Click image for larger version

Name:	UnevenRibbon.png
Views:	59
Size:	10.6 KB
ID:	238099

            So, my follow up question would be how could I make all RibbonGroups the same height, which is the desired look I get by using group.setHeight()?

            Thanks!!

            Comment


              #7
              This is fairly obviously different code - please post the latest version, that shows your new sizing code - also, please confirm what you *expect* the ribbon to look like - it looks like you have one group with two rows, and other groups with one row - each group is sizing to its own content, according to rowHeight, and the ribbon itself sizes to the largest group.

              If you want the groups to be the same height, you can either halve the rowHeight on the 3rd group, or make all groups numRows:2.

              Comment


                #8
                Hi Isomorphic. No, code is very similar. Just applied the suggested corrections. See the code below with changes highlighted in bold (the method called getRibbonGroupsByVisibility was deleted, because after the fix, it wasn't required anymore).

                I think the mixup comes from me posting the image of my real Ribbon (the one I show on my first post of this thread), and not the one for the Ribbon in the test case. Sorry for that!!! Here is the Ribbon I get with the new code: Click image for larger version

Name:	UnevenRibbonTestCase.png
Views:	94
Size:	6.2 KB
ID:	238121






                Please note that this is the result I get, even after setting all my RibbonGroups to be 2 rows high in respondToWindowChanges. So all my groups get to be 2 rows under this setting, but as you can see, the heights of the groups is not even (very likely due to the amount of items they hold).

                I would like all RibbonGroups to have the same height, regardless of the number of items they hold, which is what I currently manage to do with group.setHeight(). Using this approach, this is what I get: Click image for larger version

Name:	EvenRibbonTestCase.png
Views:	64
Size:	5.5 KB
ID:	238122






                What am I missing here to make your suggested change of using setRowHeight work?

                Thanks!

                Code:
                package com.myApp.testcases.client;
                
                import java.util.ArrayList;
                
                import com.smartgwt.client.util.Page;
                import com.smartgwt.client.widgets.Canvas;
                import com.smartgwt.client.widgets.IconButton;
                import com.smartgwt.client.widgets.events.ClickEvent;
                import com.smartgwt.client.widgets.events.ClickHandler;
                import com.smartgwt.client.widgets.events.ResizedEvent;
                import com.smartgwt.client.widgets.events.ResizedHandler;
                import com.smartgwt.client.widgets.form.DynamicForm;
                import com.smartgwt.client.widgets.form.fields.SpacerItem;
                import com.smartgwt.client.widgets.toolbar.RibbonBar;
                import com.smartgwt.client.widgets.toolbar.RibbonGroup;
                
                public class MyRibbon extends RibbonBar{
                
                    private static final int ICON_SIZE = 22;
                    private static final int TEXTBOX_SIZE = 26;
                    private static final int RIBBON_WIDTH = 1024;
                            
                    // constants to hold all RibbonGroups titles/labels and the logout URL
                    private static final String RIBBONGROUP_VIEWMODE = "View Mode";
                    private static final String RIBBONGROUP_SETUP = "Setup";
                    private static final String RIBBONGROUP_PLAYBACK = "Playback";
                    private static final String RIBBONGROUP_PADDING = "";
                    
                    // variables to hold all RibbonGroups and to hold them classified by ViewMode
                    private ArrayList<RibbonGroup> setupRibbonGroups = new ArrayList<RibbonGroup>();
                    private ArrayList<RibbonGroup> playbackRibbonGroups = new ArrayList<RibbonGroup>();
                    private ArrayList<RibbonGroup> allRibbonGroups = new ArrayList<RibbonGroup>();
                    
                    // variables to control changes in ViewMode and userMode
                    private IconButton viewModeButton;
                    private ViewMode currentViewMode;
                    
                    public MyRibbon(){
                        addRibbonGroup(RIBBONGROUP_VIEWMODE, ViewMode.BOTH);
                        addRibbonGroup(RIBBONGROUP_SETUP, ViewMode.SETUP);
                        addRibbonGroup(RIBBONGROUP_PLAYBACK, ViewMode.PLAYBACK);
                        // this group is added only for a better appearance, to make the ribbon fill the screen
                        addRibbonGroup(RIBBONGROUP_PADDING, ViewMode.BOTH);
                        
                        this.addResizedHandler(new RibbonResizedHandler());
                    }
                
                    private void addRibbonGroup(String title, ViewMode mode) {
                        RibbonGroup group = new RibbonGroup();
                        group.setTitle(title);
                        if(group.getTitle().equals(RIBBONGROUP_PADDING)){
                            group.setWidth100();
                        }
                        setRibbonGroupControls(group);
                        this.addGroup(group);
                        addRibbonGroupToLists(mode, group);
                    }
                
                    private void addRibbonGroupToLists(ViewMode mode, RibbonGroup group) {
                        allRibbonGroups.add(group);
                        switch (mode){
                            case SETUP:
                                setupRibbonGroups.add(group);
                                break;
                            case PLAYBACK:
                                playbackRibbonGroups.add(group);
                                break;
                            default:
                                setupRibbonGroups.add(group);
                                playbackRibbonGroups.add(group);
                        }
                    }
                    
                    private void setRibbonGroupControls(RibbonGroup group){
                        
                        Canvas[] controls = null;
                        String groupName = group.getTitle();
                        
                        if(groupName.equals(RIBBONGROUP_VIEWMODE)){
                            viewModeButton = newIconButton(ViewMode.SETUP.value);
                            controls = new Canvas[]{
                                viewModeButton
                            };
                        }else if(groupName.equals(RIBBONGROUP_SETUP)){
                            controls = new Canvas[]{
                                newIconButton("Load SKUs")
                            };
                        }else if(groupName.equals(RIBBONGROUP_PLAYBACK)){
                            controls = new Canvas[]{
                                newIconButton("No Animation"),
                                newIconButton("With Animation"),
                                newIconButton("Stop Run")
                            };
                        }else if(groupName.equals(RIBBONGROUP_PADDING)){
                            controls = new Canvas[]{
                                newPaddingItem()
                            };
                        }
                        
                        group.setControls(controls);
                    }
                        
                    private IconButton newIconButton(String title) {  
                        IconButton button = new IconButton(title);  
                        button.setIconSize(ICON_SIZE);
                        if(title.equals(ViewMode.SETUP.value)){
                            button.addClickHandler(new ViewModeHandler());
                        }
                        return button;
                    }  
                    
                    private DynamicForm newPaddingItem() {
                        DynamicForm form = new DynamicForm();
                        SpacerItem padding = new SpacerItem();
                        padding.setHeight(TEXTBOX_SIZE);
                        form.setItems(padding);
                        return form;
                    }
                
                    private void toggleViewModeButton() {
                        currentViewMode = (currentViewMode == ViewMode.PLAYBACK) ? ViewMode.SETUP : ViewMode.PLAYBACK;
                        viewModeButton.setTitle(currentViewMode.value);
                    }
                    
                    [B]// THIS IS THE METHOD WERE I APPLIED YOUR SUGGESTED FIX[/B]
                [B]    private void toggleRibbonGroups() {
                        for(RibbonGroup group: allRibbonGroups){
                            this.removeMember(group);
                        }
                        
                        ArrayList<RibbonGroup> visibleRibbonGroups = 
                                (currentViewMode == ViewMode.PLAYBACK)
                                ? playbackRibbonGroups 
                                : setupRibbonGroups;
                        for(RibbonGroup group: visibleRibbonGroups){
                            this.addGroup(group);
                        }
                    }[/B]
                
                    private void respondToWindowChanges() {      
                        int requiredRows = (Page.getWidth() > RIBBON_WIDTH) ? 1 : 2;
                        int currentRows = allRibbonGroups.get(0).getNumRows();
                        if(currentRows != requiredRows){
                            for(RibbonGroup group: allRibbonGroups){
                                group.setNumRows(requiredRows); [B]// NOTE THAT HERE I AM SETTING THE SAME ROW NUMBER FOR ALL GROUPS[/B]
                                [B]// [/B][B]THIS IS YOUR OTHER SUGGESTION, WHICH PRODUCES UNDESIRED RESULT[/B]
                                [B]group.setRowHeight(ICON_SIZE * 2);[/B]
                                group.reflowControls();
                            }
                        }
                    }
                    
                    private class RibbonResizedHandler implements ResizedHandler{
                        @Override
                        public void onResized(ResizedEvent event) {
                            respondToWindowChanges();
                        }
                    }
                      
                    private class ViewModeHandler implements ClickHandler{
                        @Override
                        public void onClick(ClickEvent event) {
                            toggleViewModeButton();
                            toggleRibbonGroups();
                        }
                    }
                    
                    public enum ViewMode {
                        SETUP("Setup"),
                        PLAYBACK("Playback"),
                        BOTH("Both");
                
                        private String value;
                
                        ViewMode(String value) {
                            this.value = value;
                        }
                
                        public String getValue() {
                            return this.value;
                        }
                    }
                }
                Last edited by carlossierra; 20 May 2016, 15:58. Reason: Code format

                Comment


                  #9
                  After some testing, it turns out that group.setHeight() *is* the correct way to get the effect you're after - in this case, you can disregard our suggestion about using rowHeight and numRows.

                  Comment


                    #10
                    Thanks Isomorphic!

                    Comment

                    Working...
                    X