]> git.sesse.net Git - vlc/blob - modules/gui/skins/src/window.cpp
* changed OSGraphics constructor (needed for X11)
[vlc] / modules / gui / skins / src / window.cpp
1 /*****************************************************************************
2  * window.cpp: Window class
3  *****************************************************************************
4  * Copyright (C) 2003 VideoLAN
5  * $Id: window.cpp,v 1.23 2003/05/13 19:25:59 asmax Exp $
6  *
7  * Authors: Olivier Teulière <ipkiss@via.ecp.fr>
8  *          Emmanuel Puig    <karibu@via.ecp.fr>
9  *
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.
14  *
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.
19  *
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,
23  * USA.
24  *****************************************************************************/
25
26
27 //--- VLC -------------------------------------------------------------------
28 #include <vlc/intf.h>
29
30 //--- SKIN ------------------------------------------------------------------
31 #include "anchor.h"
32 #include "../controls/generic.h"
33 #include "window.h"
34 #include "event.h"
35 #include "../os_api.h"
36 #include "graphics.h"
37 #include "../os_graphics.h"
38 #include "banks.h"
39 #include "theme.h"
40 #include "skin_common.h"
41
42 #include <stdio.h>
43
44
45 //---------------------------------------------------------------------------
46 // Skinable Window
47 //---------------------------------------------------------------------------
48 SkinWindow::SkinWindow( intf_thread_t *_p_intf, int x, int y, bool visible,
49     int transition, int normalalpha, int movealpha, bool dragdrop )
50 {
51     p_intf = _p_intf;
52
53     // Set position parameters
54     Left         = x;
55     Top          = y;
56     Width        = 0;
57     Height       = 0;
58     WindowMoving = false;
59     Moved        = false;
60
61     // Set transparency
62     Transition   = transition;
63     if( Transition < 1 )
64         Transition = 1;
65     NormalAlpha  = normalalpha;
66     MoveAlpha    = movealpha;
67     Alpha        = normalalpha;
68     StartAlpha   = 0;
69     EndAlpha     = 0;
70     StartTime    = 0;
71     EndTime      = 0;
72     Lock         = 0;
73
74     // Visible parameters
75     Image               = NULL;
76     Hidden              = true;
77     Changing            = false;
78     OnStartThemeVisible = visible;
79
80     // Drag & drop
81     DragDrop = dragdrop;
82
83     // ToolTip
84     ToolTipText = "none";
85 }
86 //---------------------------------------------------------------------------
87 SkinWindow::~SkinWindow()
88 {
89     // Destroy the controls
90     for( unsigned int i = 0; i < ControlList.size(); i++ )
91         delete ControlList[i];
92 }
93 //---------------------------------------------------------------------------
94 void SkinWindow::Open()
95 {
96     if( !Hidden )
97         return;
98
99     Changing = true;
100
101 #ifdef WIN32
102     if( Transition && IS_WINNT )
103     {
104         SetTransparency( 0 );
105         OSAPI_PostMessage( this, WINDOW_SHOW, 0, 0 );
106         Fade( NormalAlpha, Transition );
107     }
108     else
109     {
110 #endif
111         OSAPI_PostMessage( this, WINDOW_SHOW, 0, 0 );
112 #ifdef WIN32
113     }
114 #endif
115
116 }
117 //---------------------------------------------------------------------------
118 void SkinWindow::Close()
119 {
120     Changing = true;
121
122 #ifdef WIN32
123     if( Transition && IS_WINNT )
124         Fade( 0, Transition, WINDOW_HIDE );
125     else
126 #endif
127         OSAPI_PostMessage( this, WINDOW_FADE, WINDOW_HIDE, 1242 );
128 }
129 //---------------------------------------------------------------------------
130 void SkinWindow::Show()
131 {
132     Changing = false;
133     Hidden   = false;
134     OSShow( true );
135 }
136 //---------------------------------------------------------------------------
137 void SkinWindow::Hide()
138 {
139     if( Hidden )
140         return;
141
142     Changing = false;
143     Hidden   = true;
144     OSShow( false );
145     OSAPI_PostMessage( NULL, VLC_TEST_ALL_CLOSED, 0, 0 );
146 }
147 //---------------------------------------------------------------------------
148 void SkinWindow::Fade( int To, int Time, unsigned int evt )
149 {
150     // No fading effect on win9x
151 #ifdef WIN32
152     if( IS_WINNT )
153     {
154         StartAlpha = Alpha;
155         EndAlpha   = To;
156         StartTime  = OSAPI_GetTime();
157         EndTime    = StartTime + Time;
158         Lock++;
159
160         OSAPI_PostMessage( this, WINDOW_FADE, evt, Lock );
161     }
162 #endif
163 }
164 //---------------------------------------------------------------------------
165 bool SkinWindow::ProcessEvent( Event *evt )
166 {
167     unsigned int i;
168     unsigned int msg = evt->GetMessage();
169     unsigned int p1  = evt->GetParam1();
170     int          p2  = evt->GetParam2();
171
172     // Send event to control if necessary
173     if( msg > VLC_CONTROL )
174     {
175         for( i = 0; i < ControlList.size(); i++ )
176             ControlList[i]->GenericProcessEvent( evt );
177         return true;
178     }
179
180     // Message processing
181     switch( msg )
182     {
183         case WINDOW_FADE:
184             if( Lock == p2 && ChangeAlpha( OSAPI_GetTime() ) )
185             {
186                 OSAPI_PostMessage( this, WINDOW_FADE, p1, p2 );
187             }
188             else
189             {
190                 OSAPI_PostMessage( this, p1, 0, 0 );
191             }
192             return true;
193
194         case WINDOW_MOVE:
195             WindowManualMoveInit();
196             WindowMoving = true;
197             if( MoveAlpha )
198                 Fade( MoveAlpha, 100 );
199             return true;
200
201         case WINDOW_OPEN:
202             switch( p1 )
203             {
204                 case 0:
205                     Close();
206                     break;
207                 case 1:
208                     Open();
209                     break;
210                 case 2:
211                     if( Hidden )
212                         Open();
213                     else
214                         Close();
215                     break;
216             }
217             return true;
218
219         case WINDOW_CLOSE:
220             switch( p1 )
221             {
222                 case 0:
223                     Open();
224                     break;
225                 case 1:
226                     Close();
227                     break;
228                 case 2:
229                     if( Hidden )
230                         Open();
231                     else
232                         Close();
233                     break;
234             }
235             return true;
236
237         case WINDOW_SHOW:
238             Show();
239             return true;
240
241         case WINDOW_HIDE:
242             Hide();
243             return true;
244
245         case WINDOW_LEAVE:
246             MouseMove( -1, -1, 0 );
247             return true;
248
249         case WINDOW_REFRESH:
250             RefreshAll();
251             return true;
252
253         default:
254             // OS specific messages processing
255             return ProcessOSEvent( evt );
256     }
257 }
258 //---------------------------------------------------------------------------
259 bool SkinWindow::ChangeAlpha( int time )
260 {
261 #ifdef WIN32
262     if( IS_WINNT )
263     {
264         if( time >= EndTime )
265         {
266             if( Lock )
267             {
268                 SetTransparency( EndAlpha );
269                 Lock = 0;
270             }
271             return false;
272         }
273
274         int NewAlpha = StartAlpha + (EndAlpha - StartAlpha) * (time - StartTime)
275             / (EndTime - StartTime);
276         if( NewAlpha != Alpha )
277             SetTransparency( NewAlpha );
278         if( NewAlpha == EndAlpha )
279         {
280             Lock = 0;
281             return false;
282         }
283     }
284 #endif
285     return true;
286 }
287 //---------------------------------------------------------------------------
288 void SkinWindow::RefreshImage( int x, int y, int w, int h )
289 {
290     unsigned int i;
291
292     // Create Bitmap Buffer
293     Graphics *Buffer = (Graphics *)new OSGraphics( p_intf, w, h, this );
294 //    Graphics *Buffer = (Graphics *)new OSGraphics( w, h, this );
295
296     // Draw every control
297         for( i = 0; i < ControlList.size(); i++ )
298             ControlList[i]->Draw( x, y, w, h, Buffer );
299
300     // Copy buffer in Image
301     Image->CopyFrom( x, y, w, h, Buffer, 0, 0, SRC_COPY );
302
303     // Free memory
304     delete Buffer;
305 }
306 //---------------------------------------------------------------------------
307 void SkinWindow::Refresh( int x, int y, int w, int h )
308 {
309     if( Image == NULL )
310         return;
311
312     // Refresh buffer image
313     RefreshImage( x, y, w, h );
314
315     if( Hidden )
316         return;
317
318     // And copy buffer to window
319     RefreshFromImage( x, y, w, h );
320
321 }
322 //---------------------------------------------------------------------------
323 void SkinWindow::RefreshAll()
324 {
325     Refresh( 0, 0, Width, Height );
326 }
327 //---------------------------------------------------------------------------
328 void SkinWindow::MouseDown( int x, int y, int button )
329 {
330     // Checking event in controls
331     for( int i = ControlList.size() - 1; i >= 0 ; i-- )
332     {
333         if( ControlList[i]->MouseDown( x, y, button ) )
334         {
335             return;
336         }
337     }
338
339 }
340 //---------------------------------------------------------------------------
341 void SkinWindow::MouseMove( int x, int y, int button  )
342 {
343     int i;
344
345     // Move window if selected !
346     if( WindowMoving )
347     {
348         WindowManualMove();
349     }
350
351     // Checking event in controls
352     for( i = ControlList.size() - 1; i >= 0 ; i-- )
353     {
354         ControlList[i]->MouseMove( x, y, button );
355     }
356
357     // Checking help text
358     for( i = ControlList.size() - 1; i >= 0 ; i-- )
359     {
360         if( ControlList[i]->MouseOver( x, y ) )
361         {
362             if( ControlList[i]->SendNewHelpText() )
363             {
364                 break;
365             }
366         }
367     }
368
369     // If help text not found, change it to ""
370     if( i == -1 )
371     {
372         p_intf->p_sys->p_theme->EvtBank->Get( "help" )
373             ->PostTextMessage( " " );
374     }
375
376     // Checking for change in Tool Tip
377     for( i = ControlList.size() - 1; i >= 0 ; i-- )
378     {
379         if( ControlList[i]->ToolTipTest( x, y ) )
380             break;
381     }
382
383     // If no change, delete tooltip text
384     if( i == -1 )
385         ChangeToolTipText( "none" );
386 }
387 //---------------------------------------------------------------------------
388 void SkinWindow::MouseUp( int x, int y, int button )
389 {
390     int i;
391
392     // Move window if selected !
393     if( WindowMoving )
394     {
395         if( MoveAlpha )
396             Fade( NormalAlpha, 100 );
397
398         // Check for magnetism
399         p_intf->p_sys->p_theme->CheckAnchors();
400
401         WindowMoving = false;
402     }
403
404     // Checking event in controls
405     for( i = ControlList.size() - 1; i >= 0 ; i-- )
406     {
407         if( ControlList[i]->MouseUp( x, y, button ) )
408         {
409             return;
410         }
411     }
412 }
413 //---------------------------------------------------------------------------
414 void SkinWindow::MouseDblClick( int x, int y, int button )
415 {
416     int i;
417
418     // Checking event in controls
419     for( i = ControlList.size() - 1; i >= 0 ; i-- )
420     {
421         if( ControlList[i]->MouseDblClick( x, y, button ) )
422             return;
423     }
424 }
425 //---------------------------------------------------------------------------
426 void SkinWindow::MouseScroll( int x, int y, int direction )
427 {
428     // Checking event in controls
429     for( int i = ControlList.size() - 1; i >= 0 ; i-- )
430     {
431         if( ControlList[i]->MouseScroll( x, y, direction ) )
432         {
433             return;
434         }
435     }
436 }
437 //---------------------------------------------------------------------------
438 void SkinWindow::Init()
439 {
440     // Get size of window
441     ReSize();
442
443     // Refresh Image buffer
444     RefreshImage( 0, 0, Width, Height );
445
446     // Move window as it hasn't been moved yet
447     Move( Left, Top );
448 }
449 //---------------------------------------------------------------------------
450 void SkinWindow::ReSize()
451 {
452     // Initialization
453     unsigned int i;
454     int w    = 0;
455     int h    = 0;
456     int MinX = 10000000;
457     int MinY = 10000000;
458
459     // Search size of window and negative values to move all
460     for( i = 0; i < ControlList.size(); i++ )
461     {
462 #define min(a,b) ((a)<(b))?(a):(b)
463 #define max(a,b) ((a)>(b))?(a):(b)
464         w    = max( w,    ControlList[i]->Left + ControlList[i]->Width );
465         h    = max( h,    ControlList[i]->Top + ControlList[i]->Height );
466         MinX = min( MinX, ControlList[i]->Left );
467         MinY = min( MinY, ControlList[i]->Top );
468 #undef max
469 #undef min
470     }
471
472     // Correct values
473     w = w - MinX;
474     h = h - MinY;
475     if( w <= 0 )
476         w = 1;
477     if( h <= 0 )
478         h = 1;
479
480     // Move window and controls !
481     if( MinX != 0 || MinY != 0 )
482     {
483         Move( Left + MinX, Top + MinY );
484         for( i = 0; i < ControlList.size(); i++ )
485             ControlList[i]->MoveRelative( -MinX, -MinY );
486     }
487
488     // Create buffer image for repainting if size has changed
489     if( w != Width || h != Height )
490     {
491         // Change image buffer
492         if( Image != NULL )
493             delete (OSGraphics *)Image;
494         Image = (Graphics *)new OSGraphics( p_intf, w, h, this );
495 //        Image = (Graphics *)new OSGraphics( w, h, this );
496
497         Size( w, h );
498     }
499
500 }
501 //---------------------------------------------------------------------------
502 void SkinWindow::GetSize( int &w, int &h )
503 {
504     w = Width;
505     h = Height;
506 }
507 //---------------------------------------------------------------------------
508 void SkinWindow::GetPos( int &x, int &y )
509 {
510     x = Left;
511     y = Top;
512 }
513 //---------------------------------------------------------------------------
514