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