//------------------------------------------------------------------------------
// emBorder.h
//
// Copyright (C) 2005-2010,2014-2016,2021 Oliver Hamann.
//
// Homepage: http://eaglemode.sourceforge.net/
//
// This program is free software: you can redistribute it and/or modify it under
// the terms of the GNU General Public License version 3 as published by the
// Free Software Foundation.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU General Public License version 3 for
// more details.
//
// You should have received a copy of the GNU General Public License version 3
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//------------------------------------------------------------------------------
#ifndef emBorder_h
#define emBorder_h
#ifndef emVarModel_h
#include <emCore/emVarModel.h>
#endif
#ifndef emLook_h
#include <emCore/emLook.h>
#endif
//==============================================================================
//================================== emBorder ==================================
//==============================================================================
class emBorder : public emPanel {
public:
// This is the base class of all toolkit panels. A panel of this class
// can have a border, a label, a how-to text and an auxiliary area. And
// it has a content area. The label can consist of a caption, a
// description and an icon. The how-to text describes how to use the
// type of panel in general, and maybe something about its state. The
// auxiliary area is for showing a custom panel with additional things
// like a configuration or an extended help text. The label, the how-to
// text and the auxiliary area are shown in the border. Alternatively, a
// derived class can manage to move the label into the content area.
emBorder(
ParentArg parent, const emString & name,
const emString & caption=emString(),
const emString & description=emString(),
const emImage & icon=emImage()
);
// Constructor.
// Arguments:
// parent - Parent for this panel (emPanel or emView).
// name - The name for this panel.
// caption - The label's caption, or empty.
// description - The label's description, or empty.
// icon - The label's icon, or empty.
virtual ~emBorder();
// Destructor.
const emString & GetCaption() const;
void SetCaption(const emString & caption);
// The caption to be shown in the label.
const emString & GetDescription() const;
void SetDescription(const emString & description);
// The description to be shown in the label.
const emImage & GetIcon() const;
void SetIcon(const emImage & icon);
// The icon to be shown in the label.
void SetLabel(
const emString & caption=emString(),
const emString & description=emString(),
const emImage & icon=emImage()
);
// Set all three things which are making up the label.
emAlignment GetLabelAlignment() const;
void SetLabelAlignment(emAlignment labelAlignment);
// Alignment of the label as a whole within its available space.
emAlignment GetCaptionAlignment() const;
void SetCaptionAlignment(emAlignment captionAlignment);
// Horizontal alignment of lines within the caption text of the
// label. The top and bottom flags are ignored.
emAlignment GetDescriptionAlignment() const;
void SetDescriptionAlignment(emAlignment descriptionAlignment);
// Horizontal alignment of lines within the description text of
// the label. The top and bottom flags are ignored.
bool IsIconAboveCaption() const;
void SetIconAboveCaption(bool iconAboveCaption=true);
// Whether the icon is shown above the caption (true), or if it
// is shown to the left of the caption (false, the default).
double GetMaxIconAreaTallness() const;
void SetMaxIconAreaTallness(double maxIconAreaTallness);
// Maximum tallness (height/width ratio) of the area in the
// label preserved for the icon (if the label has an icon). The
// default is 1.0. If you have a group of elements (e.g.
// buttons) which show icons and captions, and if the icon
// images have different tallnesses, then it is a good idea to
// set this parameter to the minimum(!) tallness of all the icon
// images. Thereby, the icons and captions of all the elements
// will be aligned pretty equal.
enum OuterBorderType {
// Possibles types for the outer border line. This even
// specifies whether the background of the panel should be
// filled or not.
OBT_NONE,
// Do not have an outer border line, do not have a
// margin and do not fill the background.
OBT_FILLED,
// Like OBT_NONE, but fill the whole background with
// background color.
OBT_MARGIN,
// Like OBT_NONE, but have a small margin (for example,
// this is used by emLabel and emCheckBox). Larger
// margins should be solved through the parent panel,
// e.g. see emLinearLayout::SetSpace.
OBT_MARGIN_FILLED,
// Like OBT_MARGIN, but fill the whole background.
OBT_RECT,
// Have a rectangular outer border line and fill the
// rectangle with background color. Have a small margin.
OBT_ROUND_RECT,
// Like OBT_RECT but with round corners.
OBT_GROUP,
// Have a small special outer border for groups (used by
// group panels like emLinearGroup and so on).
OBT_INSTRUMENT,
// Like OBT_GROUP, but the border line is thicker (for
// example, this is used by emTextField).
OBT_INSTRUMENT_MORE_ROUND,
// Like OBT_INSTRUMENT, but with a larger corner radius
// (this is used by emButton).
OBT_POPUP_ROOT
// Have a special border for root panels of views which
// have the VF_POPUP_ZOOM flag set (should not be used
// for something else).
};
enum InnerBorderType {
// Possibles types for the inner border line.
IBT_NONE,
// Do not have an inner border line.
IBT_GROUP,
// Have a special round inner border line for groups.
IBT_INPUT_FIELD,
// Have a special round inner border and background for
// editable fields.
IBT_OUTPUT_FIELD,
// Have a special round inner border and background for
// non-editable fields.
IBT_CUSTOM_RECT
// Have a special rectangular inner border for custom
// stuff. Herewith, the content rectangle never has
// round corners.
};
OuterBorderType GetOuterBorderType() const;
InnerBorderType GetInnerBorderType() const;
void SetOuterBorderType(OuterBorderType obt);
void SetInnerBorderType(InnerBorderType ibt);
void SetBorderType(OuterBorderType obt, InnerBorderType ibt);
// Outer and inner border types. The default is OBT_NONE and
// IBT_NONE.
double GetBorderScaling() const;
void SetBorderScaling(double borderScaling);
// Scale factor for the size of the border. The default is 1.0.
const emLook & GetLook() const;
virtual void SetLook(const emLook & look, bool recursively=false);
// Look of this toolkit panel. At construction of a panel, the
// look is copied from the parent panel (if the parent is not
// emBorder, the grand parent is asked, and so on). When
// setting the look with the argument recursively=true, all
// descendant panels of class emBorder are even set through
// calling emLook::Apply for every child panel.
void HaveAux(const emString & panelName, double tallness);
// Make this border having a rectangular area for auxiliary
// stuff. It could be a user interface for configuring this
// panel, or an extended function, or some additional help or
// what ever you want. Either you could show the things through
// a child panel or through custom painting, but doing it with a
// child panel is easier. Whenever you create that panel. It is
// laid out automatically into the auxiliary area.
// Arguments:
// panelName - Name of the child panel to be laid out in the
// auxiliary area.
// tallness - Height/width ratio of the auxiliary area.
void RemoveAux();
// Inversion of HaveAux (does not delete the auxiliary panel).
bool HasAux() const;
// Whether this border has an area for auxiliary stuff.
const emString & GetAuxPanelName() const;
double GetAuxTallness() const;
// Properties of the auxiliary area set with HaveAux. Valid only
// if HasAux()==true.
emPanel * GetAuxPanel();
// Returns the auxiliary child panel, or NULL if not present.
void GetAuxRect(
double * pX, double * pY, double * pW, double * pH,
emColor * pCanvasColor=NULL
) const;
// Get the coordinates and canvas color of the auxiliary area.
// Valid only if HasAux()==true.
virtual void GetSubstanceRect(double * pX, double * pY,
double * pW, double * pH,
double * pR) const;
// Overloaded from emPanel (read there).
virtual void GetContentRoundRect(
double * pX, double * pY, double * pW, double * pH, double * pR,
emColor * pCanvasColor=NULL
) const;
// Get the coordinates and canvas color of the content area as a
// round rectangle (argument pR is for returning the radius of
// the corners).
virtual void GetContentRect(
double * pX, double * pY, double * pW, double * pH,
emColor * pCanvasColor=NULL
) const;
// Get the coordinates and canvas color of the content area as a
// rectangle. If the inner border has round corners, the
// rectangle returned here is smaller than with
// GetContentRoundRect, so that it fits completely into the
// content area.
virtual void GetContentRectUnobscured(
double * pX, double * pY, double * pW, double * pH,
emColor * pCanvasColor=NULL
) const;
// Get the coordinates and canvas color of the unobscured part
// of the content area. Some border types are painting an
// overlay like a shadow at the edges of the content area, after
// PaintContent is called. This does not work for child panels,
// because they are painted after the overlay. Therefore child
// panels should be laid out in the rectangle returned by
// GetContentRectUnobscured. It returns the inner part, which is
// not painted over.
protected:
virtual void Notice(NoticeFlags flags);
virtual bool IsOpaque() const;
virtual void Paint(const emPainter & painter, emColor canvasColor) const;
virtual void LayoutChildren();
// See emPanel. Hint: For painting the content area, please
// overload PaintContent instead of Paint, because with certain
// border types, a shadow is painted over the content area.
virtual bool HasHowTo() const;
virtual emString GetHowTo() const;
// This is about a text describing how to use this panel. If
// HasHowTo()==true, the text returned by GetHowTo() is shown
// very small in the center of the left edge of the border. When
// overloading GetHowTo(), please do not forget to call the
// original version and to include that text at the beginning.
// The default implementation of GetHowTo() returns a preface,
// and optionally a description of the disable state (if
// disabled) and optionally a description of the keyboard focus
// (if focusable). The default implementation of HasHowTo()
// return false, because the default text alone is not so
// helpful, and because the text would disturb some panel types.
virtual void PaintContent(
const emPainter & painter, double x, double y, double w,
double h, emColor canvasColor
) const;
// This can be overloaded for painting the content area. The
// default implementation does nothing. The coordinates x,y,w,h
// are like from GetContentRect, but you could even use the
// coordinates returned by GetContentRoundRect.
virtual bool HasLabel() const;
// Whether this panel has a label. The default implementation
// checks whether at least one of caption, description and icon
// is not empty.
virtual double GetBestLabelTallness() const;
// Get the ideal tallness for the label area. The default
// implementation calculates this for the default implementation
// of PaintLabel.
virtual void PaintLabel(
const emPainter & painter, double x, double y, double w,
double h, emColor color, emColor canvasColor
) const;
// Paint the label. The default implementation paints the
// caption, description and icon. This could be overloaded to
// paint something else for the label.
bool IsLabelInBorder() const;
void SetLabelInBorder(bool labelInBorder);
// Whether to show the label as part of the border. The default
// is true. If a derived class wants to have the label as part
// of the content, it should set false here and call PaintLabel
// itself.
struct TkResources {
TkResources();
~TkResources();
emImage ImgButton;
emImage ImgButtonBorder;
emImage ImgButtonChecked;
emImage ImgButtonPressed;
emImage ImgCheckBox;
emImage ImgCheckBoxPressed;
emImage ImgCustomRectBorder;
emImage ImgDir;
emImage ImgDirUp;
emImage ImgGroupBorder;
emImage ImgGroupInnerBorder;
emImage ImgIOField;
emImage ImgPopupBorder;
emImage ImgRadioBox;
emImage ImgRadioBoxPressed;
emImage ImgSplitter;
emImage ImgSplitterPressed;
emImage ImgTunnel;
};
const TkResources & GetTkResources() const;
// Shared resources used by the toolkit panel implementations.
// This is more or less private stuff - do not use in custom
// classes.
// - - - - - - - - - - Depreciated methods - - - - - - - - - - - - - - -
// The following virtual non-const methods have been replaced by const
// methods (see above). The old versions still exist here with the
// "final" keyword added, so that old overridings will fail to compile.
// If you run into this, please adapt your overridings by adding "const".
public:
virtual void GetContentRoundRect(
double * pX, double * pY, double * pW, double * pH, double * pR,
emColor * pCanvasColor=NULL
) final;
virtual void GetContentRect(
double * pX, double * pY, double * pW, double * pH,
emColor * pCanvasColor=NULL
) final;
virtual void GetContentRectUnobscured(
double * pX, double * pY, double * pW, double * pH,
emColor * pCanvasColor=NULL
) final;
protected:
virtual bool HasHowTo() final;
virtual emString GetHowTo() final;
virtual void PaintContent(
const emPainter & painter, double x, double y, double w,
double h, emColor canvasColor
) final;
virtual bool HasLabel() final;
virtual double GetBestLabelTallness() final;
virtual void PaintLabel(
const emPainter & painter, double x, double y, double w,
double h, emColor color, emColor canvasColor
) final;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
private:
enum DoBorderFunc {
BORDER_FUNC_PAINT,
BORDER_FUNC_SUBSTANCE_ROUND_RECT,
BORDER_FUNC_CONTENT_ROUND_RECT,
BORDER_FUNC_CONTENT_RECT,
BORDER_FUNC_CONTENT_RECT_UNOBSCURED,
BORDER_FUNC_AUX_RECT
};
void DoBorder(
DoBorderFunc func, const emPainter * painter,
emColor canvasColor, double * pX, double * pY, double * pW,
double * pH, double * pR, emColor * pCanvasColor
) const;
enum DoLabelFunc {
LABEL_FUNC_PAINT,
LABEL_FUNC_GET_BEST_TALLNESS
};
void DoLabel(
DoLabelFunc func, const emPainter * painter, double x, double y,
double w, double h, emColor color, emColor canvasColor,
double * pBestTallness
) const;
struct AuxData {
emString PanelName;
double Tallness;
emCrossPtr<emPanel> PanelPointerCache;
};
emRef<emVarModel<TkResources> > TkResVarModel;
emString Caption;
emString Description;
emImage Icon;
AuxData * Aux;
emLook Look;
double MaxIconAreaTallness;
double BorderScaling;
emAlignment LabelAlignment;
emAlignment CaptionAlignment;
emAlignment DescriptionAlignment;
emByte OuterBorder;
emByte InnerBorder;
bool IconAboveCaption;
bool LabelInBorder;
static const char * const HowToPreface;
static const char * const HowToDisabled;
static const char * const HowToFocus;
};
inline const emString & emBorder::GetCaption() const
{
return Caption;
}
inline const emString & emBorder::GetDescription() const
{
return Description;
}
inline const emImage & emBorder::GetIcon() const
{
return Icon;
}
inline emAlignment emBorder::GetLabelAlignment() const
{
return LabelAlignment;
}
inline emAlignment emBorder::GetCaptionAlignment() const
{
return CaptionAlignment;
}
inline emAlignment emBorder::GetDescriptionAlignment() const
{
return DescriptionAlignment;
}
inline bool emBorder::IsIconAboveCaption() const
{
return IconAboveCaption;
}
inline double emBorder::GetMaxIconAreaTallness() const
{
return MaxIconAreaTallness;
}
inline emBorder::OuterBorderType emBorder::GetOuterBorderType() const
{
return (OuterBorderType)OuterBorder;
}
inline emBorder::InnerBorderType emBorder::GetInnerBorderType() const
{
return (InnerBorderType)InnerBorder;
}
inline double emBorder::GetBorderScaling() const
{
return BorderScaling;
}
inline const emLook & emBorder::GetLook() const
{
return Look;
}
inline bool emBorder::HasAux() const
{
return Aux!=NULL;
}
inline bool emBorder::IsLabelInBorder() const
{
return LabelInBorder;
}
inline const emBorder::TkResources & emBorder::GetTkResources() const
{
return TkResVarModel->Var;
}
#endif