]> git.vomp.tv Git - vompclient.git/blob - vtabsviewman.cc
Minor fixes
[vompclient.git] / vtabsviewman.cc
1 /*
2     Copyright 2004-2007 Chris Tallon, Marten Richter
3
4     This file is part of VOMP.
5
6     VOMP is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     VOMP is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with VOMP; if not, write to the Free Software
18     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 */
20 #include "vtabsviewman.h"
21 #include "video.h"
22 #include "wsymbol.h"
23 #include "remote.h"
24 #include "command.h"
25 #include "viewman.h"
26
27 VTabsViewMan::VTabsViewMan()
28 {
29     numViews = 0;
30     selectedView = 0;
31     backgroundColour = Colour::VIEWBACKGROUND;
32     tabHasControl = true;
33 }
34
35 VTabsViewMan::~VTabsViewMan()
36 {
37     removeAll();
38 }
39
40 int VTabsViewMan::add(View* v)
41 {
42     if (numViews == 16) return 0;
43
44     v->setTitleBarOn(0); //No Title Bar
45     v->setViewMan(this); //For this view, we are the viewman
46     v->setBackgroundColour(Colour::TABVIEWBACKGROUND);
47
48     views[numViews++] = v;
49
50     if (surface!=NULL) create(); //Recreating surface
51
52     return 1;
53 }
54
55 int VTabsViewMan::removeView(View* toDelete)
56 {
57     if (numViews == 0) return 0;
58
59     int i;
60
61     if (toDelete == NULL)
62     {
63         toDelete = views[numViews-1];
64         i = numViews - 1;
65     }
66     else
67     {
68         // to be deleted view is more likely to be at the top
69         for (i = numViews-1; i >= 0; i--)
70         {
71             if (views[i] == toDelete) break;
72         }
73         if (i == -1)
74         {
75             // not a View we have!
76             return 0;
77         }
78     }
79 //    deleteView(i);
80
81     // Shift the views on top down one
82     --numViews;
83     for(int j = i; j < numViews; j++) views[j] = views[j+1];
84
85     // Delete the view
86     delete toDelete;
87
88     if (surface!=NULL) create(); //Recreating surface, if we are initted
89     if (selectedView >= numViews) selectedView = numViews-1;
90
91     return 1;
92 }
93
94 void VTabsViewMan::removeAll()
95 {
96     for (; numViews > 0; --numViews)
97     {
98         delete views[numViews-1];
99     }
100 }
101
102 void VTabsViewMan::updateView(View* toUpdate, Region* regionToUpdate)
103 {
104     draw();
105     ViewMan::getInstance()->updateView(this,regionToUpdate);
106 }
107
108 void VTabsViewMan::create()
109 {
110     if (surface!=NULL)
111     {
112         delete surface;//destroy old surface
113         surface=NULL;
114     }
115     Region newarea;
116     int i;
117     if (numViews == 0)
118     {
119         newarea.h=200;
120         newarea.w=200;
121     }
122     else
123     {
124         for (i = 0; i < numViews; i++)
125         {
126             newarea.h=max(views[i]->getHeight(),newarea.h);
127             newarea.w=max(views[i]->getWidth(),newarea.w);
128         }
129     }
130     newarea.h += 30; //Title Bar
131     newarea.h += 30; //Tab bar
132     newarea.h += 2; //Border
133     newarea.w += 2;
134
135     //centering
136
137     newarea.y = Video::getInstance()->getScreenHeight()/2-newarea.h/2;
138     newarea.x = Video::getInstance()->getScreenWidth()/2-newarea.w/2;
139     setScreenPos(newarea.x,newarea.y);
140
141     //Now iterate through the views and set the position
142
143     for (i = 0; i < numViews; i++)
144     {
145         views[i]->setScreenPos(newarea.x+1,newarea.y+1+30+30);
146     }
147     View::create(newarea.w,newarea.h);
148
149 }
150
151
152 void VTabsViewMan::draw()
153 {
154     if (surface==NULL) return;
155     View::draw();
156     //Now Drawing the tabs bar
157     int xpos=1;
158     WSymbol wsy;
159     wsy.setSurface(surface);
160
161     if (selectedView>=2)
162     {
163         wsy.nextSymbol = WSymbol::LEFTARROW;
164         wsy.nextColour = Colour::BUTTONBACKGROUND;
165         wsy.setSurfaceOffset(xpos, 40);
166         wsy.draw();
167         xpos+=20;
168     }
169     int i;
170     UINT textypos=30+30-2-surface->getFontHeight();
171     for (i = max(selectedView-1,0); i < numViews && xpos+150+20 < (int)area.w; i++)
172     {
173         if (i == selectedView)
174         {
175             rectangle(xpos+1,30+1,150,30,Colour::TABVIEWBACKGROUND);
176         }
177         else
178         {
179              rectangle(xpos+1,30+1,150,28,Colour::TABVIEWBACKGROUND);
180         }
181         if (i == selectedView && tabHasControl)
182             drawText(views[i]->getTitleText(),xpos+5,textypos,Colour::SELECTHIGHLIGHT);
183         else
184             drawText(views[i]->getTitleText(),xpos+5,textypos,Colour::LIGHTTEXT);
185
186         xpos+=151;
187     }
188     if (i < numViews)
189     {
190         wsy.nextSymbol = WSymbol::RIGHTARROW;
191         wsy.nextColour = Colour::BUTTONBACKGROUND;
192         wsy.setSurfaceOffset(xpos+5, 40);
193         wsy.draw();
194         xpos+=20;
195     }
196
197
198     if (selectedView < numViews) views[selectedView]->draw();
199 }
200
201 void VTabsViewMan::blt(Region& r)
202 {
203     Box::blt(r);
204
205     if (selectedView < numViews) {
206         Region helper=r;
207         helper.x = max(helper.x,views[selectedView]->area.x);
208         helper.w -= helper.x-r.x;
209         helper.y = max(helper.y,views[selectedView]->area.y);
210         helper.h -= helper.y-r.y;
211         helper.w = min(helper.w,views[selectedView]->area.w);
212         helper.h = min(helper.h,views[selectedView]->area.h);
213         views[selectedView]->blt(helper);
214     }
215 }
216
217
218 int VTabsViewMan::handleCommand(int command)
219 {
220   int retVal;
221   int i;
222   if (command == Remote::BACK)
223   {
224       for (i=0;i<numViews;i++)
225       {
226           views[i]->handleCommand(Remote::BACK);
227       }
228       // Instead of returning 4 here which would delete this view
229       // before the doSave messages are processed, let the message queue
230       // do the doSave then this close message. That will make the options menu
231       // disappear before this view
232
233       Message* m = new Message();
234       m->message = Message::CLOSE_ME;
235       m->from = this;
236       m->to = ViewMan::getInstance();
237       Command::getInstance()->postMessageNoLock(m);
238       return 2;
239   }
240   else if (tabHasControl) //our control bar is selected, we are the master of the universe
241   {
242       switch (command)
243       {
244       case Remote::DF_DOWN:
245       case Remote::DOWN:
246       {
247           tabHasControl = false; //loose control
248           if (selectedView < numViews)
249           {
250               views[selectedView]->handleCommand(command);
251               draw();
252            
253
254     //          viewman->updateView(this);   // CJT // this line makes it flash twice, unneccessary?
255               return 2;
256           }
257           else
258             return 2;
259       }break;
260       case Remote::DF_LEFT:
261       case Remote::LEFT:
262       {
263         selectedView=max(0,selectedView-1);
264         draw();
265         viewman->updateView(this);
266         return 2;
267       }break;
268       case Remote::DF_RIGHT:
269       case Remote::RIGHT:
270       {
271         selectedView=min(numViews-1,selectedView+1);
272         draw();
273         viewman->updateView(this);
274         return 2;
275       }break;
276       }
277       return 1;
278   }
279   else if (command != Remote::NA_NONE)
280   {
281     // handle command return values
282     // 0 - drop through to next view //this means me
283     // 1 - dont drop to next view, but not handled
284     // 2 - handled - stop command here
285     // 4 - handled - delete this view //delete me too
286
287
288       if (selectedView < numViews)
289       {
290           retVal = views[selectedView]->handleCommand(command);
291           if (retVal == 1)
292           {
293               // not handled but don't give to any more views
294               return 1;
295           }
296           if (retVal == 2)
297           {
298               // command handled
299               return 2;
300           }
301           else if (retVal == 4)
302           {
303               //        Log::getInstance()->log("ViewMan", Log::DEBUG, "Return 4: i=%i, views[i]=%p", i, views[i]);
304
305               return 1;
306           } else if (retVal == 0) {
307               tabHasControl = true;
308               draw(); // I have control
309               viewman->updateView(this);
310               return 2;
311           }
312
313       }
314   }
315   else
316   {
317     // fake the return code
318     return  2;
319   }
320
321   return 0;
322
323 }
324
325 void VTabsViewMan::processMessage(Message* m)
326 {
327     /* Handle mouse events*/
328   // They come in with m->to = ViewMan and just need to be delivered to selectedView?
329   if ((numViews > 0) && ((m->message == Message::MOUSE_MOVE) || (m->message == Message::MOUSE_LBDOWN)))
330   {
331       //TODO, add Tab bar interaction
332     int x=(m->parameter>>16)-getScreenX();
333     int y=(m->parameter&0xFFFF)-getScreenY();
334     if (x<0 || y <0 || x>getWidth() || y>getHeight())
335     {
336         if (m->message == Message::MOUSE_LBDOWN)
337         {
338             Message *newm=new Message();
339             newm->from=NULL;
340             newm->to=Command::getInstance();
341             newm->message=Message::UDP_BUTTON;
342             newm->parameter=Remote::BACK;
343             Command::getInstance()->postMessage(newm);
344         }
345     } else {
346         if ( y <= 60)
347         { //my area
348             if (y >= 30 && m->message == Message::MOUSE_LBDOWN)
349             {
350                  int xpos=1;
351                  if (selectedView>=2)
352                  {
353                      if (xpos < x && x <=xpos+20)
354                      {
355                          tabHasControl=true;
356                          Message *newm=new Message();
357                          newm->from=NULL;
358                          newm->to=Command::getInstance();
359                          newm->message=Message::UDP_BUTTON;
360                          newm->parameter=Remote::LEFT;
361                          Command::getInstance()->postMessage(newm);
362                          return;
363                      }
364                      xpos+=20;
365                  }
366                  int i;
367                  for (i = max(selectedView-1,0);i < numViews && xpos+150+20 < (int)area.w; i++)
368                  {
369                      if (xpos < x && x <=xpos+150)
370                      {
371                          tabHasControl=true;
372                          selectedView = i;
373                          draw();
374                          ViewMan::getInstance()->updateView(this);
375                          return;
376                      }
377                      xpos+=151;
378                  }
379                  if (i < numViews)
380                  {
381                      if (xpos < x && x <=xpos+20)
382                      {
383                          tabHasControl=true;
384                          Message *newm=new Message();
385                          newm->from=NULL;
386                          newm->to=Command::getInstance();
387                          newm->message=Message::UDP_BUTTON;
388                          newm->parameter=Remote::RIGHT;
389                          Command::getInstance()->postMessage(newm);
390                          return;
391                      }
392                  }
393             }
394         }
395         else //tabs area
396         {
397             tabHasControl=false;
398             views[selectedView]->processMessage(m);
399         }
400     }
401     return;
402   }
403
404   if (m->to != this)
405   {
406     for (int i = numViews-1; i >= 0; i--)
407     {
408       if (views[i] == m->to)
409       {
410         Log::getInstance()->log("VTabsViewMan", Log::DEBUG, "sending message from view %p to view %p %lu", m->from, m->to, m->message);
411         views[i]->processMessage(m);
412         return;
413       }
414     }
415     return;
416   }
417
418
419
420   Log::getInstance()->log("VTabsViewMan", Log::DEBUG, "it's for meeee!");
421
422   switch(m->message)
423   {
424     case Message::CLOSE_ME:
425     {
426       removeView((View*)m->from);
427       break;
428     }
429     case Message::ADD_VIEW: // currently not used by anything but it might come in useful again
430     {
431       View* toAdd = (View*)m->parameter;
432       add(toAdd);
433       toAdd->draw();
434       ViewMan::getInstance()->updateView(this);
435       break;
436     }
437   }
438 }