~ubuntu-branches/ubuntu/edgy/pouetchess/edgy-updates

« back to all changes in this revision

Viewing changes to src/sxmlgui/GUIComboBox.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Lionel Le Folgoc (mr_pouit)
  • Date: 2006-07-15 15:45:57 UTC
  • Revision ID: james.westby@ubuntu.com-20060715154557-3paxq02hx4od0wm4
Tags: upstream-0.2.0
ImportĀ upstreamĀ versionĀ 0.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "EasyGL.h"
 
2
 
 
3
GUIComboBox::GUIComboBox(const std::string& cbs) : GUIRectangle(cbs)
 
4
 
 
5
{
 
6
  setScrollingColor(0.2f, 0.75f, 0.35f, 1.0f);
 
7
  setFontScales(1.0f, 1.0f);
 
8
  setPosition(0.5, 0.5);
 
9
 
 
10
  currentSelection = new GUILabel("Unknown", "itemCBS_0");
 
11
  dropMenuButton   = new GUIButton("cbddb");
 
12
  upperPanel       = new GUIPanel("cbup");
 
13
  lowerPanel       = new GUIPanel("cblp");
 
14
 
 
15
  upperPanel->setLayout(PL_XAXIS_LAYOUT);
 
16
 
 
17
  upperPanel->setVisibleBounds(true);
 
18
  upperPanel->enableBGColor(true);
 
19
  upperPanel->setInterval(6, 3);
 
20
  upperPanel->addWidget(currentSelection);
 
21
  upperPanel->addWidget(dropMenuButton);
 
22
 
 
23
  lowerPanel->setLayout(PL_YAXIS_LAYOUT);
 
24
  lowerPanel->setInterval(6, 2);
 
25
  lowerPanel->setVisible(false);
 
26
  lowerPanel->enableBGColor(true);
 
27
  lowerPanel->setVisibleBounds(true);
 
28
  lowerPanel->setAnchorPoint(AT_CORNERLU);
 
29
  lowerPanel->setClipSize(0);
 
30
 
 
31
  displayScrollingRectangle =      true;
 
32
  selectionIndex            =        -1;
 
33
  widgetType                = WT_COMBO_BOX;
 
34
  fontIndex                 =         0;
 
35
  lockItems                 =     false;
 
36
  deployed                  =     false;
 
37
}
 
38
 
 
39
GUIComboBox::~GUIComboBox()
 
40
{
 
41
  deleteObject(upperPanel);
 
42
  deleteObject(lowerPanel); 
 
43
}
 
44
 
 
45
GUIEventListener  *GUIComboBox::getEventsListener()
 
46
{
 
47
  return this;
 
48
}
 
49
 
 
50
void  GUIComboBox::setFontScales(const Tuple2f &scales)
 
51
{
 
52
  setFontScales(scales.x, scales.y);
 
53
}
 
54
 
 
55
void  GUIComboBox::setFontScales(float wScale, float hScale)
 
56
{
 
57
  fontScales.x = clamp(hScale, 0.01f, 20.0f);
 
58
  fontScales.y = clamp(wScale, 0.01f, 20.0f);
 
59
}
 
60
 
 
61
const Tuple2f  &GUIComboBox::getFontScales()
 
62
{
 
63
  return fontScales;
 
64
}
 
65
 
 
66
bool GUIComboBox::loadXMLSettings(const TiXmlElement *element)
 
67
{
 
68
  if(!XMLArbiter::inspectElementInfo(element, "ComboBox"))
 
69
    return Logger::writeErrorLog("Need a ComboBox node in the xml file");
 
70
 
 
71
  const   TiXmlElement *child  = NULL;
 
72
  Tuple3f bordersColor         = upperPanel->getBordersColor();
 
73
  Tuple4f bgColor              = upperPanel->getBGColor();
 
74
  float   lowerPanelColorScale = 1.0f;
 
75
 
 
76
  child = XMLArbiter::getChildElementByName(element, "Button");
 
77
  if(child)
 
78
  {
 
79
    dropMenuButton->loadXMLClippedRectangleInfo(child);
 
80
    dropMenuButton->loadXMLSettings(child);
 
81
    dropMenuButton->setCallbackString("cbddb");
 
82
    dropMenuButton->setLabelString("");
 
83
    dropMenuButton->setActive(true);
 
84
    dropMenuButton->setVisible(true);
 
85
  }
 
86
 
 
87
  displayScrollingRectangle = XMLArbiter::analyzeBooleanAttr(element, "displayScrollingRectangle", displayScrollingRectangle);
 
88
  lowerPanelColorScale      = XMLArbiter::fillComponents1f(element,   "lowerPanelColorScale", lowerPanelColorScale);
 
89
  fontScales.y              = XMLArbiter::fillComponents1f(element,   "hScale",    fontScales.y);
 
90
  fontScales.x              = XMLArbiter::fillComponents1f(element,   "wScale",    fontScales.x);
 
91
  fontIndex                 = XMLArbiter::fillComponents1i(element,   "fontIndex", fontIndex);
 
92
 
 
93
  for(child = element->FirstChildElement();     
 
94
      child;
 
95
          child = child->NextSiblingElement() )
 
96
  {
 
97
    const char *value = child->Value();
 
98
    if(!value)
 
99
      continue;
 
100
 
 
101
    if(!strcmp(value, "ScrollingColor"))
 
102
      setScrollingColor(XMLArbiter::fillComponents4f(child, scrollingColor));
 
103
 
 
104
    if(!strcmp(value, "BordersColor"))
 
105
      XMLArbiter::fillComponents3f(child, bordersColor);
 
106
 
 
107
    if(!strcmp(value, "BGColor"))
 
108
      XMLArbiter::fillComponents4f(child, bgColor);
 
109
 
 
110
    if(!strcmp(value, "Item"))
 
111
      addItem(child->Attribute("string"));
 
112
  }
 
113
 
 
114
  upperPanel->setBordersColor(bordersColor);
 
115
  lowerPanel->setBordersColor(bordersColor);
 
116
 
 
117
  upperPanel->setBGColor(bgColor);
 
118
  lowerPanel->setBGColor(bgColor.x*lowerPanelColorScale,
 
119
                         bgColor.y*lowerPanelColorScale,
 
120
                         bgColor.z*lowerPanelColorScale,
 
121
                         bgColor.w);
 
122
 
 
123
  setFontScales(fontScales);
 
124
 
 
125
  return GUIRectangle::loadXMLSettings(element) && (items.size() != 0);
 
126
}
 
127
 
 
128
void GUIComboBox::checkMouseEvents(MouseEvent &evt, int extraInfo, bool rBits)
 
129
{
 
130
  upperPanel->checkMouseEvents(evt, extraInfo, rBits);
 
131
  scrollingRectangle.x = 1;
 
132
 
 
133
  if(lowerPanel->isVisible())
 
134
    lowerPanel->checkMouseEvents(evt, extraInfo, rBits);
 
135
 
 
136
  if(!currentSelection->isFocused() && !dropMenuButton->isFocused())
 
137
    deployed = false;
 
138
 
 
139
  if(deployed)
 
140
  {
 
141
    lowerPanel->setVisible(true);
 
142
    evt.consume();
 
143
  }
 
144
  else
 
145
    lowerPanel->setVisible(false);
 
146
}
 
147
 
 
148
void GUIComboBox::actionPerformed(GUIEvent &evt)
 
149
{
 
150
  GUIEventListener  *eventsListener  = parent->getEventsListener();
 
151
  //const std::string &cbs             = evt.getCallbackString();
 
152
  GUIRectangle      *sourceRectangle = evt.getEventSource();
 
153
  int                widgetType      = sourceRectangle->getWidgetType();
 
154
 
 
155
  if(currentSelection->isClicked() || dropMenuButton->isClicked())
 
156
    deployed = !deployed;
 
157
 
 
158
  if(widgetType == WT_LABEL && (sourceRectangle->getParent() == lowerPanel))
 
159
  {
 
160
    GUILabel *newSelection = (GUILabel*)sourceRectangle;
 
161
    if(newSelection->isMouseOver())
 
162
      scrollingRectangle = newSelection->getWindowBounds();
 
163
 
 
164
    if(newSelection->isClicked() && (newSelection->getLabelString() != currentSelection->getLabelString()))
 
165
    {
 
166
      currentSelection->setLabelString(newSelection->getLabelString());
 
167
      selectionIndex = getItemIndex(newSelection->getLabelString());
 
168
      update         = true;
 
169
      if(eventsListener)
 
170
                {
 
171
                                GUIEvent evt(this);
 
172
        eventsListener->actionPerformed(evt);
 
173
                        }
 
174
    }
 
175
  }
 
176
}
 
