2016-07-02 7 views
5

Wie kann ich die Größe eines bestimmten Knotens in xul Fenster ändern, wenn ein Splitter gezogen wird? Die Attribute resizebefore/resizeafter können aufgrund der Komplexität des xul-Fensters nicht verwendet werden.Splitter - Größe spezifischen Knoten ändern

Ich habe versucht, ondrag Ereignis auf Splitter zu verwenden, aber es feuert überhaupt nicht. ondragstart Event feuert gut und ich kann event.offsetY verwenden, um zu erfassen, wie viele Pixel der Splitter bewegte. Mit diesem Wert könnte ich es auf die Höhe der Notwendigkeit Element hinzufügen, was gut funktioniert, aber leider wird dieses Ereignis nur einmal pro Drag-Sitzung ausgelöst.

Irgendwelche Ideen?

Vielen Dank.

Ein Beispiel, um es zu testen. Aufgrund der Komplexität meiner ursprünglichen xul ich nicht die xul Struktur verändern kann, (Benutzer kann Reihenfolge der Zeilen verstecken und ändern) so wahrscheinlich nur Javascript-Lösung ist lebensfähig):

<?xml version="1.0"?> 

<?xml-stylesheet href="chrome://global/skin/" type="text/css"?> 

<window id="testWindow" 
      title="testing resizing element by splitter" 
      xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" 
      style="color: white;" 
> 
    <vbox id="resizeme" flex="1" style="background-color: yellow; color: black;"> 
    <hbox flex="1"> 
     <label value="#1"/> 
     <hbox flex="1" align="center" pack="center"> 
     <label value="Resizable by top and bottom splitter"/> 
     </hbox> 
    </hbox> 
    </vbox> 
    <splitter tooltiptext="Top splitter"/> 
    <grid flex="1"> 
    <columns> 
     <column/> 
     <column flex="1"/> 
    </columns> 
    <rows> 
     <row style="background-color: black;"> 
     <label value="#2"/> 
     <vbox flex="1" pack="center" align="center"> 
     <label value="Must stay constant size at all times"/> 
     </vbox> 
     </row> 
     <row flex="1" style="background-color: blue;"> 
     <label value="#3"/> 
     <vbox flex="1" pack="center" align="center"> 
      <label value="Resizable by top splitter only"/> 
     </vbox> 
     </row> 
     <row style="background-color: black;"> 
     <label value="#4"/> 
     <hbox flex="1" pack="center" align="center"> 
      <label value="Must stay constant size at all times, content must fit"/> 
      <button label="blah"/> 
     </hbox> 
     </row> 
     <splitter tooltiptext="Bottom splitter"/> 
     <row flex="1" style="background-color: green;"> 
     <label value="#5"/> 
     <vbox flex="1" pack="center" align="center"> 
     <label value="Resizable by bottom splitter only"/> 
     </vbox> 
     </row> 
     <row style="background-color: black;"> 
     <label value="#6"/> 
     <vbox flex="1" pack="center" align="center"> 
     <label value="Must stay constant size at all times"/> 
     </vbox> 
     </row> 
    </rows> 
    </grid> 
</window> 
+0

Ok, hinzugefügt Beispiel. – vanowm

+0

Mein Fehler, beide Beispiele durcheinander gebracht ... jetzt behoben. Beide Splitter sollten die Größe der gelben Box ändern, der obere Splitter sollte jedoch nur die blaue Zeile und der untere Splitter nur die grüne Zeile betreffen. Seitliche Notiz, es gibt ein merkwürdiges Verhalten passiert, wenn nach dem Öffnen Xul-Datei und Verschieben Bottom Splitter nach oben springt, unerwartete Größe der schwarzen # 4 Zeile. – vanowm

Antwort

1

Es gibt keine Lager Art und Weise einen bestimmten Knoten zu spezifizieren für eine <splitter> Größe zu ändern.

Wie bei allen Größenänderung in XUL, die Absicht ist, dass Sie in der Lage sein sollten Ihre XUL so codieren, dass Sie die Benutzeroberfläche Ihres Layouts die Größe haben kann, oder einen inneren Teil davon <splitter> Elemente verwenden, automatisch, ohne Es muss JavaScript aktiviert sein, damit Sie Ereignisse anhören und die Größenänderung durchführen können. Sie können jedoch sicher sein, dass Ihre JavaScript die <splitter> Größenanpassung durchführt. Sie würden das im Allgemeinen tun, wenn Sie etwas komplexes tun, Sie haben einen der Fehler in der <splitter> Implementierung kennengelernt, Sie finden es einfach einfacher als Feinabstimmung Ihres XUL, um die Aktienfunktionalität zu verwenden, oder wenn Sie nur wollen vollständige Kontrolle über das Schreiben Ihres eigenen Codes. Der Punkt ist, dass die <splitter> und das zugrunde liegende System die gesamte Größe für Sie durchführen soll.

Die Elemente <splitter> haben jedoch erhebliche Einschränkungen und einige Fehler, die dazu führen können, dass Sie Ihren eigenen Code zur Größenänderung schreiben müssen. Zu diesen Einschränkungen gehören:

  • Die flex Eigenschaft ist überlastet. Es wird verwendet, um zu steuern, wie Objekte zuerst platziert werden, wie sie in der Größe geändert werden, wenn das Fenster in der Größe geändert wird, und wie sie von allen <splitters> in der Größe geändert werden. Es ist durchaus möglich, dass in jedem Fall unterschiedliche Dinge passieren sollen.
  • Es gibt Fehler im Bestand <splitter> Code. Ich habe mindestens ein paar verschiedene beobachtet, darunter auch einige, bei denen Elemente, die explizit als nicht flexibel deklariert sind, immer noch in der Größe geändert werden. IIRC, scheinen diese am meisten zu sein, wenn man versucht, einen <splitter> zu benutzen, der innerhalb eines Behälters ist, um die Größe eines Gegenstandes zu ändern, der dieses Behälter übergroß ist.
  • Es ist nicht möglich, die Elemente, die die <splitter> Größe ändern soll, explizit anzugeben (z. B. nach ID).

[I wurde über weitere Einschränkungen zu denken, aber ich erinnere sie nicht im Moment.]

Wenn Sie JavaScript verwenden werden Ihre eigene Verarbeitung zu tun, es scheint, dass Sie das müssen implementieren Funktionalität vollständig durch Hören auf mouse events. Die Bewegung eines scheint nicht zu feuern drag events.Ich nehme an, dass dies daran liegt, dass das Verschieben einer nicht als Teil einer "Drag-and-Drop" -Aktion betrachtet wird (d. H. Sie nehmen sie nicht tatsächlich auf und legen sie auf ein Drop-Ziel). Während ich erwartete, die Drag-Events zu hören, ist es klar, dass sie nicht feuern.

Für mich ist die wichtigste Funktionalität, die in <splitters> fehlt, die fehlende Möglichkeit, nach ID die zwei Elemente zu spezifizieren, die in der Größe geändert werden sollen. Offensichtlich ist aus dem Titel Ihrer Frage klar, dass dies auch Ihnen fehlt.

Hinzufügen einer ID zu <splitter> Angabe:

Die folgenden Code implementiert und stellt ein Beispiel der Verwendung, <splitter> Elemente, die die ID der Elemente angeben, die in den resizebefore und resizeafter Attribute innerhalb der XUL Größe verändert werden .

Um es auf einen bestimmten <splitter> zu verwenden, müssen Sie eine der öffentlichen Funktionen aufrufen, die <splitter> entweder mit dem <splitter> ‚s ID oder das <splitter> Element zu registrieren. Zum Beispiel werden die beiden <spliter> Elemente im Beispiel XUL (etwas von dem Code in Ihrer Frage geändert) registriert mit:

splitterById.registerSplitterById("firstSplitter"); 
splitterById.registerSplitterById("secondSplitter"); 

splitterById.js:

/****************************************************************************** 
* splitterById                * 
*                    * 
* XUL <splitter> elements which are registered will resize only the two  * 
* specific elements for which the ID is contained in the <splitter>'s   * 
* resizebefore and resizeafter attributes. The orient attribute is used to * 
* specify if the <splitter> is resizing in the "vertical" or "horizontal"  * 
* orientation. "vertical" is the default.          * 
*                    * 
* For a particular <splitter> this is an all or nothing choice. In other  * 
* words, you _must_ specify both a before and after element (e.g. You can not * 
* mix using an ID on the resizebefore and not on resizeafter with the   * 
* expectation that the after will be resized with the normal <splitter>  * 
* functionality.                * 
*                    * 
* On both elements, the attributes minheight, maxheight, minwidth, and  * 
* maxwidth will be obeyed. It may be necessary to explicitly set these  * 
* attributes in order to prevent one or the other element from growing or  * 
* shrinking when the other element is prevented from changing size by other * 
* XUL UI constraints. For example, an element can not be reduced in size  * 
* beyond the minimum needed to display it. This code does not check for these * 
* other constraints. Thus, setting these attributes, at least the ones  * 
* specifying the minimum height or minimum width will almost always be  * 
* desirable.                 * 
*                    * 
* Public methods:                * 
* registerSplitterById(id) : registers the <splitter> with that ID   * 
* registerSplitterByElement(element) : registers the <splitter> element  * 
* unregisterSplitterById(id) : unregisters the <splitter> with that ID  * 
* unregisterSplitterByElement(element) : unregisters the <splitter> element * 
*                    * 
******************************************************************************/ 

