]> git.sesse.net Git - vlc/blob - modules/gui/skins/controls/text.cpp
b4657e857b8a3b86850f7bdf5f1ca734396f6cf3
[vlc] / modules / gui / skins / controls / text.cpp
1 /*****************************************************************************
2  * text.cpp: Text control
3  *****************************************************************************
4  * Copyright (C) 2003 VideoLAN
5  * $Id: text.cpp,v 1.5 2003/04/17 16:34:31 karibu 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 "../os_api.h"
32 #include "../src/bitmap.h"
33 #include "../src/banks.h"
34 #include "../src/graphics.h"
35 #include "../os_graphics.h"
36 #include "../src/font.h"
37 #include "generic.h"
38 #include "text.h"
39 #include "../src/event.h"
40 #include "../src/theme.h"
41 #include "../src/window.h"
42 #include "../os_window.h"
43 #include "../src/skin_common.h"
44
45
46
47 //---------------------------------------------------------------------------
48 // Scrolling : one for each OS
49 //---------------------------------------------------------------------------
50
51     #if defined( WIN32 )
52     //-----------------------------------------------------------------------
53     // Win32 methods
54     //-----------------------------------------------------------------------
55     void CALLBACK ScrollingTextTimer( HWND hwnd, UINT uMsg, UINT_PTR idEvent,
56         DWORD dwTime )
57     {
58         if( (ControlText *)idEvent != NULL
59             && !( (ControlText *)idEvent )->GetSelected() )
60         {
61             ( (ControlText *)idEvent )->DoScroll();
62         }
63
64     }
65     //-----------------------------------------------------------------------
66     void ControlText::StartScrolling()
67     {
68         SetTimer( ( (Win32Window *)ParentWindow )->GetHandle(), (UINT_PTR)this,
69                   100, (TIMERPROC)ScrollingTextTimer );
70     }
71     //-----------------------------------------------------------------------
72     void ControlText::StopScrolling()
73     {
74         KillTimer( ( (Win32Window *)ParentWindow )->GetHandle(),
75                    (UINT_PTR)this );
76     }
77     //-----------------------------------------------------------------------
78
79     #else
80
81     //-----------------------------------------------------------------------
82     // Gtk2 methods
83     //-----------------------------------------------------------------------
84     gboolean ScrollingTextTimer( gpointer data )
85     {
86         if( (ControlText *)data != NULL )
87         {
88             if( !( (ControlText *)data )->IsScrolling() )
89                 return false;
90
91             if( !( (ControlText *)data )->GetSelected() )
92                ( (ControlText *)data )->DoScroll();
93
94             return true;
95         }
96         else
97         {
98             return false;
99         }
100     }
101     //-----------------------------------------------------------------------
102     void ControlText::StartScrolling()
103     {
104         g_timeout_add( 100, (GSourceFunc)ScrollingTextTimer, (gpointer)this );
105     }
106     //-----------------------------------------------------------------------
107     void ControlText::StopScrolling()
108     {
109     }
110     //-----------------------------------------------------------------------
111
112
113     #endif
114 //---------------------------------------------------------------------------
115
116
117
118
119 //---------------------------------------------------------------------------
120 // CONTROL TEXT
121 //---------------------------------------------------------------------------
122 ControlText::ControlText( string id, bool visible, int x, int y, string text,
123     string font, int align, int width, string display, bool scroll,
124     int scrollspace, string help, Window *Parent )
125     : GenericControl( id, visible, help, Parent )
126 {
127     InitLeft         = x;
128     Top              = y;
129     InitWidth        = width;
130     FontName         = font;
131     Text             = text;
132     Align            = align;
133     Selected         = false;
134
135     // Scrolling parameters
136     InitScroll       = scroll;
137     Scroll           = false;
138     ScrollSpace      = scrollspace;
139     PauseScroll      = false;
140
141     // Initialize display
142     if( display != "none" )
143     {
144         int begin = 0;
145         int pos = display.find( ';', 0 );
146         while( pos > 0 )
147         {
148             DisplayList.push_back( display.substr( begin, pos - begin ) );
149             begin = pos + 1;
150             pos = display.find( ';', begin );
151         }
152         DisplayList.push_back(
153             display.substr( begin, display.size() - begin ) );
154         Display = DisplayList.begin();
155     }
156
157 }
158 //---------------------------------------------------------------------------
159 ControlText::~ControlText()
160 {
161     if( TextClipRgn != NULL )
162         delete TextClipRgn;
163     TextWidth = 0;
164     SetScrolling();
165 }
166 //---------------------------------------------------------------------------
167 void ControlText::Init()
168 {
169     TextFont     = p_intf->p_sys->p_theme->FntBank->Get( FontName );
170
171     // Init clipping region
172     TextClipRgn = NULL;
173
174     // Get size of control
175     SetSize();
176     SetScrolling();
177 }
178 //---------------------------------------------------------------------------
179 void ControlText::SetScrolling()
180 {
181     if( !Scroll && TextWidth > Width )
182     {
183         if( InitScroll )
184         {
185             Scroll = true;
186             StartScrolling();
187         }
188     }
189     else if( Scroll && TextWidth <= Width )
190     {
191         Scroll = false;
192         StopScrolling();
193     }
194 }
195 //---------------------------------------------------------------------------
196 void ControlText::SetSize()
197 {
198     // Get size parameters
199     int w, h;
200     TextFont->GetSize( Text, w, h );
201     TextWidth = w;
202
203     // Get width if not set
204     if( InitWidth <= 0 )
205         Width  = w;
206     else
207         Width  = InitWidth;
208
209     // Set height
210     Height = h;
211
212     // Set position wether alignment
213     if( Align == DT_CENTER )
214     {
215         Left     = InitLeft - Width / 2;
216         TextLeft = InitLeft - TextWidth / 2;
217     }
218     else if( Align == DT_RIGHT )
219     {
220         Left     = InitLeft - Width;
221         TextLeft = InitLeft - TextWidth;
222     }
223     else
224     {
225         Left     = InitLeft;
226         TextLeft = InitLeft;
227     }
228
229     // Create clipping region
230     if( TextClipRgn != NULL )
231         delete TextClipRgn;
232
233     TextClipRgn = (Region *)new OSRegion( Left, Top, Width, Height );
234
235 }
236 //---------------------------------------------------------------------------
237 bool ControlText::ProcessEvent( Event *evt )
238 {
239     unsigned int msg = evt->GetMessage();
240     unsigned int p1  = evt->GetParam1();
241     long         p2  = evt->GetParam2();
242
243     switch( msg )
244     {
245         case CTRL_SET_TEXT:
246             if( DisplayList.size() > 0 )
247             {
248                 if( p_intf->p_sys->p_theme->EvtBank->Get( (*Display) )
249                     ->IsEqual( (Event*)p1 ) )
250                 {
251                     SetText( (char *)p2 );
252                 }
253             }
254             break;
255     }
256     return false;
257 }
258 //---------------------------------------------------------------------------
259 void ControlText::Draw( int x, int y, int w, int h, Graphics *dest )
260 {
261     if( !Visible )
262         return;
263
264     // Test if control is in refresh zone
265     int xI, yI, wI, hI;
266     if( !GetIntersectRgn( x,y,w,h, Left,Top,Width,Height, xI,yI,wI,hI) )
267         return;
268
269     // Change clipping region
270     TextClipRgn->Move( -x, -y );
271     dest->SetClipRegion( TextClipRgn );
272
273     // Draw text
274     if( TextWidth <= Width || !Scroll )
275     {
276         TextFont->Print( dest, Text, Left - x, Top - y, Width, Height, Align );
277     }
278     else
279     {
280         if( TextLeft > Left + ScrollSpace )
281         {
282             TextFont->Print( dest, Text, TextLeft - x, Top - y,
283                          TextWidth, Height, Align );
284             TextFont->Print( dest, Text, TextLeft - x - TextWidth - ScrollSpace,
285                          Top - y, TextWidth, Height, Align );
286         }
287         else if( TextLeft + TextWidth + ScrollSpace < Left + Width )
288         {
289             TextFont->Print( dest, Text, TextLeft - x, Top - y,
290                          TextWidth, Height, Align );
291             TextFont->Print( dest, Text, TextLeft - x + TextWidth + ScrollSpace,
292                          Top - y, TextWidth, Height, Align );
293         }
294         else
295         {
296             TextFont->Print( dest, Text, TextLeft - x, Top - y,
297                          TextWidth, Height, Align );
298         }
299     }
300
301     // Reset clipping region to old region
302     Region *destClipRgn = (Region *)new OSRegion( 0, 0, w, h );
303     dest->SetClipRegion( destClipRgn );
304     delete destClipRgn;
305     TextClipRgn->Move( x, y );
306 }
307 //---------------------------------------------------------------------------
308 void ControlText::SetText( const string newText )
309 {
310     if( Text != newText )
311     {
312         Selected = false;
313         Text     = newText;
314         SetSize();
315         SetScrolling();
316         ParentWindow->Refresh( Left, Top, Width, Height );
317     }
318 }
319 //---------------------------------------------------------------------------
320 void ControlText::DoScroll()
321 {
322     if( !PauseScroll )
323     {
324         TextLeft -= 2;
325         if( TextLeft + TextWidth < Left )
326             TextLeft += TextWidth + ScrollSpace;
327
328         ParentWindow->Refresh( Left, Top, Width, Height );
329     }
330 }
331 //---------------------------------------------------------------------------
332 void ControlText::MoveRelative( int xOff, int yOff )
333 {
334     InitLeft += xOff;
335     Top      += yOff;
336     SetSize();
337 }
338 //---------------------------------------------------------------------------
339 bool ControlText::MouseUp( int x, int y, int button )
340 {
341     Selected = false;
342     if( MouseOver( x, y ) && button == 1 )
343     {
344         if( DisplayList.size() > 1 || TextWidth > Width )
345             return true;
346     }
347     return false;
348
349 }
350 //---------------------------------------------------------------------------
351 bool ControlText::MouseDown( int x, int y, int button )
352 {
353     if( MouseOver( x, y ) && button == 1 )
354     {
355         if( TextWidth > Width )
356         {
357             PauseScroll = !PauseScroll;
358             OSAPI_GetMousePos( MouseX, MouseY );
359             SelectedX = MouseX;
360             Selected = true;
361             return true;
362         }
363         else if( DisplayList.size() > 1 )
364         {
365             return true;
366         }
367     }
368     return false;
369 }
370 //---------------------------------------------------------------------------
371 bool ControlText::MouseMove( int x, int y, int button )
372 {
373     if( Selected && button == 1 )
374     {
375         OSAPI_GetMousePos( MouseX, MouseY );
376
377         if( MouseX != SelectedX )
378         {
379             TextLeft += MouseX - SelectedX;
380             SelectedX = MouseX;
381
382             while( TextLeft + TextWidth < Left )
383                 TextLeft += TextWidth + ScrollSpace;
384
385             while( TextLeft > Left + ScrollSpace )
386                 TextLeft -= TextWidth + ScrollSpace;
387
388             ParentWindow->Refresh( Left, Top, Width, Height );
389         }
390     }
391     return false;
392 }
393 //---------------------------------------------------------------------------
394 bool ControlText::MouseOver( int x, int y )
395 {
396     if( x >= Left && x < Left + Width && y >= Top && y < Top + Height )
397         return true;
398     else
399         return false;
400 }
401 //---------------------------------------------------------------------------
402 bool ControlText::MouseDblClick( int x, int y, int button )
403 {
404     Selected = false;
405     if( x >= Left && x < Left + Width && y >= Top && y < Top + Height
406         && button == 1 && DisplayList.size() > 1 )
407     {
408         Display++;
409         if( Display == DisplayList.end() )
410             Display = DisplayList.begin();
411         return true;
412     }
413     else
414     {
415         return false;
416     }
417 }
418 //---------------------------------------------------------------------------
419