177
 
 
178
void GUIComboBox::setItemIndex(int index)
 
179
{
 
180
        selectionIndex = index;
 
181
        update         = true;
 
182
        currentSelection->setLabelString(items[selectionIndex]);
 
183
}
 
184
 
 
185
void GUIComboBox::render(float clockTick)
 
186
{
 
187
  if(!parent || !visible)
 
188
    return;
 
189
 
 
190
  computeWindowBounds();
 
191
  upperPanel->render(clockTick);
 
192
 
 
193
  if(lowerPanel->isVisible())
 
194
  {
 
195
    lowerPanel->renderClippedBounds();
 
196
    lowerPanel->enableBGColor(false);
 
197
    lowerPanel->setVisibleBounds(false);
 
198
 
 
199
    if(scrollingRectangle.x >= lowerPanel->getWindowBounds().x && displayScrollingRectangle)
 
200
    {
 
201
 
 
202
      glEnable(GL_BLEND);
 
203
      glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 
204
      glColor4fv(scrollingColor);
 
205
 
 
206
      glBegin(GL_TRIANGLE_STRIP);
 
207
      glVertex2i(scrollingRectangle.x - 2, scrollingRectangle.y);
 
208
      glVertex2i(scrollingRectangle.x - 2, scrollingRectangle.w);
 
209
      glVertex2i(scrollingRectangle.z + 1, scrollingRectangle.y);
 
210
      glVertex2i(scrollingRectangle.z + 1, scrollingRectangle.w);
 
211
      glEnd();
 
212
 
 
213
      glDisable(GL_BLEND);
 
214
    }
 
215
 
 
216
    lowerPanel->render(clockTick);
 
217
    lowerPanel->enableBGColor(true);
 
218
    lowerPanel->setVisibleBounds(true);
 
219
  }
 
220
}
 
221
 
 
222
void GUIComboBox::finalizeSize()
 
223
{
 
224
  if(!items.size() || lockItems )
 
225
    return;
 
226
 
 
227
  GUIFont *font             = GUIFontManager::getFont(fontIndex);
 
228
  const    int    *spaces   = font ? font->getFontObject()->getCharHorizontalGlyphs() : NULL;
 
229
  float            maxWidth = 0,
 
230
                   height   = 0;
 
231
  int              cbsIndex = 1;
 
232
  if(spaces)
 
233
  {
 
234
    float  width    = 0;
 
235
    size_t length   = 0;
 
236
 
 
237
    height   =  float(font->getFontObject()->getHeight());
 
238
 
 
239
    for(size_t l = 0; l < items.size(); l++)
 
240
    {
 
241
      length = items[l].size();
 
242
      width  = 0.0f;
 
243
 
 
244
      for(size_t t = 0; t < length; t++)
 
245
        width += spaces[items[l][t]];
 
246
 
 
247
      maxWidth = width > maxWidth ? width : maxWidth;
 
248
    }
 
249
  }
 
250
  else
 
251
    return;
 
252
 
 
253
  currentSelection->setLabelString(items[0]);
 
254
  currentSelection->setDimensions(maxWidth*fontScales.x + 2.0f, height*fontScales.y);
 
255
  currentSelection->getLabel()->setFontIndex(fontIndex);
 
256
  currentSelection->getLabel()->setScales(fontScales);
 
257
  dropMenuButton->setDimensions(height*fontScales.y + 4.0f, height*fontScales.y + 4.0f);
 
258
 
 
259
  char buffer[256];
 
260
  
 
261
  for(size_t l = 0; l < items.size(); l++)
 
262
  {
 
263
    sprintf(buffer, "itemCBS %d", (cbsIndex++));
 
264
    GUILabel *newLabel = new GUILabel(items[l].c_str(), buffer);
 
265
    newLabel->getLabel()->setFontIndex(fontIndex);
 
266
    newLabel->setDimensions(maxWidth*fontScales.x + 2.0f /*+ height*fontScales.y + 10.0f*/, height*fontScales.y);
 
267
    newLabel->getLabel()->setScales(fontScales);
 
268
    if(!lowerPanel->addWidget(newLabel))
 
269
      deleteObject(newLabel);
 
270
  }
 
271
  selectionIndex =    0;
 
272
  lockItems      = true;
 
273
}
 