var splitterById = (function(){ 

    let beforeER = {}; 
    let afterER = {}; 
    let splitIsVertical = true; 
    let origClientY = -1; 
    let origClientX = -1; 

    function ElementRec(_el) { 
     this.element = _el; 
     this.origHeight = getElementHeight(_el); 
     this.origWidth = getElementWidth(_el); 
     //The .minHeight and .maxHeight attributes/properties 
     // do not appear to be valid when first starting, so don't 
     // get them here. 
     //this.minHeight = getMinHeightAsValue(_el); 
     //this.maxHeight = getMaxHeightAsValue(_el); 
    } 
    function getElementHeight(el) { 
     //.height can be invalid and does not indicate the actual 
     // height displayed, only the desired height. 
     let boundingRec = el.getBoundingClientRect(); 
     return boundingRec.bottom - boundingRec.top; 
    } 
    function getElementWidth(el) { 
     //.width can be invalid and does not indicate the actual 
     // width displayed, only the desired width. 
     let boundingRec = el.getBoundingClientRect(); 
     return boundingRec.right - boundingRec.left; 
    } 
    function getMaxHeightAsValue(el) { 
     return asValueWithDefault(el.maxHeight,99999999); 
    } 
    function getMinHeightAsValue(el) { 
     return asValueWithDefault(el.minHeight,0); 
    } 
    function getMaxWidthAsValue(el) { 
     return asValueWithDefault(el.maxHeight,99999999); 
    } 
    function getMinWidthAsValue(el) { 
     return asValueWithDefault(el.minHeight,0); 
    } 
    function asValueWithDefault(value,myDefault) { 
     if(value === null || value === "" || value === undefined) { 
      value = myDefault; 
     } 
     //What is returned by the various attributes/properties is 
     // usually text, but not always. 
     value++; 
     value--; 
     return value; 
    } 
    function storeSplitterStartingValues(el) { 
     //Remember if the splitter is vertical or horizontal, 
     // references to the elements being resized and their initial sizes. 
     splitIsVertical = true; 
     if(el.getAttribute("orient") === "horizontal") { 
      splitIsVertical = false; 
     } 
     beforeER=new ElementRec(document.getElementById(el.getAttribute("resizebefore"))); 
     afterER=new ElementRec(document.getElementById(el.getAttribute("resizeafter"))); 
     if(beforeER.element === undefined || afterER.element === undefined) { 
      //Did not find one or the other element. We must have both. 
      return false; 
     } 
     return true; 
    } 
    function mousedownOnSplitter(event) { 
     if(event.button != 0) { 
      //Only drag with the left button. 
      return; 
     } 
     //Remember the mouse position at the start of the resize. 
     origClientY = event.clientY; 
     origClientX = event.clientX; 
     //Remember what we are acting upon 
     if(storeSplitterStartingValues(event.target)) { 
      //Start listening to mousemove and mouse up events on the whole document. 
      document.addEventListener("mousemove",resizeSplitter,true); 
      document.addEventListener("mouseup",endResizeSplitter,true); 
     } 
    } 
    function endResizeSplitter(event) { 
     if(event.button != 0) { 
      //Only drag with the left button. 
      return; 
     } 
     removeResizeListeners(); 
    } 
    function removeResizeListeners() { 
     //Don't listen to document mousemove, mouseup events when not 
     // actively resizing. 
     document.removeEventListener("mousemove",resizeSplitter,true); 
     document.removeEventListener("mouseup",endResizeSplitter,true); 
    } 
    function resizeSplitter(event) { 
     //Prevent the splitter from acting normally: 
     event.preventDefault(); 
     event.stopPropagation(); 

     //Get the new size for the before and after elements based on the 
     // mouse position relative to where it was when the mousedown event fired. 
     let newBeforeSize = -1; 
     let newAfterSize = -1; 
     if(splitIsVertical) { 
      newBeforeSize = beforeER.origHeight + (event.clientY - origClientY); 
      newAfterSize = afterER.origHeight - (event.clientY - origClientY); 
     } else { 
      newBeforeSize = beforeER.origWidth + (event.clientX - origClientX); 
      newAfterSize = afterER.origWidth - (event.clientX - origClientX); 
     } 

     //Get any maximum and minimum sizes defined for the elements we are changing. 
     //Get these here because they may not have been populated/valid 
     // when the drag was first initiated (i.e. we should have been able 
     // to do this only once when the mousedown event fired, but testing showed 
     // the values are not necessarily valid at that time. 
     let beforeMinSize; 
     let beforeMaxSize; 
     let afterMinSize; 
     let afterMaxSize; 
     if(splitIsVertical) { 
      beforeMinSize = getMinHeightAsValue(beforeER.element); 
      beforeMaxSize = getMaxHeightAsValue(beforeER.element); 
      afterMinSize = getMinHeightAsValue(afterER.element); 
      afterMaxSize = getMaxHeightAsValue(afterER.element); 
     } else { 
      beforeMinSize = getMinWidthAsValue(beforeER.element); 
      beforeMaxSize = getMaxWidthAsValue(beforeER.element); 
      afterMinSize = getMinWidthAsValue(afterER.element); 
      afterMaxSize = getMaxWidthAsValue(afterER.element); 
     } 

     //Apply the limits to sizes we want to change to. 
     //These do appear to work better sequentially rather than optimized. 
     if(newBeforeSize < beforeMinSize) { 
      //Set to beforeMinSize limit if have passed. 
      let diff = beforeMinSize - newBeforeSize; 
      newBeforeSize += diff; 
      newAfterSize -= diff; 
     } 
     if(newBeforeSize > beforeMaxSize) { 
      //Set to beforeMaxSize limit if have passed. 
      let diff = beforeMaxSize - newBeforeSize; 
      newBeforeSize += diff; 
      newAfterSize -= diff; 
     } 
     if(newAfterSize < afterMinSize) { 
      //Set to afterMinSize limit if have passed. 
      let diff = afterMinSize - newAfterSize; 
      newAfterSize += diff; 
      newBeforeSize -= diff; 
     } 
     if(newAfterSize > afterMaxSize) { 
      //Set to afterMaxSize limit if have passed. 
      let diff = afterMaxSize - newAfterSize; 
      newAfterSize += diff; 
      newBeforeSize -= diff; 
     } 

     //Don't make any changes if we are still violating the limits. 
     //There are some pathological cases where we could still be violating 
     // a limit (where limits are set such that it is not possible to have 
     // a valid height). 
     if(newBeforeSize < beforeMinSize || newBeforeSize > beforeMaxSize 
      || newAfterSize < afterMinSize || newAfterSize > afterMaxSize) { 
      return; 
     } 

     //Make the size changes 
     if(splitIsVertical) { 
      beforeER.element.height = newBeforeSize; 
      afterER.element.height = newAfterSize; 
     } else { 
      beforeER.element.width = newBeforeSize; 
      afterER.element.width = newAfterSize; 
     } 
    } 
    function _registerSplitterById(id) { 
     _registerSplitterByElement(document.getElementById(id)); 
    } 
    function _registerSplitterByElement(el) { 
     el.addEventListener("mousedown",mousedownOnSplitter,false); 
    } 
    function _unregisterSplitterById(id) { 
     _unregisterSplitterByElement(document.getElementById(id)); 
    } 
    function _unregisterSplitterByElement(el) { 
     el.removeEventListener("mousedown",mousedownOnSplitter,false); 
     removeResizeListeners(); 
    } 

    return { 
     registerSplitterById : function(id) { 
      _registerSplitterById(id); 
     }, 
     registerSplitterByElement : function(el) { 
      _registerSplitterByElement(el); 
     }, 
     unregisterSplitterById : function(id) { 
      _unregisterSplitterById(id); 
     }, 
     unregisterSplitterByElement : function(el) { 
      _unregisterSplitterByElement(el); 
     } 
    }; 
})(); 

