1 //------------------------------------------------------------------------------
2 // emBorder.h
3 //
4 // Copyright (C) 2005-2010,2014-2016 Oliver Hamann.
5 //
6 // Homepage: http://eaglemode.sourceforge.net/
7 //
8 // This program is free software: you can redistribute it and/or modify it under
9 // the terms of the GNU General Public License version 3 as published by the
10 // Free Software Foundation.
11 //
12 // This program is distributed in the hope that it will be useful, but WITHOUT
13 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 // FOR A PARTICULAR PURPOSE. See the GNU General Public License version 3 for
15 // more details.
16 //
17 // You should have received a copy of the GNU General Public License version 3
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
19 //------------------------------------------------------------------------------
20 
21 #ifndef emBorder_h
22 #define emBorder_h
23 
24 #ifndef emVarModel_h
25 #include <emCore/emVarModel.h>
26 #endif
27 
28 #ifndef emLook_h
29 #include <emCore/emLook.h>
30 #endif
31 
32 
33 //==============================================================================
34 //================================== emBorder ==================================
35 //==============================================================================
36 
37 class emBorder : public emPanel {
38 
39 public:
40 
41 	// This is the base class of all toolkit panels. A panel of this class
42 	// can have a border, a label, a how-to text and an auxiliary area. And
43 	// it has a content area. The label can consist of a caption, a
44 	// description and an icon. The how-to text describes how to use the
45 	// type of panel in general, and maybe something about its state. The
46 	// auxiliary area is for showing a custom panel with additional things
47 	// like a configuration or an extended help text. The label, the how-to
48 	// text and the auxiliary area are shown in the border. Alternatively, a
49 	// derived class can manage to move the label into the content area.
50 
51 	emBorder(
52 		ParentArg parent, const emString & name,
53 		const emString & caption=emString(),
54 		const emString & description=emString(),
55 		const emImage & icon=emImage()
56 	);
57 		// Constructor.
58 		// Arguments:
59 		//   parent      - Parent for this panel (emPanel or emView).
60 		//   name        - The name for this panel.
61 		//   caption     - The label's caption, or empty.
62 		//   description - The label's description, or empty.
63 		//   icon        - The label's icon, or empty.
64 
65 	virtual ~emBorder();
66 		// Destructor.
67 
68 	const emString & GetCaption() const;
69 	void SetCaption(const emString & caption);
70 		// The caption to be shown in the label.
71 
72 	const emString & GetDescription() const;
73 	void SetDescription(const emString & description);
74 		// The description to be shown in the label.
75 
76 	const emImage & GetIcon() const;
77 	void SetIcon(const emImage & icon);
78 		// The icon to be shown in the label.
79 
80 	void SetLabel(
81 		const emString & caption=emString(),
82 		const emString & description=emString(),
83 		const emImage & icon=emImage()
84 	);
85 		// Set all three things which are making up the label.
86 
87 	emAlignment GetLabelAlignment() const;
88 	void SetLabelAlignment(emAlignment labelAlignment);
89 		// Alignment of the label as a whole within its available space.
90 
91 	emAlignment GetCaptionAlignment() const;
92 	void SetCaptionAlignment(emAlignment captionAlignment);
93 		// Horizontal alignment of lines within the caption text of the
94 		// label. The top and bottom flags are ignored.
95 
96 	emAlignment GetDescriptionAlignment() const;
97 	void SetDescriptionAlignment(emAlignment descriptionAlignment);
98 		// Horizontal alignment of lines within the description text of
99 		// the label. The top and bottom flags are ignored.
100 
101 	bool IsIconAboveCaption() const;
102 	void SetIconAboveCaption(bool iconAboveCaption=true);
103 		// Whether the icon is shown above the caption (true), or if it
104 		// is shown to the left of the caption (false, the default).
105 
106 	double GetMaxIconAreaTallness() const;
107 	void SetMaxIconAreaTallness(double maxIconAreaTallness);
108 		// Maximum tallness (height/width ratio) of the area in the
109 		// label preserved for the icon (if the label has an icon). The
110 		// default is 1.0. If you have a group of elements (e.g.
111 		// buttons) which show icons and captions, and if the icon
112 		// images have different tallnesses, then it is a good idea to
113 		// set this parameter to the minimum(!) tallness of all the icon
114 		// images. Thereby, the icons and captions of all the elements
115 		// will be aligned pretty equal.
116 
117 	enum OuterBorderType {
118 		// Possibles types for the outer border line. This even
119 		// specifies whether the background of the panel should be
120 		// filled or not.
121 		OBT_NONE,
122 			// Do not have an outer border line, do not have a
123 			// margin and do not fill the background.
124 		OBT_FILLED,
125 			// Like OBT_NONE, but fill the whole background with
126 			// background color.
127 		OBT_MARGIN,
128 			// Like OBT_NONE, but have a small margin (for example,
129 			// this is used by emLabel and emCheckBox). Larger
130 			// margins should be solved through the parent panel,
131 			// e.g. see emLinearLayout::SetSpace.
132 		OBT_MARGIN_FILLED,
133 			// Like OBT_MARGIN, but fill the whole background.
134 		OBT_RECT,
135 			// Have a rectangular outer border line and fill the
136 			// rectangle with background color. Have a small margin.
137 		OBT_ROUND_RECT,
138 			// Like OBT_RECT but with round corners.
139 		OBT_GROUP,
140 			// Have a small special outer border for groups (used by
141 			// group panels like emLinearGroup and so on).
142 		OBT_INSTRUMENT,
143 			// Like OBT_GROUP, but the border line is thicker (for
144 			// example, this is used by emTextField).
145 		OBT_INSTRUMENT_MORE_ROUND,
146 			// Like OBT_INSTRUMENT, but with a larger corner radius
147 			// (this is used by emButton).
148 		OBT_POPUP_ROOT
149 			// Have a special border for root panels of views which
150 			// have the VF_POPUP_ZOOM flag set (should not be used
151 			// for something else).
152 	};
153 
154 	enum InnerBorderType {
155 		// Possibles types for the inner border line.
156 		IBT_NONE,
157 			// Do not have an inner border line.
158 		IBT_GROUP,
159 			// Have a special round inner border line for groups.
160 		IBT_INPUT_FIELD,
161 			// Have a special round inner border and background for
162 			// editable fields.
163 		IBT_OUTPUT_FIELD,
164 			// Have a special round inner border and background for
165 			// non-editable fields.
166 		IBT_CUSTOM_RECT
167 			// Have a special rectangular inner border for custom
168 			// stuff. Herewith, the content rectangle never has
169 			// round corners.
170 	};
171 
172 	OuterBorderType GetOuterBorderType() const;
173 	InnerBorderType GetInnerBorderType() const;
174 	void SetOuterBorderType(OuterBorderType obt);
175 	void SetInnerBorderType(InnerBorderType ibt);
176 	void SetBorderType(OuterBorderType obt, InnerBorderType ibt);
177 		// Outer and inner border types. The default is OBT_NONE and
178 		// IBT_NONE.
179 
180 	double GetBorderScaling() const;
181 	void SetBorderScaling(double borderScaling);
182 		// Scale factor for the size of the border. The default is 1.0.
183 
184 	const emLook & GetLook() const;
185 	virtual void SetLook(const emLook & look, bool recursively=false);
186 		// Look of this toolkit panel. At construction of a panel, the
187 		// look is copied from the parent panel (if the parent is not
188 		// emBorder, the grand parent is asked, and so on). When
189 		// setting the look with the argument recursively=true, all
190 		// descendant panels of class emBorder are even set through
191 		// calling emLook::Apply for every child panel.
192 
193 	void HaveAux(const emString & panelName, double tallness);
194 		// Make this border having a rectangular area for auxiliary
195 		// stuff. It could be a user interface for configuring this
196 		// panel, or an extended function, or some additional help or
197 		// what ever you want. Either you could show the things through
198 		// a child panel or through custom painting, but doing it with a
199 		// child panel is easier. Whenever you create that panel. It is
200 		// laid out automatically into the auxiliary area.
201 		// Arguments:
202 		//   panelName - Name of the child panel to be laid out in the
203 		//               auxiliary area.
204 		//   tallness  - Height/width ratio of the auxiliary area.
205 
206 	void RemoveAux();
207 		// Inversion of HaveAux (does not delete the auxiliary panel).
208 
209 	bool HasAux() const;
210 		// Whether this border has an area for auxiliary stuff.
211 
212 	const emString & GetAuxPanelName() const;
213 	double GetAuxTallness() const;
214 		// Properties of the auxiliary area set with HaveAux. Valid only
215 		// if HasAux()==true.
216 
217 	emPanel * GetAuxPanel();
218 		// Returns the auxiliary child panel, or NULL if not present.
219 
220 	void GetAuxRect(
221 		double * pX, double * pY, double * pW, double * pH,
222 		emColor * pCanvasColor=NULL
223 	) const;
224 		// Get the coordinates and canvas color of the auxiliary area.
225 		// Valid only if HasAux()==true.
226 
227 	virtual void GetSubstanceRect(double * pX, double * pY,
228 	                              double * pW, double * pH,
229 	                              double * pR) const;
230 		// Overloaded from emPanel (read there).
231 
232 	virtual void GetContentRoundRect(
233 		double * pX, double * pY, double * pW, double * pH, double * pR,
234 		emColor * pCanvasColor=NULL
235 	) const;
236 		// Get the coordinates and canvas color of the content area as a
237 		// round rectangle (argument pR is for returning the radius of
238 		// the corners).
239 
240 	virtual void GetContentRect(
241 		double * pX, double * pY, double * pW, double * pH,
242 		emColor * pCanvasColor=NULL
243 	) const;
244 		// Get the coordinates and canvas color of the content area as a
245 		// rectangle. If the inner border has round corners, the
246 		// rectangle returned here is smaller than with
247 		// GetContentRoundRect, so that it fits completely into the
248 		// content area.
249 
250 	virtual void GetContentRectUnobscured(
251 		double * pX, double * pY, double * pW, double * pH,
252 		emColor * pCanvasColor=NULL
253 	) const;
254 		// Get the coordinates and canvas color of the unobscured part
255 		// of the content area. Some border types are painting an
256 		// overlay like a shadow at the edges of the content area, after
257 		// PaintContent is called. This does not work for child panels,
258 		// because they are painted after the overlay. Therefore child
259 		// panels should be laid out in the rectangle returned by
260 		// GetContentRectUnobscured. It returns the inner part, which is
261 		// not painted over.
262 
263 protected:
264 
265 	virtual void Notice(NoticeFlags flags);
266 	virtual bool IsOpaque() const;
267 	virtual void Paint(const emPainter & painter, emColor canvasColor) const;
268 	virtual void LayoutChildren();
269 		// See emPanel. Hint: For painting the content area, please
270 		// overload PaintContent instead of Paint, because with certain
271 		// border types, a shadow is painted over the content area.
272 
273 	virtual bool HasHowTo() const;
274 	virtual emString GetHowTo() const;
275 		// This is about a text describing how to use this panel. If
276 		// HasHowTo()==true, the text returned by GetHowTo() is shown
277 		// very small in the center of the left edge of the border. When
278 		// overloading GetHowTo(), please do not forget to call the
279 		// original version and to include that text at the beginning.
280 		// The default implementation of GetHowTo() returns a preface,
281 		// and optionally a description of the disable state (if
282 		// disabled) and optionally a description of the keyboard focus
283 		// (if focusable). The default implementation of HasHowTo()
284 		// return false, because the default text alone is not so
285 		// helpful, and because the text would disturb some panel types.
286 
287 	virtual void PaintContent(
288 		const emPainter & painter, double x, double y, double w,
289 		double h, emColor canvasColor
290 	) const;
291 		// This can be overloaded for painting the content area. The
292 		// default implementation does nothing. The coordinates x,y,w,h
293 		// are like from GetContentRect, but you could even use the
294 		// coordinates returned by GetContentRoundRect.
295 
296 	virtual bool HasLabel() const;
297 		// Whether this panel has a label. The default implementation
298 		// checks whether at least one of caption, description and icon
299 		// is not empty.
300 
301 	virtual double GetBestLabelTallness() const;
302 		// Get the ideal tallness for the label area. The default
303 		// implementation calculates this for the default implementation
304 		// of PaintLabel.
305 
306 	virtual void PaintLabel(
307 		const emPainter & painter, double x, double y, double w,
308 		double h, emColor color, emColor canvasColor
309 	) const;
310 		// Paint the label. The default implementation paints the
311 		// caption, description and icon. This could be overloaded to
312 		// paint something else for the label.
313 
314 	bool IsLabelInBorder() const;
315 	void SetLabelInBorder(bool labelInBorder);
316 		// Whether to show the label as part of the border. The default
317 		// is true. If a derived class wants to have the label as part
318 		// of the content, it should set false here and call PaintLabel
319 		// itself.
320 
321 	struct TkResources {
322 		TkResources();
323 		~TkResources();
324 		emImage ImgButton;
325 		emImage ImgButtonBorder;
326 		emImage ImgButtonChecked;
327 		emImage ImgButtonPressed;
328 		emImage ImgCheckBox;
329 		emImage ImgCheckBoxPressed;
330 		emImage ImgCustomRectBorder;
331 		emImage ImgDir;
332 		emImage ImgDirUp;
333 		emImage ImgGroupBorder;
334 		emImage ImgGroupInnerBorder;
335 		emImage ImgIOField;
336 		emImage ImgPopupBorder;
337 		emImage ImgRadioBox;
338 		emImage ImgRadioBoxPressed;
339 		emImage ImgSplitter;
340 		emImage ImgSplitterPressed;
341 		emImage ImgTunnel;
342 	};
343 	const TkResources & GetTkResources() const;
344 		// Shared resources used by the toolkit panel implementations.
345 		// This is more or less private stuff - do not use in custom
346 		// classes.
347 
348 	// - - - - - - - - - - Depreciated methods - - - - - - - - - - - - - - -
349 	// The following virtual non-const methods have been replaced by const
350 	// methods (see above). The old versions still exist here with the
351 	// "final" keyword added, so that old overridings will fail to compile.
352 	// If you run into this, please adapt your overridings by adding "const".
353 public:
354 	virtual void GetContentRoundRect(
355 		double * pX, double * pY, double * pW, double * pH, double * pR,
356 		emColor * pCanvasColor=NULL
357 	) final;
358 	virtual void GetContentRect(
359 		double * pX, double * pY, double * pW, double * pH,
360 		emColor * pCanvasColor=NULL
361 	) final;
362 	virtual void GetContentRectUnobscured(
363 		double * pX, double * pY, double * pW, double * pH,
364 		emColor * pCanvasColor=NULL
365 	) final;
366 protected:
367 	virtual bool HasHowTo() final;
368 	virtual emString GetHowTo() final;
369 	virtual void PaintContent(
370 		const emPainter & painter, double x, double y, double w,
371 		double h, emColor canvasColor
372 	) final;
373 	virtual bool HasLabel() final;
374 	virtual double GetBestLabelTallness() final;
375 	virtual void PaintLabel(
376 		const emPainter & painter, double x, double y, double w,
377 		double h, emColor color, emColor canvasColor
378 	) final;
379 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
380 
381 private:
382 
383 	enum DoBorderFunc {
384 		BORDER_FUNC_PAINT,
385 		BORDER_FUNC_SUBSTANCE_ROUND_RECT,
386 		BORDER_FUNC_CONTENT_ROUND_RECT,
387 		BORDER_FUNC_CONTENT_RECT,
388 		BORDER_FUNC_CONTENT_RECT_UNOBSCURED,
389 		BORDER_FUNC_AUX_RECT
390 	};
391 	void DoBorder(
392 		DoBorderFunc func, const emPainter * painter,
393 		emColor canvasColor, double * pX, double * pY, double * pW,
394 		double * pH, double * pR, emColor * pCanvasColor
395 	) const;
396 
397 	enum DoLabelFunc {
398 		LABEL_FUNC_PAINT,
399 		LABEL_FUNC_GET_BEST_TALLNESS
400 	};
401 	void DoLabel(
402 		DoLabelFunc func, const emPainter * painter, double x, double y,
403 		double w, double h, emColor color, emColor canvasColor,
404 		double * pBestTallness
405 	) const;
406 
407 	struct AuxData {
408 		emString PanelName;
409 		double Tallness;
410 		emCrossPtr<emPanel> PanelPointerCache;
411 	};
412 
413 	emRef<emVarModel<TkResources> > TkResVarModel;
414 	emString Caption;
415 	emString Description;
416 	emImage Icon;
417 	AuxData * Aux;
418 	emLook Look;
419 	double MaxIconAreaTallness;
420 	double BorderScaling;
421 	emAlignment LabelAlignment;
422 	emAlignment CaptionAlignment;
423 	emAlignment DescriptionAlignment;
424 	emByte OuterBorder;
425 	emByte InnerBorder;
426 	bool IconAboveCaption;
427 	bool LabelInBorder;
428 
429 	static const char * HowToPreface;
430 	static const char * HowToDisabled;
431 	static const char * HowToFocus;
432 };
433 
GetCaption()434 inline const emString & emBorder::GetCaption() const
435 {
436 	return Caption;
437 }
438 
GetDescription()439 inline const emString & emBorder::GetDescription() const
440 {
441 	return Description;
442 }
443 
GetIcon()444 inline const emImage & emBorder::GetIcon() const
445 {
446 	return Icon;
447 }
448 
GetLabelAlignment()449 inline emAlignment emBorder::GetLabelAlignment() const
450 {
451 	return LabelAlignment;
452 }
453 
GetCaptionAlignment()454 inline emAlignment emBorder::GetCaptionAlignment() const
455 {
456 	return CaptionAlignment;
457 }
458 
GetDescriptionAlignment()459 inline emAlignment emBorder::GetDescriptionAlignment() const
460 {
461 	return DescriptionAlignment;
462 }
463 
IsIconAboveCaption()464 inline bool emBorder::IsIconAboveCaption() const
465 {
466 	return IconAboveCaption;
467 }
468 
GetMaxIconAreaTallness()469 inline double emBorder::GetMaxIconAreaTallness() const
470 {
471 	return MaxIconAreaTallness;
472 }
473 
GetOuterBorderType()474 inline emBorder::OuterBorderType emBorder::GetOuterBorderType() const
475 {
476 	return (OuterBorderType)OuterBorder;
477 }
478 
GetInnerBorderType()479 inline emBorder::InnerBorderType emBorder::GetInnerBorderType() const
480 {
481 	return (InnerBorderType)InnerBorder;
482 }
483 
GetBorderScaling()484 inline double emBorder::GetBorderScaling() const
485 {
486 	return BorderScaling;
487 }
488 
GetLook()489 inline const emLook & emBorder::GetLook() const
490 {
491 	return Look;
492 }
493 
HasAux()494 inline bool emBorder::HasAux() const
495 {
496 	return Aux!=NULL;
497 }
498 
IsLabelInBorder()499 inline bool emBorder::IsLabelInBorder() const
500 {
501 	return LabelInBorder;
502 }
503 
GetTkResources()504 inline const emBorder::TkResources & emBorder::GetTkResources() const
505 {
506 	return TkResVarModel->Var;
507 }
508 
509 
510 #endif
511