From 4999de8d3c4e95cffb32a2091025d62c17e023a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Teuli=C3=A8re?= Date: Tue, 2 Mar 2004 21:45:15 +0000 Subject: [PATCH] - skins2/utils/bezier.*: Added support for curves made of one point - skins2/theme/skin.dtd: Removed Event and Rectangle tags - skins2/src/theme.cpp: Destroy curves explicitely - ALL: Anchors can be defined using a Bezier curve, which allows rectilinear anchors (but it is still possible to define anchors reduced to a single point). A "curved anchor" only attracts "single point anchors" --- modules/gui/skins2/controls/ctrl_slider.cpp | 24 +- modules/gui/skins2/controls/ctrl_slider.hpp | 6 +- modules/gui/skins2/parser/builder.cpp | 18 +- modules/gui/skins2/parser/builder_data.def | 2 +- modules/gui/skins2/parser/builder_data.hpp | 7 +- modules/gui/skins2/parser/gen_builder.py | 6 +- modules/gui/skins2/parser/skin_parser.cpp | 4 +- modules/gui/skins2/src/anchor.cpp | 45 +++- modules/gui/skins2/src/anchor.hpp | 14 +- modules/gui/skins2/src/theme.cpp | 3 +- modules/gui/skins2/theme/skin.dtd | 23 +- modules/gui/skins2/theme/theme.xml | 240 ++++++++++---------- modules/gui/skins2/utils/bezier.cpp | 34 +-- modules/gui/skins2/utils/bezier.hpp | 5 +- 14 files changed, 237 insertions(+), 194 deletions(-) diff --git a/modules/gui/skins2/controls/ctrl_slider.cpp b/modules/gui/skins2/controls/ctrl_slider.cpp index 95321efa93..645bd78525 100644 --- a/modules/gui/skins2/controls/ctrl_slider.cpp +++ b/modules/gui/skins2/controls/ctrl_slider.cpp @@ -2,7 +2,7 @@ * ctrl_slider.cpp ***************************************************************************** * Copyright (C) 2003 VideoLAN - * $Id: ctrl_slider.cpp,v 1.4 2004/02/29 16:49:55 asmax Exp $ + * $Id: ctrl_slider.cpp,v 1.5 2004/03/02 21:45:15 ipkiss Exp $ * * Authors: Cyril Deguet * Olivier Teulière @@ -55,7 +55,7 @@ CtrlSliderCursor::CtrlSliderCursor( intf_thread_t *pIntf, m_cmdUpOver( this, &transUpOver ), m_cmdMove( this, &transMove ), m_cmdScroll( this, &transScroll ), m_lastPercentage( 0 ), m_xOffset( 0 ), m_yOffset( 0 ), - m_pEvt( NULL ), m_curve( rCurve ) + m_pEvt( NULL ), m_rCurve( rCurve ) { // Build the images of the cursor OSFactory *pOsFactory = OSFactory::instance( getIntf() ); @@ -120,7 +120,7 @@ bool CtrlSliderCursor::mouseOver( int x, int y ) const { // Compute the position of the cursor int xPos, yPos; - m_curve.getPoint( m_rVariable.get(), xPos, yPos ); + m_rCurve.getPoint( m_rVariable.get(), xPos, yPos ); // Compute the resize factors float factorX, factorY; @@ -144,7 +144,7 @@ void CtrlSliderCursor::draw( OSGraphics &rImage, int xDest, int yDest ) { // Compute the position of the cursor int xPos, yPos; - m_curve.getPoint( m_rVariable.get(), xPos, yPos ); + m_rCurve.getPoint( m_rVariable.get(), xPos, yPos ); // Compute the resize factors float factorX, factorY; @@ -181,7 +181,7 @@ void CtrlSliderCursor::transOverDown( SkinObject *pCtrl ) // Compute the offset int tempX, tempY; - pThis->m_curve.getPoint( pThis->m_rVariable.get(), tempX, tempY ); + pThis->m_rCurve.getPoint( pThis->m_rVariable.get(), tempX, tempY ); pThis->m_xOffset = pEvtMouse->getXPos() - pPos->getLeft() - (int)(tempX * factorX); pThis->m_yOffset = pEvtMouse->getYPos() - pPos->getTop() @@ -244,10 +244,10 @@ void CtrlSliderCursor::transMove( SkinObject *pCtrl ) int relYPond = (int)(relY / factorY); // Update the position - if( pThis->m_curve.getMinDist( relXPond, relYPond ) < RANGE ) + if( pThis->m_rCurve.getMinDist( relXPond, relYPond ) < RANGE ) { - float percentage = pThis->m_curve.getNearestPercent( relXPond, - relYPond ); + float percentage = pThis->m_rCurve.getNearestPercent( relXPond, + relYPond ); pThis->m_rVariable.set( percentage ); } else @@ -304,7 +304,7 @@ CtrlSliderBg::CtrlSliderBg( intf_thread_t *pIntf, CtrlSliderCursor &rCursor, int thickness, VarBool *pVisible, const UString &rHelp ): CtrlGeneric( pIntf, rHelp, pVisible ), m_rCursor( rCursor ), - m_rVariable( rVariable ), m_thickness( thickness ), m_curve( rCurve ), + m_rVariable( rVariable ), m_thickness( thickness ), m_rCurve( rCurve ), m_width( rCurve.getWidth() ), m_height( rCurve.getHeight() ) { } @@ -316,8 +316,8 @@ bool CtrlSliderBg::mouseOver( int x, int y ) const float factorX, factorY; getResizeFactors( factorX, factorY ); - return (m_curve.getMinDist( (int)(x / factorX), - (int)(y / factorY) ) < m_thickness ); + return (m_rCurve.getMinDist( (int)(x / factorX), + (int)(y / factorY) ) < m_thickness ); } @@ -336,7 +336,7 @@ void CtrlSliderBg::handleEvent( EvtGeneric &rEvent ) EvtMouse &rEvtMouse = (EvtMouse&)rEvent; int x = rEvtMouse.getXPos(); int y = rEvtMouse.getYPos(); - m_rVariable.set( m_curve.getNearestPercent( + m_rVariable.set( m_rCurve.getNearestPercent( (int)((x - pPos->getLeft()) / factorX), (int)((y - pPos->getTop()) / factorY) ) ); diff --git a/modules/gui/skins2/controls/ctrl_slider.hpp b/modules/gui/skins2/controls/ctrl_slider.hpp index 4464cefcac..a0962165f2 100755 --- a/modules/gui/skins2/controls/ctrl_slider.hpp +++ b/modules/gui/skins2/controls/ctrl_slider.hpp @@ -2,7 +2,7 @@ * ctrl_slider.hpp ***************************************************************************** * Copyright (C) 2003 VideoLAN - * $Id: ctrl_slider.hpp,v 1.3 2004/02/29 16:49:55 asmax Exp $ + * $Id: ctrl_slider.hpp,v 1.4 2004/03/02 21:45:15 ipkiss Exp $ * * Authors: Cyril Deguet * Olivier Teulière @@ -92,7 +92,7 @@ class CtrlSliderCursor: public CtrlGeneric, public Observer /// Current image OSGraphics *m_pImg; /// Bezier curve of the slider - const Bezier m_curve; + const Bezier &m_rCurve; /// Callback functions static void transOverDown( SkinObject *pCtrl ); @@ -133,7 +133,7 @@ class CtrlSliderBg: public CtrlGeneric /// Thickness of the curve int m_thickness; /// Bezier curve of the slider - const Bezier m_curve; + const Bezier &m_rCurve; /// Initial size of the control int m_width, m_height; diff --git a/modules/gui/skins2/parser/builder.cpp b/modules/gui/skins2/parser/builder.cpp index b8d6f0a63e..5061fa3240 100755 --- a/modules/gui/skins2/parser/builder.cpp +++ b/modules/gui/skins2/parser/builder.cpp @@ -2,7 +2,7 @@ * builder.cpp ***************************************************************************** * Copyright (C) 2003 VideoLAN - * $Id: builder.cpp,v 1.8 2004/03/01 18:33:31 asmax Exp $ + * $Id: builder.cpp,v 1.9 2004/03/02 21:45:15 ipkiss Exp $ * * Authors: Cyril Deguet * Olivier Teulière @@ -182,8 +182,18 @@ void Builder::addAnchor( const BuilderData::Anchor &rData ) return; } + Bezier *pCurve = getPoints( rData.m_points.c_str() ); + if( pCurve == NULL ) + { + msg_Err( getIntf(), "Invalid format in tag points=\"%s\"", + rData.m_points.c_str() ); + return; + } + m_pTheme->m_curves.push_back( BezierPtr( pCurve ) ); + Anchor *pAnc = new Anchor( getIntf(), rData.m_xPos, rData.m_yPos, - rData.m_range, rData.m_priority, *pWin ); + rData.m_range, rData.m_priority, + *pCurve, *pWin ); pWin->addAnchor( pAnc ); } @@ -615,16 +625,18 @@ Bezier *Builder::getPoints( const char *pTag ) const int x, y, n; while( 1 ) { - if( sscanf( pTag, "(%d,%d)%n", &x, &y, &n ) < 2 ) + if( sscanf( pTag, "(%d,%d)%n", &x, &y, &n ) < 1 ) { 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; diff --git a/modules/gui/skins2/parser/builder_data.def b/modules/gui/skins2/parser/builder_data.def index eb9804f905..159798693e 100644 --- a/modules/gui/skins2/parser/builder_data.def +++ b/modules/gui/skins2/parser/builder_data.def @@ -3,7 +3,7 @@ Bitmap id:string fileName:string alphaColor:uint32_t Font id:string fontName:string size:int 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 range:int priority:int windowId:string +Anchor xPos:int yPos:int range:int priority:int points:string windowId:string Button id:string xPos:int yPos:int leftTop:string rightBottom: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 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 visible:bool bmpId:string onclickId:string help:string layer:int windowId:string layoutId:string diff --git a/modules/gui/skins2/parser/builder_data.hpp b/modules/gui/skins2/parser/builder_data.hpp index 1c1353a772..bfab368c16 100644 --- a/modules/gui/skins2/parser/builder_data.hpp +++ b/modules/gui/skins2/parser/builder_data.hpp @@ -2,7 +2,7 @@ * builder_data.hpp ***************************************************************************** * Copyright (C) 2003 VideoLAN - * $Id: builder_data.hpp,v 1.5 2004/02/29 16:49:55 asmax Exp $ + * $Id: builder_data.hpp,v 1.6 2004/03/02 21:45:15 ipkiss Exp $ * * Authors: Cyril Deguet * Olivier Teulière @@ -116,13 +116,14 @@ m_id( id ), m_width( width ), m_height( height ), m_minWidth( minWidth ), m_maxW /// Type definition struct Anchor { - Anchor( int xPos, int yPos, int range, int priority, const string & windowId ): -m_xPos( xPos ), m_yPos( yPos ), m_range( range ), m_priority( priority ), m_windowId( windowId ) {} + Anchor( int xPos, int yPos, int range, int priority, const string & points, const string & windowId ): +m_xPos( xPos ), m_yPos( yPos ), m_range( range ), m_priority( priority ), m_points( points ), m_windowId( windowId ) {} int m_xPos; int m_yPos; int m_range; int m_priority; + const string m_points; const string m_windowId; }; /// List diff --git a/modules/gui/skins2/parser/gen_builder.py b/modules/gui/skins2/parser/gen_builder.py index 98a30dbd57..5bf3c8c3b2 100755 --- a/modules/gui/skins2/parser/gen_builder.py +++ b/modules/gui/skins2/parser/gen_builder.py @@ -15,7 +15,7 @@ hppfile.write( * builder_data.hpp ***************************************************************************** * Copyright (C) 2003 VideoLAN - * $Id: gen_builder.py,v 1.1 2004/01/03 23:31:33 asmax Exp $ + * $Id: gen_builder.py,v 1.2 2004/03/02 21:45:15 ipkiss Exp $ * * Authors: Cyril Deguet * Olivier Teulière @@ -41,13 +41,13 @@ hppfile.write( #ifndef BUILDER_DATA_HPP #define BUILDER_DATA_HPP -using namespace std; - #include #include #include #include +using namespace std; + /// Structure for mapping data from XML file struct BuilderData { diff --git a/modules/gui/skins2/parser/skin_parser.cpp b/modules/gui/skins2/parser/skin_parser.cpp index bf609f6ff3..7d92e8583f 100644 --- a/modules/gui/skins2/parser/skin_parser.cpp +++ b/modules/gui/skins2/parser/skin_parser.cpp @@ -2,7 +2,7 @@ * skin_parser.cpp ***************************************************************************** * Copyright (C) 2004 VideoLAN - * $Id: skin_parser.cpp,v 1.4 2004/03/01 19:36:43 asmax Exp $ + * $Id: skin_parser.cpp,v 1.5 2004/03/02 21:45:15 ipkiss Exp $ * * Authors: Cyril Deguet * @@ -40,7 +40,7 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr ) { const BuilderData::Anchor anchor( atoi( attr["x"] ) + m_xOffset, atoi( attr["y"] ) + m_yOffset, atoi( attr["range"] ), - atoi( attr["priority"] ), m_curWindowId ); + atoi( attr["priority"] ), attr["points"], m_curWindowId ); m_data.m_listAnchor.push_back( anchor ); } diff --git a/modules/gui/skins2/src/anchor.cpp b/modules/gui/skins2/src/anchor.cpp index 2585782a44..38a3610c8a 100755 --- a/modules/gui/skins2/src/anchor.cpp +++ b/modules/gui/skins2/src/anchor.cpp @@ -2,7 +2,7 @@ * anchor.cpp ***************************************************************************** * Copyright (C) 2003 VideoLAN - * $Id: anchor.cpp,v 1.1 2004/01/03 23:31:33 asmax Exp $ + * $Id: anchor.cpp,v 1.2 2004/03/02 21:45:15 ipkiss Exp $ * * Authors: Cyril Deguet * Olivier Teulière @@ -27,20 +27,47 @@ bool Anchor::isHanging( const Anchor &rOther ) const { - return (getXPosAbs() == rOther.getXPosAbs() && - getYPosAbs() == rOther.getYPosAbs() && - m_priority > rOther.m_priority ); + if( m_priority <= rOther.m_priority ) + return false; + + // Compute delta coordinates between anchors, since the Bezier class + // uses coordinates relative to (0;0) + int deltaX = getXPosAbs() - rOther.getXPosAbs(); + int deltaY = getYPosAbs() - rOther.getYPosAbs(); + + // One of the anchors (at least) must be a point, else it has no meaning + return (isPoint() && rOther.m_rCurve.getMinDist( deltaX, deltaY ) == 0) || + (rOther.isPoint() && m_rCurve.getMinDist( -deltaX, -deltaY ) == 0); } bool Anchor::canHang( const Anchor &rOther, int &xOffset, int &yOffset ) const { - int xDist = getXPosAbs() - (rOther.getXPosAbs() + xOffset); - int yDist = getYPosAbs() - (rOther.getYPosAbs() + yOffset); - if( m_range > 0 && xDist*xDist + yDist*yDist <= m_range*m_range ) + int deltaX = getXPosAbs() - (rOther.getXPosAbs() + xOffset); + int deltaY = getYPosAbs() - (rOther.getYPosAbs() + yOffset); + + // One of the anchors (at least) must be a point, else it has no meaning + if( (isPoint() && rOther.m_rCurve.getMinDist( deltaX, deltaY ) < m_range) ) { - xOffset = getXPosAbs() - rOther.getXPosAbs(); - yOffset = getYPosAbs() - rOther.getYPosAbs(); + // Compute the coordinates of the nearest point of the curve + int xx, yy; + float p = rOther.m_rCurve.getNearestPercent( deltaX, deltaY ); + rOther.m_rCurve.getPoint( p, xx, yy ); + + xOffset = getXPosAbs() - (rOther.getXPosAbs() + xx); + yOffset = getYPosAbs() - (rOther.getYPosAbs() + yy); + return true; + } + else if( (rOther.isPoint() && + m_rCurve.getMinDist( -deltaX, -deltaY ) < m_range) ) + { + // Compute the coordinates of the nearest point of the curve + int xx, yy; + float p = m_rCurve.getNearestPercent( -deltaX, -deltaY ); + m_rCurve.getPoint( p, xx, yy ); + + xOffset = (getXPosAbs() + xx) - rOther.getXPosAbs(); + yOffset = (getYPosAbs() + yy) - rOther.getYPosAbs(); return true; } else diff --git a/modules/gui/skins2/src/anchor.hpp b/modules/gui/skins2/src/anchor.hpp index 4eaba98dae..0f9ecafc66 100644 --- a/modules/gui/skins2/src/anchor.hpp +++ b/modules/gui/skins2/src/anchor.hpp @@ -2,7 +2,7 @@ * anchor.hpp ***************************************************************************** * Copyright (C) 2003 VideoLAN - * $Id: anchor.hpp,v 1.1 2004/01/03 23:31:33 asmax Exp $ + * $Id: anchor.hpp,v 1.2 2004/03/02 21:45:15 ipkiss Exp $ * * Authors: Cyril Deguet * Olivier Teulière @@ -27,6 +27,7 @@ #include "skin_common.hpp" #include "generic_window.hpp" +#include "../utils/bezier.hpp" /// Class for the windows anchors @@ -34,9 +35,10 @@ class Anchor: public SkinObject { public: Anchor( intf_thread_t *pIntf, int xPos, int yPos, int range, - int priority, GenericWindow &rWindow ): + int priority, const Bezier &rCurve, GenericWindow &rWindow ): SkinObject( pIntf ), m_xPos( xPos ), m_yPos( yPos ), - m_range( range ), m_priority( priority ), m_rWindow( rWindow ) {} + m_rCurve( rCurve ), m_range( range ), m_priority( priority ), + m_rWindow( rWindow ) {} virtual ~Anchor() {} /// Return true if the given anchor is hanged by this one @@ -56,6 +58,9 @@ class Anchor: public SkinObject /// doesn't "jump" in a strange way). bool canHang( const Anchor &rOther, int &xOffset, int &yOffset ) const; + // Indicate whether this anchor is reduced to a single point + bool isPoint() const { return m_rCurve.getNbCtrlPoints() == 1; } + // Getters int getXPosAbs() const { return (m_xPos + m_rWindow.getLeft()); } int getYPosAbs() const { return (m_yPos + m_rWindow.getTop()); } @@ -64,6 +69,9 @@ class Anchor: public SkinObject /// Coordinates relative to the window int m_xPos, m_yPos; + /// Curve of the anchor + const Bezier &m_rCurve; + /// Range of action int m_range; diff --git a/modules/gui/skins2/src/theme.cpp b/modules/gui/skins2/src/theme.cpp index 6c9ff04aac..204ef8bdb8 100755 --- a/modules/gui/skins2/src/theme.cpp +++ b/modules/gui/skins2/src/theme.cpp @@ -2,7 +2,7 @@ * theme.cpp ***************************************************************************** * Copyright (C) 2003 VideoLAN - * $Id: theme.cpp,v 1.3 2004/02/08 11:23:17 gbazin Exp $ + * $Id: theme.cpp,v 1.4 2004/03/02 21:45:15 ipkiss Exp $ * * Authors: Cyril Deguet * Olivier Teulière @@ -37,6 +37,7 @@ Theme::~Theme() m_fonts.clear(); m_commands.clear(); m_vars.clear(); + m_curves.clear(); } diff --git a/modules/gui/skins2/theme/skin.dtd b/modules/gui/skins2/theme/skin.dtd index 1f05cb046b..256d4c95c5 100644 --- a/modules/gui/skins2/theme/skin.dtd +++ b/modules/gui/skins2/theme/skin.dtd @@ -2,7 +2,7 @@ --> - + - - + Anchor)+> @@ -89,18 +84,6 @@ onclick CDATA "none" help CDATA "\0" > - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -