]> git.vomp.tv Git - vompclient.git/blob - boxx.cc
Add -s option to select server
[vompclient.git] / boxx.cc
1 /*
2     Copyright 2007 Chris Tallon
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
21 #include "boxx.h"
22
23 #include "log.h"
24
25 char Boxx::numBoxxes = 0;
26
27 Boxx::Boxx()
28 {
29   // I want a parent box or a surface.
30   parent = NULL;
31   surface = NULL;
32
33   area.x = 0;
34   area.y = 0;
35   area.w = 0;
36   area.h = 0;
37
38   paraVSpace = 6; // default gap for drawPara
39
40   backgroundColourSet = false;
41   visible = true;
42
43   numBoxxes++;
44   Log::getInstance()->log("Boxx", Log::DEBUG, "Construct, now %u", numBoxxes);
45 }
46
47 Boxx::~Boxx()
48 {
49   if (surface) delete surface;
50   numBoxxes--;
51   Log::getInstance()->log("Boxx", Log::DEBUG, "Destruct, now %u", numBoxxes);
52 }
53
54 void Boxx::draw()
55 {
56   //Log::getInstance()->log("Boxx", Log::DEBUG, "Draw this %p surface %p", this, surface);
57   if (backgroundColourSet) fillColour(backgroundColour);
58
59   Boxx* currentBoxx;
60   vector<Boxx*>::iterator j;
61   for (j = children.begin(); j != children.end(); j++)
62   {
63     currentBoxx = *j;
64     if (currentBoxx->getVisible()) currentBoxx->draw();
65   }  
66 }
67
68 int Boxx::handleCommand(int x)
69 {
70   // A similar comment for this? FIXME make a commandreceiver thingy
71   return 0;
72 }
73
74 void Boxx::processMessage(Message* m)
75 {
76   // And this?
77 }
78
79 void Boxx::setSize(UINT w, UINT h)
80 {
81   area.w = w;
82   area.h = h;
83 }
84
85 void Boxx::setPosition(UINT x, UINT y)
86 {
87   area.x = x;
88   area.y = y;
89 }
90
91 void Boxx::createBuffer()
92 {
93   surface = new Surface_TYPE();
94   surface->create(area.w, area.h);
95 }
96
97 void Boxx::add(Boxx* newChild)
98 {
99   newChild->setParent(this);
100   children.push_back(newChild);
101 }
102
103 void Boxx::remove(Boxx* oldChild)
104 {
105   for(vector<Boxx*>::iterator i = children.begin(); i != children.end(); i++)
106   {
107     if (*i == oldChild)
108     {
109       children.erase(i);
110       return;
111     }
112   }
113   Log::getInstance()->log("Boxx", Log::ERR, "Remove child box called, child %p not found", oldChild);
114 }
115
116 void Boxx::setParent(Boxx* newParent)
117 {
118   parent = newParent;
119 }
120
121 void Boxx::setBackgroundColour(Colour& Tcolour)
122 {
123   backgroundColour = Tcolour;
124   backgroundColourSet = true;
125 }
126
127 void Boxx::setVisible(bool isVisible)
128 {
129   visible = isVisible;
130 }
131
132 bool Boxx::getVisible()
133 {
134   return visible;
135 }
136
137 void Boxx::setGap(UINT gap)
138 {
139   paraVSpace = gap;
140 }
141
142 void Boxx::blt(Region& r)
143 {
144   /* surface update to screen needs:
145   source x distance into this surface
146   source y distance into this surface
147   width of update
148   height of update
149   destination x on screen
150   destination y on screen
151   */
152
153   if (parent)
154   {
155     printf("parent blt???\n");
156     abort();
157     return;
158   }
159
160   // this shouldn't be here
161   r.x -= area.x;
162   r.y -= area.y;
163
164   surface->updateToScreen(r.x, r.y, r.w, r.h, area.x + r.x, area.y + r.y);
165   
166 }
167
168 int Boxx::getScreenX()
169 {
170   if (parent) return area.x + parent->getScreenX();
171   return area.x;
172 }
173
174 int Boxx::getScreenY()
175 {
176   if (parent) return area.y + parent->getScreenY();
177   return area.y;
178 }
179
180 int Boxx::getRootBoxOffsetX()  // convert this to be getX and silently do the parent/not thing? same for Y below?
181 {
182   if (parent) return area.x + parent->getRootBoxOffsetX();
183   return 0;
184 }
185
186 int Boxx::getRootBoxOffsetY()
187 {
188   if (parent) return area.y + parent->getRootBoxOffsetY();
189   return 0;
190 }
191
192 int Boxx::getX()
193 {
194   return area.x;
195 }
196
197 int Boxx::getY()
198 {
199   return area.y;
200 }
201
202 UINT Boxx::getWidth()
203 {
204   return area.w;
205 }
206
207 UINT Boxx::getHeight()
208 {
209   return area.h;
210 }
211
212 // Level 1 drawing functions
213
214 void Boxx::fillColour(Colour& colour)
215 {
216   rectangle(0, 0, area.w, area.h, colour);
217 }
218
219 void Boxx::drawPara(char* text, int x, int y, Colour& colour)
220 {
221   char line[256];
222   int lineHeight = surface->getFontHeight() + paraVSpace;
223
224   int lineWidth;
225   int thisCharWidth;
226   int textPos;
227   int linePos;
228   int ypos;
229   int printLine;
230
231   textPos = 0;
232   ypos = y;
233
234   while(1)
235   {
236     linePos = 0;
237     lineWidth = 0;
238     while(1)
239     {
240       printLine = 0;
241
242       if (text[textPos] == '\0') break;
243
244       if (text[textPos] == '\n')
245       {
246         textPos++; // ignore the \n
247         printLine = 1;
248         break;
249       }
250
251       thisCharWidth = surface->getCharWidth(text[textPos]);
252       if ((lineWidth + thisCharWidth) > (int)(area.w - (2 * paraMargin)))
253       {
254         // this character would break the right margin
255         if (text[textPos] == ' ')
256         {
257           // this char is a space, ignore and break
258           textPos++;
259           break;
260         }
261         else
262         {
263           // Need to go back to the last space in the line
264           while ((text[textPos] != ' ') && (linePos >= 0))
265           {
266             textPos--;
267             linePos--;
268           }
269           // Now take the space we just found
270           textPos++;
271           break;
272         }
273       }
274       line[linePos++] = text[textPos];
275       lineWidth += thisCharWidth;
276       textPos++;
277     }
278
279 //    line[linePos++] = '\0';
280     if (linePos>=0) line[linePos++] = '\0'; //Here is the change
281
282     if (printLine || (linePos > 1)) // if some text was put in line
283     {
284       drawText(line, x, ypos, colour);
285       ypos += lineHeight;
286       if (ypos > (int)(area.h - lineHeight)) break;
287     }
288     else
289     {
290       break;
291     }
292   }
293 }
294
295 void Boxx::rectangle(Region& region, Colour& colour)
296 {
297   rectangle(region.x, region.y, region.w, region.h, colour);
298 }
299
300 // Level 0 drawing functions
301
302 void Boxx::rectangle(UINT x, UINT y, UINT w, UINT h, Colour& colour)
303 {
304   if (parent) parent->rectangle(area.x + x, area.y + y, w, h, colour);
305   else surface->fillblt(x, y, w, h, colour.rgba());
306 }
307
308 void Boxx::drawText(const char* text, int x, int y, Colour& colour)
309 {
310   if (parent) parent->drawText(text, area.x + x, area.y + y, colour);
311   else surface->drawText(text, x, y, colour.rgba());
312 }
313
314 void Boxx::drawTextRJ(const char* text, int x, int y, Colour& colour)
315 {
316   if (parent) parent->drawTextRJ(text, area.x + x, area.y + y, colour);
317   else surface->drawTextRJ(text, x, y, colour.rgba());
318 }
319
320 void Boxx::drawTextCentre(const char* text, int x, int y, Colour& colour)
321 {
322   if (parent) parent->drawTextCentre(text, area.x + x, area.y + y, colour);
323   else surface->drawTextCentre(text, x, y, colour.rgba());
324 }
325
326 void Boxx::drawPixel(UINT x, UINT y, Colour& colour)
327 {
328   if (parent) parent->drawPixel(area.x + x, area.y + y, colour);
329   else
330   {
331     int c = (  (0xFF000000         )
332              | (colour.red    << 16)
333              | (colour.green  <<  8)
334              | (colour.blue        ) );
335
336     surface->drawPixel(x, y, c);
337   }
338 }
339
340 void Boxx::startFastDraw()
341 {
342     if (parent) parent->startFastDraw();
343     else
344     {
345         surface->startFastDraw();
346     }
347 }
348
349 void Boxx::endFastDraw()
350 {
351     if (parent) parent->endFastDraw();
352     else
353     {
354         surface->endFastDraw();
355     }
356 }
357  
358
359 int Boxx::charWidth(char c)
360 {
361   if (parent) return parent->charWidth(c);
362   else return surface->getCharWidth(c);
363 }
364