274
 
 
275
const void GUIComboBox::computeWindowBounds()
 
276
{
 
277
  finalizeSize();
 
278
 
 
279
  if(parent && update)
 
280
  {
 
281
    upperPanel->setAnchorPoint(getAnchorPoint());
 
282
    upperPanel->setPosition(getPosition());
 
283
    upperPanel->setParent(parent);
 
284
    upperPanel->forceUpdate(true);
 
285
    upperPanel->computeWindowBounds();
 
286
    upperPanel->forceUpdate(false);
 
287
    windowBounds = upperPanel->getWindowBounds();
 
288
 
 
289
    lowerPanel->setPosition(0.0f, float(upperPanel->getHeight()));
 
290
    lowerPanel->setParent(upperPanel);
 
291
    lowerPanel->forceUpdate(true);
 
292
 
 
293
    //Redirect mouse events to combo box action listener
 
294
    lowerPanel->setParent(this);
 
295
    upperPanel->setParent(this);
 
296
  }
 
297
}
 
298
 
 
299
void GUIComboBox::addItem(const std::string &item)
 
300
{
 
301
  if(lockItems || !item.size())
 
302
    return;
 
303
 
 
304
  for(size_t t = 0; t < items.size(); t++)
 
305
    if(items[t] == item)
 
306
      return;
 
307
 
 
308
  items.push_back(item);
 
309
}
 
310
 
 
311
int  GUIComboBox::getItemIndex(const std::string &item)
 
312
{
 
313
  for(size_t t = 0; t < items.size(); t++)
 
314
    if(items[t] == item)
 
315
      return int(t);
 
316
 
 
317
  return -1;
 
318
}
 
319
 
 
320
const std::vector<std::string> &GUIComboBox::getItems() const
 
321
{
 
322
  return items;
 
323
}
 
324
 
 
325
const char  *GUIComboBox::getSelectedItem()  const
 
326
{
 
327
  return selectionIndex < 0 ? NULL : items[selectionIndex].c_str();
 
328
}
 
329
 
 
330
const char  *GUIComboBox::getItem(size_t index) const
 
331
{
 
332
  return index >= items.size() ? NULL :  items[index].c_str();
 
333
}
 
334
 
 
335
void    GUIComboBox::setScrollingColor(float r, float g, float b, float a)
 
336
{
 
337
  scrollingColor.set(clamp(r, 0.0f, 255.0f),
 
338
                     clamp(g, 0.0f, 255.0f),
 
339
                     clamp(b, 0.0f, 255.0f),
 
340
                     clamp(a, 0.0f, 255.0f));
 
341
 
 
342
  scrollingColor.x /= (scrollingColor.x > 1.0) ? 255.0f : 1.0f;
 
343
  scrollingColor.y /= (scrollingColor.y > 1.0) ? 255.0f : 1.0f;
 
344
  scrollingColor.z /= (scrollingColor.z > 1.0) ? 255.0f : 1.0f;
 
345
  scrollingColor.w /= (scrollingColor.w > 1.0) ? 255.0f : 1.0f;
 
346
}
 
347
 
 
348
void    GUIComboBox::setScrollingColor(const Tuple4f &rgba)
 
349
{
 
350
  setScrollingColor(rgba.x, rgba.y, rgba.z, rgba.w);
 
351
}
 
352
 
 
353
const   Tuple4f &GUIComboBox::getScrollingColor() const
 
354
{
 
355
  return  scrollingColor;
 
356
}
 
357
 
 
358
void    GUIComboBox::enableScrollingRectangle(bool on)
 
359
{
 
360
  displayScrollingRectangle = on;
 
361
}
 
362
 
 
363
bool    GUIComboBox::scrollingRectangleEnabled()
 
364
{
 
365
  return displayScrollingRectangle;
 
366
}
 
367
 
 
368
bool GUIComboBox::isDeployed()
 
369
{
 
370
  if(lowerPanel) return lowerPanel->isVisible();
 
371
  return false;
 
372
}