Style.h
1 /* Copyright (C) 2016 Laurentiu-Gheorghe Crisan
2  Copyright (C) 2016 Marc Boris Duerner
3 
4  This library is free software; you can redistribute it and/or
5  modify it under the terms of the GNU Lesser General Public
6  License as published by the Free Software Foundation; either
7  version 2.1 of the License, or (at your option) any later version.
8 
9  As a special exception, you may use this file as part of a free
10  software library without restriction. Specifically, if other files
11  instantiate templates or use macros or inline functions from this
12  file, or you compile this file and link it with other files to
13  produce an executable, this file does not by itself cause the
14  resulting executable to be covered by the GNU General Public
15  License. This exception does not however invalidate any other
16  reasons why the executable file might be covered by the GNU Library
17  General Public License.
18 
19  This library is distributed in the hope that it will be useful,
20  but WITHOUT ANY WARRANTY; without even the implied warranty of
21  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22  Lesser General Public License for more details.
23 
24  You should have received a copy of the GNU Lesser General Public
25  License along with this library; if not, write to the Free Software
26  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
27  MA 02110-1301 USA
28 */
29 
30 #ifndef Pt_Forms_Style_h
31 #define Pt_Forms_Style_h
32 
33 #include <Pt/Forms/Api.h>
34 #include <Pt/Forms/Alignment.h>
35 #include <Pt/Forms/Direction.h>
36 #include <Pt/Forms/Spacing.h>
37 #include <Pt/Forms/StyleOptions.h>
38 #include <Pt/Forms/PaintSurface.h>
39 #include <Pt/Gfx/Color.h>
40 #include <Pt/Gfx/Brush.h>
41 #include <Pt/Gfx/Pen.h>
42 #include <Pt/Gfx/Rect.h>
43 #include <Pt/Gfx/Font.h>
44 #include <Pt/Gfx/FontMetrics.h>
45 #include <Pt/Gfx/TextMetrics.h>
46 #include <Pt/TypeInfo.h>
47 #include <Pt/NonCopyable.h>
48 #include <Pt/SmartPtr.h>
49 
50 #include <map>
51 #include <cstddef>
52 
53 namespace Pt {
54 
55 namespace Forms {
56 
57 class PaintContext;
58 class Painter;
59 class Pixmap;
60 class TextBlock;
61 class PushButton;
62 class Menu;
63 class MenuItem;
64 class MenuBar;
65 class MenuBarItem;
66 class ProgressBar;
67 
68 template <typename T>
69 class FacetPtr
70 {
71  public:
72  FacetPtr(T* facet = 0)
73  : _facet(facet)
74  {
75  if( _facet )
76  _facet->ref();
77  }
78 
79  FacetPtr(const FacetPtr& ptr)
80  : _facet(ptr._facet)
81  {
82  if( _facet )
83  _facet->ref();
84  }
85 
86  ~FacetPtr()
87  {
88  if(_facet)
89  {
90  if( 0 == _facet->unref() )
91  delete _facet;
92  }
93  }
94 
95  FacetPtr& operator=(const FacetPtr& ptr)
96  {
97  if(this == &ptr)
98  return *this;
99 
100  if(_facet)
101  {
102  if( 0 == _facet->unref() )
103  delete _facet;
104  }
105 
106  _facet = ptr._facet;
107  if( _facet )
108  _facet->ref();
109 
110  return *this;
111  }
112 
113  void reset(T* facet = 0)
114  {
115  if (_facet == facet)
116  return;
117 
118  if(_facet)
119  {
120  if( 0 == _facet->unref() )
121  delete _facet;
122  }
123 
124  _facet = facet;
125  if( _facet )
126  _facet->ref();
127  }
128 
129  T* operator->() const
130  { return _facet; }
131 
132  T& operator*() const
133  { return *_facet; }
134 
135  bool operator! () const
136  { return _facet == 0; }
137 
138  operator bool () const
139  { return _facet != 0; }
140 
141  T* get()
142  { return _facet; }
143 
144  const T* get() const
145  { return _facet; }
146 
147  private:
148  T* _facet;
149 };
150 
153 class PT_FORMS_API Style
154 {
155  public:
156  class Facet : private NonCopyable
157  {
158  public:
159  explicit Facet(const std::type_info& ti, std::size_t refs = 0)
160  : _typeId(&ti)
161  , _refs(refs)
162  {}
163 
164  virtual ~Facet()
165  {}
166 
167  const std::type_info& typeId() const
168  {
169  return *_typeId;
170  }
171 
172  void ref()
173  {
174  ++_refs;
175  }
176 
177  std::size_t unref()
178  {
179  return --_refs;
180  }
181 
184  void reset(const StyleOptions& options)
185  {
186  onReset(options);
187  }
188 
189  protected:
192  virtual void onReset(const StyleOptions& /*options*/)
193  {
194  }
195 
196  private:
197  const std::type_info* _typeId;
198  std::size_t _refs;
199  };
200 
201  public:
204  Style();
205 
208  Style(const Style& style);
209 
212  virtual ~Style();
213 
216  Style& operator=(const Style& style);
217 
220  void assign(const Style& style);
221 
224  void set(Facet* facet);
225 
228  void reset(const StyleOptions& options);
229 
236  std::size_t generation() const
237  {
238  return _generation;
239  }
240 
241  template <typename FacetT>
242  FacetT* get() const
243  {
244  Facet* facet = find( typeid(FacetT) );
245  return static_cast<FacetT*>(facet);
246  }
247 
248  private:
249  Facet* find(const std::type_info& ti) const;
250 
251  private:
252  typedef std::map<TypeInfo, Facet*> FacetMap;
253  FacetMap _facets;
254  std::size_t _generation;
255 };
256 
257 
269 template <typename RendererT,
270  typename OptionsT>
271 class StyleBinder : private NonCopyable
272 {
273  public:
277 
280  bool isBound() const;
281 
284  bool isCustom() const;
285 
295  RendererT* bind(const Pt::Forms::Style& style,
296  const StyleOptions& options,
297  const OptionsT& localOptions);
298 
304  RendererT* bind(RendererT& renderer,
305  const StyleOptions& options,
306  const OptionsT& localOptions);
307 
315  RendererT* rebind(const Pt::Forms::Style& style,
316  const StyleOptions& options,
317  const OptionsT& localOptions);
318 
321  RendererT* renderer();
322 
325  const RendererT* renderer() const;
326 
327  protected:
328  enum Binding
329  {
330  SharedRenderer,
331  CustomOverrides,
332  CustomRenderer
333  };
334 
335  private:
336  FacetPtr<RendererT> _renderer;
337  Binding _binding;
338  std::size_t _boundStyleGeneration;
339  std::size_t _styleOptionsGeneration;
340  std::size_t _localOptionsGeneration;
341 };
342 
343 
344 template <typename RendererT,
345  typename OptionsT>
347 : _binding(SharedRenderer)
348 , _boundStyleGeneration( std::size_t(-1) )
349 , _styleOptionsGeneration( std::size_t(-1) )
350 , _localOptionsGeneration( std::size_t(-1) )
351 {
352 }
353 
354 
355 template <typename RendererT,
356  typename OptionsT>
358 {
359  return _renderer != 0;
360 }
361 
362 
363 template <typename RendererT,
364  typename OptionsT>
366 {
367  return _binding == CustomRenderer;
368 }
369 
370 
371 template <typename RendererT,
372  typename OptionsT>
373 RendererT*
375  const StyleOptions& options,
376  const OptionsT& localOptions)
377 {
378  _styleOptionsGeneration = std::size_t(-1);
379  _localOptionsGeneration = std::size_t(-1);
380 
381  if( localOptions.hasOverrides() )
382  {
383  RendererT* renderer = style.get<RendererT>();
384  if( renderer )
385  renderer = renderer->create();
386 
387  _renderer.reset(renderer);
388  _binding = CustomOverrides;
389 
390  if( _renderer )
391  {
392  _renderer->prepare(options, localOptions);
393  _styleOptionsGeneration = options.generation();
394  _localOptionsGeneration = localOptions.generation();
395  }
396  }
397  else
398  {
399  _renderer.reset( style.get<RendererT>() );
400  _binding = SharedRenderer;
401  }
402 
403  _boundStyleGeneration = style.generation();
404 
405  return _renderer.get();
406 }
407 
408 
409 template <typename RendererT,
410  typename OptionsT>
411 RendererT*
413  const StyleOptions& options,
414  const OptionsT& localOptions)
415 {
416  _renderer.reset(&renderer);
417 
418  _binding = CustomRenderer;
419  _boundStyleGeneration = std::size_t(-1);
420  _styleOptionsGeneration = std::size_t(-1);
421  _localOptionsGeneration = std::size_t(-1);
422 
423  _renderer->prepare(options, localOptions);
424 
425  _styleOptionsGeneration = options.generation();
426  _localOptionsGeneration = localOptions.generation();
427 
428  return _renderer.get();
429 }
430 
431 
432 template <typename RendererT,
433  typename OptionsT>
434 RendererT*
436  const StyleOptions& options,
437  const OptionsT& localOptions)
438 {
439  if( ! _renderer || _binding != CustomRenderer )
440  return bind(style, options, localOptions);
441 
442  bool needsPrepare = _styleOptionsGeneration != options.generation() ||
443  _localOptionsGeneration != localOptions.generation();
444 
445  if( needsPrepare )
446  _renderer->prepare(options, localOptions);
447 
448  _styleOptionsGeneration = options.generation();
449  _localOptionsGeneration = localOptions.generation();
450 
451  return _renderer.get();
452 }
453 
454 
455 template <typename RendererT,
456  typename OptionsT>
458 {
459  return _renderer.get();
460 }
461 
462 
463 template <typename RendererT,
464  typename OptionsT>
466 {
467  return _renderer.get();
468 }
469 
470 
471 } // namespace
472 
473 } // namespace
474 
475 #endif
Core module.
Definition: Allocator.h:33
Common renderer-binding controller for Forms style slices.
Definition: Style.h:272
bool isCustom() const
Returns true if a custom renderer is currently bound.
Definition: Style.h:365
RendererT * renderer()
Returns the currently bound renderer or 0 if none is available.
Definition: Style.h:457
void assign(const Style &style)
Replaces all facets with those from another style.
RendererT * bind(const Pt::Forms::Style &style, const StyleOptions &options, const OptionsT &localOptions)
Binds to the current style renderer path.
Definition: Style.h:374
Style(const Style &style)
Constructs a style by copying another style.
RendererT * rebind(const Pt::Forms::Style &style, const StyleOptions &options, const OptionsT &localOptions)
Refreshes the current renderer binding.
Definition: Style.h:435
Style()
Constructs an empty style.
Style for widgets.
Definition: Style.h:154
StyleBinder()
Constructs an unbound style controller.
Definition: Style.h:346
void set(Facet *facet)
Registers or replaces a facet.
Style & operator=(const Style &style)
Assigns the contents of another style.
RendererT * bind(RendererT &renderer, const StyleOptions &options, const OptionsT &localOptions)
Binds to an externally assigned renderer.
Definition: Style.h:412
bool isBound() const
Returns true if a renderer is currently bound.
Definition: Style.h:357
Stores the global theme option values shared across styles.
Definition: StyleOptions.h:186
std::size_t generation() const
Returns the current style generation.
Definition: Style.h:236
virtual ~Style()
Destroys the style and releases all registered facets.
Protects derived classes from being copied.
Definition: NonCopyable.h:54
std::size_t generation() const
Returns the current change generation.
const RendererT * renderer() const
Returns the currently bound renderer or 0 if none is available.
Definition: Style.h:465
void reset(const StyleOptions &options)
Resets all registered facets to the given global style options.