Beispiel XUL (modifiziert nach die Frage):

<?xml version="1.0"?> 
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?> 
<window id="testWindow" 
     title="testing resizing element by splitter" 
     xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" 
     style="color: white;" 
> 
    <vbox id="resizeme" height="120" minheight="30" maxheight="250" 
     style="background-color: yellow; color: black;"> 
    <hbox flex="1"> 
     <label value="#1"/> 
     <hbox flex="1" align="center" pack="center"> 
     <label id="yellowLabel" value="Resizable by top and bottom splitter"/> 
     </hbox> 
    </hbox> 
    </vbox> 
    <splitter id="firstSplitter" tooltiptext="Top splitter" orient="vertical" 
      resizebefore="resizeme" resizeafter="blueVbox"/> 
    <grid> 
    <columns> 
     <column/> 
     <column flex="1"/> 
    </columns> 
    <rows> 
     <row style="background-color: black;"> 
     <label value="#2"/> 
     <vbox pack="center" align="center"> 
     <label value="Must stay constant size at all times"/> 
     </vbox> 
     </row> 
     <row id="blueRow" style="background-color: blue;"> 
     <label value="#3"/> 
     <vbox id="blueVbox" height="120" minheight="30" pack="center" align="center"> 
      <label id="blueLabel" value="Resizable by top splitter only"/> 
     </vbox> 
     </row> 
     <row style="background-color: black;"> 
     <label value="#4"/> 
     <hbox pack="center" align="center"> 
      <label value="Must stay constant size at all times, content must fit"/> 
      <button label="blah"/> 
     </hbox> 
     </row> 
     <splitter id="secondSplitter" tooltiptext="Bottom splitter" orient="vertical" 
       resizebefore="resizeme" resizeafter="greenVbox"/> 
     <row id="greenRow" style="background-color: green;"> 
     <label value="#5"/> 
     <vbox id="greenVbox" height="120" minheight="30" pack="center" align="center"> 
     <label id="greenLabel" value="Resizable by bottom splitter only"/> 
     </vbox> 
     </row> 
     <row style="background-color: black;"> 
     <label value="#6"/> 
     <vbox pack="center" align="center"> 
     <label value="Must stay constant size at all times"/> 
     </vbox> 
     </row> 
    </rows> 
    </grid> 
