]> git.sesse.net Git - vlc/commitdiff
* skins2:
authorOlivier Teulière <ipkiss@videolan.org>
Sun, 28 Jan 2007 16:49:30 +0000 (16:49 +0000)
committerOlivier Teulière <ipkiss@videolan.org>
Sun, 28 Jan 2007 16:49:30 +0000 (16:49 +0000)
    - New Panel tag, allowing to group the resizing behaviour of controls
    - Documentation updated accordingly
    - Fixed a memory leak due to CtrlMove/CtrlResize objects

16 files changed:
doc/skins/skins2-howto.xml
modules/gui/skins2/parser/builder.cpp
modules/gui/skins2/parser/builder.hpp
modules/gui/skins2/parser/builder_data.def
modules/gui/skins2/parser/builder_data.hpp
modules/gui/skins2/parser/skin_parser.cpp
modules/gui/skins2/parser/skin_parser.hpp
modules/gui/skins2/src/generic_layout.cpp
modules/gui/skins2/src/generic_layout.hpp
modules/gui/skins2/src/theme.cpp
modules/gui/skins2/src/theme.hpp
modules/gui/skins2/src/window_manager.cpp
modules/gui/skins2/src/window_manager.hpp
modules/gui/skins2/utils/position.cpp
modules/gui/skins2/utils/position.hpp
share/skins2/skin.dtd

index 0fb610baaba859ec7d5b368f19d955e351fd5a29..55db43dc2daca0a598e640e6777bc323258d2733 100644 (file)
@@ -65,24 +65,6 @@ difficulty to understand how VLC skins work.</para>
 
 </sect1>
 
-<sect1 id="bezier">
-<title>Bezier curves</title>
-
-<para>One cool thing with VLC sliders is that they are not necessarily rectilinear, but they can follow any Bezier curve. So if you want to have a slider moving on a half-circle, or even doing a loop, you can!</para>
-
-<para>This is not the place to explain how Bezier curves work (see <ulink url="http://astronomy.swin.edu.au/~pbourke/curves/bezier/">http://astronomy.swin.edu.au/~pbourke/curves/bezier/</ulink> for a nice introduction), the main thing to know is that a Bezier curve can be characterized by a set of points. Once you have them (thanks to the <link linkend="CurveMaker">CurveMaker</link> utility for example<!--XXX: deprecated-->), you just need to enter the list of points in the <link linkend="sliderpoints">points</link> attribute. Here is an example with 3 points: points="(2,50),(45,120),(88,50)".</para>
-
-<para>Bezier curves can be used with the <link linkend="Slider">Slider</link> and <link linkend="Anchor">Anchor</link> tags:</para>
-
-<itemizedlist>
-  <listitem><para>For sliders, it defines the curve followed by the cursor of the slider. This curve is of course invisible, so if you want a visible background for your <link linkend="Slider">Slider</link> you need to provide it yourself using the <link linkend="Image">Image</link> tag.</para></listitem>
-  <listitem><para>For anchors, the use of Bezier curves is more anecdotic. Its purpose is to have non-ponctual anchor, the whole curve becoming the anchor. In this case, a ponctual anchor (and only a ponctual one) can be attracted by any point of the curve, if it is in its range of action. In fact, you can consider the curve as an easy way to define at once many anchors that share the same properties (except their position, of course :)).</para></listitem>
-</itemizedlist>
-
-<note><para>The coordinates are relative to the upper-left corner of the control (i.e. to its <link linkend="x">x</link> and <link linkend="y">y</link> attributes).</para></note>
-
-</sect1>
-
 <sect1>
 <title>The bitmaps</title>
 
@@ -321,12 +303,12 @@ difficulty to understand how VLC skins work.</para>
   </sect3>
   <sect3 id="layoutwidth">
     <title>width</title>
-    <para><!--TODO: calculate it in VLC :)-->Width of the layout. this value is required since VLC is not (yet?) able to calculate it using the sizes and positions of the controls.</para>
+    <para><!--TODO: calculate it in VLC :)-->Initial width of the layout. This value is required since VLC is not (yet?) able to calculate it using the sizes and positions of the controls.</para>
     <para><emphasis>Required.</emphasis></para>
   </sect3>
   <sect3 id="layoutheight">
     <title>height</title>
-    <para><!--TODO: calculate it in VLC :)-->Height of the layout. this value is required since VLC is not (yet?) able to calculate it using the sizes and positions of the controls.</para>
+    <para><!--TODO: calculate it in VLC :)-->Initial height of the layout. This value is required since VLC is not (yet?) able to calculate it using the sizes and positions of the controls.</para>
     <para><emphasis>Required.</emphasis></para>
   </sect3>
   <sect3 id="minwidth">
@@ -353,25 +335,63 @@ difficulty to understand how VLC skins work.</para>
 
 <sect2 id="Group">
   <title>Group</title>
-  <para>Adds an offset to the elements it contains. A Group is only supposed to ease the job of the skin designer, who can adjust the position of a group of controls without modifying all the coordinates, but you can ignore it if you want (only one Group is necessary, inside the <link linkend="Layout">Layout</link> tag). Group tags can be nested.</para>
+  <para>Add an offset to the elements it contains. A Group is only supposed to ease the job of the skin designer, who can adjust the position of a group of controls without modifying all the coordinates, but you can ignore it if you want (only one Group is necessary, inside the <link linkend="Layout">Layout</link> tag). Group tags can be nested. Note that Group elements are deprecated, since <link linkend="Panel">Panel</link> elements are more powerful.</para>
   <sect3 id="groupx">
     <title>x</title>
-    <para>Try and guess.</para>
+    <para>Horizontal offset, relative to the container box (see the <link linkend="layoutmodel">Layout model</link> for more details).</para>
     <para>Default value: 0</para>
   </sect3>
   <sect3 id="groupy">
     <title>y</title>
-    <para>What do you think?</para>
+    <para>Vertical offset, relative to the container box (see the <link linkend="layoutmodel">Layout model</link> for more details).</para>
     <para>Default value: 0</para>
   </sect3>
 </sect2>
 
+<sect2 id="Panel">
+  <title>Panel</title>
+  <para>A Panel can be seen as an enhanced <link linkend="Layout">Group</link>. It also adds an offset to the elements it contains, but in addition it becomes their reference for the lefttop, rightbottom, xkeepratio and ykeepratio attributes. Panel tags can be nested. Since VLC 0.9.0.</para>
+  <para>See the <link linkend="commattr">common attributes</link>.</para>
+  <sect3 id="panelx">
+    <title>x</title>
+    <para>Same as the <link linkend="x">x</link> attribute of the <link linkend="commattr">common attributes</link>.</para>
+  </sect3>
+  <sect3 id="panely">
+    <title>y</title>
+    <para>Same as the <link linkend="y">y</link> attribute of the <link linkend="commattr">common attributes</link>.</para>
+  </sect3>
+  <sect3 id="panelwidth">
+    <title>width</title>
+    <para>Initial width of this container box (see the <link linkend="layoutmodel">Layout model</link> for more details).</para>
+  </sect3>
+  <sect3 id="panelheight">
+    <title>height</title>
+    <para>Initial height of this container box (see the <link linkend="layoutmodel">Layout model</link> for more details).</para>
+  </sect3>
+  <sect3 id="panellefttop">
+    <title>lefttop</title>
+    <para>Same as the <link linkend="lefttop">lefttop</link> attribute of the <link linkend="commattr">common attributes</link>.</para>
+  </sect3>
+  <sect3 id="panelrightbottom">
+    <title>rightbottom</title>
+    <para>Same as the <link linkend="rightbottom">rightbottom</link> attribute of the <link linkend="commattr">common attributes</link>.</para>
+  </sect3>
+  <sect3 id="panelxkeepratio">
+    <title>xkeepratio</title>
+    <para>Same as the <link linkend="xkeepratio">xkeepratio</link> attribute of the <link linkend="commattr">common attributes</link>.</para>
+  </sect3>
+  <sect3 id="panelykeepratio">
+    <title>ykeepratio</title>
+    <para>Same as the <link linkend="ykeepratio">ykeepratio</link> attribute of the <link linkend="commattr">common attributes</link>.</para>
+  </sect3>
+</sect2>
+
 <sect2 id="Anchor">
   <title>Anchor</title>
   <para>Create a "magnetic point" (or curve) in the current window. If an anchor of another window enters in the range of action of this anchor, the 2 anchors will automatically be on the same place, and the windows are "sticked". Each anchor has a priority (<link linkend="anchorpriority">priority</link> attribute), and the anchor with the highest priority is the winner, which means that when moving its window all the other anchored windows will move too. To break the effect of 2 anchored windows, you need to move the window whose anchor has the lower priority.</para>
   <sect3 id="anchorx">
     <title>x</title>
-    <para>Is it really necessary to explain ?</para>
+    <para>Is it really necessary to explain?</para>
     <para>Default value: 0</para>
   </sect3>
   <sect3 id="anchory">
@@ -419,34 +439,34 @@ difficulty to understand how VLC skins work.</para>
   </sect3>
   <sect3 id="x">
     <title>x</title>
-    <para>Horizontal offset of the control, relative to the parent tag (usually <link linkend="Group">Group</link> or <link linkend="Layout">Layout</link>).</para>
+    <para>Horizontal offset of the control, relative to the container box (see the <link linkend="layoutmodel">Layout model</link>) or to the parent <link linkend="Group">Group</link>.</para>
     <para>Default value: 0</para>
   </sect3>
   <sect3 id="y">
     <title>y</title>
-    <para>Vertical offset of the control, relative to the parent tag (usually <link linkend="Group">Group</link> or <link linkend="Layout">Layout</link>).</para>
+    <para>Vertical offset of the control, relative to the container box (see the <link linkend="layoutmodel">Layout model</link>) or to the parent <link linkend="Group">Group</link>.</para>
     <para>Default value: 0</para>
   </sect3>
   <sect3 id="lefttop">
     <title>lefttop</title>
-    <para>Indicate to which corner of the Layout the top-left-hand corner of this control is attached, in case of resizing. Possible values are 'lefttop', 'leftbottom', 'righttop' and 'rightbottom'.</para>
+    <para>Indicate to which corner of the container box the top-left-hand corner of this control is attached, in case of resizing. Possible values are 'lefttop', 'leftbottom', 'righttop' and 'rightbottom'. See the <link linkend="layoutmodel">Layout model</link> for more details.</para>
     <para>Default value: lefttop</para>
   </sect3>
   <sect3 id="rightbottom">
     <title>rightbottom</title>
-    <para>Indicate to which corner of the Layout the bottom-right-hand corner of this control is attached, in case of resizing.</para>
+    <para>Indicate to which corner of the container box the bottom-right-hand corner of this control is attached, in case of resizing. See the <link linkend="layoutmodel">Layout model</link> for more details.</para>
     <para>Default value: lefttop</para>
   </sect3>
   <sect3 id="xkeepratio">
     <title>xkeepratio</title>
-    <para>When set to true, the behaviour of the horizontal resizing is changed. Instead of taking into account the <link linkend="lefttop">lefttop</link> and <link linkend="rightbottom">rightbottom</link> attributes to determine how the control will be moved/resized, only its initial position inside the <link linkend="Layout">Layout</link> matters. For example, if initially the space to the left of the control is twice as big as the one to its right, this will stay the same during any horizontal resizing. The width of the control stays constant.</para>
-    <para>This attribute can be particularly useful to keep a control centered in the layout, without resizing it (to resize it, you would rather use the lefttop/rightbottom attributes). Available since VLC 0.8.6.</para>
+    <para>When set to true, the behaviour of the horizontal resizing is changed. Instead of taking into account the <link linkend="lefttop">lefttop</link> and <link linkend="rightbottom">rightbottom</link> attributes to determine how the control will be moved/resized, only its initial position inside the container box matters. For example, if initially the space to the left of the control is twice as big as the one to its right, this will stay the same during any horizontal resizing. The width of the control stays constant.</para>
+    <para>This attribute can be particularly useful to keep a control centered in the container box, without resizing it (to resize it, you would rather use the lefttop/rightbottom attributes). See the <link linkend="layoutmodel">Layout model</link> for more details. Available since VLC 0.8.6.</para>
     <para>Default value: false</para>
   </sect3>
   <sect3 id="ykeepratio">
     <title>ykeepratio</title>
     <para>When set to true, the behaviour of the vertical resizing is changed. Instead of taking into account the <link linkend="lefttop">lefttop</link> and <link linkend="rightbottom">rightbottom</link> attributes to determine how the control will be moved/resized, only its initial position inside the <link linkend="Layout">Layout</link> matters. For example, if initially the space to the top of the control is twice as big as the one to its bottom, this will stay the same during any vertical resizing. The height of the control stays constant.</para>
