Commit 8086b07c authored by Olivier Teulière's avatar Olivier Teulière

* skins2:

    - New Panel tag, allowing to group the resizing behaviour of controls
    - Documentation updated accordingly
    - Fixed a memory leak due to CtrlMove/CtrlResize objects
parent 7c23b5c7
This diff is collapsed.
This diff is collapsed.
......@@ -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
......
......@@ -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
This diff is collapsed.
......@@ -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();
}
}
......
......@@ -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
......
......@@ -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 )
{
......@@ -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() )
......
......@@ -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;
......
......@@ -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 );
}
......@@ -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
......
......@@ -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();
}
}
......
......@@ -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
......
......@@ -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
......
......@@ -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>
......
......@@ -87,12 +87,25 @@
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>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment