Announcement

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

    Would like layout "fullscreen mode" thoughts

    Please consider the image below, which is used in desktop mode.

    We sometimes have components in the rightmost layout that need a lot of space, so we're thinking about having some way for them to go in and out of "fullscreen mode". This would be a button to the topleft in the blue area that, when clicked, would make the blue area take up the entire page, with a button to make it go back into its place.

    In this example the "rapporter" is a splitpane within an outer splitpane.

    My question is basically if there's an easy way to accomplish this? I looked into the showcase and reference but didn't see much about 'fullscreen'. Setting a layout to fullscreen is maybe not so hard, but getting it back into its place after?

    Pointers appreciated.



    Click image for larger version

Name:	fullscreen.png
Views:	111
Size:	86.6 KB
ID:	267077


    #2
    There is no special "fullscreen" code - fullscreen is just a widget that is top-level and 100% height and width.

    So use layout.removeMember() and resizeTo(100%, 100%) before you draw() at top level. To leave fullscreen mode, remember the index in the layout and place back at the same index.

    Note, depending on how you want the "pop-out" to behave, instead of removeMember()/addMember(), you might want to use replaceMember() with a placholder member (just a LayoutSpacer, for example), to prevent reflowing around the temporarily removed member, depending on the use case).

    Comment


      #3

      Hey, as always thanks for quick feedback. From where i'm standing you've gotten even better at this lately and i just want to say i notice and appreciate it.

      Thanks for the tips. Yeah that's kind of what i thought i needed. Alos, thanks for the tip regarding remove/replace, will look into it.

      EDIT: Also i could also use some more tips re. what you said, i didn't get all of it:

      1. How do i draw 'at top level'? Right now, i make sure that the root is a canvas i call draw on, then add my splitpane to that. When i want one of the nodes to go fullscreen, i add it to the root canvas, hide the splitpane then draw the layout with the same width/height as the root canvas.
      Is there an easier way to at "top level"?

      2. What do you mean by "remember the index in the layout"? if that's something that would make it easier, great, but how do you do that? Couldn't find any methods in layouts that had this kind of logic.

      ------

      I have made a complete test case below of how i have solved it based on your feedback. If you could find it in your hearts to take a peek and suggest any improvements / cleanups you can find, i'd be most obliged.


      Code:
      package com.test;
      
      import com.google.gwt.core.client.EntryPoint;
      import com.google.gwt.core.client.GWT;
      import com.smartgwt.client.data.Record;
      import com.smartgwt.client.types.SelectionStyle;
      import com.smartgwt.client.types.Visibility;
      import com.smartgwt.client.widgets.layout.Layout;
      import com.smartgwt.client.widgets.layout.SplitPane;
      import com.smartgwt.client.widgets.layout.VLayout;
      import com.smartgwt.client.widgets.toolbar.ToolStrip;
      import com.smartgwt.client.widgets.toolbar.ToolStripButton;
      import com.smartgwt.client.widgets.tree.Tree;
      import com.smartgwt.client.widgets.tree.TreeGrid;
      import com.smartgwt.client.widgets.tree.TreeGridField;
      import com.smartgwt.client.widgets.tree.TreeNode;
      
      public class TheTest implements EntryPoint {
      
          TestLayout fullscreenTest;
          TestLayout other;
          Layout replacer;
          Layout root;
      
          ToolStripButton back;
          ToolStripButton fullscreen;
          SplitPane split;
      
          public void onModuleLoad() {
      
              replacer = new Layout();
              replacer.setBackgroundColor("red");
              replacer.setVisibility(Visibility.INHERIT);
      
              TreeGrid grid = createTree();
      
              back = new ToolStripButton("Back");
              back.setVisibility(Visibility.HIDDEN);
              back.addClickHandler(clickEvent -> back());
              fullscreen = new ToolStripButton("Fullscreen");
              fullscreen.addClickHandler(clickEvent -> fullscreen());
              ToolStrip strip = new ToolStrip();
              strip.addButton(back);
              strip.addButton(fullscreen);
              fullscreenTest.addMember(strip, 0);
      
              split = new SplitPane(grid, null);
              split.setShowDetailToolStrip(false);
      
              root = new Layout();
              root.setWidth100();
              root.setHeight100();
      
      
              root.addMember(split);
              root.draw();
          }
      
          private TreeGrid createTree(){
              TreeNode first = new TreeNode("First");
              TreeNode second = new TreeNode("Second");
              TreeNode[] nodes = new TreeNode[]{first, second};
      
              DefaultTreeGrid grid = new DefaultTreeGrid(nodes);
              grid.setHeight100();
              grid.addRecordClickHandler(recordClickEvent -> handleTreeClick(recordClickEvent.getRecord()));
      
              fullscreenTest = new TestLayout("blue", "black");
              other = new TestLayout("green", "brown");
              return grid;
          }
      
          private void handleTreeClick(Record record) {
              GWT.log("record!: " + record.getAttribute("name"));
              split.setDetailPane(record.getAttribute("name").equals("First") ? fullscreenTest : other);
          }
      
          private void back(){
              GWT.log("BACK");
              back.setVisibility(Visibility.HIDDEN);
              fullscreen.setVisibility(Visibility.INHERIT);
              root.replaceMember(fullscreenTest, split);
              ((Layout) replacer.getParentCanvas()).replaceMember(replacer, fullscreenTest);
              split.setVisibility(Visibility.INHERIT);
          }
      
          private void fullscreen() {
              GWT.log("FULLSCREEN");
              fullscreen.setVisibility(Visibility.HIDDEN);
              back.setVisibility(Visibility.INHERIT);
              ((Layout) fullscreenTest.getParentCanvas()).replaceMember(fullscreenTest, replacer);
              root.replaceMember(split, fullscreenTest);
              split.setVisibility(Visibility.HIDDEN);
          }
      
      
          public class DefaultTreeGrid extends TreeGrid {
      
              public DefaultTreeGrid(TreeNode[] nodes) {
                  Tree tree = new Tree();
                  tree.setData(nodes);
                  setSelectionType(SelectionStyle.SINGLE);
                  setAlwaysShowScrollbars(true);
                  TreeGridField nameField = new TreeGridField("name");
                  nameField.setWidth("100%");
                  setWidth100();
                  setLeaveScrollbarGap(false);
                  setData(tree);
                  setFields(nameField);
                  setShowSelectedIcons(true);
                  setCanSort(false);
                  setShowHeaderContextMenu(false);
                  setShowHeader(false);
              }
          }
      
          class TestLayout extends VLayout{
      
              public TestLayout(String col, String border) {
                  setBackgroundColor(col);
                  if (border != null) {
                      setBorder("5px solid " + border);
                  }
      
              }
          }
      }
      Last edited by mathias; 27 Dec 2021, 02:49.

      Comment


        #4
        Before you layout.removeMember(member), store the result of layout.getMemberNumber(member) and pass it to addMember() when you pop the member back in.

        Here's a simple JS implementation for reference

        Code:
        popoutMember = function (layout, member) {
            // remember where the member is now
            var config = { layout: layout, member: member, index: layout.getMemberNumber(member) };
        
            // popout the member
            layout.removeMember(member);
            member.resizeTo("100%", "100%")
            member.draw();
        
            // return the config
            return config;
        }
        
        popinMember = function (config) {
            // put the member back where it came from
            config.layout.addMember(config.member, config.index);
        }
        
        
        // pop a member and store the config
        var config = popoutMember(layout, member);
        
        // and pop back in
        popinMember(config);
        Last edited by Isomorphic; 27 Dec 2021, 04:06.

        Comment


          #5
          Great, but i have to double check - i am instead using replacemember in my code example as per you suggested. If i use that, do i still need to remove/keep track of index? I thought replace was pretty neat, since i then only have to keep track of my "place holder" layout as you can see in the code.

          The "replace" layout i put in where the fullscreen layout was before knows where has been placed, so i don't have to keep track of the parent layout, only do a replacelayout() with the parent layout of where the replace-layout was put. This way i don't have to know the parent, and not the index. Should work, right?

          Finally - is there any way to just draw something on top of "everything else" without knowing the root canvas? Just curious.
          Last edited by mathias; 27 Dec 2021, 06:09.

          Comment


            #6
            You can use add/remove or replace, doesn't matter - personally, I would add/remove, for the control - but either is fine, if you manage things properly.

            The code we posted shows the member "on top of everything else" anyway - but you can always canvas.bringToFront() on any canvas.
            Last edited by Isomorphic; 27 Dec 2021, 10:39.

            Comment


              #7
              ok, is it the "draw()" call that makes it appear "on top"? Just trying to understand, i'm not very good at this layout stuff.

              Comment


                #8
                It's the removal of the widget from a layout, which makes it top-level, plus the draw().

                That said - the sample code we posted was knocked up against our JS showcase, which is kind of a special environment - it might be best to always bringToFront() anyway, in your app, for clearer code.

                Just to be clear - if you're moving a widget from one layout to another, that's not really making a widget full-screen, per se - that is, it's not a top-level canvas.

                If you want it to be full-screen, show it at top-level as we suggested, not as a member of another layout, unless that layout itself is top-level.
                Last edited by Isomorphic; 28 Dec 2021, 10:28.

                Comment


                  #9
                  RIght, i was basically wondering what it is that makes a layout "top-level".
                  If i understand it correctly, in my case it is lying in a child splitpane as a detailpane. "Showing it top-level" in my instance would be removing it from its parent and calling bringtofront?

                  (Sorry if i'm thick, i haven't spent much time considering this stuff, my layouts have historically always kept static in their hiearchical places...)

                  Comment


                    #10
                    Something is “top level” if it simply doesn’t have a parent.

                    Amongst everything that is top level, zIndex controls what’s on top.

                    Comment


                      #11
                      OK, thanks. I would like to move over to a related topic, since i could reeeeaaally use some help, been struggling since yesterday.

                      ISSUE:
                      I have a problem in my "real" application that i cannot replicate in my test case. It is, like the test code above, a two-level nested splitpane with navigation trees inside them. In one of the child nodes, i have a Timeline.

                      So, the fullscreenbutton i have, which works fine in my test case, ONLY works in my "real" code if i don't resize it when i remove it from it's original position. If i resize it, this happens:

                      1. when i go "back" from fullscreen, the layout goes back to its original place.
                      2. HOWEVER, if click the fullscreen button again, i get an exception.
                      3. If i move the sub-splitpane to the other child, then back, i again get the same exception.

                      Again, the above only happens if i resize the layout, otherwise all is ok.

                      -----

                      I included the latest version of my testcase (which works...) for reference at the bottom. It has been changed around to try and move it closer to my "real" application code, but again, i have failed to make it crash in the same way. I have tried a 100 different variations of going in and out of fullscreen (adding to root, showing hiding all other components, redrawing multiple times etc etc), nothing affects the outcome.

                      Still, i hope that the exception and my description can help you get an idea about giving me some tips as to what i can do to sort this out.

                      EDIT: ADDITIONAL INFO:
                      1. If put an empty layout in instead, with just the fullscreen button, in the same place as the timeline layout, it works.
                      2. If i just have the timeline layout with fullscreen button under the root splitpane, it also works.


                      The error i get:
                      Code:
                      Uncaught TypeError: can't access property "textColor", e is null
                          isc_EventCanvas_updateCanvasColors http://127.0.0.1:8888/nw/sc/modules/ISC_Calendar.js?v=1:760
                          isc_EventCanvas_draw http://127.0.0.1:8888/nw/sc/modules/ISC_Calendar.js?v=1:732
                          isc_Canvas_drawChildren http://127.0.0.1:8888/nw/sc/modules/ISC_Core.js?v=1:3168
                          isc_Canvas_draw http://127.0.0.1:8888/nw/sc/modules/ISC_Core.js?v=1:3122
                          isc_c_Class_invokeSuper http://127.0.0.1:8888/nw/sc/modules/ISC_Core.js?v=1:321
                          isc_c_Class_Super http://127.0.0.1:8888/nw/sc/modules/ISC_Core.js?v=1:313
                          isc_GridRenderer_draw http://127.0.0.1:8888/nw/sc/modules/ISC_Grids.js?v=1:272
                          isc_c_Class_invokeSuper http://127.0.0.1:8888/nw/sc/modules/ISC_Core.js?v=1:321
                          isc_GridBody_draw http://127.0.0.1:8888/nw/sc/modules/ISC_Grids.js?v=1:827
                          isc_Layout_layoutChildren http://127.0.0.1:8888/nw/sc/modules/ISC_Foundation.js?v=1:365
                          isc_Layout_drawChildren http://127.0.0.1:8888/nw/sc/modules/ISC_Foundation.js?v=1:275
                          isc_Canvas_draw http://127.0.0.1:8888/nw/sc/modules/ISC_Core.js?v=1:3122
                          isc_Layout_layoutChildren http://127.0.0.1:8888/nw/sc/modules/ISC_Foundation.js?v=1:363
                          isc_ListGrid_layoutChildren http://127.0.0.1:8888/nw/sc/modules/ISC_Grids.js?v=1:1392
                          isc_Layout_drawChildren http://127.0.0.1:8888/nw/sc/modules/ISC_Foundation.js?v=1:275
                          isc_Canvas_draw http://127.0.0.1:8888/nw/sc/modules/ISC_Core.js?v=1:3122
                          isc_c_Class_invokeSuper http://127.0.0.1:8888/nw/sc/modules/ISC_Core.js?v=1:321
                          isc_ListGrid_draw http://127.0.0.1:8888/nw/sc/modules/ISC_Grids.js?v=1:1476
                          isc_c_Class_invokeSuper http://127.0.0.1:8888/nw/sc/modules/ISC_Core.js?v=1:321
                          isc_c_Class_Super http://127.0.0.1:8888/nw/sc/modules/ISC_Core.js?v=1:313
                          isc_CalendarView_draw http://127.0.0.1:8888/nw/sc/modules/ISC_Calendar.js?v=1:264
                          isc_c_Class_invokeSuper http://127.0.0.1:8888/nw/sc/modules/ISC_Core.js?v=1:321
                          isc_TimelineView_draw http://127.0.0.1:8888/nw/sc/modules/ISC_Calendar.js?v=1:454
                          isc_Layout_layoutChildren http://127.0.0.1:8888/nw/sc/modules/ISC_Foundation.js?v=1:365
                          isc_Layout_drawChildren http://127.0.0.1:8888/nw/sc/modules/ISC_Foundation.js?v=1:275
                          isc_Canvas_draw http://127.0.0.1:8888/nw/sc/modules/ISC_Core.js?v=1:3122
                          isc_Layout_layoutChildren http://127.0.0.1:8888/nw/sc/modules/ISC_Foundation.js?v=1:363
                          isc_Layout_drawChildren http://127.0.0.1:8888/nw/sc/modules/ISC_Foundation.js?v=1:275
                          isc_Canvas_draw http://127.0.0.1:8888/nw/sc/modules/ISC_Core.js?v=1:3122
                          isc_Canvas_drawChildren http://127.0.0.1:8888/nw/sc/modules/ISC_Core.js?v=1:3168
                          isc_Canvas_draw http://127.0.0.1:8888/nw/sc/modules/ISC_Core.js?v=1:3122
                          isc_c_Class_invokeSuper http://127.0.0.1:8888/nw/sc/modules/ISC_Core.js?v=1:321
                          isc_Calendar_draw http://127.0.0.1:8888/nw/sc/modules/ISC_Calendar.js?v=1:615
                          isc_Layout_layoutChildren http://127.0.0.1:8888/nw/sc/modules/ISC_Foundation.js?v=1:365
                          isc_Layout_drawChildren http://127.0.0.1:8888/nw/sc/modules/ISC_Foundation.js?v=1:275
                          isc_Canvas_draw http://127.0.0.1:8888/nw/sc/modules/ISC_Core.js?v=1:3122
                          isc_Layout_layoutChildren http://127.0.0.1:8888/nw/sc/modules/ISC_Foundation.js?v=1:363
                          isc_Layout_reflowNow http://127.0.0.1:8888/nw/sc/modules/ISC_Foundation.js?v=1:397
                          isc_c_Layout_clearReflowQueue http://127.0.0.1:8888/nw/sc/modules/ISC_Foundation.js?v=1:257
                          isc_c_Layout_reflowOnTEA http://127.0.0.1:8888/nw/sc/modules/ISC_Foundation.js?v=1:257
                          isc_c_EventHandler_runTeas http://127.0.0.1:8888/nw/sc/modules/ISC_Core.js?v=1:2602
                          isc_c_EventHandler__clearThread http://127.0.0.1:8888/nw/sc/modules/ISC_Core.js?v=1:2599
                          isc_c_EventHandler_dispatch http://127.0.0.1:8888/nw/sc/modules/ISC_Core.js?v=1:2604


                      TESTCASE:
                      Code:
                      package com.test;
                      
                      import com.google.gwt.core.client.EntryPoint;
                      import com.google.gwt.core.client.GWT;
                      import com.google.gwt.user.datepicker.client.CalendarUtil;
                      import com.smartgwt.client.types.SelectionStyle;
                      import com.smartgwt.client.types.TimeDisplayFormat;
                      import com.smartgwt.client.types.TimeUnit;
                      import com.smartgwt.client.types.Visibility;
                      import com.smartgwt.client.util.SC;
                      import com.smartgwt.client.widgets.Canvas;
                      import com.smartgwt.client.widgets.calendar.*;
                      import com.smartgwt.client.widgets.events.ClickEvent;
                      import com.smartgwt.client.widgets.events.ClickHandler;
                      import com.smartgwt.client.widgets.layout.Layout;
                      import com.smartgwt.client.widgets.layout.SplitPane;
                      import com.smartgwt.client.widgets.layout.VLayout;
                      import com.smartgwt.client.widgets.toolbar.ToolStrip;
                      import com.smartgwt.client.widgets.toolbar.ToolStripButton;
                      import com.smartgwt.client.widgets.tree.Tree;
                      import com.smartgwt.client.widgets.tree.TreeGrid;
                      import com.smartgwt.client.widgets.tree.TreeGridField;
                      import com.smartgwt.client.widgets.tree.TreeNode;
                      
                      import java.util.Date;
                      
                      public class TheTest implements EntryPoint {
                      
                          //these layouts are the ones used as details in the splitpanes
                          Layout fullscreenTest;
                          Layout placeHolderLayout;
                      
                          //topmost fullscreen canvas
                          Layout root;
                          SplitPane split;//root splitpane
                      
                          public void onModuleLoad() {
                      
                              placeHolderLayout = new Layout();
                              placeHolderLayout.setBackgroundColor("red");
                              placeHolderLayout.setVisibility(Visibility.INHERIT);
                      
                              fullscreenTest = createFullScreenTestLayout();
                              split = createMainSplitPane();
                      
                              root = new Layout();
                              root.setWidth100();
                              root.setHeight100();
                      
                              root.addMember(split);
                      
                              fullscreenTest.addMember(createFullScreenToolStrip(), 0);
                      
                              root.draw();
                          }
                      
                          private SplitPane createMainSplitPane() {
                      
                              TreeNode first = new TreeNode("First");
                              TreeNode second = new TreeNode("Second");
                              TreeNode[] nodes = new TreeNode[]{first, second};
                      
                              SplitPane details = createChildSplitPane();
                              TestLayout other = new TestLayout("green", "brown");
                      
                              DefaultTreeGrid grid = new DefaultTreeGrid("groot", nodes);
                              DefaultSplitPane main = new DefaultSplitPane("rootSplit", grid);
                              main.setNavigationPane(grid);
                      
                              grid.addRecordClickHandler(recordClickEvent -> {
                                  GWT.log("record!: " + recordClickEvent.getRecord().getAttribute("name"));
                                  main.setDetailPane(recordClickEvent.getRecord().getAttribute("name").equals("First") ? details : other);
                              });
                      
                              return main;
                          }
                      
                          private SplitPane createChildSplitPane() {
                              TreeNode third = new TreeNode("Third");
                              TreeNode fourth = new TreeNode("Fourth");
                              TreeNode[] nodes = new TreeNode[]{third, fourth};
                              TestLayout child2 = new TestLayout("black", "white");
                      
                              DefaultTreeGrid childGrid = new DefaultTreeGrid("gr2", nodes);
                              childGrid.setBodyBackgroundColor("cyan");
                      
                              SplitPane child = new DefaultSplitPane("childsplit", childGrid);
                              childGrid.addRecordClickHandler(recordClickEvent ->
                              {
                                  child.setDetailPane(recordClickEvent.getRecord().getAttribute("name").equals("Third") ? fullscreenTest : child2);
                              });
                      
                              return child;
                          }
                      
                          private Layout createFullScreenTestLayout() {
                      
                              Layout fullscreen = new VLayout();
                              fullscreen.setWidth100().setHeight100();
                              fullscreen.addMember(new SchedTimeline());
                              return fullscreen;
                          }
                      
                          public ToolStrip createFullScreenToolStrip() {
                              FullScreenButton button = new FullScreenButton(fullscreenTest);
                              ToolStrip strip = new ToolStrip();
                              strip.addButton(button);
                              return strip;
                          }
                      
                          public class DefaultSplitPane extends SplitPane {
                      
                              public DefaultSplitPane(String id, DefaultTreeGrid grid) {
                                  setID(id);
                                  setShowDetailToolStrip(false);
                                  setNavigationPane(grid);
                              }
                          }
                      
                          public class DefaultTreeGrid extends TreeGrid {
                      
                              public DefaultTreeGrid(String id, TreeNode[] nodes) {
                                  setID(id);
                                  Tree tree = new Tree();
                                  tree.setData(nodes);
                                  setSelectionType(SelectionStyle.SINGLE);
                                  setAlwaysShowScrollbars(true);
                                  TreeGridField nameField = new TreeGridField("name");
                                  nameField.setWidth("100%");
                                  setHeight100();
                                  setWidth100();
                                  setLeaveScrollbarGap(false);
                                  setData(tree);
                                  setFields(nameField);
                                  setShowSelectedIcons(true);
                                  setCanSort(false);
                                  setShowHeaderContextMenu(false);
                                  setShowHeader(false);
                              }
                          }
                      
                          class TestLayout extends VLayout {
                      
                              public TestLayout(String col, String border) {
                                  setBackgroundColor(col);
                                  if (border != null) {
                                      setBorder("5px solid " + border);
                                  }
                              }
                          }
                      
                          public class FullScreenButton extends ToolStripButton implements ClickHandler {
                      
                              Canvas layout;
                              Layout placeHolder;
                              boolean fullscreen = false;
                      
                              public FullScreenButton(Canvas layout) {
                                  super("Full screen");
                                  this.layout = layout;
                                  placeHolder = new VLayout();
                                  placeHolder.setBackgroundColor("red");
                                  layout.setBackgroundColor("white");
                                  layout.setBorder("5px solid brown");
                                  addClickHandler(this);
                              }
                      
                              @Override
                              public void onClick(ClickEvent clickEvent) {
                                  if (!fullscreen) goFullScreen();
                                  else exitFullScreen();
                              }
                      
                              private void goFullScreen() {
                                  try {
                                      fullscreen = true;
                                      setTitle("Go Back");
                                      try {
                                          ((Layout) layout.getParentCanvas()).replaceMember(layout, placeHolder);
                                      } catch (Exception e) {
                                          SC.say("error: " + e.getMessage());
                                      }
                                      layout.setSize("100%", "100%");///CANNOT DO THIS IN 'REAL' CODE
                                      layout.draw();
                                  } catch (Exception e) {
                                      GWT.log(e.toString());
                                      SC.say("error: " + e.getMessage());
                                  }
                                  //LayoutConf.mainLayout.setVisibility(Visibility.HIDDEN);
                              }
                      
                              private void exitFullScreen() {
                                  fullscreen = false;
                                  setTitle("FullScreen");
                                  ((Layout) placeHolder.getParentCanvas()).replaceMember(placeHolder, layout);
                                  layout.redraw();
                              }
                          }
                      
                          public class SchedTimeline extends Timeline {
                      
                              String userIdRestriction;
                      
                              public SchedTimeline() {
                                  super();
                                  this.userIdRestriction = userIdRestriction;
                                  setup();
                                  Date end = new Date();
                                  CalendarUtil.addMonthsToDate(end, 1);
                                  setStartDate(new Date()).setEndDate(end);
                              }
                      
                              private void setup() {
                                  setWidth100().setHeight100();
                                  setShowLaneRollOver(false);//this would have displayed a ribbon on the lane the mouse hovered over. It still shows when popups appear which is jarring, so we've turned it off
                                  setShowQuickEventDialog(false);
                                  int[] workdays = {1,2,3,4,5,6,7};
                                  setWorkdays(workdays);
                                  setDisableWeekends(false);
                      
                                  setCanEditLane(true);
                                  setShowEventDescriptions(true);
                                  setLaneNameField("userid");//this is what must match the "id" values for the lane data
                      
                                  setDataPageSize(4000);//this controls the "limit" parameter sent to the server, i.e. how many rows that will be fetched.
                      
                                  setStartDateField("intime");
                                  setEndDateField("outtime");
                                  setNameField("locname");
                                  setShowEventDescriptions(true);
                                  setDescriptionField("note");
                                  setMinLaneWidth(130);
                                  setTimeFormatter(TimeDisplayFormat.TOSHORTPADDED24HOURTIME);
                      
                                  setHeaderLevels(getDayHeaderLevels());
                                  setLaneEventPadding(2);
                                  setCanRemoveEvents(false);
                      
                      
                                  setEventStyleName("schedWin");
                                  /*setEventBodyHTMLCustomizer(new EventBodyHTMLCustomizer() {
                                      @Override
                                      public String getEventBodyHTML(CalendarEvent calendarEvent, CalendarView calendarView) {
                                          return WebConstants.timeFormat.format(calendarEvent.getAttributeAsDate(CSConstants.FIELD_INTIME)) + " - " + WebConstants.timeFormat.format(calendarEvent.getAttributeAsDate(CSConstants.FIELD_OUTTIME));
                                      }
                                  });*/
                                  setEventHeaderHTMLCustomizer(new EventHeaderHTMLCustomizer() {
                                      @Override
                                      public String getEventHeaderHTML(CalendarEvent calendarEvent, CalendarView calendarView) {
                                          return "Scooby doo";
                                      }
                                  });
                              }
                      
                              public HeaderLevel[] getDayHeaderLevels() {
                      
                                  HeaderLevel week = new HeaderLevel(TimeUnit.WEEK);
                                  week.setHeaderWidth(100);
                                  return new HeaderLevel[]{
                                      week, new DayHeaderLevel(100)
                                  };
                              }
                          }
                      
                          public class DayHeaderLevel extends HeaderLevel {
                      
                              public DayHeaderLevel(int width) {
                                  super(TimeUnit.DAY);
                                  setHeaderWidth(width);
                              }
                          }
                      }
                      Last edited by mathias; 29 Dec 2021, 07:04.

                      Comment


                        #12
                        There was an order of operations bug in EventCanvas logic - updateCanvasColors() is called from draw(), in this case unnecessarily, since it was being invoked before the canvas had been assigned an event (during pooling modifications as a result of drawing after a hide and resize).

                        We've fixed that bug back to 12.1 - if this crash was your only remaining issue, you should find it addressed in builds dated December 31 and later.

                        If not, please confirm the framework versions/build-dates of the test and live environments.
                        Last edited by Isomorphic; 29 Dec 2021, 23:24.

                        Comment


                          #13
                          That's great! Sounds plausible to me, since it works when i use a Timeline that doesn't have any events.

                          Waiting eagerly for new build - happy new year!

                          Comment


                            #14
                            A quick follow-up on this - we tracked down exactly how your usage was ending up hitting this problem, and we've fixed that underlying issue as well, for tomorrow's builds.

                            Builtin framework logic in this example flow was causing an unexpected extra draw for all EventCanvases, including ones that were currently in the pool and not attached to any CalendarEvent - so, as a happy aside, this fix doubles up as a minor render-time optimization.
                            Last edited by Isomorphic; 30 Dec 2021, 03:29.

                            Comment


                              #15
                              Great stuff, I'll take it! :)

                              Comment

                              Working...
                              X