-    <para>This attribute can be particularly useful to keep a control centered in the layout, without resizing it (to resize it, you would rather use the lefttop/rightbottom attributes). Available since VLC 0.8.6.</para>
+    <para>This attribute can be particularly useful to keep a control centered in the container box, without resizing it (to resize it, you would rather use the lefttop/rightbottom attributes). See the <link linkend="layoutmodel">Layout model</link> for more details. Available since VLC 0.8.6.</para>
     <para>Default value: false</para>
   </sect3>
   <sect3 id="help">
@@ -1114,6 +1134,38 @@ difficulty to understand how VLC skins work.</para>
 
 </sect1>
 
+<sect1 id="layoutmodel">
+<title>Layout model</title>
+
+<para>Placing the controls on a window is easy, using their x and y attributes, but these positions become insufficient for a resizable window. Some controls (or groups of controls) should stay centered in the window, others should follow the right side of the window, others should change their size automatically, etc... To handle these various behaviours, the layout model followed by the skins engine is a model based on nested boxes.</para>
+
+<para>There are 2 kinds of boxes:</para>
+
+<itemizedlist>
+  <listitem><para>
+    <emphasis>simple boxes</emphasis>: These boxes cannot contain other boxes. All the visible controls are simple boxes: Image, Button, Checkbox, Text, Slider, RadialSlider, Playlist, Playtree, Video.
+  </para></listitem>
+  <listitem><para>
+    <emphasis>container boxes</emphasis>: These boxes can contain other boxes. Only two XML tags create container boxes: <link linkend="Panel">Panel</link> and <link linkend="Layout">Layout</link>. The Layout tag is necessarily the top-level box for the current layout, and cannot be contained, but Panel elements can be contained.
+  </para></listitem>
+</itemizedlist>
+
+<para>A box inside a container box always defines how it should react when its container box is resized. Two different mechanisms are provided: corners anchoring (useful when resizing of the inner box is wanted, for example) and constant ratio (mainly useful to keep the inner box centered inside its parent):</para>
+<itemizedlist>
+  <listitem><para>
+    <emphasis>corners anchoring</emphasis>: The top-left-hand corner (TL) and the bottom-right-hand corner (BR) of the inner box are "tied" to corners of the container box (TL, TR, BL or BR). When any resizing occurs, tied corners move together, which can move or resize the inner box. For example, if the TL corner of the inner box is tied to the TL corner of the container (let's write it TL/TL), and if the BR corner of the inner box is also tied to the TL corner of the container box (BR/TL), the inner box will not be resized, and will always stay at the same place (this is the default behaviour). If we have TL/TL and TL/BL, the inner box is resized vertically its container is resized. If we have TL/TR and BR/TR, the inner box moves with the TR corner of its container. We could even define TL/BR and BR/TL, in which case increasing the size of the container box would shrink the size of the inner box... until it disappears completely!
+  </para>
+  <para>This mechanism is controlled by the <link linkend="lefttop">lefttop</link> and <link linkend="rightbottom">rightbottom</link> attributes of the controls.
+  </para></listitem>
+  <listitem><para>
+    <emphasis>constant ratio</emphasis>: When a box doesn't fill completely its container box, there is space on the top, bottom, left and right of the inner box. It is possible to force the ratio between the space on the top and the space on the bottom (or the one on the left and the one on the right)  to be constant. Any resizing of the container box will then move the inner box accordingly, and the size of the inner box will never change (it overrides the corners anchoring mechanism). The horizontal and vertical ratios being independent, it is for example possible to keep only the horizontal ratio constant, in which case the inner box can still resize vertically (depending on its attributes for the corners anchoring, of course).
+  </para>
+  <para>This mechanism is controlled by the <link linkend="xkeepratio">xkeepratio</link> and <link linkend="ykeepratio">ykeepratio</link> attributes of the controls.
+  </para></listitem>
+</itemizedlist>
+
+</sect1>
+
 
 <sect1>
 
@@ -1136,6 +1188,24 @@ difficulty to understand how VLC skins work.</para>
 
 </sect1>
 
+<sect1 id="bezier">
+<title>Bezier curves</title>
+
+<para>One cool thing with VLC sliders is that they are not necessarily rectilinear, but they can follow any Bezier curve. So if you want to have a slider moving on a half-circle, or even doing a loop, you can!</para>
+
+<para>This is not the place to explain how Bezier curves work (see <ulink url="http://astronomy.swin.edu.au/~pbourke/curves/bezier/">http://astronomy.swin.edu.au/~pbourke/curves/bezier/</ulink> for a nice introduction), the main thing to know is that a Bezier curve can be characterized by a set of points. Once you have them (thanks to the <link linkend="CurveMaker">CurveMaker</link> utility for example<!--XXX: deprecated-->), you just need to enter the list of points in the <link linkend="sliderpoints">points</link> attribute. Here is an example with 3 points: points="(2,50),(45,120),(88,50)".</para>
+
+<para>Bezier curves can be used with the <link linkend="Slider">Slider</link> and <link linkend="Anchor">Anchor</link> tags:</para>
+
+<itemizedlist>
+    <listitem><para>For sliders, it defines the curve followed by the cursor of the slider. This curve is of course invisible, so if you want a visible background for your <link linkend="Slider">Slider</link> you need to provide it yourself using a <link linkend="SliderBackground">SliderBackground</link> or <link linkend="Image">Image</link> tag.</para></listitem>
+  <listitem><para>For anchors, the use of Bezier curves is more anecdotic. Its purpose is to have non-ponctual anchor, the whole curve becoming the anchor. In this case, a ponctual anchor (and only a ponctual one) can be attracted by any point of the curve, if it is in its range of action. In fact, you can consider the curve as an easy way to define at once many anchors that share the same properties (except their position, of course :)).</para></listitem>
+</itemizedlist>
+
+<note><para>The coordinates are relative to the upper-left corner of the control (i.e. to its <link linkend="x">x</link> and <link linkend="y">y</link> attributes).</para></note>
+
+</sect1>
+
 <sect1>
 <title>Tools and advice</title>
 
@@ -1143,7 +1213,7 @@ difficulty to understand how VLC skins work.</para>
   <title>Generating Bezier curves</title>
 
   <para>
-To generate easily Bezier curves, you can use the <ulink url="/vlc/skins/VLC-curve-maker.exe">curve-maker</ulink> (sorry, this is for Windows users only). Basically, you add and remove points at will, and you can move them to see how the curve evolves. When you have reached the perfect curve, you just have to copy-paste the list of abscissas and ordinates to form the <link linkend="sliderpoints">points</link> attribute of your <link linkend="Slider">Slider</link> or <link linkend="Playlist">Playlist</link>. The curve-maker also allows to load a .bmp file, this could be useful if you want to follow a specific pattern of a slider, for example.
+To generate easily Bezier curves, you can use the <ulink url="/vlc/skins/VLC-curve-maker.exe">CurveMaker</ulink> utility (sorry, this is for Windows users only). Basically, you add and remove points at will, and you can move them to see how the curve evolves. When you have reached the perfect curve, you just have to copy-paste the list of abscissas and ordinates to form the <link linkend="sliderpoints">points</link> attribute of your <link linkend="Slider">Slider</link> or <link linkend="Anchor">Anchor</link>. The curve-maker also allows to load a .bmp file, this could be useful if you want to follow a specific pattern of a slider, for example.
   </para>
 
 <note><para>This tool was made for the first version of the skins and has not been modified since then. This explains why it does not use PNG files and why it does not generate directly the value of the <link linkend="sliderpoints">points</link> attribute.</para></note>
index f35f844992d17269b9649d532903308a210e5388..7acddf2b3198601c4edfd8a4c455f84848b3e798 100644 (file)
@@ -107,6 +107,7 @@ Theme *Builder::build()
     // (at least) can give a valid window handle to the OSPopup objects
     ADD_OBJECTS( PopupMenu );
     ADD_OBJECTS( Layout );
+    ADD_OBJECTS( Panel );
     ADD_OBJECTS( Anchor );
     ADD_OBJECTS( Button );
     ADD_OBJECTS( Checkbox );
@@ -138,6 +139,25 @@ Theme *Builder::build()
         } \
     }
 
+
+// Macro to get the parent box of a control, given the panel ID
+#define GET_BOX( pRect, id, pLayout ) \
+    if( id == "none" ) \
+        pRect = &pLayout->getRect(); \
+    else \
+    { \
+        const Position *pParent = \
+            m_pTheme->getPositionById( rData.m_panelId ); \
+        if( pParent == NULL ) \
+        { \
+            msg_Err( getIntf(), "parent panel could not be found: %s", \
+                     rData.m_panelId.c_str() ); \
+            return; \
+        } \
+        pRect = pParent; \
+    }
+
+
 void Builder::addTheme( const BuilderData::Theme &rData )
 {
     WindowManager &rManager = m_pTheme->getWindowManager();
@@ -382,7 +402,8 @@ void Builder::addAnchor( const BuilderData::Anchor &rData )
     const Position pos = makePosition( rData.m_leftTop, rData.m_leftTop,
                                        rData.m_xPos, rData.m_yPos,
                                        pCurve->getWidth(),
-                                       pCurve->getHeight(), *pLayout );
+                                       pCurve->getHeight(),
+                                       pLayout->getRect() );
 
     Anchor *pAnc = new Anchor( getIntf(), pos, rData.m_range, rData.m_priority,
                                *pCurve, *pLayout );
@@ -424,18 +445,19 @@ void Builder::addButton( const BuilderData::Button &rData )
     CtrlButton *pButton = new CtrlButton( getIntf(), *pBmpUp, *pBmpOver,
         *pBmpDown, *pCommand, UString( getIntf(), rData.m_tooltip.c_str() ),
         UString( getIntf(), rData.m_help.c_str() ), pVisible );
+    m_pTheme->m_controls[rData.m_id] = CtrlGenericPtr( pButton );
 
     // Compute the position of the control
     // XXX (we suppose all the images have the same size...)
+    const GenericRect *pRect;
+    GET_BOX( pRect, rData.m_panelId , pLayout);
     const Position pos = makePosition( rData.m_leftTop, rData.m_rightBottom,
                                        rData.m_xPos, rData.m_yPos,
                                        pBmpUp->getWidth(),
-                                       pBmpUp->getHeight(), *pLayout,
+                                       pBmpUp->getHeight(), *pRect,
                                        rData.m_xKeepRatio, rData.m_yKeepRatio );
 
     pLayout->addControl( pButton, pos, rData.m_layer );
-
-    m_pTheme->m_controls[rData.m_id] = CtrlGenericPtr( pButton );
 }
 
 
@@ -500,18 +522,19 @@ void Builder::addCheckbox( const BuilderData::Checkbox &rData )
         *pCommand2, UString( getIntf(), rData.m_tooltip1.c_str() ),
         UString( getIntf(), rData.m_tooltip2.c_str() ), *pVar,
         UString( getIntf(), rData.m_help.c_str() ), pVisible );
+    m_pTheme->m_controls[rData.m_id] = CtrlGenericPtr( pCheckbox );
 
     // Compute the position of the control
     // XXX (we suppose all the images have the same size...)