<script type="application/x-javascript" src="file://b:/SplitterById.js"/> 
<script type="application/javascript"> 
    <![CDATA[ 
    splitterById.registerSplitterById("firstSplitter"); 
    splitterById.registerSplitterById("secondSplitter"); 
    ]]> 
</script> 
</window> 

Dieses Beispiel sieht so aus:
Resizing using splitterById

[Hinweis: Während der Code geschrieben ist sowohl mit <splitters> vertikal und horizontal zu arbeiten, ich habe es nur mit der vertikalen <splitters> in dem obigen Beispiel getestet.]

<splitter> normalerweise verwenden (ohne Warten auf Ereignisse):
Das Beispiel, das Sie ursprünglich in Ihrer Frage hatten, war wesentlich weniger komplex als das Beispiel, das Sie jetzt haben. Es war durchaus möglich, es unter Verwendung von XUL zu codieren, um die Funktion so zu aktivieren, wie Sie es gewünscht haben.

Es gibt mehrere Möglichkeiten (von denen viele in verschiedenen Kombinationen zusammenwirken), die verwendet werden können, zu steuern, welches Objekt oder Objekte werden über ein <splitter> Element oder eine allgemeine Resize des Gesamt-Layout angepasst. Unter anderem sind dies unter Verwendung der resizebefore und resizeafter Attribute der <splitter> in Kombination mit den entsprechenden Werten für das flex Attribut auf die Elemente in Ihrem XUL und möglicherweise einschließlich jene Elemente in box, hbox oder vbox Elemente, die nur verwendet werden, die verteilen "biegen". Zusätzlich kann es wünschenswert sein, für jedes Element innerhalb des Bereichs, der in der Größe geändert wird, unter Verwendung der verschiedenen attributes available to an XUL element (zusätzliche MDN-Dokumente: 1, 2, 3) eine Vielzahl von Beschränkungen anzugeben.

Eines der Dinge, die Sie übersehen haben, ist, dass das flex Attribut andere Werte als nur 1 oder 0 sein kann.Der numerische Wert wird verwendet, um den Umfang der Größenanpassung für ein bestimmtes Element proportional zu den anderen Elementen anzugeben, die von der Größenänderung betroffen sind (sei es die Größenänderung aufgrund eines <splitter> oder eine Größenänderung eines Containerelements (z. B. <window>). <box>, <vbox>, <hbox>, usw.), die das Element enthält, an dem Sie interessiert sind).

