1 /*****************************************************************************
2 * slider.cpp: Slider control
3 *****************************************************************************
4 * Copyright (C) 2003 VideoLAN
5 * $Id: slider.cpp,v 1.7 2003/04/21 21:51:16 asmax Exp $
7 * Authors: Olivier Teulière <ipkiss@via.ecp.fr>
8 * Emmanuel Puig <karibu@via.ecp.fr>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111,
24 *****************************************************************************/
27 //--- GENERAL ---------------------------------------------------------------
31 //--- VLC -------------------------------------------------------------------
34 //--- SKIN ------------------------------------------------------------------
35 #include "../os_api.h"
36 #include "../src/bitmap.h"
37 #include "../src/bezier.h"
38 #include "../src/banks.h"
39 #include "../src/graphics.h"
40 #include "../os_graphics.h"
43 #include "../src/event.h"
44 #include "../src/theme.h"
45 #include "../src/window.h"
46 #include "../src/skin_common.h"
50 //---------------------------------------------------------------------------
52 //---------------------------------------------------------------------------
53 ControlSlider::ControlSlider( string id, bool visible, string type,
54 string cursorUp, string cursorDown, double *ptx, double *pty, int nb,
55 string tooltiptext, string help, SkinWindow *Parent )
56 : GenericControl( id, visible, help, Parent )
65 this->cursorUp = cursorUp;
66 this->cursorDown = cursorDown;
67 Curve = new Bezier( ptx, pty, nb );
69 SliderRange = SLIDER_RANGE;
70 LastRefreshTime = OSAPI_GetTime();
73 BaseToolTipText = tooltiptext;
74 FullToolTipText = BaseToolTipText;
76 //---------------------------------------------------------------------------
77 ControlSlider::~ControlSlider()
81 delete (OSRegion *)HitRgn;
83 //---------------------------------------------------------------------------
84 void ControlSlider::Init()
87 // Get bitmap from list
88 Img = new (::Bitmap*)[2];
89 Img[0] = p_intf->p_sys->p_theme->BmpBank->Get( cursorUp );
90 Img[1] = p_intf->p_sys->p_theme->BmpBank->Get( cursorDown );
93 Img[0]->GetSize( CWidth, CHeight );
95 // Computing slider curve : get points
96 MaxValue = Curve->GetNumOfDifferentPoints();
97 CursorX = new int[MaxValue + 1];
98 CursorY = new int[MaxValue + 1];
99 Curve->GetDifferentPoints( CursorX, CursorY, -CWidth / 2, -CHeight / 2 );
101 // Search for size value
106 for( i = 1; i <= MaxValue; i++ )
108 if( CursorX[i] < Left )
110 if( CursorY[i] < Top )
112 if( CursorX[i] > Width )
114 if( CursorY[i] > Height )
117 Width += CWidth - Left;
118 Height += CHeight - Top;
120 // Curve is no more needed so delete it
124 HitRgn = (Region *)new OSRegion;
126 // Create slider hit region and move cursor inside control
127 for( i = 0; i <= MaxValue; i++ )
129 HitRgn->AddElipse( CursorX[i], CursorY[i], CWidth, CHeight );
134 // Select type of slider
138 UpdateEvent = p_intf->p_sys->p_theme->EvtBank->Get( "time" );
140 else if( Type == "volume" )
143 UpdateEvent = p_intf->p_sys->p_theme->EvtBank->Get( "volume_refresh" );
148 UpdateEvent = p_intf->p_sys->p_theme->EvtBank->Get( "none" );
151 //---------------------------------------------------------------------------
152 bool ControlSlider::ProcessEvent( Event *evt )
154 unsigned int msg = evt->GetMessage();
155 unsigned int p1 = evt->GetParam1();
156 int p2 = evt->GetParam2();
161 Enable( (Event*)p1, (bool)p2 );
164 case CTRL_SET_SLIDER:
165 if( UpdateEvent->IsEqual( (Event*)p1 ) )
167 SetCursorPosition( (long)p2 );
174 //---------------------------------------------------------------------------
175 void ControlSlider::MoveRelative( int xOff, int yOff )
179 HitRgn->Move( xOff, yOff );
181 //---------------------------------------------------------------------------
182 void ControlSlider::SetCursorPosition( long Pos )
186 if( Pos > SliderRange )
191 if( SliderRange == 0 )
194 MoveCursor( Pos * MaxValue / SliderRange );
197 //---------------------------------------------------------------------------
198 long ControlSlider::GetCursorPosition()
200 return SliderRange * Value / MaxValue;
202 //---------------------------------------------------------------------------
203 void ControlSlider::MoveCursor( int newValue )
206 int OldValue = Value;
208 if( OldValue != Value )
210 X = (CursorX[Value] > CursorX[OldValue])
211 ? Left + CursorX[OldValue] : Left + CursorX[Value];
212 Y = (CursorY[Value] > CursorY[OldValue])
213 ? Top + CursorY[OldValue] : Top + CursorY[Value];
214 W = (CursorX[Value] > CursorX[OldValue])
215 ? CursorX[Value] - CursorX[OldValue] + CWidth
216 : CursorX[OldValue] - CursorX[Value] + CWidth;
217 H = (CursorY[Value] > CursorY[OldValue])
218 ? CursorY[Value] - CursorY[OldValue] + CHeight
219 : CursorY[OldValue] - CursorY[Value] + CHeight;
220 if( 2 * CWidth * CHeight < W * H )
222 ParentWindow->Refresh( Left + CursorX[OldValue],
223 Top + CursorY[OldValue], CWidth, CHeight );
224 ParentWindow->Refresh( Left + CursorX[Value],
225 Top + CursorY[Value], CWidth, CHeight );
229 ParentWindow->Refresh( X, Y, W, H );
233 if( BaseToolTipText != "none" )
235 char *percent = new char[6];
236 sprintf( percent, "%i %%", Value * 100 / MaxValue );
237 FullToolTipText = BaseToolTipText + " - " + (string)percent;
242 //---------------------------------------------------------------------------
243 void ControlSlider::Draw( int x, int y, int w, int h, Graphics *dest )
250 if( GetIntersectRgn( x, y, w, h, Left+CursorX[Value], Top+CursorY[Value],
251 CWidth, CHeight, xI, yI, wI, hI ) )
253 Img[1 - State]->DrawBitmap( xI - Left - CursorX[Value],
254 yI - Top - CursorY[Value], wI, hI, xI - x, yI - y, dest );
257 //---------------------------------------------------------------------------
258 bool ControlSlider::MouseUp( int x, int y, int button )
261 if( Enabled && Selected )
264 ParentWindow->Refresh( Left + CursorX[Value],
265 Top + CursorY[Value], CWidth, CHeight );
266 UpdateEvent->SetParam2( GetCursorPosition() );
267 UpdateEvent->SendEvent();
271 //---------------------------------------------------------------------------
272 bool ControlSlider::MouseDown( int x, int y, int button )
277 // If hit into cursor or indide active slider region
278 if( HitRgn->Hit( x, y ) && button == 1 )
282 ParentWindow->Refresh( Left + CursorX[Value],
283 Top + CursorY[Value], CWidth, CHeight );
284 MoveCursor( FindNearestPoint( x, y ) );
285 UpdateEvent->SetParam2( GetCursorPosition() );
286 UpdateEvent->SendEvent();
291 //---------------------------------------------------------------------------
292 bool ControlSlider::MouseMove( int x, int y, int button )
294 if( !Enabled || !Selected || !button )
297 MoveCursor( FindNearestPoint( x, y ) );
299 // Refresh value if time ellapsed since last refresh is more than 200 ms
300 int time = OSAPI_GetTime();
301 if( time > LastRefreshTime + 250 )
303 UpdateEvent->SetParam2( GetCursorPosition() );
304 UpdateEvent->SendEvent();
305 LastRefreshTime = time;
309 //---------------------------------------------------------------------------
310 bool ControlSlider::MouseOver( int x, int y )
312 if( HitRgn->Hit( x, y ) )
317 //---------------------------------------------------------------------------
318 bool ControlSlider::MouseScroll( int x, int y, int direction )
320 if( !Enabled || !MouseOver( x, y ) )
327 case MOUSE_SCROLL_DOWN:
331 case MOUSE_SCROLL_UP:
332 if( val < MaxValue ) val++;
339 //---------------------------------------------------------------------------
340 bool ControlSlider::ToolTipTest( int x, int y )
342 if( MouseOver( x, y ) )
344 if( BaseToolTipText == "none" )
346 ParentWindow->ChangeToolTipText( BaseToolTipText );
350 ParentWindow->ChangeToolTipText( FullToolTipText );
356 //---------------------------------------------------------------------------
357 void ControlSlider::ChangeSliderRange( int NewRange )
359 if( NewRange == SliderRange )
362 SliderRange = NewRange;
364 int Pos = GetCursorPosition();
365 SetCursorPosition( Pos );
368 //---------------------------------------------------------------------------
369 void ControlSlider::Enable( Event *event, bool enabled )
371 if( !UpdateEvent->IsEqual( event ) )
374 if( enabled && !Enabled )
377 ParentWindow->Refresh( Left, Top, Width, Height );
379 else if( !enabled && Enabled )
382 ParentWindow->Refresh( Left, Top, Width, Height );
385 //---------------------------------------------------------------------------
386 int ControlSlider::FindNearestPoint( int x, int y )
391 int RefValue = Value;
392 // Move point inside control
393 OSAPI_GetMousePos( x, y ); // This is used to avoid bug with
395 ParentWindow->GetPos( wx, wy );
396 x += -wx - Left - CWidth / 2;
397 y += -wy - Top - CHeight / 2;
399 // Search nearest point
400 for( i = 0; i <= MaxValue; i++ )
402 D = sqrt( ( CursorX[i] - x ) * ( CursorX[i] - x ) +
403 ( CursorY[i] - y ) * ( CursorY[i] - y ) );
412 //---------------------------------------------------------------------------