+    const GenericRect *pRect;
+    GET_BOX( pRect, rData.m_panelId , pLayout);
     const Position pos = makePosition( rData.m_leftTop, rData.m_rightBottom,
                                        rData.m_xPos, rData.m_yPos,
                                        pBmpUp1->getWidth(),
-                                       pBmpUp1->getHeight(), *pLayout,
+                                       pBmpUp1->getHeight(), *pRect,
                                        rData.m_xKeepRatio, rData.m_yKeepRatio );
 
     pLayout->addControl( pCheckbox, pos, rData.m_layer );
-
-    m_pTheme->m_controls[rData.m_id] = CtrlGenericPtr( pCheckbox );
 }
 
 
@@ -550,20 +573,23 @@ void Builder::addImage( const BuilderData::Image &rData )
         (rData.m_resize == "scale" ? CtrlImage::kScale : CtrlImage::kMosaic);
     CtrlImage *pImage = new CtrlImage( getIntf(), *pBmp, *pCommand,
         resizeMethod, UString( getIntf(), rData.m_help.c_str() ), pVisible );
+    m_pTheme->m_controls[rData.m_id] = CtrlGenericPtr( pImage );
 
     // Compute the position of the control
+    const GenericRect *pRect;
+    GET_BOX( pRect, rData.m_panelId , pLayout);
     const Position pos = makePosition( rData.m_leftTop, rData.m_rightBottom,
                                        rData.m_xPos, rData.m_yPos,
                                        pBmp->getWidth(), pBmp->getHeight(),
-                                       *pLayout, rData.m_xKeepRatio,
+                                       *pRect, rData.m_xKeepRatio,
                                        rData.m_yKeepRatio );
 
-    // XXX: test to be changed! XXX
     if( rData.m_actionId == "move" )
     {
         CtrlMove *pMove = new CtrlMove( getIntf(), m_pTheme->getWindowManager(),
              *pImage, *pWindow, UString( getIntf(), rData.m_help.c_str() ),
              pVisible );
+        m_pTheme->m_controls[rData.m_id + "_move"] = CtrlGenericPtr( pMove );
         pLayout->addControl( pMove, pos, rData.m_layer );
     }
     else if( rData.m_actionId == "resizeS" )
@@ -572,6 +598,7 @@ void Builder::addImage( const BuilderData::Image &rData )
                 m_pTheme->getWindowManager(), *pImage, *pLayout,
                 UString( getIntf(), rData.m_help.c_str() ), pVisible,
                 WindowManager::kResizeS );
+        m_pTheme->m_controls[rData.m_id + "_rsz"] = CtrlGenericPtr( pResize );
         pLayout->addControl( pResize, pos, rData.m_layer );
     }
     else if( rData.m_actionId == "resizeE" )
@@ -580,6 +607,7 @@ void Builder::addImage( const BuilderData::Image &rData )
                 m_pTheme->getWindowManager(), *pImage, *pLayout,
                 UString( getIntf(), rData.m_help.c_str() ), pVisible,
                 WindowManager::kResizeE );
+        m_pTheme->m_controls[rData.m_id + "_rsz"] = CtrlGenericPtr( pResize );
         pLayout->addControl( pResize, pos, rData.m_layer );
     }
     else if( rData.m_actionId == "resizeSE" )
@@ -588,14 +616,38 @@ void Builder::addImage( const BuilderData::Image &rData )
                 m_pTheme->getWindowManager(), *pImage, *pLayout,
                 UString( getIntf(), rData.m_help.c_str() ), pVisible,
                 WindowManager::kResizeSE );
+        m_pTheme->m_controls[rData.m_id + "_rsz"] = CtrlGenericPtr( pResize );
         pLayout->addControl( pResize, pos, rData.m_layer );
     }
     else
     {
         pLayout->addControl( pImage, pos, rData.m_layer );
     }
+}
 
-    m_pTheme->m_controls[rData.m_id] = CtrlGenericPtr( pImage );
+
+void Builder::addPanel( const BuilderData::Panel &rData )
+{
+    // This method makes the assumption that the Panels are created in the
+    // order of the XML, because each child Panel expects its parent Panel
+    // in order to be fully created
+
+    GenericLayout *pLayout = m_pTheme->getLayoutById( rData.m_layoutId );
+    if( pLayout == NULL )
+    {
+        msg_Err( getIntf(), "unknown layout id: %s", rData.m_layoutId.c_str() );
+        return;
+    }
+
+    const GenericRect *pRect;
+    GET_BOX( pRect, rData.m_panelId , pLayout);
+    Position *pPos =
+        new Position( makePosition( rData.m_leftTop, rData.m_rightBottom,
+                                    rData.m_xPos, rData.m_yPos,
+                                    rData.m_width, rData.m_height,
+                                    *pRect, rData.m_xKeepRatio,
+                                    rData.m_yKeepRatio ) );
+    m_pTheme->m_positions[rData.m_id] = PositionPtr( pPos );
 }
 
 
@@ -657,13 +709,16 @@ void Builder::addText( const BuilderData::Text &rData )
     CtrlText *pText = new CtrlText( getIntf(), *pVar, *pFont,
         UString( getIntf(), rData.m_help.c_str() ), rData.m_color, pVisible,
         scrolling, alignment );
+    m_pTheme->m_controls[rData.m_id] = CtrlGenericPtr( pText );
 
     int height = pFont->getSize();
 
     // Compute the position of the control
+    const GenericRect *pRect;
+    GET_BOX( pRect, rData.m_panelId , pLayout);
     const Position pos = makePosition( rData.m_leftTop, rData.m_rightBottom,
                                        rData.m_xPos, rData.m_yPos,
-                                       rData.m_width, height, *pLayout,
+                                       rData.m_width, height, *pRect,
                                        rData.m_xKeepRatio, rData.m_yKeepRatio );
 
     pLayout->addControl( pText, pos, rData.m_layer );
@@ -671,8 +726,6 @@ void Builder::addText( const BuilderData::Text &rData )
     // Set the text of the control
     UString msg( getIntf(), rData.m_text.c_str() );
     pVar->set( msg );
-
-    m_pTheme->m_controls[rData.m_id] = CtrlGenericPtr( pText );
 }
 
 
@@ -708,19 +761,20 @@ void Builder::addRadialSlider( const BuilderData::RadialSlider &rData )
                               rData.m_minAngle, rData.m_maxAngle,
                               UString( getIntf(), rData.m_help.c_str() ),
                               pVisible );
+    m_pTheme->m_controls[rData.m_id] = CtrlGenericPtr( pRadial );
 
     // XXX: resizing is not supported
     // Compute the position of the control
+    const GenericRect *pRect;
+    GET_BOX( pRect, rData.m_panelId , pLayout);
     const Position pos = makePosition( rData.m_leftTop, rData.m_rightBottom,
                                        rData.m_xPos, rData.m_yPos,
                                        pSeq->getWidth(),
                                        pSeq->getHeight() / rData.m_nbImages,
-                                       *pLayout,
+                                       *pRect,
                                        rData.m_xKeepRatio, rData.m_yKeepRatio );
 
     pLayout->addControl( pRadial, pos, rData.m_layer );
-
-    m_pTheme->m_controls[rData.m_id] = CtrlGenericPtr( pRadial );
 }
 
 
@@ -772,18 +826,19 @@ void Builder::addSlider( const BuilderData::Slider &rData )
         *pCurve, *pVar, rData.m_thickness, pBgImage, rData.m_nbHoriz,
         rData.m_nbVert, rData.m_padHoriz, rData.m_padVert,
         pVisible, UString( getIntf(), rData.m_help.c_str() ) );
+    m_pTheme->m_controls[rData.m_id + "_bg"] = CtrlGenericPtr( pBackground );
 
     // Compute the position of the control
+    const GenericRect *pRect;
+    GET_BOX( pRect, rData.m_panelId , pLayout);
     const Position pos = makePosition( rData.m_leftTop, rData.m_rightBottom,
                                        rData.m_xPos, rData.m_yPos,
                                        pCurve->getWidth(), pCurve->getHeight(),
-                                       *pLayout,
+                                       *pRect,
                                        rData.m_xKeepRatio, rData.m_yKeepRatio );
 
     pLayout->addControl( pBackground, pos, rData.m_layer );
 
-    m_pTheme->m_controls[rData.m_id + "_bg"] = CtrlGenericPtr( pBackground );
-
     // Get the bitmaps of the cursor
     GenericBitmap *pBmpUp = NULL;
     GET_BMP( pBmpUp, rData.m_upId );
@@ -799,11 +854,10 @@ void Builder::addSlider( const BuilderData::Slider &rData )
         *pBmpOver, *pBmpDown, *pCurve, *pVar, pVisible,
         UString( getIntf(), rData.m_tooltip.c_str() ),
         UString( getIntf(), rData.m_help.c_str() ) );
+    m_pTheme->m_controls[rData.m_id] = CtrlGenericPtr( pCursor );
 
     pLayout->addControl( pCursor, pos, rData.m_layer );
 
-    m_pTheme->m_controls[rData.m_id] = CtrlGenericPtr( pCursor );
-
     // Associate the cursor to the background
     pBackground->associateCursor( *pCursor );
 }
@@ -853,17 +907,18 @@ void Builder::addList( const BuilderData::List &rData )
     CtrlList *pList = new CtrlList( getIntf(), *pVar, *pFont, pBgBmp,
        fgColor, playColor, bgColor1, bgColor2, selColor,
        UString( getIntf(), rData.m_help.c_str() ), pVisible );
+    m_pTheme->m_controls[rData.m_id] = CtrlGenericPtr( pList );
 
     // Compute the position of the control
+    const GenericRect *pRect;
+    GET_BOX( pRect, rData.m_panelId , pLayout);
     const Position pos = makePosition( rData.m_leftTop, rData.m_rightBottom,
                                        rData.m_xPos, rData.m_yPos,
                                        rData.m_width, rData.m_height,
-                                       *pLayout,
+                                       *pRect,
                                        rData.m_xKeepRatio, rData.m_yKeepRatio );
 
     pLayout->addControl( pList, pos, rData.m_layer );
-
-    m_pTheme->m_controls[rData.m_id] = CtrlGenericPtr( pList );
 }
 
 void Builder::addTree( const BuilderData::Tree &rData )
@@ -918,17 +973,18 @@ void Builder::addTree( const BuilderData::Tree &rData )
        pItemBmp, pOpenBmp, pClosedBmp,
        fgColor, playColor, bgColor1, bgColor2, selColor,
        UString( getIntf(), rData.m_help.c_str() ), pVisible, pFlat );
+    m_pTheme->m_controls[rData.m_id] = CtrlGenericPtr( pTree );
 
     // Compute the position of the control
+    const GenericRect *pRect;
+    GET_BOX( pRect, rData.m_panelId , pLayout);
     const Position pos = makePosition( rData.m_leftTop, rData.m_rightBottom,
                                        rData.m_xPos, rData.m_yPos,
                                        rData.m_width, rData.m_height,
-                                       *pLayout,
+                                       *pRect,
                                        rData.m_xKeepRatio, rData.m_yKeepRatio );
 
     pLayout->addControl( pTree, pos, rData.m_layer );
-
-    m_pTheme->m_controls[rData.m_id] = CtrlGenericPtr( pTree );
 }
 
 void Builder::addVideo( const BuilderData::Video &rData )
@@ -948,32 +1004,33 @@ void Builder::addVideo( const BuilderData::Video &rData )
     CtrlVideo *pVideo = new CtrlVideo( getIntf(), *pLayout,
         rData.m_autoResize, UString( getIntf(), rData.m_help.c_str() ),
         pVisible );
+    m_pTheme->m_controls[rData.m_id] = CtrlGenericPtr( pVideo );
 
     // Compute the position of the control
+    const GenericRect *pRect;
+    GET_BOX( pRect, rData.m_panelId , pLayout);
     const Position pos = makePosition( rData.m_leftTop, rData.m_rightBottom,
                                        rData.m_xPos, rData.m_yPos,
                                        rData.m_width, rData.m_height,
-                                       *pLayout,
+                                       *pRect,
                                        rData.m_xKeepRatio, rData.m_yKeepRatio );
 
     pLayout->addControl( pVideo, pos, rData.m_layer );
