Creating a Custom Hot Zone Style
- 5 minutes to read
A Splitter control (a TcxCustomSplitter descendant) provides a hot zone facility. Hot zones are control elements that can be clicked to collapse the splitter (set its bound control to the minimum size) and subsequently re-open it.
The style of the hot zone used is specified by the HotZone property of TcxCustomSplitter descendants. This property can hold a TcxHotZoneStyle descendant object representing the hot zone style. There are four descendants shipped – TcxSimpleStyle, TcxMediaPlayer8Style, TcxMediaPlayer9Style and TcxXPTaskBarStyle. However, you can also create your own descendant if you need a custom hot zone style. This topic describes how to perform this.
If you need to create a custom hot zone style, derive an object from the TcxHotZoneStyle. The table below lists the members that need to be overridden or must be used when implementing your object’s functionality.
Member | Description |
---|---|
Changed | This method tells the owning splitter control to invalidate its hot zone. Call this method whenever changing settings which affect the hot zone’s appearance. |
SplitterDirection | Gets a value indicating the orientation of the splitter. Use this method to determine whether the splitter is oriented vertically or horizontally. |
CalculateHotZoneRect | This method is called whenever the bounding rectangle of the hot zone needs to be obtained (for instance, when passing the bounding rectangle of the hot zone to the DrawHotZone method). As implemented in the TcxHotZoneStyle class, this method calculates the bounding rectangle according to the SizePercent property value. Override this method if you need to correct the hot zone’s bounding rectangle. |
DrawHotZone | This method is called whenever the hot zone needs to be repainted. Override it to paint the hot zone as desired. |
The following code declares a TcxHotZoneStyle descendant. This descendant paints the hot zone as a button. The button is flat in normal state. If it is hot-tracked or pressed, it is painted raised and lowered respectively. The descendant created provides a ButtonColor property to specify the color of the button. When the property value changes, the Changed method is called to invalidate the hot zone.
The descendant also overrides the CalculateHotZoneRect method. This is used to decrease the width of the hot zone if it is vertically oriented. If the hot zone is horizontally oriented, the height is decreased. The SplitterDirection method is used to determine the hot zone orientation.
TcxCustomButtonHotZoneStyle = class(TcxHotZoneStyle)
private
FButtonColor: TColor;
procedure SetButtonColor(Value: TColor);
protected
function CalculateHotZoneRect(const ABounds: TRect): TRect; override;
function DrawHotZone(ACanvas: TcxCanvas; const ARect: TRect; const AHighlighted, AClicked: Boolean): TRect; override;
procedure DrawBackground(ACanvas: TcxCanvas; const ARect: TRect; const AHighlighted, AClicked: Boolean); override;
public
constructor Create(AOwner: TcxCustomSplitter); override;
published
property ButtonColor: TColor read FButtonColor write SetButtonColor;
property SizePercent;
end;
// ...
procedure TcxCustomButtonHotZoneStyle.SetButtonColor(Value: TColor);
begin
if Value = FButtonColor then Exit;
FButtonColor := Value;
Changed;
end;
constructor TcxCustomButtonHotZoneStyle.Create(AOwner: TcxCustomSplitter);
begin
inherited Create(AOwner);
FButtonColor := clBtnFace;
end;
function TcxCustomButtonHotZoneStyle.CalculateHotZoneRect(const ABounds: TRect): TRect;
begin
// obtaining the default bounding rectangle of the hot zone
Result := inherited CalculateHotZoneRect(ABounds);
if (SplitterDirection = cxsdLeftToRight) or (SplitterDirection = cxsdRightToLeft) then
begin
// splitter is vertically oriented, its width is decreased
Inc(Result.Left);
Dec(Result.Right);
end
else
// splitter is horizontally oriented, its height is decreased
Inc(Result.Top);
Dec(Result.Bottom);
begin
end;
end;
function TcxCustomButtonHotZoneStyle.DrawHotZone(ACanvas: TcxCanvas; const ARect: TRect; const AHighlighted, AClicked: Boolean): TRect;
var
ATopLeftBorderColor, ABottomRightBorderColor: TColor;
ABounds: TRect;
begin
// specifying button's border colors
if AHighlighted then
begin
ATopLeftBorderColor := clBtnHighlight;
ABottomRightBorderColor := clBtnShadow;
end;
if AClicked then
begin
ATopLeftBorderColor := clBtnShadow;
ABottomRightBorderColor := clBtnHighlight;
end;
if not (AHighlighted or AClicked) then
begin
ATopLeftBorderColor := clBtnShadow;
ABottomRightBorderColor := clBtnShadow;
end;
ABounds := CalculateHotZoneRect(ARect);
// painting the borders
ACanvas.FrameRect(ABounds, ATopLeftBorderColor, 1, [bLeft, bTop]);
ACanvas.FrameRect(ABounds, ABottomRightBorderColor, 1, [bBottom, bRight]);
// filling the button's client area
ACanvas.Brush.Color := FButtonColor;
ACanvas.Brush.Style := bsSolid;
ABounds.TopLeft := Point(ABounds.Left + 1, ABounds.Top + 1);
ABounds.BottomRight := Point(ABounds.Right - 1, ABounds.Bottom - 1);
ACanvas.FillRect(ABounds);
end;
procedure TcxCustomButtonHotZoneStyle.DrawBackground(ACanvas: TcxCanvas; const ARect: TRect; const AHighlighted, AClicked: Boolean);
begin
ACanvas.Brush.Color := clYellow;
ACanvas.FillRect(ARect);
end;
After the code is written, you can assign this hot zone style to a splitter control using the following code lines.
cxSplitter1.HotZoneStyleClass := TcxCustomButtonHotZoneStyle;
(cxSplitter1.HotZone as TcxCustomButtonHotZoneStyle).ButtonColor := clMoneyGreen;
The image below shows the appearance the hot zone will have in the normal, highlighted and clicked states, respectively.
Note that you can also make use of the new hot zone style at design time. To implement this, perform the following steps:
Move the TcxCustomButtonHotZoneStyle class declaration to the cxSplitter.pas unit.
Add the following line to the initialization section of the unit:
GetRegisteredHotZoneStyles.Register(TcxCustomButtonHotZoneStyle, 'Button');
- Add the following line to the finalization section of the unit:
GetRegisteredHotZoneStyles.UnRegister(TcxCustomButtonHotZoneStyle);
- Recompile the package containing the unit.
After doing this, you can choose the Button hot zone style from the HotZone combo box at design time.
If the Button style is selected, you can expand the HotZone property to access the published properties of the TcxCustomButtonHotZoneStyle class. These are the ButtonColor and SizePercent properties. You can change them to change the color of the button and its size relative to the splitter control.