1 /* BStyles.hpp
2  * Copyright (C) 2018  Sven Jähnichen
3  *
4  * This program 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 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program 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 this program.  If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef BSTYLES_HPP_
19 #define BSTYLES_HPP_
20 
21 #include <stdint.h>
22 #include <cstring>
23 #include <string>
24 #include <cairo/cairo.h>
25 #include "cairoplus.h"
26 #include <iostream>
27 
28 #include "BColors.hpp"
29 
30 #define STYLEPTR(ptr) (void*) (ptr)
31 
32 namespace BStyles
33 {
34 /**
35  * Class BStyles::Line
36  *
37  * Line style class. A BStyles::Line is defined by its color, width and
38  * TODO dashes
39  */
40 class Line
41 {
42 public:
43 	Line ();
44 	Line (const BColors::Color& color, const double width);
45 
46 	/**
47 	 * Sets color of the line style
48 	 * @param color BColors::Color
49 	 */
50 	void setColor (const BColors::Color& color);
51 
52 	/**
53 	 * Gets (a pointer to the) color of the line style
54 	 * @return Returns BColors::Color.
55 	 */
56 	BColors::Color* getColor ();
57 
58 	/**
59 	 * Sets width of the line
60 	 * @param width Width of the line in pt.
61 	 */
62 	void setWidth (const double width);
63 
64 	/**
65 	 * Gets width of the line
66 	 * @return Width of the line in pt.
67 	 */
68 	double getWidth () const;
69 
70 private:
71 	BColors::Color lineColor;
72 	int lineWidth;
73 };
74 /*
75  * End of class BWidgets::Line
76  *****************************************************************************/
77 
78 const Line blackLine1pt = Line (BColors::black, 1.0);
79 const Line whiteLine1pt = Line (BColors::white, 1.0);
80 const Line greyLine1pt = Line (BColors::grey, 1.0);
81 const Line lightgreyLine1pt = Line (BColors::lightgrey, 1.0);
82 const Line noLine = Line (BColors::invisible, 0.0);
83 
84 
85 /**
86  * Class BStyles::Border
87  *
88  * Border style class. A BStyles::Border is defined by its margin, padding,
89  * line and corner radius
90  */
91 class Border
92 {
93 public:
94 	Border ();
95 	Border (const Line& line);
96 	Border (const Line& line, const double margin, const double padding);
97 	Border (const Line& line, const double margin, const double padding, const double radius);
98 
99 	/**
100 	 * Sets the line of a border style
101 	 * @param line BStyles::Line
102 	 */
103 	void setLine (const Line& line);
104 
105 	/**
106 	 * Gets a pointer to the line of a border style
107 	 * @return BStyles::Line
108 	 */
109 	Line* getLine ();
110 
111 	/**
112 	 * Sets the margin of a border style
113 	 * @param margin Distance from border line to the outer limits of the
114 	 * 				 border.
115 	 */
116 	void setMargin (const double margin);
117 
118 	/**
119 	 * Gets the margin of a border style
120 	 * @return Distance from border line to the outer limits of the border.
121 	 */
122 	double getMargin () const;
123 
124 	/**
125 	 * Sets the padding of a border style
126 	 * @param padding Distance from border line to the inner limits of the
127 	 * 				  border.
128 	 */
129 	void setPadding (const double padding);
130 
131 	/**
132 	 * Gets the padding of a border style
133 	 * @return Distance from border line to the inner limits of the border.
134 	 */
135 	double getPadding () const;
136 
137 	/**
138 	 * Sets the radius of the corners of a border style
139 	 * @param radius Radius of the corners. If (radius != 0), the corners will
140 	 * 				 be rounded.
141 	 */
142 	void setRadius (const double radius);
143 
144 	/**
145 	 * Gets the radius of the corners of a border style
146 	 * @param radius Radius of the corners.
147 	 */
148 	double getRadius () const;
149 
150 protected:
151 	Line borderLine;
152 	double borderMargin;
153 	double borderPadding;
154 	double borderRadius;
155 };
156 /*
157  * End of class BWidgets::Border
158  *****************************************************************************/
159 
160 const Border blackBorder1pt = Border (blackLine1pt);
161 const Border whiteBorder1pt = Border (whiteLine1pt);
162 const Border greyBorder1pt = Border (greyLine1pt);
163 const Border lightgreyBorder1pt = Border (lightgreyLine1pt);
164 const Border noBorder = Border (noLine);
165 
166 
167 
168 /**
169  * Class BStyles::Fill
170  *
171  * Fill style class. A BStyles::Fill can be a plain color or a Cairo image
172  * surface (higher priority).
173  */
174 class Fill
175 {
176 public:
177 	Fill ();
178 	Fill (const BColors::Color& color);
179 	Fill (const std::string& filename);
180 	Fill (const Fill& that);
181 	Fill& operator= (const Fill& that);
182 	~Fill ();
183 
184 	/**
185 	 * Sets the color of a fill style
186 	 * @param color BColors::Color
187 	 */
188 	void setColor (const BColors::Color& color);
189 
190 	/**
191 	 * Gets (a pointer to) the color of a fill style
192 	 * @return BColors::Color
193 	 */
194 	BColors::Color* getColor ();
195 
196 	/**
197 	 * Loads a PNG file into a Cairo image surface and uses it for the fill
198 	 * style.
199 	 * @param filename File name of the PNG file
200 	 */
201 	void loadFillFromFile (const std::string& filename);
202 
203 	/**
204 	 * Copies a Cairo image surface and uses it for the fill style.
205 	 * @param surface Pointer to the source cairo image surface
206 	 */
207 	void loadFillFromCairoSurface (cairo_surface_t* surface);
208 
209 	//TODO purgeFillSurface ();
210 
211 	/**
212 	 * Gets a pointer to the cairo image surface used for the fill style.
213 	 * @return Pointer to a cairo image surface or nullptr if no surface is
214 	 * 		   used (plain color mode).
215 	 */
216 	cairo_surface_t* getCairoSurface ();
217 
218 
219 protected:
220 	BColors::Color fillColor;
221 	cairo_surface_t* fillSurface;
222 
223 };
224 /*
225  * End of class BWidgets::Fill
226  *****************************************************************************/
227 
228 const Fill blackFill = Fill (BColors::black);
229 const Fill whiteFill = Fill (BColors::white);
230 const Fill redFill = Fill (BColors::red);
231 const Fill greenFill = Fill (BColors::green);
232 const Fill blueFill = Fill (BColors::blue);
233 const Fill greyFill = Fill (BColors::grey);
234 const Fill darkgreyFill = Fill (BColors::darkgrey);
235 const Fill grey20Fill = Fill (BColors::grey20);
236 const Fill noFill = Fill (BColors::invisible);
237 
238 typedef enum {
239 	TEXT_ALIGN_LEFT,
240 	TEXT_ALIGN_CENTER,
241 	TEXT_ALIGN_RIGHT,
242 } TextAlign;
243 
244 typedef enum {
245 	TEXT_VALIGN_TOP,
246 	TEXT_VALIGN_MIDDLE,
247 	TEXT_VALIGN_BOTTOM
248 } TextVAlign;
249 
250 /**
251  * Class BStyles::Font
252  *
253  * Font style class. A BStyles::Font is defined by the Cairo font properties
254  * font family, slant, weight and its size
255  */
256 class Font
257 {
258 public:
259 	Font ();
260 	Font (const std::string& family, const cairo_font_slant_t slant, const cairo_font_weight_t weight, const double size,
261 		  TextAlign align = TEXT_ALIGN_LEFT, TextVAlign valign = TEXT_VALIGN_TOP, double lineSpacing = 1.25);
262 
263 	/**
264 	 * Sets font family of the font style
265 	 * @param family Cairo font family name (as std::string)
266 	 */
267 	void setFontFamily (const std::string& family);
268 
269 	/**
270 	 * Gets font family of the font style
271 	 * @return Cairo font family name (as std::string)
272 	 */
273 	std::string getFontFamily () const;
274 
275 	/**
276 	 * Sets font slant of the font style
277 	 * @param slant Cairo font slant
278 	 */
279 	void setFontSlant (const cairo_font_slant_t slant);
280 
281 	/**
282 	 * Gets font slant of the font style
283 	 * @return Cairo font slant
284 	 */
285 	cairo_font_slant_t getFontSlant () const;
286 
287 	/**
288 	 * Sets font weight of the font style
289 	 * @param weight Cairo font weight
290 	 */
291 	void setFontWeight (const cairo_font_weight_t weight);
292 
293 	/**
294 	 * Gets font weight of the font style
295 	 * @return Cairo font weight
296 	 */
297 	cairo_font_weight_t getFontWeight () const;
298 
299 	/**
300 	 * Sets the horizonal text alignment of the font style
301 	 * @param align Enum of text alignment
302 	 */
303 	void setTextAlign (const TextAlign align);
304 
305 	/**
306 	 * Gets the horizonal text alignment of the font style
307 	 * @return Enum of text alignment
308 	 */
309 	TextAlign getTextAlign () const;
310 
311 	/**
312 	 * Sets the vertical text alignment of the font style
313 	 * @param align Enum of text alignment
314 	 */
315 	void setTextVAlign (const TextVAlign valign);
316 
317 	/**
318 	 * Gets the vertical text alignment of the font style
319 	 * @return Enum of text alignment
320 	 */
321 	TextVAlign getTextVAlign () const;
322 
323 	/**
324 	 * Sets line spacing of the font style
325 	 * @param lineSpacing Line spacing factor
326 	 */
327 	void setLineSpacing (const double lineSpacing);
328 
329 	/**
330 	 * Gets line spacing of the font style
331 	 * @return Line spacing factor
332 	 */
333 	double getLineSpacing () const;
334 
335 	/**
336 	 * Sets font size of the font style
337 	 * @param size Font size as used by Cairo
338 	 */
339 	void setFontSize (const double size);
340 
341 	/**
342 	 * Gets font size of the font style
343 	 * @return Font size as used by Cairo
344 	 */
345 	double getFontSize () const;
346 
347 	/**
348 	 * Gets the output dimensions of a text
349 	 * @param cr Pointer to a Cairo context that will be used to calculate the
350 	 * 			 output dimensions of the text.
351 	 * @param text Text to calculate output dimensions for.
352 	 * @return Output dimensions as Cairo text extents.
353 	 */
354 	cairo_text_extents_t getTextExtents (cairo_t* cr, const std::string& text) const;
355 
356 private:
357 	std::string fontFamily;
358 	cairo_font_slant_t fontSlant;
359 	cairo_font_weight_t fontWeight;
360 	double fontSize;
361 	TextAlign textAlign;
362 	TextVAlign textVAlign;
363 	double textLineSpacing;
364 };
365 
366 /*
367  * End of class BWidgets::Font
368  *****************************************************************************/
369 
370 const Font sans12pt = Font ("Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL, 12.0);
371 
372 
373 /**
374  * Struct BStyles::Style
375  *
376  * A style is defined by its name and (a pointer to) a style element (e.g.,
377  * BColors::Color, BColors::ColorSet, BStyle::Line, BStyle::Border,
378  * BStyle::Fill, BStyle::Font).
379  */
380 typedef struct {
381 	std::string name;
382 	void* stylePtr;
383 } Style;
384 
385 /**
386  * Class BStyles::StyleSet
387  *
388  * A BStyles::StyleSet is a collection of different styles (and therefore
389  * different style elements). The BStyles::StyleSet itself is defined by its
390  * name. A BStyles::StyleSet is intended to be used for an object (like a
391  * BWidgets::Widget) to set up its properties.
392  *
393  * For example, a BStyles::StyleSet can look like this:
394  * {"example", {{"color", &BColors::white},
395  * 				{"border", &BStyles::noBorder},
396  * 				{"font", &BStyles::sans12pt}
397  * 			   }
398  * }
399  *
400  * Feature:
401  * The style name "uses" means that another BStyles::StyleSet (to which
402  * Style.ptr points to) is used to this (pre-)define BStyles::StyleSet.
403  */
404 class StyleSet {
405 public:
406 	StyleSet ();
407 	StyleSet (const std::string& name, const std::vector<Style>& styles);
408 
409 	/**
410 	 * Adds a style to (or overwrites an existing of) the BStyles::StyleSet.
411 	 * @param styleName Name of the style to be added or overwritten.
412 	 * @param ptr Pointer to the style element.
413 	 */
414 	void addStyle (const std::string& styleName, void* ptr);
415 
416 	//TODO void addStyle (Style& style);
417 
418 	/**
419 	 * Removes an existing style from the BStyles::StyleSet.
420 	 * @param styleName Name of the style to be removed from the
421 	 * 					BStyles::StyleSet.
422 	 * TODO throws style doesn't exist
423 	 */
424 	void removeStyle (const std::string& styleName);
425 
426 	/**
427 	 * Gets a pointer to an existing style from the BStyles::StyleSet.
428 	 * @param styleName Name of the style.
429 	 * TODO throws style doesn't exist
430 	 */
431 	void* getStyle (const std::string& styleName);
432 
433 	/**
434 	 * Sets the name of the BStyles::StyleSet
435 	 * @param name Name of the BStyles::StyleSet.
436 	 */
437 	void setName (const std::string& name);
438 
439 	/**
440 	 * Gets the name of the BStyles::StyleSet
441 	 * @return Name of the BStyles::StyleSet
442 	 */
443 	std::string getName () const;
444 
445 protected:
446 	std::string stylesetName;
447 	std::vector<Style> styleVector;
448 };
449 /*
450  * End of class BWidgets::StyleSet
451  *****************************************************************************/
452 
453 /**
454  * Class BStyles::Theme
455  *
456  * A BStyles::Theme is a collection of different BStyles::StyleSets. A theme is
457  * intended to be used set up all properties of objects (like a GUI based on
458  * BWidgets) at once.
459  */
460 class Theme
461 {
462 public:
463 	Theme ();
464 	Theme (const std::vector<StyleSet>& theme);
465 
466 	/**
467 	 * Adds (or overwrites an existing) style to an BStyles::StyleSet
468 	 * within the Theme. If the respective BStyles::StyleSet doesn't
469 	 * exist yet, it will be created.
470 	 * @param setName Name of the BStyles::StyleSet
471 	 * @param styleName Name of the BStyles::Style
472 	 * @param ptr Pointer to the style element
473 	 */
474 	void addStyle (const std::string& setName, const std::string& styleName, void* ptr);
475 
476 	//TODO void addStyle (Style style);
477 	//TODO void addStyleSet (StyleSet styleSet);
478 	//TODO StyleSet* getStyleSet (std::string setName);
479 
480 	/**
481 	 * Removes an existing style.
482 	 * @param setName Name of the BStyles::StyleSet
483 	 * @param styleName Name of the style to be removed.
484 	 * TODO throws style doesn't exist
485 	 */
486 	void removeStyle (const std::string& setName, const std::string& styleName);
487 
488 	/**
489 	 * Gets an existing style.
490 	 * @param setName Name of the BStyles::StyleSet
491 	 * @param styleName Name of the style to be removed.
492 	 * TODO throws style doesn't exist
493 	 */
494 	void* getStyle (const std::string& setName, const std::string& styleName);
495 
496 protected:
497 	std::vector<StyleSet> stylesetVector;
498 };
499 /*
500  * End of class BWidgets::Theme
501  *****************************************************************************/
502 
503 }
504 
505 #endif /* BSTYLES_HPP_ */
506