-
-    m_pTheme->m_controls[rData.m_id] = CtrlGenericPtr( pVideo );
 }
 
 
 const Position Builder::makePosition( const string &rLeftTop,
                                       const string &rRightBottom,
                                       int xPos, int yPos, int width,
-                                      int height, const Box &rBox,
+                                      int height, const GenericRect &rRect,
                                       bool xKeepRatio, bool yKeepRatio ) const
 {
     int left = 0, top = 0, right = 0, bottom = 0;
     Position::Ref_t refLeftTop = Position::kLeftTop;
     Position::Ref_t refRightBottom = Position::kLeftTop;
 
-    int boxWidth = rBox.getWidth();
-    int boxHeight = rBox.getHeight();
+    int boxWidth = rRect.getWidth();
+    int boxHeight = rRect.getHeight();
 
     // Position of the left top corner
     if( rLeftTop == "lefttop" )
@@ -1042,7 +1099,7 @@ const Position Builder::makePosition( const string &rLeftTop,
         bottom = yPos + height;
     }
 
-    return Position( left, top, right, bottom, rBox, refLeftTop,
+    return Position( left, top, right, bottom, rRect, refLeftTop,
                      refRightBottom, xKeepRatio, yKeepRatio );
 }
 
@@ -1101,14 +1158,7 @@ Bezier *Builder::getPoints( const char *pTag ) const
         {
             return NULL;
         }
-#if 0
-        if( x < 0 || y < 0 )
-        {
-            msg_Err( getIntf(),
-                     "Slider points cannot have negative coordinates!" );
-            return NULL;
-        }
-#endif
+
         xBez.push_back( x );
         yBez.push_back( y );
         pTag += n;
index 49f4b365fd86d3b6378f67e95b34f1064cf7f936..f771e1c9a7ba6bf92563b2d09895f9632d026b6f 100644 (file)
@@ -37,7 +37,7 @@ class Bezier;
 class CmdGeneric;
 class GenericFont;
 class Position;
-class Box;
+class GenericRect;
 
 
 /// Class for skin construction
@@ -79,6 +79,7 @@ class Builder: public SkinObject
         void addButton( const BuilderData::Button &rData );
         void addCheckbox( const BuilderData::Checkbox &rData );
         void addImage( const BuilderData::Image &rData );
+        void addPanel( const BuilderData::Panel &rData );
         void addText( const BuilderData::Text &rData );
         void addRadialSlider( const BuilderData::RadialSlider &rData );
         void addSlider( const BuilderData::Slider &rData );
@@ -90,7 +91,8 @@ class Builder: public SkinObject
         const Position makePosition( const string &rLeftTop,
                                      const string &rRightBottom,
                                      int xPos, int yPos, int width, int height,
-                                     const Box &rBox, bool xKeepRatio = false,
+                                     const GenericRect &rRect,
+                                     bool xKeepRatio = false,
                                      bool yKeepRatio = false ) const;
 
         // Build the full path of a file
index eebde0e2656ae7fb8f73889733f9e273100c909d..5a84045ca1af8576c69bf60432adc1776fb775f1 100644 (file)
@@ -9,13 +9,14 @@ MenuSeparator pos:int popupId:string
 Window id:string xPos:int yPos:int visible:bool dragDrop:bool playOnDrop:bool
 Layout id:string width:int height:int minWidth:int maxWidth:int minHeight:int maxHeight:int windowId:string
 Anchor xPos:int yPos:int leftTop:string range:int priority:int points:string layoutId:string
-Button id:string xPos:int yPos:int leftTop:string rightBottom:string xKeepRatio:bool yKeepRatio:bool visible:string upId:string downId:string overId:string actionId:string tooltip:string help:string layer:int windowId:string layoutId:string
-Checkbox id:string xPos:int yPos:int leftTop:string rightBottom:string xKeepRatio:bool yKeepRatio:bool visible:string up1Id:string down1Id:string over1Id:string up2Id:string down2Id:string over2Id:string state:string action1:string action2:string tooltip1:string tooltip2:string help:string layer:int windowId:string layoutId:string
-Image id:string xPos:int yPos:int leftTop:string rightBottom:string xKeepRatio:bool yKeepRatio:bool visible:string bmpId:string actionId:string action2Id:string resize:string help:string layer:int windowId:string layoutId:string
+Button id:string xPos:int yPos:int leftTop:string rightBottom:string xKeepRatio:bool yKeepRatio:bool visible:string upId:string downId:string overId:string actionId:string tooltip:string help:string layer:int windowId:string layoutId:string panelId:string
+Checkbox id:string xPos:int yPos:int leftTop:string rightBottom:string xKeepRatio:bool yKeepRatio:bool visible:string up1Id:string down1Id:string over1Id:string up2Id:string down2Id:string over2Id:string state:string action1:string action2:string tooltip1:string tooltip2:string help:string layer:int windowId:string layoutId:string panelId:string
+Image id:string xPos:int yPos:int leftTop:string rightBottom:string xKeepRatio:bool yKeepRatio:bool visible:string bmpId:string actionId:string action2Id:string resize:string help:string layer:int windowId:string layoutId:string panelId:string
 IniFile id:string file:string
-Text id:string xPos:int yPos:int visible:string fontId:string text:string width:int leftTop:string rightBottom:string xKeepRatio:bool yKeepRatio:bool color:uint32_t scrolling:string alignment:string help:string layer:int windowId:string layoutId:string
-RadialSlider id:string visible:string xPos:int yPos:int leftTop:string rightBottom:string xKeepRatio:bool yKeepRatio:bool sequence:string nbImages:int minAngle:float maxAngle:float value:string tooltip:string help:string layer:int windowId:string layoutId:string
-Slider id:string visible:string xPos:int yPos:int leftTop:string rightBottom:string xKeepRatio:bool yKeepRatio:bool upId:string downId:string overId:string points:string thickness:int value:string imageId:string nbHoriz:int nbVert:int padHoriz:int padVert:int tooltip:string help:string layer:int windowId:string layoutId:string
-List id:string xPos:int yPos:int visible:string width:int height:int leftTop:string rightBottom:string xKeepRatio:bool yKeepRatio:bool fontId:string var:string bgImageId:string fgColor:string playColor:string bgColor1:string bgColor2:string selColor:string help:string layer:int windowId:string layoutId:string
-Tree id:string xPos:int yPos:int visible:string flat:string width:int height:int leftTop:string rightBottom:string xKeepRatio:bool yKeepRatio:bool fontId:string var:string bgImageId:string itemImageId:string openImageId:string closedImageId:string fgColor:string playColor:string bgColor1:string bgColor2:string selColor:string help:string layer:int windowId:string layoutId:string
-Video id:string xPos:int yPos:int width:int height:int leftTop:string rightBottom:string xKeepRatio:bool yKeepRatio:bool visible:string autoResize:bool help:string layer:int windowId:string layoutId:string
+Panel id:string xPos:int yPos:int leftTop:string rightBottom:string xKeepRatio:bool yKeepRatio:bool width:int height:int layer:int windowId:string layoutId:string panelId:string
+Text id:string xPos:int yPos:int visible:string fontId:string text:string width:int leftTop:string rightBottom:string xKeepRatio:bool yKeepRatio:bool color:uint32_t scrolling:string alignment:string help:string layer:int windowId:string layoutId:string panelId:string
+RadialSlider id:string visible:string xPos:int yPos:int leftTop:string rightBottom:string xKeepRatio:bool yKeepRatio:bool sequence:string nbImages:int minAngle:float maxAngle:float value:string tooltip:string help:string layer:int windowId:string layoutId:string panelId:string
+Slider id:string visible:string xPos:int yPos:int leftTop:string rightBottom:string xKeepRatio:bool yKeepRatio:bool upId:string downId:string overId:string points:string thickness:int value:string imageId:string nbHoriz:int nbVert:int padHoriz:int padVert:int tooltip:string help:string layer:int windowId:string layoutId:string panelId:string
+List id:string xPos:int yPos:int visible:string width:int height:int leftTop:string rightBottom:string xKeepRatio:bool yKeepRatio:bool fontId:string var:string bgImageId:string fgColor:string playColor:string bgColor1:string bgColor2:string selColor:string help:string layer:int windowId:string layoutId:string panelId:string
+Tree id:string xPos:int yPos:int visible:string flat:string width:int height:int leftTop:string rightBottom:string xKeepRatio:bool yKeepRatio:bool fontId:string var:string bgImageId:string itemImageId:string openImageId:string closedImageId:string fgColor:string playColor:string bgColor1:string bgColor2:string selColor:string help:string layer:int windowId:string layoutId:string panelId:string
+Video id:string xPos:int yPos:int width:int height:int leftTop:string rightBottom:string xKeepRatio:bool yKeepRatio:bool visible:string autoResize:bool help:string layer:int windowId:string layoutId:string panelId:string
index d0c6ec08f00c8f388e884dab0735b3ebf21ed3a4..d4ede19c75a8115ac9f017f44d05df446e14d1ae 100644 (file)
@@ -203,8 +203,8 @@ m_xPos( xPos ), m_yPos( yPos ), m_leftTop( leftTop ), m_range( range ), m_priori
     /// Type definition
     struct Button
     {
-        Button( const string & id, int xPos, int yPos, const string & leftTop, const string & rightBottom, bool xKeepRatio, bool yKeepRatio, const string & visible, const string & upId, const string & downId, const string & overId, const string & actionId, const string & tooltip, const string & help, int layer, const string & windowId, const string & layoutId ):
-m_id( id ), m_xPos( xPos ), m_yPos( yPos ), m_leftTop( leftTop ), m_rightBottom( rightBottom ), m_xKeepRatio( xKeepRatio ), m_yKeepRatio( yKeepRatio ), m_visible( visible ), m_upId( upId ), m_downId( downId ), m_overId( overId ), m_actionId( actionId ), m_tooltip( tooltip ), m_help( help ), m_layer( layer ), m_windowId( windowId ), m_layoutId( layoutId ) {}
+        Button( const string & id, int xPos, int yPos, const string & leftTop, const string & rightBottom, bool xKeepRatio, bool yKeepRatio, const string & visible, const string & upId, const string & downId, const string & overId, const string & actionId, const string & tooltip, const string & help, int layer, const string & windowId, const string & layoutId, const string & panelId ):
+m_id( id ), m_xPos( xPos ), m_yPos( yPos ), m_leftTop( leftTop ), m_rightBottom( rightBottom ), m_xKeepRatio( xKeepRatio ), m_yKeepRatio( yKeepRatio ), m_visible( visible ), m_upId( upId ), m_downId( downId ), m_overId( overId ), m_actionId( actionId ), m_tooltip( tooltip ), m_help( help ), m_layer( layer ), m_windowId( windowId ), m_layoutId( layoutId ), m_panelId( panelId ) {}
 
         string m_id;
         int m_xPos;
@@ -223,6 +223,7 @@ m_id( id ), m_xPos( xPos ), m_yPos( yPos ), m_leftTop( leftTop ), m_rightBottom(
         int m_layer;
         string m_windowId;
         string m_layoutId;
+        string m_panelId;
     };
     /// List
     list<Button> m_listButton;
@@ -230,8 +231,8 @@ m_id( id ), m_xPos( xPos ), m_yPos( yPos ), m_leftTop( leftTop ), m_rightBottom(
     /// Type definition
     struct Checkbox
     {
-        Checkbox( const string & id, int xPos, int yPos, const string & leftTop, const string & rightBottom, bool xKeepRatio, bool yKeepRatio, const string & visible, const string & up1Id, const string & down1Id, const string & over1Id, const string & up2Id, const string & down2Id, const string & over2Id, const string & state, const string & action1, const string & action2, const string & tooltip1, const string & tooltip2, const string & help, int layer, const string & windowId, const string & layoutId ):
-m_id( id ), m_xPos( xPos ), m_yPos( yPos ), m_leftTop( leftTop ), m_rightBottom( rightBottom ), m_xKeepRatio( xKeepRatio ), m_yKeepRatio( yKeepRatio ), m_visible( visible ), m_up1Id( up1Id ), m_down1Id( down1Id ), m_over1Id( over1Id ), m_up2Id( up2Id ), m_down2Id( down2Id ), m_over2Id( over2Id ), m_state( state ), m_action1( action1 ), m_action2( action2 ), m_tooltip1( tooltip1 ), m_tooltip2( tooltip2 ), m_help( help ), m_layer( layer ), m_windowId( windowId ), m_layoutId( layoutId ) {}
+        Checkbox( const string & id, int xPos, int yPos, const string & leftTop, const string & rightBottom, bool xKeepRatio, bool yKeepRatio, const string & visible, const string & up1Id, const string & down1Id, const string & over1Id, const string & up2Id, const string & down2Id, const string & over2Id, const string & state, const string & action1, const string & action2, const string & tooltip1, const string & tooltip2, const string & help, int layer, const string & windowId, const string & layoutId, const string & panelId ):
+m_id( id ), m_xPos( xPos ), m_yPos( yPos ), m_leftTop( leftTop ), m_rightBottom( rightBottom ), m_xKeepRatio( xKeepRatio ), m_yKeepRatio( yKeepRatio ), m_visible( visible ), m_up1Id( up1Id ), m_down1Id( down1Id ), m_over1Id( over1Id ), m_up2Id( up2Id ), m_down2Id( down2Id ), m_over2Id( over2Id ), m_state( state ), m_action1( action1 ), m_action2( action2 ), m_tooltip1( tooltip1 ), m_tooltip2( tooltip2 ), m_help( help ), m_layer( layer ), m_windowId( windowId ), m_layoutId( layoutId ), m_panelId( panelId ) {}
 
         string m_id;
         int m_xPos;
@@ -256,6 +257,7 @@ m_id( id ), m_xPos( xPos ), m_yPos( yPos ), m_leftTop( leftTop ), m_rightBottom(
         int m_layer;
         string m_windowId;
         string m_layoutId;
+        string m_panelId;
     };
     /// List
     list<Checkbox> m_listCheckbox;
@@ -263,8 +265,8 @@ m_id( id ), m_xPos( xPos ), m_yPos( yPos ), m_leftTop( leftTop ), m_rightBottom(
     /// Type definition
     struct Image
     {
-        Image( const string & id, int xPos, int yPos, const string & leftTop, const string & rightBottom, bool xKeepRatio, bool yKeepRatio, const string & visible, const string & bmpId, const string & actionId, const string & action2Id, const string & resize, const string & help, int layer, const string & windowId, const string & layoutId ):
-m_id( id ), m_xPos( xPos ), m_yPos( yPos ), m_leftTop( leftTop ), m_rightBottom( rightBottom ), m_xKeepRatio( xKeepRatio ), m_yKeepRatio( yKeepRatio ), m_visible( visible ), m_bmpId( bmpId ), m_actionId( actionId ), m_action2Id( action2Id ), m_resize( resize ), m_help( help ), m_layer( layer ), m_windowId( windowId ), m_layoutId( layoutId ) {}
+        Image( const string & id, int xPos, int yPos, const string & leftTop, const string & rightBottom, bool xKeepRatio, bool yKeepRatio, const string & visible, const string & bmpId, const string & actionId, const string & action2Id, const string & resize, const string & help, int layer, const string & windowId, const string & layoutId, const string & panelId ):
+m_id( id ), m_xPos( xPos ), m_yPos( yPos ), m_leftTop( leftTop ), m_rightBottom( rightBottom ), m_xKeepRatio( xKeepRatio ), m_yKeepRatio( yKeepRatio ), m_visible( visible ), m_bmpId( bmpId ), m_actionId( actionId ), m_action2Id( action2Id ), m_resize( resize ), m_help( help ), m_layer( layer ), m_windowId( windowId ), m_layoutId( layoutId ), m_panelId( panelId ) {}
 
         string m_id;
         int m_xPos;
@@ -282,6 +284,7 @@ m_id( id ), m_xPos( xPos ), m_yPos( yPos ), m_leftTop( leftTop ), m_rightBottom(
         int m_layer;
         string m_windowId;
         string m_layoutId;
+        string m_panelId;
     };
     /// List
     list<Image> m_listImage;
@@ -298,11 +301,34 @@ m_id( id ), m_file( file ) {}
     /// List
     list<IniFile> m_listIniFile;
 
+    /// Type definition
+    struct Panel
+    {
+        Panel( const string & id, int xPos, int yPos, const string & leftTop, const string & rightBottom, bool xKeepRatio, bool yKeepRatio, int width, int height, int layer, const string & windowId, const string & layoutId, const string & panelId ):
+m_id( id ), m_xPos( xPos ), m_yPos( yPos ), m_leftTop( leftTop ), m_rightBottom( rightBottom ), m_xKeepRatio( xKeepRatio ), m_yKeepRatio( yKeepRatio ), m_width( width ), m_height( height ), m_layer( layer ), m_windowId( windowId ), m_layoutId( layoutId ), m_panelId( panelId ) {}
+
+        string m_id;
+        int m_xPos;
+        int m_yPos;
+        string m_leftTop;
+        string m_rightBottom;
+        bool m_xKeepRatio;
+        bool m_yKeepRatio;
+        int m_width;
+        int m_height;
+        int m_layer;
+        string m_windowId;
+        string m_layoutId;
+        string m_panelId;
+    };
+    /// List
+    list<Panel> m_listPanel;
+
     /// Type definition
     struct Text
     {
-        Text( const string & id, int xPos, int yPos, const string & visible, const string & fontId, const string & text, int width, const string & leftTop, const string & rightBottom, bool xKeepRatio, bool yKeepRatio, uint32_t color, const string & scrolling, const string & alignment, const string & help, int layer, const string & windowId, const string & layoutId ):
-m_id( id ), m_xPos( xPos ), m_yPos( yPos ), m_visible( visible ), m_fontId( fontId ), m_text( text ), m_width( width ), m_leftTop( leftTop ), m_rightBottom( rightBottom ), m_xKeepRatio( xKeepRatio ), m_yKeepRatio( yKeepRatio ), m_color( color ), m_scrolling( scrolling ), m_alignment( alignment ), m_help( help ), m_layer( layer ), m_windowId( windowId ), m_layoutId( layoutId ) {}
+        Text( const string & id, int xPos, int yPos, const string & visible, const string & fontId, const string & text, int width, const string & leftTop, const string & rightBottom, bool xKeepRatio, bool yKeepRatio, uint32_t color, const string & scrolling, const string & alignment, const string & help, int layer, const string & windowId, const string & layoutId, const string & panelId ):
+m_id( id ), m_xPos( xPos ), m_yPos( yPos ), m_visible( visible ), m_fontId( fontId ), m_text( text ), m_width( width ), m_leftTop( leftTop ), m_rightBottom( rightBottom ), m_xKeepRatio( xKeepRatio ), m_yKeepRatio( yKeepRatio ), m_color( color ), m_scrolling( scrolling ), m_alignment( alignment ), m_help( help ), m_layer( layer ), m_windowId( windowId ), m_layoutId( layoutId ), m_panelId( panelId ) {}
 
         string m_id;
         int m_xPos;
@@ -322,6 +348,7 @@ m_id( id ), m_xPos( xPos ), m_yPos( yPos ), m_visible( visible ), m_fontId( font
         int m_layer;
         string m_windowId;
         string m_layoutId;
+        string m_panelId;
     };
     /// List
     list<Text> m_listText;
@@ -329,8 +356,8 @@ m_id( id ), m_xPos( xPos ), m_yPos( yPos ), m_visible( visible ), m_fontId( font
     /// Type definition
     struct RadialSlider
     {
-        RadialSlider( const string & id, const string & visible, int xPos, int yPos, const string & leftTop, const string & rightBottom, bool xKeepRatio, bool yKeepRatio, const string & sequence, int nbImages, float minAngle, float maxAngle, const string & value, const string & tooltip, const string & help, int layer, const string & windowId, const string & layoutId ):
-m_id( id ), m_visible( visible ), m_xPos( xPos ), m_yPos( yPos ), m_leftTop( leftTop ), m_rightBottom( rightBottom ), m_xKeepRatio( xKeepRatio ), m_yKeepRatio( yKeepRatio ), m_sequence( sequence ), m_nbImages( nbImages ), m_minAngle( minAngle ), m_maxAngle( maxAngle ), m_value( value ), m_tooltip( tooltip ), m_help( help ), m_layer( layer ), m_windowId( windowId ), m_layoutId( layoutId ) {}
+        RadialSlider( const string & id, const string & visible, int xPos, int yPos, const string & leftTop, const string & rightBottom, bool xKeepRatio, bool yKeepRatio, const string & sequence, int nbImages, float minAngle, float maxAngle, const string & value, const string & tooltip, const string & help, int layer, const string & windowId, const string & layoutId, const string & panelId ):
+m_id( id ), m_visible( visible ), m_xPos( xPos ), m_yPos( yPos ), m_leftTop( leftTop ), m_rightBottom( rightBottom ), m_xKeepRatio( xKeepRatio ), m_yKeepRatio( yKeepRatio ), m_sequence( sequence ), m_nbImages( nbImages ), m_minAngle( minAngle ), m_maxAngle( maxAngle ), m_value( value ), m_tooltip( tooltip ), m_help( help ), m_layer( layer ), m_windowId( windowId ), m_layoutId( layoutId ), m_panelId( panelId ) {}
 
         string m_id;
         string m_visible;
@@ -350,6 +377,7 @@ m_id( id ), m_visible( visible ), m_xPos( xPos ), m_yPos( yPos ), m_leftTop( lef
         int m_layer;
         string m_windowId;
         string m_layoutId;
+        string m_panelId;
     };
     /// List
     list<RadialSlider> m_listRadialSlider;
@@ -357,8 +385,8 @@ m_id( id ), m_visible( visible ), m_xPos( xPos ), m_yPos( yPos ), m_leftTop( lef
     /// Type definition
     struct Slider
     {
-        Slider( const string & id, const string & visible, int xPos, int yPos, const string & leftTop, const string & rightBottom, bool xKeepRatio, bool yKeepRatio, const string & upId, const string & downId, const string & overId, const string & points, int thickness, const string & value, const string & imageId, int nbHoriz, int nbVert, int padHoriz, int padVert, const string & tooltip, const string & help, int layer, const string & windowId, const string & layoutId ):
-m_id( id ), m_visible( visible ), m_xPos( xPos ), m_yPos( yPos ), m_leftTop( leftTop ), m_rightBottom( rightBottom ), m_xKeepRatio( xKeepRatio ), m_yKeepRatio( yKeepRatio ), m_upId( upId ), m_downId( downId ), m_overId( overId ), m_points( points ), m_thickness( thickness ), m_value( value ), m_imageId( imageId ), m_nbHoriz( nbHoriz ), m_nbVert( nbVert ), m_padHoriz( padHoriz ), m_padVert( padVert ), m_tooltip( tooltip ), m_help( help ), m_layer( layer ), m_windowId( windowId ), m_layoutId( layoutId ) {}
+        Slider( const string & id, const string & visible, int xPos, int yPos, const string & leftTop, const string & rightBottom, bool xKeepRatio, bool yKeepRatio, const string & upId, const string & downId, const string & overId, const string & points, int thickness, const string & value, const string & imageId, int nbHoriz, int nbVert, int padHoriz, int padVert, const string & tooltip, const string & help, int layer, const string & windowId, const string & layoutId, const string & panelId ):
+m_id( id ), m_visible( visible ), m_xPos( xPos ), m_yPos( yPos ), m_leftTop( leftTop ), m_rightBottom( rightBottom ), m_xKeepRatio( xKeepRatio ), m_yKeepRatio( yKeepRatio ), m_upId( upId ), m_downId( downId ), m_overId( overId ), m_points( points ), m_thickness( thickness ), m_value( value ), m_imageId( imageId ), m_nbHoriz( nbHoriz ), m_nbVert( nbVert ), m_padHoriz( padHoriz ), m_padVert( padVert ), m_tooltip( tooltip ), m_help( help ), m_layer( layer ), m_windowId( windowId ), m_layoutId( layoutId ), m_panelId( panelId ) {}
 
         string m_id;
         string m_visible;
@@ -384,6 +412,7 @@ m_id( id ), m_visible( visible ), m_xPos( xPos ), m_yPos( yPos ), m_leftTop( lef
         int m_layer;
         string m_windowId;
         string m_layoutId;
+        string m_panelId;
     };
     /// List
     list<Slider> m_listSlider;
@@ -391,8 +420,8 @@ m_id( id ), m_visible( visible ), m_xPos( xPos ), m_yPos( yPos ), m_leftTop( lef
     /// Type definition
     struct List
     {
-        List( const string & id, int xPos, int yPos, const string & visible, int width, int height, const string & leftTop, const string & rightBottom, bool xKeepRatio, bool yKeepRatio, const string & fontId, const string & var, const string & bgImageId, const string & fgColor, const string & playColor, const string & bgColor1, const string & bgColor2, const string & selColor, const string & help, int layer, const string & windowId, const string & layoutId ):
-m_id( id ), m_xPos( xPos ), m_yPos( yPos ), m_visible( visible ), m_width( width ), m_height( height ), m_leftTop( leftTop ), m_rightBottom( rightBottom ), m_xKeepRatio( xKeepRatio ), m_yKeepRatio( yKeepRatio ), m_fontId( fontId ), m_var( var ), m_bgImageId( bgImageId ), m_fgColor( fgColor ), m_playColor( playColor ), m_bgColor1( bgColor1 ), m_bgColor2( bgColor2 ), m_selColor( selColor ), m_help( help ), m_layer( layer ), m_windowId( windowId ), m_layoutId( layoutId ) {}
+        List( const string & id, int xPos, int yPos, const string & visible, int width, int height, const string & leftTop, const string & rightBottom, bool xKeepRatio, bool yKeepRatio, const string & fontId, const string & var, const string & bgImageId, const string & fgColor, const string & playColor, const string & bgColor1, const string & bgColor2, const string & selColor, const string & help, int layer, const string & windowId, const string & layoutId, const string & panelId ):
+m_id( id ), m_xPos( xPos ), m_yPos( yPos ), m_visible( visible ), m_width( width ), m_height( height ), m_leftTop( leftTop ), m_rightBottom( rightBottom ), m_xKeepRatio( xKeepRatio ), m_yKeepRatio( yKeepRatio ), m_fontId( fontId ), m_var( var ), m_bgImageId( bgImageId ), m_fgColor( fgColor ), m_playColor( playColor ), m_bgColor1( bgColor1 ), m_bgColor2( bgColor2 ), m_selColor( selColor ), m_help( help ), m_layer( layer ), m_windowId( windowId ), m_layoutId( layoutId ), m_panelId( panelId ) {}
 
         string m_id;
         int m_xPos;
@@ -416,6 +445,7 @@ m_id( id ), m_xPos( xPos ), m_yPos( yPos ), m_visible( visible ), m_width( width
         int m_layer;
         string m_windowId;
         string m_layoutId;
+        string m_panelId;
     };
     /// List
     list<List> m_listList;
@@ -423,8 +453,8 @@ m_id( id ), m_xPos( xPos ), m_yPos( yPos ), m_visible( visible ), m_width( width
     /// Type definition
     struct Tree
     {
-        Tree( const string & id, int xPos, int yPos, const string & visible, const string & flat, int width, int height, const string & leftTop, const string & rightBottom, bool xKeepRatio, bool yKeepRatio, const string & fontId, const string & var, const string & bgImageId, const string & itemImageId, const string & openImageId, const string & closedImageId, const string & fgColor, const string & playColor, const string & bgColor1, const string & bgColor2, const string & selColor, const string & help, int layer, const string & windowId, const string & layoutId ):
-m_id( id ), m_xPos( xPos ), m_yPos( yPos ), m_visible( visible ), m_flat( flat ), m_width( width ), m_height( height ), m_leftTop( leftTop ), m_rightBottom( rightBottom ), m_xKeepRatio( xKeepRatio ), m_yKeepRatio( yKeepRatio ), m_fontId( fontId ), m_var( var ), m_bgImageId( bgImageId ), m_itemImageId( itemImageId ), m_openImageId( openImageId ), m_closedImageId( closedImageId ), m_fgColor( fgColor ), m_playColor( playColor ), m_bgColor1( bgColor1 ), m_bgColor2( bgColor2 ), m_selColor( selColor ), m_help( help ), m_layer( layer ), m_windowId( windowId ), m_layoutId( layoutId ) {}
+        Tree( const string & id, int xPos, int yPos, const string & visible, const string & flat, int width, int height, const string & leftTop, const string & rightBottom, bool xKeepRatio, bool yKeepRatio, const string & fontId, const string & var, const string & bgImageId, const string & itemImageId, const string & openImageId, const string & closedImageId, const string & fgColor, const string & playColor, const string & bgColor1, const string & bgColor2, const string & selColor, const string & help, int layer, const string & windowId, const string & layoutId, const string & panelId ):
+m_id( id ), m_xPos( xPos ), m_yPos( yPos ), m_visible( visible ), m_flat( flat ), m_width( width ), m_height( height ), m_leftTop( leftTop ), m_rightBottom( rightBottom ), m_xKeepRatio( xKeepRatio ), m_yKeepRatio( yKeepRatio ), m_fontId( fontId ), m_var( var ), m_bgImageId( bgImageId ), m_itemImageId( itemImageId ), m_openImageId( openImageId ), m_closedImageId( closedImageId ), m_fgColor( fgColor ), m_playColor( playColor ), m_bgColor1( bgColor1 ), m_bgColor2( bgColor2 ), m_selColor( selColor ), m_help( help ), m_layer( layer ), m_windowId( windowId ), m_layoutId( layoutId ), m_panelId( panelId ) {}
 
         string m_id;
         int m_xPos;
@@ -452,6 +482,7 @@ m_id( id ), m_xPos( xPos ), m_yPos( yPos ), m_visible( visible ), m_flat( flat )
         int m_layer;
         string m_windowId;
         string m_layoutId;
+        string m_panelId;
     };
     /// List
     list<Tree> m_listTree;
@@ -459,8 +490,8 @@ m_id( id ), m_xPos( xPos ), m_yPos( yPos ), m_visible( visible ), m_flat( flat )
     /// Type definition
     struct Video
     {
-        Video( const string & id, int xPos, int yPos, int width, int height, const string & leftTop, const string & rightBottom, bool xKeepRatio, bool yKeepRatio, const string & visible, bool autoResize, const string & help, int layer, const string & windowId, const string & layoutId ):
-m_id( id ), m_xPos( xPos ), m_yPos( yPos ), m_width( width ), m_height( height ), m_leftTop( leftTop ), m_rightBottom( rightBottom ), m_xKeepRatio( xKeepRatio ), m_yKeepRatio( yKeepRatio ), m_visible( visible ), m_autoResize( autoResize ), m_help( help ), m_layer( layer ), m_windowId( windowId ), m_layoutId( layoutId ) {}
+        Video( const string & id, int xPos, int yPos, int width, int height, const string & leftTop, const string & rightBottom, bool xKeepRatio, bool yKeepRatio, const string & visible, bool autoResize, const string & help, int layer, const string & windowId, const string & layoutId, const string & panelId ):
+m_id( id ), m_xPos( xPos ), m_yPos( yPos ), m_width( width ), m_height( height ), m_leftTop( leftTop ), m_rightBottom( rightBottom ), m_xKeepRatio( xKeepRatio ), m_yKeepRatio( yKeepRatio ), m_visible( visible ), m_autoResize( autoResize ), m_help( help ), m_layer( layer ), m_windowId( windowId ), m_layoutId( layoutId ), m_panelId( panelId ) {}
 
         string m_id;
         int m_xPos;
@@ -477,6 +508,7 @@ m_id( id ), m_xPos( xPos ), m_yPos( yPos ), m_width( width ), m_height( height )
         int m_layer;
         string m_windowId;
         string m_layoutId;
+        string m_panelId;
     };
     /// List
     list<Video> m_listVideo;
index f5ebdcf0135c9b5ece7889a77ccb469a75447f29..aa222263f6071a1b46dffaa96e5c9b7b92f1196f 100644 (file)
@@ -36,6 +36,11 @@ SkinParser::SkinParser( intf_thread_t *pIntf, const string &rFileName,
     {
         m_pData = new BuilderData();
     }
+
+    // Special id, we don't want any control to have the same one
+    m_idSet.insert( "none" );
+    // At the beginning, there is no Panel
+    m_panelStack.push_back( "none" );
 }
 
 
@@ -196,7 +201,7 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr )
                 convertBoolean( attr["ykeepratio"] ), attr["visible"],
                 attr["up"], attr["down"], attr["over"], attr["action"],
                 attr["tooltiptext"], attr["help"],
-                m_curLayer, m_curWindowId, m_curLayoutId );
+                m_curLayer, m_curWindowId, m_curLayoutId, m_panelStack.back() );
         m_curLayer++;
         m_pData->m_listButton.push_back( button );
     }
@@ -233,7 +238,7 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr )
                 attr["up2"], attr["down2"], attr["over2"], attr["state"],
                 attr["action1"], attr["action2"], attr["tooltiptext1"],
                 attr["tooltiptext2"], attr["help"], m_curLayer, m_curWindowId,
-                m_curLayoutId );
+                m_curLayoutId, m_panelStack.back() );
         m_curLayer++;
         m_pData->m_listCheckbox.push_back( checkbox );
     }
@@ -282,7 +287,8 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr )
                 convertBoolean( attr["xkeepratio"] ),
                 convertBoolean( attr["ykeepratio"] ), attr["visible"],
                 attr["image"], attr["action"], attr["action2"], attr["resize"],
-                attr["help"], m_curLayer, m_curWindowId, m_curLayoutId );
+                attr["help"], m_curLayer, m_curWindowId, m_curLayoutId,
+                m_panelStack.back() );
         m_curLayer++;
         m_pData->m_listImage.push_back( imageData );
     }
@@ -305,6 +311,32 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr )
         m_pData->m_listLayout.push_back( layout );
         m_curLayer = 0;
     }
+
+    else if( rName == "Panel" )
+    {
+        CheckDefault( "x", "0" );
+        CheckDefault( "y", "0" );
+        CheckDefault( "lefttop", "lefttop" );
+        CheckDefault( "rightbottom", "lefttop" );
+        CheckDefault( "xkeepratio", "false" );
+        CheckDefault( "ykeepratio", "false" );
+        RequireDefault( "width" );
+        RequireDefault( "height" );
+
+        string panelId = uniqueId( "none" );
+        const BuilderData::Panel panel( panelId,
+                atoi( attr["x"] ) + m_xOffset, atoi( attr["y"] ) + m_yOffset,
+                attr["lefttop"], attr["rightbottom"],
+                convertBoolean( attr["xkeepratio"] ),
+                convertBoolean( attr["ykeepratio"] ),
+                atoi( attr["width"] ), atoi( attr["height" ] ),
+                m_curLayer, m_curWindowId, m_curLayoutId, m_panelStack.back() );
+        m_curLayer++;
+        m_pData->m_listPanel.push_back( panel );
+        // Add the panel to the stack
+        m_panelStack.push_back( panelId );
+    }
+
     else if( rName == "Playlist" )
     {
         RequireDefault( "id" );
@@ -346,7 +378,7 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr )
                 attr["bgcolor1"],
                 attr["bgcolor2"],
                 attr["selcolor"], attr["help"],
-                m_curLayer, m_curWindowId, m_curLayoutId );
+                m_curLayer, m_curWindowId, m_curLayoutId, m_panelStack.back() );
         m_curLayer++;
         m_pData->m_listTree.push_back( treeData );
     }
@@ -389,7 +421,7 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr )
                 attr["fgcolor"], attr["playcolor"],
                 attr["bgcolor1"], attr["bgcolor2"],
                 attr["selcolor"], attr["help"],
-                m_curLayer, m_curWindowId, m_curLayoutId );
+                m_curLayer, m_curWindowId, m_curLayoutId, m_panelStack.back() );
         m_curLayer++;
         m_pData->m_listTree.push_back( treeData );
     }
@@ -421,7 +453,7 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr )
                 atoi( attr["nbImages"] ), atof( attr["minAngle"] ) * M_PI /180,
                 atof( attr["maxAngle"] ) * M_PI / 180, attr["value"],
                 attr["tooltiptext"], attr["help"], m_curLayer, m_curWindowId,
-                m_curLayoutId );
+                m_curLayoutId, m_panelStack.back() );
         m_curLayer++;
         m_pData->m_listRadialSlider.push_back( radial );
     }
@@ -458,7 +490,8 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr )
                 convertBoolean( attr["ykeepratio"] ), attr["up"], attr["down"],
                 attr["over"], attr["points"], atoi( attr["thickness"] ),
                 newValue, "none", 0, 0, 0, 0, attr["tooltiptext"],
