|
@@ -15,36 +15,66 @@ type
|
|
|
TBCComboBox = class(TCustomControl)
|
|
TBCComboBox = class(TCustomControl)
|
|
|
private
|
|
private
|
|
|
FButton: TBCButton;
|
|
FButton: TBCButton;
|
|
|
|
|
+ FDropDownBorderSize: integer;
|
|
|
|
|
+ FDropDownCount: integer;
|
|
|
|
|
+ FDropDownFontColor: TColor;
|
|
|
|
|
+ FDropDownFontHighlight: TColor;
|
|
|
|
|
+ FDropDownHighlight: TColor;
|
|
|
FForm: TForm;
|
|
FForm: TForm;
|
|
|
|
|
+ FFormHideDate: TDateTime;
|
|
|
FHoverItem: integer;
|
|
FHoverItem: integer;
|
|
|
|
|
+ FItemHeight: integer;
|
|
|
FListBox: TListBox;
|
|
FListBox: TListBox;
|
|
|
|
|
+ FDropDownBorderColor: TColor;
|
|
|
|
|
+ FOnDrawItem: TDrawItemEvent;
|
|
|
|
|
+ FOnChange: TNotifyEvent;
|
|
|
procedure ButtonClick(Sender: TObject);
|
|
procedure ButtonClick(Sender: TObject);
|
|
|
|
|
+ procedure FormDeactivate(Sender: TObject);
|
|
|
|
|
+ procedure FormHide(Sender: TObject);
|
|
|
|
|
+ function GetItemText: string;
|
|
|
|
|
+ function GetDropDownBorderStyle: TBorderStyle;
|
|
|
|
|
+ function GetDropDownColor: TColor;
|
|
|
function GetItemIndex: integer;
|
|
function GetItemIndex: integer;
|
|
|
function GetItems: TStrings;
|
|
function GetItems: TStrings;
|
|
|
- procedure ListBoxClick(Sender: TObject);
|
|
|
|
|
|
|
+ procedure ListBoxMouseUp({%H-}Sender: TObject; {%H-}Button: TMouseButton;
|
|
|
|
|
+ {%H-}Shift: TShiftState; {%H-}X, {%H-}Y: Integer);
|
|
|
procedure ListBoxMouseLeave(Sender: TObject);
|
|
procedure ListBoxMouseLeave(Sender: TObject);
|
|
|
- procedure ListBoxMouseMove(Sender: TObject; Shift: TShiftState; X,
|
|
|
|
|
|
|
+ procedure ListBoxMouseMove(Sender: TObject; {%H-}Shift: TShiftState; X,
|
|
|
Y: Integer);
|
|
Y: Integer);
|
|
|
- procedure ListBoxSelectionChange(Sender: TObject; User: boolean);
|
|
|
|
|
|
|
+ procedure ListBoxSelectionChange(Sender: TObject; {%H-}User: boolean);
|
|
|
|
|
+ procedure ListBoxDrawItem(Control: TWinControl; Index: Integer;
|
|
|
|
|
+ ARect: TRect; State: TOwnerDrawState);
|
|
|
|
|
+ procedure SetDropDownBorderStyle(AValue: TBorderStyle);
|
|
|
|
|
+ procedure SetDropDownColor(AValue: TColor);
|
|
|
procedure SetItemIndex(AValue: integer);
|
|
procedure SetItemIndex(AValue: integer);
|
|
|
procedure SetItems(AValue: TStrings);
|
|
procedure SetItems(AValue: TStrings);
|
|
|
- protected
|
|
|
|
|
- procedure UpdateCaption;
|
|
|
|
|
public
|
|
public
|
|
|
constructor Create(AOwner: TComponent); override;
|
|
constructor Create(AOwner: TComponent); override;
|
|
|
property HoverItem: integer read FHoverItem;
|
|
property HoverItem: integer read FHoverItem;
|
|
|
property Button: TBCButton read FButton write FButton;
|
|
property Button: TBCButton read FButton write FButton;
|
|
|
property ListBox: TListBox read FListBox write FListBox;
|
|
property ListBox: TListBox read FListBox write FListBox;
|
|
|
|
|
+ property Text: string read GetItemText;
|
|
|
|
|
+ published
|
|
|
property Items: TStrings read GetItems write SetItems;
|
|
property Items: TStrings read GetItems write SetItems;
|
|
|
property ItemIndex: integer read GetItemIndex write SetItemIndex;
|
|
property ItemIndex: integer read GetItemIndex write SetItemIndex;
|
|
|
- published
|
|
|
|
|
-
|
|
|
|
|
|
|
+ property ItemHeight: integer read FItemHeight write FItemHeight default 0;
|
|
|
|
|
+ property DropDownBorderColor: TColor read FDropDownBorderColor write FDropDownBorderColor default clWindowText;
|
|
|
|
|
+ property DropDownBorderSize: integer read FDropDownBorderSize write FDropDownBorderSize default 1;
|
|
|
|
|
+ property DropDownColor: TColor read GetDropDownColor write SetDropDownColor default clWindow;
|
|
|
|
|
+ property DropDownFontColor: TColor read FDropDownFontColor write FDropDownFontColor default clWindowText;
|
|
|
|
|
+ property DropDownCount: integer read FDropDownCount write FDropDownCount default 8;
|
|
|
|
|
+ property DropDownHighlight: TColor read FDropDownHighlight write FDropDownHighlight default clHighlight;
|
|
|
|
|
+ property DropDownFontHighlight: TColor read FDropDownFontHighlight write FDropDownFontHighlight default clHighlightText;
|
|
|
|
|
+ property OnDrawItem: TDrawItemEvent read FOnDrawItem write FOnDrawItem;
|
|
|
|
|
+ property OnChange: TNotifyEvent read FOnChange write FOnChange;
|
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
procedure Register;
|
|
procedure Register;
|
|
|
|
|
|
|
|
implementation
|
|
implementation
|
|
|
|
|
|
|
|
|
|
+uses math;
|
|
|
|
|
+
|
|
|
procedure Register;
|
|
procedure Register;
|
|
|
begin
|
|
begin
|
|
|
RegisterComponents('BGRA Controls', [TBCComboBox]);
|
|
RegisterComponents('BGRA Controls', [TBCComboBox]);
|
|
@@ -53,8 +83,10 @@ end;
|
|
|
{ TBCComboBox }
|
|
{ TBCComboBox }
|
|
|
|
|
|
|
|
procedure TBCComboBox.ButtonClick(Sender: TObject);
|
|
procedure TBCComboBox.ButtonClick(Sender: TObject);
|
|
|
|
|
+const MinDelayReopen = 500/(1000*60*60*24);
|
|
|
var
|
|
var
|
|
|
p: TPoint;
|
|
p: TPoint;
|
|
|
|
|
+ h: Integer;
|
|
|
begin
|
|
begin
|
|
|
if FForm=nil then
|
|
if FForm=nil then
|
|
|
begin
|
|
begin
|
|
@@ -63,24 +95,66 @@ begin
|
|
|
FForm.ShowInTaskBar:= stNever;
|
|
FForm.ShowInTaskBar:= stNever;
|
|
|
FForm.FormStyle := fsStayOnTop;
|
|
FForm.FormStyle := fsStayOnTop;
|
|
|
FForm.BorderStyle := bsNone;
|
|
FForm.BorderStyle := bsNone;
|
|
|
- FForm.AutoSize := True;
|
|
|
|
|
- p := ControlToScreen(Point(FButton.Left, FButton.Top + FButton.Height));
|
|
|
|
|
- FForm.Left := p.X;
|
|
|
|
|
- FForm.Top := p.Y;
|
|
|
|
|
|
|
+ FForm.OnDeactivate:= FormDeactivate;
|
|
|
|
|
+ FForm.OnHide:=FormHide;
|
|
|
FListBox.Parent := FForm;
|
|
FListBox.Parent := FForm;
|
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
if FForm.Visible then
|
|
if FForm.Visible then
|
|
|
FForm.Visible := false
|
|
FForm.Visible := false
|
|
|
else
|
|
else
|
|
|
|
|
+ if Now > FFormHideDate+MinDelayReopen then
|
|
|
begin
|
|
begin
|
|
|
- FForm.Constraints.MinWidth := FButton.Width;
|
|
|
|
|
|
|
+ p := ControlToScreen(Point(FButton.Left, FButton.Top + FButton.Height));
|
|
|
|
|
+ FForm.Left := p.X;
|
|
|
|
|
+ FForm.Top := p.Y;
|
|
|
|
|
+ FForm.Color := FDropDownBorderColor;
|
|
|
|
|
+ FListBox.Font.Name := Button.StateNormal.FontEx.Name;
|
|
|
|
|
+ FListBox.Font.Style := Button.StateNormal.FontEx.Style;
|
|
|
|
|
+ FListBox.Font.Height := Button.StateNormal.FontEx.Height;
|
|
|
|
|
+ FListBox.Canvas.Font.Assign(FListBox.Font);
|
|
|
|
|
+ if Assigned(FOnDrawItem) and (FItemHeight <> 0) then
|
|
|
|
|
+ h := FItemHeight else h := FListBox.Canvas.GetTextHeight('Hg');
|
|
|
|
|
+ FListBox.ItemHeight := h;
|
|
|
|
|
+ FForm.ClientWidth := FButton.Width;
|
|
|
|
|
+ FForm.ClientHeight := (h+6)*min(Items.Count, FDropDownCount) + 2*FDropDownBorderSize;
|
|
|
|
|
+ FListBox.SetBounds(FDropDownBorderSize,FDropDownBorderSize,
|
|
|
|
|
+ FForm.ClientWidth-2*FDropDownBorderSize,
|
|
|
|
|
+ FForm.ClientHeight-2*FDropDownBorderSize);
|
|
|
FForm.Visible := True;
|
|
FForm.Visible := True;
|
|
|
if FListBox.CanSetFocus then
|
|
if FListBox.CanSetFocus then
|
|
|
FListBox.SetFocus;
|
|
FListBox.SetFocus;
|
|
|
end;
|
|
end;
|
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
+procedure TBCComboBox.FormDeactivate(Sender: TObject);
|
|
|
|
|
+begin
|
|
|
|
|
+ FForm.Visible:= false;
|
|
|
|
|
+end;
|
|
|
|
|
+
|
|
|
|
|
+procedure TBCComboBox.FormHide(Sender: TObject);
|
|
|
|
|
+begin
|
|
|
|
|
+ FFormHideDate := Now;
|
|
|
|
|
+end;
|
|
|
|
|
+
|
|
|
|
|
+function TBCComboBox.GetItemText: string;
|
|
|
|
|
+begin
|
|
|
|
|
+ if FListBox.ItemIndex<>-1 then
|
|
|
|
|
+ result := FListBox.Items[FListBox.ItemIndex]
|
|
|
|
|
+ else
|
|
|
|
|
+ result := '';
|
|
|
|
|
+end;
|
|
|
|
|
+
|
|
|
|
|
+function TBCComboBox.GetDropDownBorderStyle: TBorderStyle;
|
|
|
|
|
+begin
|
|
|
|
|
+ result := FListBox.BorderStyle;
|
|
|
|
|
+end;
|
|
|
|
|
+
|
|
|
|
|
+function TBCComboBox.GetDropDownColor: TColor;
|
|
|
|
|
+begin
|
|
|
|
|
+ result := FListBox.Color;
|
|
|
|
|
+end;
|
|
|
|
|
+
|
|
|
function TBCComboBox.GetItemIndex: integer;
|
|
function TBCComboBox.GetItemIndex: integer;
|
|
|
begin
|
|
begin
|
|
|
result := FListBox.ItemIndex;
|
|
result := FListBox.ItemIndex;
|
|
@@ -91,9 +165,11 @@ begin
|
|
|
Result := FListBox.Items;
|
|
Result := FListBox.Items;
|
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
-procedure TBCComboBox.ListBoxClick(Sender: TObject);
|
|
|
|
|
|
|
+procedure TBCComboBox.ListBoxMouseUp(Sender: TObject; Button: TMouseButton;
|
|
|
|
|
+ Shift: TShiftState; X, Y: Integer);
|
|
|
begin
|
|
begin
|
|
|
FForm.Visible := false;
|
|
FForm.Visible := false;
|
|
|
|
|
+ FFormHideDate := 0;
|
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
procedure TBCComboBox.ListBoxMouseLeave(Sender: TObject);
|
|
procedure TBCComboBox.ListBoxMouseLeave(Sender: TObject);
|
|
@@ -112,13 +188,55 @@ begin
|
|
|
if TempItem <> FHoverItem then
|
|
if TempItem <> FHoverItem then
|
|
|
begin
|
|
begin
|
|
|
FHoverItem := TempItem;
|
|
FHoverItem := TempItem;
|
|
|
|
|
+ if (FHoverItem<>-1) and ([ssLeft,ssRight]*Shift <> []) then
|
|
|
|
|
+ FListBox.ItemIndex := FHoverItem;
|
|
|
FListBox.Repaint;
|
|
FListBox.Repaint;
|
|
|
end;
|
|
end;
|
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
procedure TBCComboBox.ListBoxSelectionChange(Sender: TObject; User: boolean);
|
|
procedure TBCComboBox.ListBoxSelectionChange(Sender: TObject; User: boolean);
|
|
|
begin
|
|
begin
|
|
|
- UpdateCaption;
|
|
|
|
|
|
|
+ Button.Caption := GetItemText;
|
|
|
|
|
+ if User and Assigned(FOnChange) then FOnChange(self);
|
|
|
|
|
+end;
|
|
|
|
|
+
|
|
|
|
|
+procedure TBCComboBox.ListBoxDrawItem(Control: TWinControl; Index: Integer;
|
|
|
|
|
+ ARect: TRect; State: TOwnerDrawState);
|
|
|
|
|
+var
|
|
|
|
|
+ aCanvas: TCanvas;
|
|
|
|
|
+begin
|
|
|
|
|
+ if Assigned(FOnDrawItem) then
|
|
|
|
|
+ begin
|
|
|
|
|
+ FOnDrawItem(Control, Index, ARect, State);
|
|
|
|
|
+ exit;
|
|
|
|
|
+ end;
|
|
|
|
|
+
|
|
|
|
|
+ aCanvas := TListBox(Control).Canvas;
|
|
|
|
|
+ if Index = HoverItem then
|
|
|
|
|
+ begin
|
|
|
|
|
+ aCanvas.Brush.Color := DropDownHighlight;
|
|
|
|
|
+ aCanvas.Font.Color := DropDownFontHighlight;
|
|
|
|
|
+ end
|
|
|
|
|
+ else
|
|
|
|
|
+ begin
|
|
|
|
|
+ aCanvas.Brush.Color := DropDownColor;
|
|
|
|
|
+ aCanvas.Font.Color := DropDownFontColor;
|
|
|
|
|
+ end;
|
|
|
|
|
+ aCanvas.Pen.Style := psClear;
|
|
|
|
|
+ aCanvas.FillRect(ARect);
|
|
|
|
|
+ aCanvas.TextRect(ARect, ARect.Left+4, ARect.Top +
|
|
|
|
|
+ (ARect.Height - aCanvas.GetTextHeight(Items[Index])) div 2,
|
|
|
|
|
+ Items[Index]);
|
|
|
|
|
+end;
|
|
|
|
|
+
|
|
|
|
|
+procedure TBCComboBox.SetDropDownBorderStyle(AValue: TBorderStyle);
|
|
|
|
|
+begin
|
|
|
|
|
+ FListBox.BorderStyle:= AValue;
|
|
|
|
|
+end;
|
|
|
|
|
+
|
|
|
|
|
+procedure TBCComboBox.SetDropDownColor(AValue: TColor);
|
|
|
|
|
+begin
|
|
|
|
|
+ FListBox.Color := AValue;
|
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
procedure TBCComboBox.SetItemIndex(AValue: integer);
|
|
procedure TBCComboBox.SetItemIndex(AValue: integer);
|
|
@@ -131,14 +249,6 @@ begin
|
|
|
Items := AValue;
|
|
Items := AValue;
|
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
-procedure TBCComboBox.UpdateCaption;
|
|
|
|
|
-begin
|
|
|
|
|
- if FListBox.ItemIndex<>-1 then
|
|
|
|
|
- FButton.Caption := FListBox.Items[FListBox.ItemIndex]
|
|
|
|
|
- else
|
|
|
|
|
- FButton.Caption := '';
|
|
|
|
|
-end;
|
|
|
|
|
-
|
|
|
|
|
constructor TBCComboBox.Create(AOwner: TComponent);
|
|
constructor TBCComboBox.Create(AOwner: TComponent);
|
|
|
begin
|
|
begin
|
|
|
inherited Create(AOwner);
|
|
inherited Create(AOwner);
|
|
@@ -149,14 +259,24 @@ begin
|
|
|
FButton.DropDownArrow := True;
|
|
FButton.DropDownArrow := True;
|
|
|
|
|
|
|
|
FListBox := TListBox.Create(FForm);
|
|
FListBox := TListBox.Create(FForm);
|
|
|
- FListBox.Align := alClient;
|
|
|
|
|
|
|
+ FListBox.Anchors := [akTop, akLeft, akRight, akBottom];
|
|
|
FListBox.Parent := FForm;
|
|
FListBox.Parent := FForm;
|
|
|
- FListBox.BorderStyle := bsNone;
|
|
|
|
|
- FListBox.OnClick := ListBoxClick;
|
|
|
|
|
|
|
+ FListBox.BorderStyle:= bsNone;
|
|
|
FListBox.OnSelectionChange := ListBoxSelectionChange;
|
|
FListBox.OnSelectionChange := ListBoxSelectionChange;
|
|
|
FListBox.OnMouseLeave:=ListBoxMouseLeave;
|
|
FListBox.OnMouseLeave:=ListBoxMouseLeave;
|
|
|
FListBox.OnMouseMove:=ListBoxMouseMove;
|
|
FListBox.OnMouseMove:=ListBoxMouseMove;
|
|
|
|
|
+ FListBox.OnMouseUp:= ListBoxMouseUp;
|
|
|
|
|
+ FListBox.Style := lbOwnerDrawFixed;
|
|
|
|
|
+ FListBox.OnDrawItem:= ListBoxDrawItem;
|
|
|
|
|
+ FListBox.Options := []; // do not draw focus rect
|
|
|
FHoverItem := -1;
|
|
FHoverItem := -1;
|
|
|
|
|
+
|
|
|
|
|
+ FDropDownBorderSize := 1;
|
|
|
|
|
+ DropDownColor:= clWindow;
|
|
|
|
|
+ FDropDownCount := 8;
|
|
|
|
|
+ FDropDownFontColor:= clWindowText;
|
|
|
|
|
+ FDropDownHighlight:= clHighlight;
|
|
|
|
|
+ FDropDownFontHighlight:= clHighlightText;
|
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
end.
|
|
end.
|