Search code examples
qooxdoo

Create responsive Qooxdoo HBox layout where widgets don't show without enough space


How can I create with Qooxdoo a user resizeable Window where the content is made out of a few widgets (e.g. Labels) where the display of some is disabled when the space isn't enough?

Example:
I have the three labels "unimportant" (right aligned), "very important" (left aligned) and "must have" (right) in the HBox. Any extra space should go just right of the left most label to keep the alignment requirements.
In ASCII art this would look like:

--------------------------------------------------------
|very important|                 |unimportant|must have|
--------------------------------------------------------

-----------------------------------------------
|very important|        |unimportant|must have|
-----------------------------------------------

--------------------------------------
|very important|unimportant|must have|
--------------------------------------

-------------------------------
|very important|    |must have|
-------------------------------
                                         <-- making the window smaller
--------------------------
|very important|must have|
--------------------------

-------------------
|       |must have|
-------------------

-----------
|must have|
-----------

The minimal width of the Window would be the space that "must have" requires.

Bonus question: the "unimportant" would actually be a label for "must have" which can be a widget that takes more vertical space. So both should be centered to each other, something that an Atom with those two might be normally used for.


Solution

  • Don't like implementation but it does work as intended:

    const mainBar = new qx.ui.container.Composite(new qx.ui.layout.HBox());
    
    // sub bar for right and center labels
    const subBar = new qx.ui.container.Composite(new qx.ui.layout.HBox());
    subBar.setMinWidth(0);// this line is important
    
    // left static label
    const left = new qx.ui.basic.Atom("very important");
    subBar.add(left);
    
    // center label has a minor priority
    const center = new qx.ui.container.Composite(new qx.ui.layout.HBox());
    const dummy = new qx.ui.basic.Atom();
    center.add(dummy, {flex: 1});
    const centerLabel = new qx.ui.basic.Atom("unimportant");
    center.add(centerLabel);
    subBar.add(center, {flex: 1});
    mainBar.add(subBar, {flex: 1});
    
    const right = new qx.ui.form.Button("must have");
    mainBar.add(right);
    
    const win = new qx.ui.window.Window().set({width: 600, height: 100});
    win.setLayout(new qx.ui.layout.Grow());
    win.add(mainBar);
    win.setUseResizeFrame(false);
    win.open();
    
    const defaultLeftWidth = left.getSizeHint().width;
    const defaultCenterWidth = center.getSizeHint().width;
    win.addListener("resize", function(){
      this.info(center.getBounds().width, defaultCenterWidth);
      if (center.getBounds().width <= defaultCenterWidth){
        centerLabel.setVisibility("hidden");
      } else {
        centerLabel.setVisibility("visible");
      }
      
      if (subBar.getBounds().width < defaultLeftWidth){
        left.setVisibility("hidden");
      } else {
        left.setVisibility("visible");
      }
    }, this);
    
    // Document is the application root
    const doc = this.getRoot();
    
    // Add button to document at fixed coordinates
    doc.add(win,
    {
      left : 100,
      top  : 50
      
    });