Commit 4999de8d authored by Olivier Teulière's avatar Olivier Teulière

- 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"
parent 0ba71b8c
......@@ -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 <asmax@via.ecp.fr>
* Olivier Teulire <ipkiss@via.ecp.fr>
......@@ -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) ) );
......
......@@ -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 <asmax@via.ecp.fr>
* Olivier Teulire <ipkiss@via.ecp.fr>
......@@ -92,7 +92,7 @@ class CtrlSliderCursor: public CtrlGeneric, public Observer<VarPercent>
/// 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;
......
......@@ -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 <asmax@via.ecp.fr>
* Olivier Teulire <ipkiss@via.ecp.fr>
......@@ -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;
......
......@@ -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
......
......@@ -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 <asmax@via.ecp.fr>
* Olivier Teulière <ipkiss@via.ecp.fr>
......@@ -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
......
......@@ -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 <asmax@via.ecp.fr>
* Olivier Teulire <ipkiss@via.ecp.fr>
......@@ -41,13 +41,13 @@ hppfile.write(
#ifndef BUILDER_DATA_HPP
#define BUILDER_DATA_HPP
using namespace std;
#include <vlc/vlc.h>
#include <list>
#include <map>
#include <string>
using namespace std;
/// Structure for mapping data from XML file
struct BuilderData
{
......
......@@ -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 <asmax@via.ecp.fr>
*
......@@ -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 );
}
......
......@@ -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 <asmax@via.ecp.fr>
* Olivier Teulière <ipkiss@via.ecp.fr>
......@@ -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
......
......@@ -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 <asmax@via.ecp.fr>
* Olivier Teulière <ipkiss@via.ecp.fr>
......@@ -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;
......
......@@ -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 <asmax@via.ecp.fr>
* Olivier Teulire <ipkiss@via.ecp.fr>
......@@ -37,6 +37,7 @@ Theme::~Theme()
m_fonts.clear();
m_commands.clear();
m_vars.clear();
m_curves.clear();
}
......
......@@ -2,7 +2,7 @@
-->
<!ELEMENT Theme (ThemeInfo,(Bitmap|Font|Window|Event)*)>
<!ELEMENT Theme (ThemeInfo,(Bitmap|Font|Window)*)>
<!ATTLIST Theme
version CDATA "1.0"
magnet CDATA "15"
......@@ -18,12 +18,6 @@
file CDATA #REQUIRED
alphacolor CDATA #REQUIRED
>
<!ELEMENT Event EMPTY>
<!ATTLIST Event
id CDATA #REQUIRED
event CDATA #REQUIRED
key CDATA "none"
>
<!ELEMENT Font EMPTY>
<!ATTLIST Font
id CDATA #REQUIRED
......@@ -61,7 +55,7 @@
maxheight CDATA "-1"
>
<!ELEMENT Group (Group|Image|Button|Playlist|Slider|RadialSlider|Text|CheckBox|
Rectangle|Anchor)+>
Anchor)+>
<!ATTLIST Group
x CDATA "0"
y CDATA "0"
......@@ -73,6 +67,7 @@
x CDATA "0"
y CDATA "0"
priority CDATA #REQUIRED
points CDATA "(0,0)"
range CDATA "10"
>
......@@ -89,18 +84,6 @@
onclick CDATA "none"
help CDATA "\0"
>
<!ELEMENT Rectangle EMPTY>
<!ATTLIST Rectangle
id CDATA "none"
visible CDATA "true"
x CDATA "0"
y CDATA "0"
w CDATA "50"
h CDATA "50"
color CDATA "#C0C0C0"
onclick CDATA "none"
help CDATA "\0"
>
<!ELEMENT Button EMPTY>
<!ATTLIST Button
id CDATA "none"
......
This diff is collapsed.
......@@ -2,7 +2,7 @@
* bezier.cpp
*****************************************************************************
* Copyright (C) 2003 VideoLAN
* $Id: bezier.cpp,v 1.3 2004/02/01 21:13:04 ipkiss Exp $
* $Id: bezier.cpp,v 1.4 2004/03/02 21:45:15 ipkiss Exp $
*
* Authors: Cyril Deguet <asmax@via.ecp.fr>
* Olivier Teulire <ipkiss@via.ecp.fr>
......@@ -30,13 +30,13 @@ Bezier::Bezier( intf_thread_t *p_intf, const vector<float> &rAbscissas,
const vector<float> &rOrdinates, Flag_t flag )
: SkinObject( p_intf )
{
// We expect rAbscissas and rOrdinates to have the same size, of course
m_nbCtrlPt = rAbscissas.size();
// Copy the control points coordinates
m_ptx.assign( rAbscissas.begin(), rAbscissas.end() );
m_pty.assign( rOrdinates.begin(), rOrdinates.end() );
// We expect m_ptx and m_pty to have the same size, of course
m_nbCtrlPt = m_ptx.size();
// Precalculate the factoriels
m_ft.push_back( 1 );
for( int i = 1; i < m_nbCtrlPt; i++ )
......@@ -44,18 +44,16 @@ Bezier::Bezier( intf_thread_t *p_intf, const vector<float> &rAbscissas,
m_ft.push_back( i * m_ft[i - 1] );
}
// Initialization
int cx, cy, oldx, oldy;
m_leftVect.reserve( MAX_BEZIER_POINT + 1 );
m_topVect.reserve( MAX_BEZIER_POINT + 1 );
// Calculate the first point
int oldx, oldy;
computePoint( 0, oldx, oldy );
m_leftVect[0] = oldx;
m_topVect[0] = oldy;
m_leftVect.push_back( oldx );
m_topVect.push_back( oldy );
m_percVect.push_back( 0 );
// Calculate the other points
float percentage;
int cx, cy;
for( float j = 1; j <= MAX_BEZIER_POINT; j++ )
{
percentage = j / MAX_BEZIER_POINT;
......@@ -71,9 +69,19 @@ Bezier::Bezier( intf_thread_t *p_intf, const vector<float> &rAbscissas,
oldy = cy;
}
}
m_nbPoints = m_percVect.size();
m_nbPoints = m_leftVect.size();
// If we have only one control point, we duplicate it
// This allows to simplify the algorithms used in the class
if( m_nbPoints == 1 )
{
m_leftVect.push_back( m_leftVect[0] );
m_topVect.push_back( m_topVect[0] );
m_percVect.push_back( 1 );
m_nbPoints = 2;
}
// Small hack to ensure that the percentage of the last point is always 1
// Ensure that the percentage of the last point is always 1
m_percVect[m_nbPoints - 1] = 1;
}
......
......@@ -2,7 +2,7 @@
* bezier.hpp
*****************************************************************************
* Copyright (C) 2003 VideoLAN
* $Id: bezier.hpp,v 1.4 2004/02/01 21:13:04 ipkiss Exp $
* $Id: bezier.hpp,v 1.5 2004/03/02 21:45:15 ipkiss Exp $
*
* Authors: Cyril Deguet <asmax@via.ecp.fr>
* Olivier Teulière <ipkiss@via.ecp.fr>
......@@ -51,6 +51,9 @@ class Bezier: public SkinObject
Flag_t flag = kCoordsBoth );
~Bezier() {}
/// Get the number of control points used to define the curve
int getNbCtrlPoints() const { return m_nbCtrlPt; }
/// Return the percentage (between 0 and 1) of the curve point nearest
/// from (x, y)
float getNearestPercent( int x, int y ) const;
......
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