JNR
uiContainer.cpp
1 /*
2 
3 Jump'n'Run Engine
4 http://www.atanaslaskov.com/jnr/
5 
6 BSD LICENSE
7 Copyright (c) 2007-2013, Atanas Laskov
8 All rights reserved.
9 
10 Redistribution and use in source and binary forms, with or without
11 modification, are permitted provided that the following conditions are met:
12 1. Redistributions of source code must retain the above copyright notice,
13 this list of conditions and the following disclaimer.
14 2. Redistributions in binary form must reproduce the above copyright notice,
15 this list of conditions and the following disclaimer in the documentation
16 and/or other materials provided with the distribution.
17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 DISCLAIMED. IN NO EVENT SHALL ATANAS LASKOV BE LIABLE FOR ANY
21 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 
28 */
29 
30 //
31 // uiContainer.cpp
32 // Dependent: -
33 //
34 // UI Moveable windows, capable of containing controls
35 //
36 #include "stdafx.h"
37 #include "GUI.h"
38 
39 uiContainer* uiContainer::_pDrag = NULL;
40 
41 // Internal construction method,
42 // called by create() and load()
43 void uiContainer::init()
44 {
45  //Textures
46  tbg = _pSkin->parameter("TX_WNDBG").texture();
47  tborder_h = _pSkin->parameter("TX_WNDBR_H").texture();
48  tborder_v = _pSkin->parameter("TX_WNDBR_V").texture();
49  tangle = _pSkin->parameter("TX_WNDAN").texture();
50 
51  col = _pSkin->parameter("CL_CONTAINER").color();
52  ptShadowOffset[0] = _pSkin->parameter("SHADOW_OFFSETX").dval();
53  ptShadowOffset[1] = _pSkin->parameter("SHADOW_OFFSETX").dval();
54 
55  // TODO: ASSERT the window is created only once,
56  // the way it is now caption is added several times for some windows
57  //
58  //Caption
59  //if(_vControls.size() == 0 )
60  {
61  caption.create( laPoint3( -((double)tangle.w), -((double)tangle.h) ), laPoint3(getSize().x(), tangle.h) );
62  caption.show();
63  caption.size( _pSkin->parameter("SZ_CAPTION").dval() );
64  caption.font( _pSkin->parameter("FN_CAPTION").font() );
65  insert(&caption);
66 
67  /*caption_hr.create( laPoint3( -((double)tangle.w)+10, 0) , laPoint3(getSize().x()-20, 1) );
68  caption_hr.show();
69  insert(&caption_hr);*/
70  }
71 
72  //Deafault flags
73  toggleBorders(M_TRUE);
74  toggleMoveable(M_TRUE);
75 }
76 
77 uiContainer::uiContainer(void)
78 {
79  //m_nCnt = 0;
80  _bDisplayBorders = M_TRUE;
81  _nDragButton = 0;
82 }
83 
84 uiContainer::uiContainer(char* strFile)
85 {
86  //m_nCnt = 0;
87  _bDisplayBorders = M_TRUE;
88  _nDragButton = 0;
89 
90  load(strFile);
91 }
92 
93 uiContainer::~uiContainer(void)
94 {
95 }
96 
97 void uiContainer::create(laPoint3 pos, laPoint3 size)
98 {
99  //Create window
100  uiWindow::create(pos, size);
101 
102  //Initialize
103  init();
104  caption.setText("Untitled Container");
105 }
106 
107 //Load from .cui file
108 void uiContainer::load(class laFileParser *fp)
109 {
110  char strFile[128];
111  fp->readText(strFile, M_FALSE);
112  uiContainer::load(strFile);
113 }
114 
115 void uiContainer::load(char* strFile)
116 {
117  laFileParser fp(strFile);
118  char str[128] = "";
119 
120  //Read caption
121  fp.readText(str);
122 
123  //Load window
124  uiWindow::load(&fp);
125 
126  //Initialize
127  init();
128  caption.setText(str);
129  loadAlignment(&fp, this);
130 
131  //Load controlls
132  while(1)
133  {
134  uiWindow* pc;
135  fp.readSectionSeparator(str);
136 
137  if(!strcmp(str, "label")) pc = new uiLabel();
138  else if(!strcmp(str, "button")) pc = new uiButton();
139  else if(!strcmp(str, "checkbox")) { pc = new uiButton(); ((uiButton*)pc)->togglePersistent(M_TRUE); }
140  else if(!strcmp(str, "edit")) pc = new uiEdit();
141  else if(!strcmp(str, "radio")) pc = new uiRadio();
142  else if(!strcmp(str, "progress")) pc = new uiProgress();
143  else if(!strcmp(str, "slider")) pc = new uiSlider();
144  else if(!strcmp(str, "dialog")) pc = new uiContainer();
145  else if(!strcmp(str, "hr")) pc = new uiHR();
146  else if(!strcmp(str, "END")) return;
147  else throw laError("uiContainer::load: Unknow control type '%s'", str);
148 
149  pc->load(&fp);
150  pc->setID(_vControls.size());
151  pc->show();
152  insert(pc);
153 
154  loadAlignment(&fp, pc);
155  }
156 }
157 
158 void uiContainer::loadAlignment(laFileParser *fp, uiWindow* pw)
159 {
160  char str[64];
161  fp->readText(str, M_FALSE);
162  unsigned h, v;
163 
164  if( strstr(str, "left") ) h = M_AL;
165  else if( strstr(str, "right") ) h = M_AR;
166  else if( strstr(str, "center") ) h = M_AC;
167 
168  if( strstr(str, "top") ) v = M_AT;
169  else if( strstr(str, "bottom") ) v = M_AB;
170  else if( strstr(str, "middle") ) v = M_AM;
171 
172  pw->move(pw->getPos(), h, v);
173 }
174 
175 
177 {
178  uiWindow::kill();
179 }
180 
181 unsigned uiContainer::insert(uiWindow* pWnd)
182 {
183  _vControls.push_back(pWnd);
184  pWnd->_pParent = this;
185 
186  return _vControls.size()-1;
187 }
188 
189 uiWindow* uiContainer::get(unsigned id)
190 {
191  ASSERT(id < _vControls.size(), "Invalid control %d (max %d)", id, _vControls.size()-1);
192  return _vControls[id];
193 }
194 
195 uiWindow* uiContainer::remove(unsigned id)
196 {
197  ASSERT(M_FALSE, "Not implemented");
198  //uiWindow*p = get(id);
199  //m_arControls[id] = NULL;
200  return NULL; //p;
201 }
202 
204 {
205  if(!isEnabled())return;
206 
207  caption.move( laPoint3( 0/*-((double)tangle.w)*/, -((double)tangle.h ) ), M_AC, M_AT);
208 
209  //Pass control to children
210  for(unsigned id=0; id<_vControls.size(); id++)
211  {
212  if( (_vControls[id]->isVisible()) && (_vControls[id]->isEnabled()))
213  _vControls[id]->reply();
214  }
215 
216  //Drag window
217  if(_pDrag==this)
218  {
219  laPoint3 pos = getPos();
220  laPoint3 change = getRelativePointerPos() - _ptDragOffset;
221 
222  _ptPos = pos + change;
223  }
224 
225  //Reply myslef
226  uiWindow::reply();
227 }
228 
229 void uiContainer::drawBorders()
230 {
231  //Get renderer
232  laRenderer* r = ::laSystemIntegrator::getRenderer();
233 
234  //Metrics
235  double nBW = tangle.w; //Border width
236  double nBH = tangle.h; //Border height
237  laPoint3 sz(tangle.w, tangle.h);
238 
239  // draw edges
240  //
241  r->vquadsMakeXYRect( 0, _ptPos, sz,
242  laPoint2(0,0.97), laPoint2(0.97, -0.97));
243 
244  r->vquadsMakeXYRect( 1, _ptPos + laPoint3(0, _ptSize.y()-nBH), sz,
245  laPoint2(), laPoint2(0.97, 0.97));
246 
247  r->vquadsMakeXYRect( 2, _ptPos + laPoint3(_ptSize.x()-nBW, 0), sz,
248  laPoint2(0.97, 0.97), laPoint2(-0.97, -0.97));
249 
250  r->vquadsMakeXYRect( 3, _ptPos + _ptSize - sz, sz,
251  laPoint2(0.97, 0), laPoint2(-0.97, 0.97));
252 
253  tangle.use();
254  r->vquadsDraw(4);
255 
256 
257  // draw borders
258  //
259  r->vquadsMakeXYRect(0, _ptPos + laPoint3(nBW, 0),
260  laPoint3(_ptSize.x()-2*nBW, nBH),
261  laPoint2(0,0.97), laPoint2(0.97, -0.97));
262 
263  r->vquadsMakeXYRect(1, _ptPos + laPoint3(nBW, _ptSize.y()-nBH),
264  laPoint3(_ptSize.x()-2*nBW, nBH),
265  laPoint2(0,0), laPoint2(0.97, 0.97));
266 
267  tborder_h.use();
268  r->vquadsDraw(2);
269 
270  r->vquadsMakeXYRect(0, _ptPos + laPoint3(0, nBH),
271  laPoint3(nBW, _ptSize.y()-2*nBH),
272  laPoint2(0,0), laPoint2(0.97, 0.97));
273 
274  r->vquadsMakeXYRect(1, _ptPos + laPoint3(_ptSize.x()-nBW, nBH),
275  laPoint3(nBW, _ptSize.y()-2*nBH),
276  laPoint2(0.97,0), laPoint2(-0.97, 0.97));
277 
278  tborder_v.use();
279  r->vquadsDraw(2);
280 
281  // draw background
282  //
283  r->vquadsMakeXYRect(0, _ptPos + sz, _ptSize - 2 * sz,
284  laPoint2(), _ptSize/256.0);
285 
286  tbg.use();
287  r->vquadsDrawSingle();
288 }
289 
291 {
292  //Get renderer
293  laRenderer* r = ::laSystemIntegrator::getRenderer();
294 
295  // Draw borders
296  if(_bDisplayBorders)
297  {
298  //drop shadow
299  r->styleSet( _pSkin->parameter("CL_SHADOW").color() );
300  r->transPush();
301  r->transTranslate( ptShadowOffset );
302  drawBorders();
303  r->transPop();
304 
305  //borders
306  r->styleSet( col );
307  drawBorders();
308  }
309 
310  // Relative translation
311  r->transPush();
312  r->transTranslate( _ptPos + getDecorationSize() );
313 
314  // Draw children in relative coords
315  for(unsigned id=0; id<_vControls.size(); id++)
316  {
317  //if( _vControls[id] )
318  if( _vControls[id]->isVisible() )
319  _vControls[id]->draw();
320  }
321 
322  // Remove translation
323  r->transPop();
324 }
325 
326 // Handle the movse movement event; Drag the window container
327 // if dragging is enabled
328 void uiContainer::onMouseMove(laPoint3 ptRelativePos)
329 {
330  laInputManager* pci = laSystemIntegrator::getInput();
331 
332  if( _bMoveable && (pci->mouseButton(_nDragButton)) && (!_pDrag) )
333  {
334  _pDrag = this;
335  _ptDragOffset = ptRelativePos;
336 
337  }
338  uiWindow::onMouseMove(ptRelativePos);
339 }
340 
341 void uiContainer::onUp(unsigned nButton)
342 {
343  if( (_pDrag == this) && (nButton==_nDragButton) ) _pDrag = NULL;
344  uiWindow::onUp(nButton);
345 }
void kill()
Discard window and all children.
laPoint3 _ptPos
Windos position (relative to parent)
Definition: uiWindow.h:75
GUI Container Window.
Definition: uiContainer.h:42
GUI Slider.
Definition: uiSlider.h:71
#define M_AB
Text align bottom.
virtual void load(class laFileParser *fp)
Load a dialog layout form .cui file.
Definition: uiWindow.cpp:113
virtual void vquadsDrawSingle(laPoint2 *ar_uv=NULL)=0
Draw a single VQ (Note this is slower than drawing an array of VQ and should be avoided) ...
virtual void move(laPoint3 ptNewPos, unsigned nHReference=M_AL, unsigned nVReference=M_AT)
Change window position.
Definition: uiWindow.cpp:51
2D Point
Definition: laPoint_novec.h:41
void vquadsMakeXYRect(unsigned nIndex, const laPoint3 &pos, const laPoint3 &sz, const laPoint2 &uv, const laPoint2 &uv_sz)
Makes a quad aligned to the XY plane; (handy for GUI rendering )
Definition: laRenderer.h:328
virtual void create(laPoint3 pos, laPoint3 size)
Create new empty window.
Definition: uiLabel.cpp:52
#define M_AM
Text align middle.
#define M_AL
Text align left.
virtual void create(laPoint3 pos, laPoint3 size)
Create new empty window.
Definition: uiContainer.cpp:97
#define M_AT
Text align top.
#define M_AR
Text align right.
uiLabel caption
Caption.
Definition: uiContainer.h:83
GUI Push-button.
Definition: uiButton.h:41
laPoint3 _ptSize
Window size.
Definition: uiWindow.h:76
GUI Editbox.
Definition: uiEdit.h:44
virtual void draw()
Display the window.
uiWindow * _pParent
Pointer to parent window, if any.
Definition: uiWindow.h:71
GUI Progress Bar.
Definition: uiProgress.h:39
Horisontal divider line.
Definition: uiLabel.h:94
virtual void vquadsDraw(unsigned nQuads, laPoint2 *ar_uv=NULL, laColor *ar_color=NULL, M_BOOL bBillboards=M_FALSE, M_BOOL bUseColorArrays=M_FALSE)=0
Draw an array of VQ, starting with the psecified pointers (or the first VQ if null) ...
Base class for GUI windows.
Definition: uiWindow.h:45
virtual void create(laPoint3 pos, laPoint3 size)
Create new empty window.
Definition: uiWindow.cpp:99
#define M_AC
Text align center.
Virtual interface for the Engine graphics renderer.
Definition: laRenderer.h:98
void toggleBorders(M_BOOL bEnable)
Toggle border visbility.
Definition: uiContainer.h:87
laPoint3 getRelativePointerPos()
Get mouse pointer position relative to window position.
Definition: uiWindow.h:81
Text Label.
Definition: uiLabel.h:41
virtual void reply()
Handle input message.
Definition: uiWindow.cpp:130
void toggleMoveable(M_BOOL bEnable, unsigned nButton=0)
Toggle moveable flag.
Definition: uiContainer.h:95
virtual void reply()
Handle input message.
laPoint3 getPos()
Get relative window position with regard to parent.
Definition: uiWindow.h:132
GUI Radio-button Group.
Definition: uiRadio.h:44
Error handling class.
Definition: laError.h:46
File Parser.
Definition: laFileParser.h:41
virtual void kill()
Discard window and all children.
Definition: uiWindow.cpp:125