YSTest  PreAlpha_b500_20140530
The YSLib Test Project
 全部  命名空间 文件 函数 变量 类型定义 枚举 枚举值 友元 宏定义  
ystyle.cpp
浏览该文件的文档.
1 /*
2  © 2010-2014 FrankHB.
3 
4  This file is part of the YSLib project, and may only be used,
5  modified, and distributed under the terms of the YSLib project
6  license, LICENSE.TXT. By continuing to use, modify, or distribute
7  this file you indicate that you have read the license and
8  understand and accept it fully.
9 */
10 
28 #include "YSLib/UI/YModules.h"
29 #include YFM_YSLib_UI_YStyle
30 #include YFM_YSLib_UI_YWindow
31 #include YFM_YSLib_UI_YGUI
32 
33 using namespace ystdex;
34 
35 namespace YSLib
36 {
37 
38 namespace Drawing
39 {
40 
41 void
42 DrawRectRoundCorner(const PaintContext& pc, const Size& s, Color c)
43 {
44  const auto& g(pc.Target);
45  const auto& pt(pc.Location);
46  const auto& r(pc.ClipArea);
47  const SPos x1(pt.X + 1), y1(pt.Y + 1), x2(pt.X + s.Width - 1),
48  y2(pt.Y + s.Height - 1);
49 
50  if(YB_LIKELY(x1 <= x2 && y1 <= y2))
51  {
52  DrawVLineSeg(g, r, x1 - 1, y1, y2, c),
53  DrawHLineSeg(g, r, y2, x1, x2, c),
54  DrawVLineSeg(g, r, x2, y1, y2, c),
55  DrawHLineSeg(g, r, y1 - 1, x1, x2, c);
56  if(YB_LIKELY(s.Width > 4 && s.Height > 4))
57  {
58  DrawPoint(g, r, x1, y1, c);
59  DrawPoint(g, r, x1, y2 - 1, c);
60  DrawPoint(g, r, x2 - 1, y2 - 1, c);
61  DrawPoint(g, r, x2 - 1, y1, c);
62  }
63  }
64 }
65 
66 
67 void
68 RectDrawArrow(const PaintContext& pc, SDst half_size, Rotation rot, Color c)
69 {
70  const auto& g(pc.Target);
71  const auto& pt(pc.Location);
72  const auto& bounds(pc.ClipArea);
73  SDst x(pt.X), y(pt.Y);
74 
75  switch(rot)
76  {
77  case RDeg0:
78  case RDeg180:
79  {
80  SDst t(pt.Y);
81 
82  for(SDst i(0); i < half_size; ++i)
83  DrawVLineSeg(g, bounds, rot == 0 ? x-- : x++, y--, t++, c);
84  }
85  break;
86  case RDeg90:
87  case RDeg270:
88  {
89  SDst t(pt.X);
90 
91  for(SDst i(0); i < half_size; ++i)
92  DrawHLineSeg(g, bounds, rot == RDeg90 ? y++ : y--, x--, t++, c);
93  }
94  default:
95  break;
96  }
97 }
98 
99 void
100 DrawArrow(const Graphics& g, const Rect& bounds, SDst half_size, Rotation rot,
101  Color c)
102 {
103  SPos x(bounds.X), y(bounds.Y);
104 
105  switch(rot)
106  {
107  case RDeg0:
108  case RDeg180:
109  x += (rot == RDeg180
110  ? (bounds.Width - half_size) : (bounds.Width + half_size)) / 2;
111  y += (bounds.Height + 1) / 2;
112  break;
113  case RDeg90:
114  case RDeg270:
115  y += (rot == RDeg90
116  ? (bounds.Height - half_size) : (bounds.Height + half_size)) / 2;
117  x += (bounds.Width + 1) / 2;
118  default:
119  break;
120  }
121  RectDrawArrow({g, Point(x, y), bounds}, half_size, rot, c);
122 }
123 
124 void
125 DrawCross(const Graphics& g, const Rect& bounds, const Rect& r, Color c)
126 {
127  if(YB_LIKELY(r.Width > 8 && r.Height > 8))
128  {
129  const SPos xmin(r.X + 4), xmax(xmin + r.Width - 8),
130  ymin(r.Y + 4), ymax(ymin + r.Height - 8);
131 
132  DrawLineSeg(g, bounds, xmin, ymin, xmax, ymax, c),
133  DrawLineSeg(g, bounds, xmax - 1, ymin, xmin - 1, ymax, c);
134  }
135 }
136 
137 void
138 DrawTick(const Graphics& g, const Rect& bounds, const Rect& r, Color c1,
139  Color c2)
140 {
141  if(YB_LIKELY(r.Width > 8 && r.Height > 8))
142  {
143  const Point p1(r.X + 2, r.Y + r.Height / 2),
144  p3(r.X + r.Width - 2, r.Y + 1);
145  Point p2(r.X + r.Width / 2 - 1, r.Y + r.Height - 3);
146 
147  --p2.Y;
148  DrawLineSeg(g, bounds, p1 + Vec(1, 0), p2, c2);
149  DrawLineSeg(g, bounds, p2, p3 + Vec(-1, 0), c2);
150  p2.Y += 2;
151  DrawLineSeg(g, bounds, p1 + Vec(0, 1), p2, c2);
152  DrawLineSeg(g, bounds, p2, p3 + Vec(0, 1), c2);
153  --p2.Y;
154  DrawLineSeg(g, bounds, p1, p2, c1);
155  DrawLineSeg(g, bounds, p2, p3, c1);
156  }
157 }
158 
159 
160 hsl_t
162 {
163  using mid_t = float; //中间类型。
164 
165  const u8 r(c.GetR()), g(c.GetG()), b(c.GetB()),
166  min_color(min(min(r, g), b)), max_color(max(max(r, g), b));
167  mid_t h(0); // 此处 h 的值每 0x6 对应一个圆周。
168  mid_t s(0);
169  decltype(hsl_t::l) l;
170 
171  if(min_color == max_color)
172  l = decltype(hsl_t::l)(min_color) / 0x100;
173  else
174  {
175  const unsigned p(max_color + min_color);
176 
177  l = decltype(hsl_t::l)(p) / 0x200;
178  /*
179  l = 0.2126 * r + 0.7152 * g + 0.0722 * b; // Rec. 601 luma;
180  l = 0.299 * r + 0.588 * g + 0.114 * b; // Rec. 709 luma;
181  */
182 
183  // chroma * 256;
184  const mid_t q(max_color - min_color);
185 
186  s = q / (p < 0x100 ? p : 0x200 - p);
187  if(r == max_color)
188  h = (g - b) / q;
189  else if(g == max_color)
190  h = (b - r) / q + 0x2;
191  else if(b == max_color)
192  h = (r - g) / q + 0x4;
193  if(h < 0)
194  h += 0x6;
195  }
196  return {h * 60, s, l};
197 }
198 
199 Color
201 {
202  YAssert(IsInInterval<Hue>(c.h, 0, 360), "Invalid hue found."),
203  YAssert(IsInClosedInterval(c.s, 0.F, 1.F), "Invalid saturation found."),
204  YAssert(IsInClosedInterval(c.l, 0.F, 1.F), "Invalid light found.");
205  if(c.s == 0)
206  return MakeGray(c.l > 255.F / 0x100 ? 0xFF : c.l * 0x100);
207 
208  using mid_t = float; //中间类型。
209 
210  mid_t t2((c.l < 0.5F ? c.l * (1 + c.s) : (c.l + c.s - c.l * c.s)) * 0x100),
211  t1((c.l * 0x200) - t2);
212  mid_t tmp[3]{c.h + 120, c.h, c.h - 120}; \
213  // 每个元素对应一个 RGB 分量,值 360 对应一个圆周。
214  float dc[3]; //对应 RGB 分量。
215 
216  for(size_t i(0); i < 3; ++i)
217  {
218  if(tmp[i] < 0)
219  tmp[i] += 360;
220  else if(tmp[i] > 360)
221  tmp[i] -= 360;
222  if(tmp[i] < 60)
223  dc[i] = t1 + (t2 - t1) * tmp[i] / 60;
224  else if(tmp[i] < 180)
225  dc[i] = t2;
226  else if(tmp[i] < 240)
227  dc[i] = t1 + (t2 - t1) * (240 - tmp[i]) / 60;
228  else
229  dc[i] = t1;
230  if(dc[i] > 0xFF)
231  dc[i] = 0xFF;
232  }
233  return Color(dc[0], dc[1], dc[2]);
234 }
235 
236 
237 Color
238 RollColor(hsl_t c, Hue delta)
239 {
240  YAssert(IsInInterval<Hue>(c.h, 0, 360), "Invalid hue found.");
241  delta += c.h;
242  c.h = delta < 360 ? delta : delta - 360;
243  return HSLToColor(c);
244 }
245 
246 } // namespace Drawing;
247 
248 namespace UI
249 {
250 
251 namespace Styles
252 {
253 
254 Palette::Palette()
255  : colors{
256  {0, 0, 0}, // Null;
257  {10, 59, 118}, // Desktop;
258  {255, 255, 255}, // Window;
259  {240, 240, 240}, // Panel;
260  {237, 237, 237}, // Track;
261  {171, 171, 171}, // Workspace;
262  {160, 160, 160}, // Shadow;
263  {105, 105, 105}, // DockShadow;
264  {227, 227, 227}, // Light;
265  {100, 100, 100}, // Frame;
266  {51, 153, 255}, // Highlight;
267  {158, 62, 255}, // BorderFill;
268  ColorSpace::Aqua, // ActiveBorder;
269  {180, 180, 180}, // InactiveBorder;
270  {153, 180, 209}, // ActiveTitle;
271  {191, 205, 219}, // InactiveTitle;
272 
273  {255, 255, 255}, // HighlightText;
274  {0, 0, 0}, // WindowText;
275  {0, 0, 0}, // PanelText;
276  {109, 109, 109}, // GrayText;
277  {0, 0, 0}, // TitleText;
278  {67, 78, 84}, // InactiveTitleText;
279  {0, 102, 204} // HotTracking;
280  }
281 {
282  // colors[ActiveBorder] = Color(180, 180, 180),
283  // colors[InactiveBorder] = Color(244, 247, 252);
284  //"GradientActiveTitle"="185 209 234"
285  //"GradientInactiveTitle"="215 228 242"
286 }
287 
288 pair<Drawing::Color, Drawing::Color>
289 Palette::GetPair(Palette::ColorListType::size_type n1,
290  Palette::ColorListType::size_type n2) const
291 {
292  return make_pair(colors[n1], colors[n2]);
293 }
294 
295 
296 void
298 {
299  FetchGUIState().Styles.PaintAsStyle(key, std::move(e));
300 }
301 
302 
303 void
304 StyleMap::PaintAsStyle(const Key& key, PaintEventArgs&& e)
305 {
307 
308  YAssert(!empty(), "No style found.");
309  YAssert(!is_undereferenceable(current), "Invalidate style state found.");
310 
311  const auto& table(current->second);
312  auto i(table.find(key));
313 
314  if(i == table.cend())
315  {
316  const auto& de_table(cbegin()->second);
317 
318  i = de_table.find(key);
319  if(i == de_table.end())
320  return;
321  }
322  i->second(std::move(e));
323 }
324 
325 void
326 StyleMap::Remove(const string& name)
327 {
328  if(!name.empty())
329  {
330  if(current->first == name)
331  current = cbegin();
332  erase(name);
333  }
334 }
335 
336 void
337 StyleMap::Switch(const string& name)
338 {
339  const auto i(find(name));
340 
341  current = i == cend() ? cbegin() : i;
342 }
343 
344 
347 {
348  return FetchGUIState().Styles.at({});
349 }
350 
351 } // namespace Styles;
352 
353 } // namespace UI;
354 
355 } // namespace YSLib;
356 
void DrawVLineSeg(const Graphics &g, const Rect &bounds, SPos x, SPos y1, SPos y2, Color c)
描画竖直线段。
Definition: ydraw.h:153
YF_API HandlerTable & FetchDefault()
取默认样式处理器表。
Definition: ystyle.cpp:346
YF_API void DrawCross(const Graphics &, const Rect &, const Rect &, Color)
在指定图形接口上下文中使用指定颜色描画交叉直线段(“×”)。
Definition: ystyle.cpp:125
const_iterator current
Definition: ystyle.h:363
YF_API GUIState & FetchGUIState()
取默认图形用户界面公共状态。
Definition: ygui.cpp:442
float s
饱和度和亮度。
Definition: ystyle.h:137
部件绘制参数。
Definition: ywgtevt.h:276
Hue h
色调。
Definition: ystyle.h:131
SDst Height
宽和高。
Definition: ygdibase.h:258
YF_API void DrawRectRoundCorner(const PaintContext &pc, const Size &s, Color)
绘制部件边框用空心标准矩形。
Definition: ystyle.cpp:42
std::uint16_t SDst
屏幕坐标距离。
Definition: Video.h:39
std::int16_t SPos
屏幕坐标度量。
Definition: Video.h:38
key second key first void operator()(PaintEventArgs &&) const
Definition: ystyle.cpp:297
YF_API void DrawTick(const Graphics &, const Rect &, const Rect &, Color, Color)
Definition: ystyle.cpp:138
hsl_t ColorToHSL(Color c)
Definition: ystyle.cpp:161
GBinaryGroup< SPos > Point
屏幕二维点(直角坐标表示)。
Definition: ygdibase.h:235
void DrawLineSeg(const Graphics &g, const Rect &bounds, SPos x1, SPos y1, SPos x2, SPos y2, Color c)
描画线段:在区域 ds 绘制端点为 p1(x1, y1) 和 p2(x2, y2) 的线段。
Definition: ydraw.h:178
yconstfn const string & name
Definition: Loader.h:110
void DrawHLineSeg(const Graphics &g, const Rect &bounds, SPos y, SPos x1, SPos x2, Color c)
描画水平线段。
Definition: ydraw.h:128
unordered_map< Key, Handler, ystdex::combined_hash< Key >> HandlerTable
样式处理器表。
Definition: ystyle.h:259
屏幕标准矩形:表示屏幕矩形区域。
Definition: ygdibase.h:416
PaintEventArgs &&void Switch(const string &)
Definition: ystyle.cpp:337
二维图形接口上下文。
Definition: ygdibase.h:721
ColorListType colors
Definition: ystyle.h:221
Rotation
逆时针旋转角度指示输出指向。
Definition: ygdibase.h:868
Color
控制台颜色枚举。
Definition: Video.h:458
std::uint8_t u8
通用数据类型。
Definition: yadaptor.h:67
按指定颜色或分量选取彩色或灰度色。
Definition: ystyle.h:124
void DrawPoint(const Graphics &g, const Rect &bounds, SPos x, SPos y, Color c)
描画点。
Definition: ydraw.h:98
YF_API void DrawArrow(const Graphics &, const Rect &, SDst=4, Rotation=RDeg0, Color=ColorSpace::Black)
在指定图形接口上下文上描画箭头。
Definition: ystyle.cpp:100
bool is_undereferenceable(const any_input_iterator< _type, _tDifference, _tPointer, _tReference > &i)
void Remove(const string &)
Definition: ystyle.cpp:326
Color HSLToColor(hsl_t c)
Definition: ystyle.cpp:200
bounds & r
Definition: ydraw.h:220
YF_API void RectDrawArrow(const PaintContext &, SDst, Rotation=RDeg0, Color=ColorSpace::Black)
在指定上下文的矩形中画箭头。
Definition: ystyle.cpp:68
c yconstfn g
Definition: ystyle.h:104
#define YB_LIKELY(expr)
Definition: ydef.h:297
YF_API Color RollColor(hsl_t, Hue)
色调偏移。
Definition: ystyle.cpp:238
颜色。
Definition: Video.h:339
static auto second(const _tIterator &i) -> decltype((i->second))
Definition: iterator.hpp:765
屏幕区域大小。
Definition: ygdibase.h:249
bool IsInClosedInterval(_type i, _type b) ynothrow
判断 i 是否在闭区间 [FetchZero<_type>(), b] 中。
Definition: ycutil.h:166
Styles::StyleMap Styles
样式映射。
Definition: ygui.h:129
GBinaryGroup< SPos > Vec
屏幕二维向量(直角坐标表示)。
Definition: ygdibase.h:242
#define YAssert(_expr, _msg)
Definition: cassert.h:73
pair< std::type_index, StyleItem > Key
标识查找样式的键。
Definition: ystyle.h:253