Announcement

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

    How can one use layoutMargin=0 on Window while reaining ability to resize

    I am using a custom skin that sets :

    isc.Window.addProperties({
    layoutMargin:0
    });

    I get the appearance that I want but I can drag click to resize.

    If I use a margin of 1 or 2 the resize area gets so small that it is very difficult to resize.

    I would like to set a larger resize area, ideally over window content.

    Is is possible?

    Thanks.

    #2
    There are a few ways to do this, but consider that doing this is going to mean that the user cannot click or mouseOver anything that happens to be right in the corner, which can be either a mild annoyance or in some rare cases, block functionality.

    Two ways to do it if you decide to anyway:

    1. add a "resizer" element, similar to one that will show with the Window footer if you set showFooter:true. Just add a child (not member) of the Window and use Canvas.snapTo positioning to place it flush in the corner. Set its dragTarget to the Window.

    2. configure the "body" AutoChild, which is now flush to the Window edge, with dragTarget:theWindow, canDragResize:true and set window.resizeFrom to whatever you like to control what edges or corners will show a resize cursor.

    Comment


      #3
      Thanks for the tips.

      I tried the suggestion #2 first.

      Code:
      Canvas body = getBody();
      body.setDragTarget(this);
      body.setCanDragResize(true);
      this.setResizeFrom(EdgeName.BR, EdgeName.B, EdgeName.R);
      It did not work. Apparently this makes the body itself a resizer for the window. But when the mouse is over some widget near the edge (within the window body) it does not resize.

      So I guessed I should go for suggestion #1.

      The ideia here is to add and set the position of a transparent canvas to work as resizer. Is this understanding correct?

      This worked partially.

      To be able to resize across the whole edge I needed to create 4 resize canvas and set size and position on the edge regions. Widgets behind these elemens will become "shadowed" / not clickable. Correct?

      Here is my code:

      Code:
      public class ResizableWindow extends Window {
      	// just for testing. the real value is aprox. 6
      	private static final int RESIZE_AREA_SIZE = 15;
      
      	public ResizableWindow() {
      		Canvas resizerR = createBaseResizer();
      		resizerR.setResizeFrom(EdgeName.R);
      		resizerR.setSnapTo("R");
      		resizerR.setHeight("100%");
      		resizerR.setWidth(RESIZE_AREA_SIZE);
      		addChild(resizerR);
      
      		Canvas resizerL = createBaseResizer();
      		resizerL.setResizeFrom(EdgeName.L);
      		resizerL.setSnapTo("L");
      		resizerL.setHeight("100%");
      		resizerL.setWidth(RESIZE_AREA_SIZE);
      		addChild(resizerL);
      
      		Canvas resizerB = createBaseResizer();
      		resizerB.setResizeFrom(EdgeName.B, EdgeName.BR);
      		resizerB.setSnapTo("B");
      		resizerB.setWidth("100%");
      		resizerB.setHeight(RESIZE_AREA_SIZE);
      		addChild(resizerB);
      
      		Canvas resizerT = createBaseResizer();
      		resizerT.setResizeFrom(EdgeName.T, EdgeName.TL);
      		resizerT.setSnapTo("T");
      		resizerT.setHeight(RESIZE_AREA_SIZE);
      		resizerT.setWidth("100%");
      		addChild(resizerT);
      		
      
      		this.setKeepInParentRect(true);
      		this.setAutoSize(false);
      		this.setCanDragResize(true);
      		this.setCanDragReposition(true); 
      		this.setShowMaximizeButton(true);		
      		this.setCanDrag(true);
      		this.setShowCloseButton(false);
      	}
      
      	private Canvas createBaseResizer() {
      		Canvas resizer = new Canvas();
      		resizer.setBackgroundColor("red"); // for testing only
      		resizer.setOpacity(20);
      		resizer.setEdgeMarginSize(6);
      		resizer.setDragTarget(this);
      		resizer.setCanDragResize(true);
      		resizer.setCanDragReposition(false);
      		return resizer;
      	}
      I am having some problems with this:


      1. Only part of the resizer canvas is actualy resizable (noticed by cursor change and effectiveness). The remaining (non resizable) part of the it becomes a broken drag movable area. It draws the outline of the moving window while draging but when drop the window remain where it was. So I guess I need to resize these areas strictly to the resizing area I need. Right?

      2. But, when using RESIZE_AREA_SIZE=6, setHeight(6) and setSnapTo("T" or "B") make it 15px height. How can I make it 6px height and snap to a edge without affecting height?

      3. Even after setting setEdgeMarginSize(RESIZE_AREA_SIZE), the resizable area is usually smaller. for instance the left resizer the resizable area becomes 1 pixel wide. How can I make the whole canvas area to be a resizer?

      Thanks again.

      For completeness here are the relevant load_skin.js lines and css rules.


      Code:
                  isc.Window.addProperties({
                      backgroundColor:null,
                      bodyStyle:"windowBody",
      //                layoutBottomMargin:3,
      //                layoutLeftMargin:3,
      //                layoutRightMargin:3,
      //                layoutTopMargin:1,
                      layoutMargin:1,
                      modalMaskOpacity:10,
                      membersMargin:0,
                      styleName:"windowBackground",
                      showHeaderBackground:false,
                      showFooter:false
                  });
      
                  isc.Window.changeDefaults("headerDefaults", {
                      height:30,
                      layoutMargin:0,
                      layoutLeftMargin:4,
                      membersMargin:2,
                  });
      
                  isc.Window.changeDefaults("resizerDefaults", { src:"[SKIN]/Window/resizer.png" });
      
                  isc.Window.changeDefaults("headerIconDefaults", {
                      height:15,
                      src:"[SKIN]/Window/headerIcon.png",
                      width:15
                  });
      
                  isc.Window.changeDefaults("restoreButtonDefaults", {
                      height:30,
                      showDown:false,
                      showRollOver:true,
                      src:"[SKIN]/headerIcons/cascade.png",
                      width:28
                  });
      
                  isc.Window.changeDefaults("closeButtonDefaults", {
                      height:30,
                      showDown:false,
                      showRollOver:true,
                      src:"[SKIN]/headerIcons/close.png",
                      width:28
                  });
      
                  isc.Window.changeDefaults("maximizeButtonDefaults", {
                      height:30,
                      showRollOver:true,
                      src:"[SKIN]/headerIcons/maximize.png",
                      width:28
                  });
      
                  isc.Window.changeDefaults("minimizeButtonDefaults", {
                      height:30,
                      showDown:false,
                      showRollOver:true,
                      src:"[SKIN]/headerIcons/minimize.png",
                      width:28
                  });
      Code:
      .windowBackground {
        background: white;
        /*border: 1px solid white;*/
        box-shadow: 0px 0px 5px #999;
      }
      
      .windowBody,
      .dialogBody {
        background-color: #b4b4b4;
      }
      
      .windowHeader,
      .dialogHeader {
        padding: 0;
        background: b4b4b4;
      }
      Attached Files

      Comment


        #4
        Yes, it's expected that the #2 suggestion would only work with a body that isn't filled with child widgets that likewise reach the edge of the Window. You could extend the approach to *also* make the child widgets of the body draggable and delegating to the Window as dragTarget, but that gets messy.

        As far as #1, from a UI perspective our suggestion would actually be not to eliminate the Window trim in the first place :) Second choice would be to emulate MacOSX Safari, and place a visible resizer (similar to the one in the Window footer, as we mentioned) in the bottom right corner only.

        Making all edges of the Window into invisible resize regions is much more likely to cover up some important piece of functionality, leading to broken apps or user annoyance at having to click very precisely to hit an interactive area that is partially covered by your resize regions.

        As far as what's wrong with your code:

        1. edgeMarginSize controls how large the area is where the user can click to resize. It defaults to 5, you need to make it match RESIZE_AREA_SIZE.

        2. set overflow:hidden, otherwise your invisible resizers will be auto-size to the default content, which is  

        The interaction between having a larger size than you intended and not properly setting edgeMarginSize is what creates the issue where some areas are non-interactive.

        Comment


          #5
          Thanks for the comments.

          I forgot to use the constant in setEdgeMarginSize.

          I have fixed the pointed issues and apparently get the sizes and positions right.

          Unfortunately I am still having non interactive areas in my resizers. Mainly on top and left resizers where I have only 1px of effective resizer area (the remaining area don't change cursor to resize on hover and have that odd broken window move behavior).

          Do you think this current issue has something to do with element stacking? I can see there basically all elements inside the window are over my resizers (higher on the stack). Can this be the cause? If so, what is the proper way to make these resizers on top of everything else inside that window?

          Comment


            #6
            Yes, if the zIndex for the Window's other children (such as the body) is higher, then that's the problem.

            bringToFront() is the right way to bring a component to the front (relative to it's siblings).

            Adding a DrawHandler and only creating the your resizers at draw time is also a way to solve this (components created later have higher zIndex as a default) and avoids doing work earlier than is necessary.

            Comment


              #7
              Hello zatix, Isomorphic,

              I am trying to achieve exactly the same in my application and I replicated the same technique described here, including the call to bringToFront() of the resizers.
              I can confirm all the resizers have large z-indexes and yet I still experience exactly the same behavior zatix described above - the right and bottom resizers work perfect, I only get 1px of 'apparently' effective resizer area on the top and left.
              I wrote 'apparently' above because this is actually only related to the cursor - if I ignore the cursor and try to drag from the resizer area it works perfectly.

              zatix - I am wondering whether you have managed to resolve that issue eventually?
              Isomorphic - any other suggestions\ideas what might cause that difference between the right\bottom resizers and the left\top ones?

              Thanks
              Gil
              Last edited by gedri; 21st Nov 2019, 01:23.

              Comment


                #8
                Your left/top resizers are most likely simply not where you intended to put them, or not the right size. Use the Watch tab of the Developer Console to find out.

                Comment


                  #9
                  The resizers are positioned and sized correctly as can be illustrated in this screenshot (the resizeres are colored opaque red as in zatix's example above).

                  Click image for larger version  Name:	2019-11-22_103800.png Views:	0 Size:	29.3 KB ID:	260108

                  Comment


                    #10
                    Hi Isomorphic,
                    I also created a basic example that can be played in the feature explorer that shows this problem.
                    Here is the code - notice how the resize cursor appears correctly over the right and bottom resizers and not on the left and top ones.

                    Code:
                    var window = isc.Window.create({
                      title: "Window with resizers",
                      width: 300, height: 200,
                      canDragResize: true,
                      canDragReposition: true,
                      edgeMarginSize: 10,
                      items: [
                        {
                          backgroundColor: "blue", opacity: 20, // for testing only            
                          height: "100%",
                        }
                      ]
                    });
                    
                    var resizerL = isc.Canvas.create({
                      backgroundColor: "red", opacity: 20, // for testing only
                      overflow: "hidden",
                      edgeMarginSize: 10,
                      dragTarget: window,
                      canDragResize: true,
                      resizeFrom: "L",
                      snapTo: "L", height: "100%", width: 10
                    });
                    window.addChild(resizerL);
                    resizerL.bringToFront();
                    
                    var resizerR = isc.Canvas.create({
                      backgroundColor: "red", opacity: 20, // for testing only
                      overflow: "hidden",
                      edgeMarginSize: 10,
                      dragTarget: window,
                      canDragResize: true,
                      resizeFrom: "R",
                      snapTo: "R", height: "100%", width: 10
                    });
                    window.addChild(resizerR);
                    resizerR.bringToFront();
                    
                    var resizerT = isc.Canvas.create({
                      backgroundColor: "red", opacity: 20, // for testing only
                      overflow: "hidden",
                      edgeMarginSize: 10,
                      dragTarget: window,
                      canDragResize: true,
                      resizeFrom: ["T", "TL", "TR"],
                      snapTo: "T", height: 10, width: "100%"
                    });
                    window.addChild(resizerT);
                    resizerT.bringToFront();
                    
                    
                    var resizerB = isc.Canvas.create({
                      backgroundColor: "red", opacity: 20, // for testing only
                      overflow: "hidden",
                      edgeMarginSize: 10,
                      dragTarget: window,
                      canDragResize: true,
                      resizeFrom: ["B", "BL", "BR"],
                      snapTo: "B", height: 10, width: "100%"
                    });
                    window.addChild(resizerB);
                    resizerB.bringToFront();
                    Thanks

                    Comment


                      #11
                      We're looking into into this now.

                      Comment


                        #12
                        This is actually not a Framework bug, but the result of the default setting of Window.resizeFrom. Unlike generic Canvii, which have a null default, allowing any edge resize, Window.resizeFrom defaults to ["R", "B", "BR"], consistent with your observation. So to fix your code you just need to add resizeFrom: null to the Window constructor like this:

                        Code:
                        var window = isc.Window.create({
                          title: "Window with resizers",
                          width: 300, height: 200,
                          canDragResize: true,
                          canDragReposition: true,
                          edgeMarginSize: 10,
                          resizeFrom: null, // *** added line
                          items: [
                            {
                              backgroundColor: "blue", opacity: 20, // for testing only            
                              height: "100%",
                            }
                          ]
                        });
                        We'll make sure the special Window default value is documented, and are discussing the fact that it can't be overridden by other Canvii that have the Window as a dragTarget, but for now just remember that resizeFrom on the dragTarget needs to be configured appropriately.

                        Comment

                        Working...
                        X