YSTest: ystyle.cpp 源文件

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
161 ColorToHSL(Color c)
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
200 HSLToColor(hsl_t c)
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
297 Painter::operator()(PaintEventArgs&& e) const
298 {
299 FetchGUIState().Styles.PaintAsStyle(key, std::move(e));
300 }
301
302
303 void
304 StyleMap::PaintAsStyle(const Key& key, PaintEventArgs&& e)
305 {
306 using ystdex::is_undereferenceable;
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
345 HandlerTable&
346 FetchDefault()
347 {
348 return FetchGUIState().Styles.at({});
349 }
350
351 } // namespace Styles;
352
353 } // namespace UI;
354
355 } // namespace YSLib;
356
YSLib::Drawing::DrawVLineSeg
void DrawVLineSeg(const Graphics &g, const Rect &bounds, SPos x, SPos y1, SPos y2, Color c)
描画竖直线段。
Definition: ydraw.h:153
YSLib::UI::Styles::FetchDefault
YF_API HandlerTable & FetchDefault()
取默认样式处理器表。
Definition: ystyle.cpp:346
YSLib::Drawing::DrawCross
YF_API void DrawCross(const Graphics &, const Rect &, const Rect &, Color)
在指定图形接口上下文中使用指定颜色描画交叉直线段（“×”）。
Definition: ystyle.cpp:125
YModules.h
YSLib::UI::Styles::StyleMap::current
const_iterator current
Definition: ystyle.h:363
YSLib::UI::FetchGUIState
YF_API GUIState & FetchGUIState()
取默认图形用户界面公共状态。
Definition: ygui.cpp:442
YSLib::Drawing::hsl_t::s
float s
饱和度和亮度。
Definition: ystyle.h:137
YSLib::Drawing::bounds
bounds
Definition: ydraw.h:188
platform_ex::Windows::l
l
Definition: MinGW32.cpp:50
YSLib::UI::PaintEventArgs
部件绘制参数。
Definition: ywgtevt.h:276
YSLib::Drawing::hsl_t::h
Hue h
色调。
Definition: ystyle.h:131
YSLib::Drawing::Size::Height
SDst Height
宽和高。
Definition: ygdibase.h:258
YSLib::Drawing::DrawRectRoundCorner
YF_API void DrawRectRoundCorner(const PaintContext &pc, const Size &s, Color)
绘制部件边框用空心标准矩形。
Definition: ystyle.cpp:42
platform::SDst
std::uint16_t SDst
屏幕坐标距离。
Definition: Video.h:39
platform::SPos
std::int16_t SPos
屏幕坐标度量。
Definition: Video.h:38
YSLib::UI::Styles::Painter::operator()
key second key first void operator()(PaintEventArgs &&) const
Definition: ystyle.cpp:297
YSLib::Drawing::DrawTick
YF_API void DrawTick(const Graphics &, const Rect &, const Rect &, Color, Color)
Definition: ystyle.cpp:138
YSLib::Drawing::RDeg270
Definition: ygdibase.h:873
YSLib::Drawing::ColorToHSL
hsl_t ColorToHSL(Color c)
Definition: ystyle.cpp:161
YSLib::Drawing::Point
GBinaryGroup< SPos > Point
屏幕二维点（直角坐标表示）。
Definition: ygdibase.h:235
YSLib::Drawing::DrawLineSeg
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
YSLib::Drawing::RDeg180
Definition: ygdibase.h:872
YSLib::UI::name
yconstfn const string & name
Definition: Loader.h:110
YSLib::Drawing::DrawHLineSeg
void DrawHLineSeg(const Graphics &g, const Rect &bounds, SPos y, SPos x1, SPos x2, Color c)
描画水平线段。
Definition: ydraw.h:128
YSLib::UI::Styles::HandlerTable
unordered_map< Key, Handler, ystdex::combined_hash< Key >> HandlerTable
样式处理器表。
Definition: ystyle.h:259
YSLib::Drawing::GBinaryGroup::Y
_type Y
分量。
Definition: ygdibase.h:59
YSLib::Drawing::Rect
屏幕标准矩形：表示屏幕矩形区域。
Definition: ygdibase.h:416
YSLib::UI::Styles::StyleMap::Switch
PaintEventArgs &&void Switch(const string &)
Definition: ystyle.cpp:337
YSLib::Drawing::GBinaryGroup< SPos >
YSLib::UI::Styles::Painter::key
Key key
Definition: ystyle.h:326
YSLib::Drawing::GBinaryGroup::X
_type X
Definition: ygdibase.h:59
YSLib::Drawing::Graphics
二维图形接口上下文。
Definition: ygdibase.h:721
YSLib::UI::Styles::Palette::colors
ColorListType colors
Definition: ystyle.h:221
YSLib::Drawing::RDeg0
Definition: ygdibase.h:870
Rotation
Rotation
逆时针旋转角度指示输出指向。
Definition: ygdibase.h:868
YSLib::Drawing::RDeg90
Definition: ygdibase.h:871
platform_ex::Windows::s
return s
Definition: MinGW32.cpp:49
platform::Consoles::Color
Color
控制台颜色枚举。
Definition: Video.h:458
YSLib::u8
std::uint8_t u8
通用数据类型。
Definition: yadaptor.h:67
YSLib::Drawing::hsl_t
按指定颜色或分量选取彩色或灰度色。
Definition: ystyle.h:124
YSLib::Drawing::DrawPoint
void DrawPoint(const Graphics &g, const Rect &bounds, SPos x, SPos y, Color c)
描画点。
Definition: ydraw.h:98
YSLib::Drawing::DrawArrow
YF_API void DrawArrow(const Graphics &, const Rect &, SDst=4, Rotation=RDeg0, Color=ColorSpace::Black)
在指定图形接口上下文上描画箭头。
Definition: ystyle.cpp:100
ystdex::is_undereferenceable
bool is_undereferenceable(const any_input_iterator< _type, _tDifference, _tPointer, _tReference > &i)
Definition: any_iterator.hpp:364
YSLib::UI::Styles::StyleMap::Remove
void Remove(const string &)
Definition: ystyle.cpp:326
YSLib::Drawing::HSLToColor
Color HSLToColor(hsl_t c)
Definition: ystyle.cpp:200
YSLib::Drawing::r
bounds & r
Definition: ydraw.h:220
YSLib::Drawing::RectDrawArrow
YF_API void RectDrawArrow(const PaintContext &, SDst, Rotation=RDeg0, Color=ColorSpace::Black)
在指定上下文的矩形中画箭头。
Definition: ystyle.cpp:68
YSLib::Drawing::g
c yconstfn g
Definition: ystyle.h:104
YB_LIKELY
#define YB_LIKELY(expr)
Definition: ydef.h:297
CHRLib::c
c
Definition: chrproc.h:76
YSLib::Drawing::hsl_t::l
float l
Definition: ystyle.h:137
YSLib::Drawing::RollColor
YF_API Color RollColor(hsl_t, Hue)
色调偏移。
Definition: ystyle.cpp:238
platform::Color
颜色。
Definition: Video.h:339
ystdex::iterator_transformation::second
static auto second(const _tIterator &i) -> decltype((i->second))
Definition: iterator.hpp:765
YSLib::Drawing::Size
屏幕区域大小。
Definition: ygdibase.h:249
YSLib::IsInClosedInterval
bool IsInClosedInterval(_type i, _type b) ynothrow
判断 i 是否在闭区间 [FetchZero<_type>(), b] 中。
Definition: ycutil.h:166
YSLib::UI::GUIState::Styles
Styles::StyleMap Styles
样式映射。
Definition: ygui.h:129
YSLib::Drawing::Size::Width
SDst Width
Definition: ygdibase.h:258
YSLib::Drawing::Vec
GBinaryGroup< SPos > Vec
屏幕二维向量（直角坐标表示）。
Definition: ygdibase.h:242
YAssert
#define YAssert(_expr, _msg)
Definition: cassert.h:73
YSLib::UI::Styles::Key
pair< std::type_index, StyleItem > Key
标识查找样式的键。
Definition: ystyle.h:253