Versuch und Irrtum:
Um genau die Funktionalität, die Sie in einem bestimmten Layout wünschen, müssen Sie wahrscheinlich einige Versuch und Irrtum durchzuführen. Je nachdem, was Sie gerade tun, ist das XUL-Prototyping-Tool XUL Explorer hilfreich. Wenn Ihr Code beispielsweise Ihr XUL dynamisch erstellt, ist XUL Explorer nicht so hilfreich. Aber selbst wenn ich dynamisch mein XUL-Layout erstelle, habe ich XUL Explorer benutzt, um schnell zu sehen, wie sich Variationen auf dem XUL, das ich gebaut habe, verhalten würden.

Ihr (original) konkretes Beispiel:
[Anmerkung: Die folgende ist basierend auf dem ersten Beispiel, das in der Frage enthalten war. Dieses Beispiel war wesentlich weniger komplex als das, was jetzt in Frage steht. Insbesondere hatte es keinen <splitter> innerhalb eines Behälters (a <grid> in dem neuen Beispiel), der Größenänderung Elemente außerhalb dieses Behälters haben wollte.]

Für Ihr spezifisches Beispiel kann das Verhalten, das Sie beschreiben, erreicht werden durch Setzen Sie den flex Wert auf den grünen <vbox> auf einen großen Wert relativ zu den anderen Elementen.

Wie bei vielen UI-Problemen ist es schwierig, in Worten alles zu sagen, was Sie haben möchten. In diesem Fall haben Sie beispielsweise keine Startgrößen für die anderen Elemente <vbox> angegeben. Um mehr von dem, was mit der <splitter> passiert, und mit einem anderen Wert für flex auf der grünen <vbox> zu zeigen, habe ich einen Start/Standard height für die anderen <vbox> Elemente enthalten. Dies führt dazu, dass diese Elemente auf dieser Höhe beginnen und dann von dieser auf ihre minimale Höhe schrumpfen, sobald die grüne <vbox> auf ihre minimale Höhe geschrumpft ist.

Hinweis: Sie verwenden das style Attribut mit einem Teil davon min-height: 30px;. Sofern Sie dies nicht in eine CSS-Klasse einfügen, ist es möglicherweise besser/einfacher, das XUL-Attribut minheight zu verwenden. Dies würde es einfacher machen, programmgesteuert zu ändern, wenn Sie dies wünschen. Da es sich um Beispielcode handelt, haben Sie möglicherweise nur das eingefügt, um nicht auch eine CSS-Datei einbeziehen zu müssen.

Der Code:

<?xml version="1.0"?> 

<?xml-stylesheet href="chrome://global/skin/" type="text/css"?> 

<window id="testWindow" 
      title="testing resizing element by splitter" 
      xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" 
> 
    <hbox flex="1"> 
    <vbox flex="1"> 
     <vbox flex="1" height="80" pack="center" align="center" 
      style="background-color: blue; min-height: 30px; color: white;"> 
     <label value="this should stay constant size until green element reached its minimum size"/> 
     </vbox> 
     <vbox id="resizeme" flex="10000" height="80" pack="center" align="center" 
      style="background-color: green; min-height: 30px; color: white;"> 
     <label value="only this should be resized until it reached minimum size of 30px"/> 
     </vbox> 
     <vbox flex="1" height="80" pack="center" align="center" 
      style="background-color: red; min-height: 30px; color: white;"> 
     <label value="this should stay constant size until green element reached its minimum size"/> 
     </vbox> 
    </vbox> 
    </hbox> 

    <splitter/> 
    <vbox flex="1"/> 

</window> 

Wie es aussieht, wenn die <splitter> mit, um die Größe:
Resizing <vbox> elements with flex

+0

Vielen Dank für die ausführliche Erklärung und das Arbeitsbeispiel! Leider war mein Beispiel nach einigen zusätzlichen Tests nicht vollständig ... Ich habe keine reine Xul-Lösung erwartet, daher erwies sich das Beispiel als zu abgespeckt. Ich habe meine ursprüngliche Frage mit einem vollständigeren Beispiel aktualisiert, das leider nicht rein in xul behoben werden kann. – vanowm

+0

@vanowm: Ich habe meine Antwort erheblich aktualisiert. Enthält jetzt JavaScript-Code, der mit dem aktuellen Beispiel in Ihrer Frage funktioniert. Tatsächlich implementiert der Code eine generische Methode zur Verwendung von IDs in den XUL-Attributen des '', um explizit die zwei Elemente anzugeben, die die' 'Größe ändern wird. – Makyen

+0

Vielen Dank! Dies ist perfekt! – vanowm