Pyrogenesis  13997
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
GUIbase.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2009 Wildfire Games.
2  * This file is part of 0 A.D.
3  *
4  * 0 A.D. is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * 0 A.D. is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 /*
19 GUI base
20 */
21 
22 #include "precompiled.h"
23 
24 #include <string>
25 
26 #include "GUI.h"
27 
28 //--------------------------------------------------------
29 // Help Classes/Structs for the GUI implementation
30 //--------------------------------------------------------
31 
32 CClientArea::CClientArea() : pixel(0.f,0.f,0.f,0.f), percent(0.f,0.f,0.f,0.f)
33 {
34 }
35 
36 CClientArea::CClientArea(const CStr& Value)
37 {
38  SetClientArea(Value);
39 }
40 
41 CClientArea::CClientArea(const CRect& pixel, const CRect& percent)
42  : pixel(pixel), percent(percent)
43 {
44 }
45 
47 {
48  // If it's a 0 0 100% 100% we need no calculations
49  if (percent == CRect(0.f,0.f,100.f,100.f) && pixel == CRect(0.f,0.f,0.f,0.f))
50  return parent;
51 
52  CRect client;
53 
54  // This should probably be cached and not calculated all the time for every object.
55  client.left = parent.left + (parent.right-parent.left)*percent.left/100.f + pixel.left;
56  client.top = parent.top + (parent.bottom-parent.top)*percent.top/100.f + pixel.top;
57  client.right = parent.left + (parent.right-parent.left)*percent.right/100.f + pixel.right;
58  client.bottom = parent.top + (parent.bottom-parent.top)*percent.bottom/100.f + pixel.bottom;
59 
60  return client;
61 }
62 
63 bool CClientArea::SetClientArea(const CStr& Value)
64 {
65  // This might lack incredible speed, but since all XML files
66  // are read at startup, reading 100 client areas will be
67  // negligible in the loading time.
68 
69  // Setup parser to parse the value
70 
71  // One of the four values:
72  // will give outputs like (in argument):
73  // (200) <== no percent, just the first $value
74  // (200) (percent) <== just the percent
75  // (200) (percent) (100) <== percent PLUS pixel
76  // (200) (percent) (-100) <== percent MINUS pixel
77  // (200) (percent) (100) (-100) <== Both PLUS and MINUS are used, INVALID
78  /*
79  string one_value = "_[-_$arg(_minus)]$value[$arg(percent)%_[+_$value]_[-_$arg(_minus)$value]_]";
80  string four_values = one_value + "$arg(delim)" +
81  one_value + "$arg(delim)" +
82  one_value + "$arg(delim)" +
83  one_value + "$arg(delim)_"; // it's easier to just end with another delimiter
84  */
85  // Don't use the above strings, because they make this code go very slowly
86  const char* four_values =
87  "_[-_$arg(_minus)]$value[$arg(percent)%_[+_$value]_[-_$arg(_minus)$value]_]" "$arg(delim)"
88  "_[-_$arg(_minus)]$value[$arg(percent)%_[+_$value]_[-_$arg(_minus)$value]_]" "$arg(delim)"
89  "_[-_$arg(_minus)]$value[$arg(percent)%_[+_$value]_[-_$arg(_minus)$value]_]" "$arg(delim)"
90  "_[-_$arg(_minus)]$value[$arg(percent)%_[+_$value]_[-_$arg(_minus)$value]_]" "$arg(delim)"
91  "_";
92  CParser& parser (CParserCache::Get(four_values));
93 
94  CParserLine line;
95  line.ParseString(parser, Value);
96 
97  if (!line.m_ParseOK)
98  return false;
99 
100  int arg_count[4] = {0,0,0,0}; // argument counts for the four values
101  int arg_start[4] = {0,0,0,0}; // location of first argument, [0] is always 0
102 
103  // Divide into the four piles (delimiter is an argument named "delim")
104  for (int i=0, valuenr=0; i<(int)line.GetArgCount(); ++i)
105  {
106  std::string str;
107  line.GetArgString(i, str);
108  if (str == "delim")
109  {
110  if (valuenr==0)
111  {
112  arg_count[0] = i;
113  arg_start[1] = i+1;
114  }
115  else
116  {
117  if (valuenr!=3)
118  {
119  ENSURE(valuenr <= 2);
120  arg_start[valuenr+1] = i+1;
121  arg_count[valuenr] = arg_start[valuenr+1] - arg_start[valuenr] - 1;
122  }
123  else
124  arg_count[3] = (int)line.GetArgCount() - arg_start[valuenr] - 1;
125  }
126 
127  ++valuenr;
128  }
129  }
130 
131  // Iterate argument
132 
133  // This is the scheme:
134  // 1 argument = Just pixel value
135  // 2 arguments = Just percent value
136  // 3 arguments = percent and pixel
137  // 4 arguments = INVALID
138 
139  // Default to 0
140  float values[4][2] = {{0.f,0.f},{0.f,0.f},{0.f,0.f},{0.f,0.f}};
141  for (int v=0; v<4; ++v)
142  {
143  if (arg_count[v] == 1)
144  {
145  std::string str;
146  line.GetArgString(arg_start[v], str);
147 
148  if (!line.GetArgFloat(arg_start[v], values[v][1]))
149  return false;
150  }
151  else
152  if (arg_count[v] == 2)
153  {
154  if (!line.GetArgFloat(arg_start[v], values[v][0]))
155  return false;
156  }
157  else
158  if (arg_count[v] == 3)
159  {
160  if (!line.GetArgFloat(arg_start[v], values[v][0]) ||
161  !line.GetArgFloat(arg_start[v]+2, values[v][1]))
162  return false;
163 
164  }
165  else return false;
166  }
167 
168  // Now store the values[][] in the right place
169  pixel.left = values[0][1];
170  pixel.top = values[1][1];
171  pixel.right = values[2][1];
172  pixel.bottom = values[3][1];
173  percent.left = values[0][0];
174  percent.top = values[1][0];
175  percent.right = values[2][0];
176  percent.bottom = values[3][0];
177  return true;
178 }
179 
180 
181 
182 //--------------------------------------------------------
183 // Error definitions
184 //--------------------------------------------------------
float top
Definition: Overlay.h:159
float left
Returning CPos representing each corner.
Definition: Overlay.h:159
bool GetArgFloat(size_t arg, float &ret)
CRect pixel
Pixel modifiers.
Definition: GUIbase.h:187
CRect percent
Percent modifiers.
Definition: GUIbase.h:190
#define ENSURE(expr)
ensure the expression &lt;expr&gt; evaluates to non-zero.
Definition: debug.h:282
bool SetClientArea(const CStr &Value)
The ClientArea can be set from a string looking like:
Definition: GUIbase.cpp:63
CRect GetClientArea(const CRect &parent) const
Get client area rectangle when the parent is given.
Definition: GUIbase.cpp:46
bool ParseString(const CParser &parser, const std::string &line)
Definition: Parser.cpp:325
bool GetArgString(size_t arg, std::string &ret)
static CParser & Get(const char *str)
Definition: Parser.cpp:1069
float right
Definition: Overlay.h:159
size_t GetArgCount() const
Definition: Parser.h:219
bool m_ParseOK
Definition: Parser.h:194
float bottom
Definition: Overlay.h:159
Rectangle class used for screen rectangles.
Definition: Overlay.h:71