-                attr["help"], m_curLayer, m_curWindowId, m_curLayoutId );
+                attr["help"], m_curLayer, m_curWindowId, m_curLayoutId,
+                m_panelStack.back() );
         m_curLayer++;
         m_pData->m_listSlider.push_back( slider );
     }
@@ -508,7 +541,8 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr )
                 convertBoolean( attr["ykeepratio"] ),
                 convertColor( attr["color"] ),
                 attr["scrolling"], attr["alignment"],
-                attr["help"], m_curLayer, m_curWindowId, m_curLayoutId );
+                attr["help"], m_curLayer, m_curWindowId, m_curLayoutId,
+                m_panelStack.back() );
         m_curLayer++;
         m_pData->m_listText.push_back( textData );
     }
@@ -568,7 +602,8 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr )
                 convertBoolean( attr["xkeepratio"] ),
                 convertBoolean( attr["ykeepratio"] ),
                 attr["visible"], convertBoolean( attr["autoresize"] ),
-                attr["help"], m_curLayer, m_curWindowId, m_curLayoutId );
+                attr["help"], m_curLayer, m_curWindowId, m_curLayoutId,
+                m_panelStack.back() );
         m_curLayer++;
         m_pData->m_listVideo.push_back( videoData );
     }
@@ -611,6 +646,10 @@ void SkinParser::handleEndElement( const string &rName )
         m_curPopupId = "";
         m_popupPosList.pop_back();
     }
+    else if( rName == "Panel" )
+    {
+        m_panelStack.pop_back();
+    }
 }
 
 
index 7813d87e444ff03c4a613768d224de9ea81db3d7..8ce64cb6521c9b5a66057e3fd9dd8dca8ec38ba9 100644 (file)
@@ -61,6 +61,8 @@ class SkinParser: public XMLParser
         /// Current offset of the controls
         int m_xOffset, m_yOffset;
         list<int> m_xOffsetList, m_yOffsetList;
+        /// Stack of panel ids
+        list<string> m_panelStack;
         /// Layer of the current control in the layout
         int m_curLayer;
         /// Set of used id
index c3bd603825f3512245467af7810553b82987326b..d899c7d6ea529601e382c5d756602cd3c5479fc0 100644 (file)
@@ -36,8 +36,8 @@
 GenericLayout::GenericLayout( intf_thread_t *pIntf, int width, int height,
                               int minWidth, int maxWidth, int minHeight,
                               int maxHeight ):
-    SkinObject( pIntf ), m_pWindow( NULL ), m_width( width ),
-    m_height( height ), m_minWidth( minWidth ), m_maxWidth( maxWidth ),
+    SkinObject( pIntf ), m_pWindow( NULL ), m_rect( 0, 0, width, height ),
+    m_minWidth( minWidth ), m_maxWidth( maxWidth ),
     m_minHeight( minHeight ), m_maxHeight( maxHeight ), m_pVideoControl( NULL ),
     m_visible( false ), m_pVarActive( NULL )
 {
@@ -106,7 +106,7 @@ void GenericLayout::addControl( CtrlGeneric *pControl,
         pControl->draw( *m_pImage, rPosition.getLeft(), rPosition.getTop() );
 
         // Add the control in the list.
-        // This list must remain sorted by layer order 
+        // This list must remain sorted by layer order
         list<LayeredControl>::iterator it;
         for( it = m_controlList.begin(); it != m_controlList.end(); it++ )
         {
@@ -165,8 +165,7 @@ void GenericLayout::onControlUpdate( const CtrlGeneric &rCtrl,
 void GenericLayout::resize( int width, int height )
 {
     // Update the window size
-    m_width = width;
-    m_height = height;
+    m_rect = Rect( 0, 0 , width, height );
 
     // Recreate a new image
     if( m_pImage )
@@ -199,7 +198,7 @@ void GenericLayout::resize( int width, int height )
 
 void GenericLayout::refreshAll()
 {
-    refreshRect( 0, 0, m_width, m_height );
+    refreshRect( 0, 0, m_rect.getWidth(), m_rect.getHeight() );
 }
 
 
@@ -231,10 +230,10 @@ void GenericLayout::refreshRect( int x, int y, int width, int height )
             x = 0;
         if( y < 0)
             y = 0;
-        if( x + width > m_width )
-            width = m_width - x;
-        if( y + height > m_height )
-            height = m_height - y;
+        if( x + width > m_rect.getWidth() )
+            width = m_rect.getWidth() - x;
+        if( y + height > m_rect.getHeight() )
+            height = m_rect.getHeight() - y;
 
         // Refresh the window... but do not paint on a visible video control!
         if( !m_pVideoControl || !m_pVideoControl->isVisible() )
index 0f3066d1450998018a5030e6c01117a19ec669a6..822608fd0567f71c3b464757087d568829df0791 100644 (file)
@@ -53,7 +53,7 @@ struct LayeredControl
 
 
 /// Base class for layouts
-class GenericLayout: public SkinObject, public Box
+class GenericLayout: public SkinObject
 {
     public:
         GenericLayout( intf_thread_t *pIntf, int width, int height,
@@ -84,12 +84,20 @@ class GenericLayout: public SkinObject, public Box
         virtual OSGraphics *getImage() const { return m_pImage; }
 
         /// Get the position of the layout (relative to the screen)
+        /**
+         * Note: These values are different from the m_rect.getLeft() and
+         * m_rect.getTop(), which always return 0.
+         * The latter methods are there as a "root rect" for the panels and
+         * controls, since each control knows its parent rect, but returns
+         * coordinates relative to the root rect.
+         */
         virtual int getLeft() const { return m_pWindow->getLeft(); }
         virtual int getTop() const { return m_pWindow->getTop(); }
 
         /// Get the size of the layout
-        virtual int getWidth() const { return m_width; }
-        virtual int getHeight() const { return m_height; }
+        virtual int getWidth() const { return m_rect.getWidth(); }
+        virtual int getHeight() const { return m_rect.getHeight(); }
+        virtual const GenericRect &getRect() const { return m_rect; }
 
         /// Get the minimum and maximum size of the layout
         virtual int getMinWidth() const { return m_minWidth; }
@@ -141,14 +149,14 @@ class GenericLayout: public SkinObject, public Box
         /// Parent window of the layout
         TopWindow *m_pWindow;
         /// Layout size
-        int m_width, m_height;
+        Rect m_rect;
         int m_minWidth, m_maxWidth;
         int m_minHeight, m_maxHeight;
         /// Image of the layout
         OSGraphics *m_pImage;
         /// List of the controls in the layout
         list<LayeredControl> m_controlList;
-        //// Video control
+        /// Video control
         CtrlVideo *m_pVideoControl;
         /// List of the anchors in the layout
         list<Anchor*> m_anchorList;
index 696e9c3f2cef8b70f1f6d84a5dbe8278f219967c..af7c2f9a2f497b47fde01dff67bd23d855c0e94f 100644 (file)
@@ -197,35 +197,39 @@ void Theme::saveConfig()
     while( pos != string::npos ); \
     return NULL;
 
-GenericBitmap *Theme::getBitmapById( const string &id )
+GenericBitmap *Theme::getBitmapById( const string &id ) const
 {
     FIND_FIRST_OBJECT( GenericBitmapPtr, m_bitmaps );
 }
 
-GenericFont *Theme::getFontById( const string &id )
+GenericFont *Theme::getFontById( const string &id ) const
 {
     FIND_FIRST_OBJECT( GenericFontPtr, m_fonts );
 }
 
-Popup *Theme::getPopupById( const string &id )
+Popup *Theme::getPopupById( const string &id ) const
 {
     FIND_OBJECT( PopupPtr, m_popups );
 }
 
-TopWindow *Theme::getWindowById( const string &id )
+TopWindow *Theme::getWindowById( const string &id ) const
 {
     FIND_OBJECT( TopWindowPtr, m_windows );
 }
 
-GenericLayout *Theme::getLayoutById( const string &id )
+GenericLayout *Theme::getLayoutById( const string &id ) const
 {
     FIND_OBJECT( GenericLayoutPtr, m_layouts );
 }
 
-CtrlGeneric *Theme::getControlById( const string &id )
+CtrlGeneric *Theme::getControlById( const string &id ) const
 {
     FIND_OBJECT( CtrlGenericPtr, m_controls );
 }
 
+Position *Theme::getPositionById( const string &id ) const
+{
+    FIND_OBJECT( PositionPtr, m_positions );
+}
 
 
index c94cbc25239d81c33514e120990b976547d58657..bcad169a2e01771be071f261ead32150caefd972 100644 (file)
@@ -33,6 +33,7 @@
 #include "../commands/cmd_generic.hpp"
 #include "../utils/bezier.hpp"
 #include "../utils/variable.hpp"
+#include "../utils/position.hpp"
 #include "../controls/ctrl_generic.hpp"
 #include <string>
 #include <list>
@@ -55,12 +56,13 @@ class Theme: public SkinObject
         void loadConfig();
         void saveConfig();
 
-        GenericBitmap *getBitmapById( const string &id );
-        GenericFont *getFontById( const string &id );
-        Popup *getPopupById( const string &id );
-        TopWindow *getWindowById( const string &id );
-        GenericLayout *getLayoutById( const string &id );
-        CtrlGeneric *getControlById( const string &id );
+        GenericBitmap *getBitmapById( const string &id ) const;
+        GenericFont *getFontById( const string &id ) const;
+        Popup *getPopupById( const string &id ) const;
+        TopWindow *getWindowById( const string &id ) const;
+        GenericLayout *getLayoutById( const string &id ) const;
+        CtrlGeneric *getControlById( const string &id ) const;
+        Position *getPositionById( const string &id ) const;
 
         WindowManager &getWindowManager() { return m_windowManager; }
 
@@ -77,6 +79,8 @@ class Theme: public SkinObject
         map<string, GenericLayoutPtr> m_layouts;
         /// Store the controls by ID
         map<string, CtrlGenericPtr> m_controls;
+        /// Store the panel positions by ID
+        map<string, PositionPtr> m_positions;
         /// Store the commands
         list<CmdGenericPtr> m_commands;
         /// Store the Bezier curves
index ccc42ff3bd5917d82f73bbf4444a1291e132c602..904e06be9740d87bf07de04fb967b7493d317e4e 100644 (file)
@@ -465,17 +465,17 @@ void WindowManager::checkAnchors( TopWindow *pWindow,
         {
             yOffset = workArea.getTop() - (*itMov)->getTop();
         }
-        if( newLeft + (*itMov)->getWidth() > workArea.getRight() - m_magnet &&
-            newLeft + (*itMov)->getWidth() < workArea.getRight() + m_magnet )
+        int right = workArea.getLeft() + workArea.getWidth();
+        if( newLeft + (*itMov)->getWidth() > right - m_magnet &&
+            newLeft + (*itMov)->getWidth() < right + m_magnet )
         {
-            xOffset = workArea.getRight() - (*itMov)->getLeft()
-                      - (*itMov)->getWidth();
+            xOffset = right - (*itMov)->getLeft() - (*itMov)->getWidth();
         }
-        if( newTop + (*itMov)->getHeight() > workArea.getBottom() - m_magnet &&
-            newTop + (*itMov)->getHeight() <  workArea.getBottom() + m_magnet )
+        int bottom = workArea.getTop() + workArea.getHeight();
+        if( newTop + (*itMov)->getHeight() > bottom - m_magnet &&
+            newTop + (*itMov)->getHeight() <  bottom + m_magnet )
         {
-            yOffset =  workArea.getBottom() - (*itMov)->getTop()
-                       - (*itMov)->getHeight();
+            yOffset =  bottom - (*itMov)->getTop() - (*itMov)->getHeight();
         }
     }
 
index 433ec11122fe36225d1321027eabfd4fa527e411..8e7b47a7a2ccc572cbbcc6dbce83e106f7c9bd8e 100644 (file)
@@ -81,7 +81,7 @@ class WindowManager: public SkinObject
          */
         void move( TopWindow &rWindow, int left, int top ) const;
 
-        /// Tell the window manager that a resize is initiated for rWindow
+        /// Tell the window manager that a resize is initiated for rLayout
         void startResize( GenericLayout &rLayout, Direction_t direction );
 
         /// Tell the window manager that the current resizing ended
index 5529fc7b5cb224edab9f8ad61b1ebed699034115..9a354108d93c2d5bad5f118ca7b3e7cebe3056aa 100644 (file)
@@ -34,28 +34,29 @@ Rect::Rect( int left, int top, int right, int bottom ):
 }
 
 
-Position::Position( int left, int top, int right, int bottom, const Box &rBox,
-                    Ref_t refLeftTop, Ref_t refRightBottom, bool xKeepRatio,
-                    bool yKeepRatio ):
+Position::Position( int left, int top, int right, int bottom,
+                    const GenericRect &rRect,
+                    Ref_t refLeftTop, Ref_t refRightBottom,
+                    bool xKeepRatio, bool yKeepRatio ):
     m_left( left ), m_top( top ), m_right( right ), m_bottom( bottom ),
-    m_rBox( rBox ), m_refLeftTop( refLeftTop ),
+    m_rRect( rRect ), m_refLeftTop( refLeftTop ),
     m_refRighBottom( refRightBottom ), m_xKeepRatio( xKeepRatio ),
     m_yKeepRatio( yKeepRatio )
 {
     // Here is how the resizing algorithm works:
     //
     //  - if we "keep the ratio" (xkeepratio="true" in the XML), the relative
-    //    position of the control in the layout (i.e. the given rBox) is
+    //    position of the control in the parent box (i.e. the given rRect) is
     //    saved, and will be kept constant. The size of the control will not
     //    be changed, only its position may vary. To do that, we consider the
-    //    part of the layout to the left of the control (for an horizontal
-    //    resizing) and the part of the layout to the right of the control,
+    //    part of the box to the left of the control (for an horizontal
+    //    resizing) and the part of the box to the right of the control,
     //    and we make sure that the ratio between their widths is constant.
     //
     //  - if we don't keep the ratio, the resizing algorithm is completely
     //    different. We consider that the top left hand corner of the control
     //    ("lefttop" attribute in the XML) is linked to one of the 4 corners
-    //    of the layouts ("lefttop", "leftbottom", "righttop" and
+    //    of the parent box ("lefttop", "leftbottom", "righttop" and
     //    "rightbottom" values for the attribute). Same thing for the bottom
     //    right hand corner ("rightbottom" attribute). When resizing occurs,
     //    the linked corners will move together, and this will drive the
@@ -65,7 +66,7 @@ Position::Position( int left, int top, int right, int bottom, const Box &rBox,
     if( m_xKeepRatio )
     {
         // First compute the width of the box minus the width of the control
-        int freeSpace = m_rBox.getWidth() - (m_right - m_left);
+        int freeSpace = m_rRect.getWidth() - (m_right - m_left);
         // Instead of computing left/right, we compute left/(left+right),
         // which is more convenient in my opinion.
         if( freeSpace != 0 )
@@ -85,9 +86,9 @@ Position::Position( int left, int top, int right, int bottom, const Box &rBox,
     // Initial the vertical ratio
     if( m_yKeepRatio )
     {
-        // First compute the width of the box minus the width of the control
-        int freeSpace = m_rBox.getHeight() - (m_bottom - m_top);
-        // Instead of computing left/right, we compute left/(left+right),
+        // First compute the height of the box minus the height of the control
+        int freeSpace = m_rRect.getHeight() - (m_bottom - m_top);
+        // Instead of computing top/bottom, we compute top/(top+bottom),
         // which is more convenient in my opinion.
         if( freeSpace != 0 )
         {
@@ -112,8 +113,8 @@ int Position::getLeft() const
     {
         // Ratio mode
         // First compute the width of the box minus the width of the control
-        int freeSpace = m_rBox.getWidth() - (m_right - m_left);
-        return (int)(m_xRatio * freeSpace);
+        int freeSpace = m_rRect.getWidth() - (m_right - m_left);
+        return m_rRect.getLeft() + (int)(m_xRatio * freeSpace);
     }
     else
     {
@@ -121,11 +122,11 @@ int Position::getLeft() const
         {
             case kLeftTop:
             case kLeftBottom:
-                return m_left;
+                return m_rRect.getLeft() + m_left;
                 break;
             case kRightTop:
             case kRightBottom:
-                return m_rBox.getWidth() + m_left - 1;
+                return m_rRect.getLeft() + m_rRect.getWidth() + m_left - 1;
                 break;
         }
         // Avoid a warning
@@ -140,8 +141,8 @@ int Position::getTop() const
     {
         // Ratio mode
         // First compute the height of the box minus the height of the control
-        int freeSpace = m_rBox.getHeight() - (m_bottom - m_top);
-        return (int)(m_yRatio * freeSpace);
+        int freeSpace = m_rRect.getHeight() - (m_bottom - m_top);
+        return m_rRect.getTop() + (int)(m_yRatio * freeSpace);
     }
     else
     {
@@ -149,11 +150,11 @@ int Position::getTop() const
         {
             case kLeftTop:
             case kRightTop:
-                return m_top;
+                return m_rRect.getTop() + m_top;
                 break;
             case kRightBottom:
             case kLeftBottom:
-                return m_rBox.getHeight() + m_top - 1;
+                return m_rRect.getTop() + m_rRect.getHeight() + m_top - 1;
                 break;
         }
         // Avoid a warning
@@ -177,11 +178,11 @@ int Position::getRight() const
         {
             case kLeftTop:
             case kLeftBottom:
-                return m_right;
+                return m_rRect.getLeft() + m_right;
                 break;
             case kRightTop:
             case kRightBottom:
-                return m_rBox.getWidth() + m_right - 1;
+                return m_rRect.getLeft() + m_rRect.getWidth() + m_right - 1;
                 break;
         }
         // Avoid a warning
@@ -205,11 +206,11 @@ int Position::getBottom() const
         {
             case kLeftTop:
             case kRightTop:
-                return m_bottom;
+                return m_rRect.getTop() + m_bottom;
                 break;
             case kLeftBottom:
             case kRightBottom:
-                return m_rBox.getHeight() + m_bottom - 1;
+                return m_rRect.getTop() + m_rRect.getHeight() + m_bottom - 1;
                 break;
         }
         // Avoid a warning
index efd20c0754ee93edf0504f56c08ce0af188d1025..106e4b675d4b32798b13532341227bc8f6017911 100644 (file)
@@ -27,6 +27,7 @@
 
 #include "variable.hpp"
 #include "observer.hpp"
+#include "pointer.hpp"
 
 
 /// Interface for rectangular objects
@@ -41,17 +42,23 @@ class Box
 };
 
 
+/// Interface for rectangular objects with a position
+class GenericRect: public Box
+{
+    public:
+        virtual int getLeft() const = 0;
+        virtual int getTop() const = 0;
+};
+
+
 /// Characterization of a rectangle
-class Rect: public Box
+class Rect: public GenericRect
 {
     public:
         Rect( int left, int top, int right, int bottom );
 
         virtual int getLeft() const { return m_left; }
         virtual int getTop() const { return m_top; }
-        virtual int getRight() const { return m_right; }
-        virtual int getBottom() const { return m_bottom; }
-
         virtual int getWidth() const { return m_right - m_left; }
         virtual int getHeight() const { return m_bottom - m_top; }
 
@@ -64,7 +71,13 @@ class Rect: public Box
 
 
 /// Relative position of a rectangle in a box
-class Position
+/**
+ * Note: Even if the object is tied to its direct container rectangle, the
+ * coordinates returned by getLeft(), getTop(), getRight() and getBottom() are
+ * not relative to the direct container (which is usually a panel or the layout)
+ * but to the root container (i.e. the layout).
+ */
+class Position: public GenericRect
 {
     public:
         /// Type for reference edge/corner
@@ -81,20 +94,21 @@ class Position
         };
 
         /// Create a new position relative to the given box
-        Position( int left, int top, int right, int bottom, const Box &rBox,
+        Position( int left, int top, int right, int bottom,
+                  const GenericRect &rRect,
                   Ref_t refLeftTop, Ref_t refRightBottom,
                   bool xKeepRatio, bool yKeepRatio );
 
         ~Position() {}
 
         /// Get the position relative to the left top corner of the box
-        int getLeft() const;
-        int getTop() const;
+        virtual int getLeft() const;
+        virtual int getTop() const;
         int getRight() const;
         int getBottom() const;
         /// Get the size of the rectangle
-        int getWidth() const;
-        int getHeight() const;
+        virtual int getWidth() const;
+        virtual int getHeight() const;
         /// Get the reference corners
         Ref_t getRefLeftTop() const { return m_refLeftTop; }
         Ref_t getRefRightBottom() const { return m_refRighBottom; }
@@ -105,7 +119,7 @@ class Position
         int m_top;
         int m_right;
         int m_bottom;
-        const Box &m_rBox;
+        const GenericRect &m_rRect;
         Ref_t m_refLeftTop;
         Ref_t m_refRighBottom;
         /// "Keep ratio" mode
@@ -117,6 +131,8 @@ class Position
         double m_yRatio;
 };
 
+typedef CountedPtr<Position> PositionPtr;
+
 
 /// Variable implementing the Box interface
 class VarBox: public Variable, public Box, public Subject<VarBox>
index e04bd635b0b698296e928fff1dd75ef156520ad0..70eee65185149effe9d669a6ef973e1754c29938 100644 (file)
         minheight   CDATA   "-1"
         maxheight   CDATA   "-1"
     >
+<!-- Grouping elements -->
 <!ELEMENT Group (Group|Image|Button|Playlist|Slider|RadialSlider|Text|Checkbox|
-                 Anchor|Video|Playtree)+>
+                 Anchor|Video|Playtree|Panel)+>
     <!ATTLIST Group
         x           CDATA   "0"
         y           CDATA   "0"
     >
+<!ELEMENT Panel (Group|Image|Button|Playlist|Slider|RadialSlider|Text|Checkbox|
+                 Anchor|Video|Playtree|Panel)+>
+    <!ATTLIST Panel
+        x           CDATA   "0"
+        y           CDATA   "0"
+        lefttop     CDATA   "lefttop"
+        rightbottom CDATA   "lefttop"
+        xkeepratio  CDATA   "false"
+        ykeepratio  CDATA   "false"
+        width       CDATA   #REQUIRED
+        height      CDATA   #REQUIRED
+    >
 
 <!-- Anchors -->
 <!ELEMENT Anchor EMPTY>