📄 bsbuttongroup.pas
字号:
while (ShouldContinue(Delay)) do
begin
StartTime := GetCurrentTime;
ElapsedTime := StartTime - CurrentTime;
if ElapsedTime < Delay then
Sleep(Delay - ElapsedTime);
CurrentTime := StartTime;
FDragImageList.HideDragImage;
ScrollPosChanged(ScrollCode, 0{ Ignored});
UpdateWindow(Handle);
FDragImageList.ShowDragImage;
end;
end;
function TbsSkinButtonGroup.TargetIndexAt(const X, Y: Integer): Integer;
var
ButtonRect: TRect;
LastRect: TRect;
begin
Result := IndexOfButtonAt(X, Y);
if Result = -1 then
begin
LastRect := GetButtonRect(Items.Count);
if (Y >= LastRect.Bottom) then
Result := Items.Count
else if (Y >= LastRect.Top) then
if (bsgboFullSize in FButtonOptions) or (X >= LastRect.Left) then
Result := Items.Count; { After the last item }
end;
if (Result > -1) and (Result < Items.Count) then
begin
{ Before the index, or after it? }
ButtonRect := GetButtonRect(Result);
if CalcButtonsPerRow = 1 then
begin
if Y > (ButtonRect.Top + (ButtonRect.Bottom - ButtonRect.Top) div 2) then
Inc(Result); { Insert above the item below it (after the index) }
end
else
if X > (ButtonRect.Left + (ButtonRect.Right - ButtonRect.Left) div 2) then
Inc(Result)
end;
end;
procedure TbsSkinButtonGroup.DoMouseLeave;
begin
if Assigned(FOnMouseLeave) then
FOnMouseLeave(Self);
end;
procedure TbsSkinButtonGroup.CNKeydown(var Message: TWMKeyDown);
var
IncAmount: Integer;
procedure FixIncAmount(const StartValue: Integer);
begin
{ Keep it within the bounds }
if StartValue + IncAmount >= FButtonItems.Count then
IncAmount := FButtonItems.Count - StartValue - 1
else if StartValue + IncAmount < 0 then
IncAmount := 0 - StartValue;
end;
var
NewIndex: Integer;
begin
IncAmount := 0;
if Message.CharCode = VK_DOWN then
IncAmount := CalcButtonsPerRow
else if Message.CharCode = VK_UP then
IncAmount := -1*CalcButtonsPerRow
else if Message.CharCode = VK_LEFT then
IncAmount := -1
else if Message.CharCode = VK_RIGHT then
IncAmount := 1
else if Message.CharCode = VK_NEXT then
IncAmount := CalcRowsSeen
else if Message.CharCode = VK_PRIOR then
IncAmount := -1*CalcRowsSeen
else if Message.CharCode = VK_HOME then
begin
if bsgboGroupStyle in ButtonOptions then
IncAmount := -1*FItemIndex
else
IncAmount := -1*FFocusIndex;
end
else if Message.CharCode = VK_END then
begin
if bsgboGroupStyle in ButtonOptions then
IncAmount := FButtonItems.Count - FItemIndex
else
IncAmount := FButtonItems.Count - FFocusIndex;
end
else if (Message.CharCode = VK_RETURN) or (Message.CharCode = VK_SPACE) then
begin
if (bsgboGroupStyle in ButtonOptions) and (FItemIndex <> -1) then
DoItemClicked(FItemIndex) { Click the current item index }
else if (bsgboGroupStyle in ButtonOptions) and
(FFocusIndex >= 0) and (FFocusIndex < FButtonItems.Count) then
DoItemClicked(FFocusIndex) { Click the focused index }
else
inherited;
end
else
inherited;
if IncAmount <> 0 then
begin
if bsgboGroupStyle in ButtonOptions then
FixIncAmount(FItemIndex)
else
FixIncAmount(FFocusIndex);
if IncAmount <> 0 then
begin
{ Do the actual scrolling work }
if bsgboGroupStyle in ButtonOptions then
begin
NewIndex := ItemIndex + IncAmount;
ScrollIntoView(NewIndex);
ItemIndex := NewIndex;
end
else
begin
NewIndex := FFocusIndex+ IncAmount;
ScrollIntoView(NewIndex);
UpdateButton(FFocusIndex);
FFocusIndex := NewIndex;
UpdateButton(FFocusIndex);
end;
end;
end;
end;
procedure TbsSkinButtonGroup.WMKillFocus(var Message: TWMKillFocus);
begin
inherited;
UpdateButton(FFocusIndex)
end;
procedure TbsSkinButtonGroup.WMSetFocus(var Message: TWMSetFocus);
begin
inherited;
if (FFocusIndex = -1) and (FButtonItems.Count > 0) then
FFocusIndex := 0; { Focus the first item }
UpdateButton(FFocusIndex)
end;
procedure TbsSkinButtonGroup.ScrollIntoView(const Index: Integer);
var
RowsSeen, ButtonsPerRow, HiddenCount, VisibleCount: Integer;
begin
if (Index >= 0) and (Index < FButtonItems.Count) then
begin
ButtonsPerRow := CalcButtonsPerRow;
HiddenCount := FHiddenItems*ButtonsPerRow;
if Index < HiddenCount then
begin
{ We have to scroll above to get the item insight }
while (Index <= HiddenCount) and (FHiddenItems > 0) do
begin
ScrollPosChanged(scLineUp, 0);
HiddenCount := FHiddenItems*ButtonsPerRow;
end;
end
else
begin
RowsSeen := CalcRowsSeen;
VisibleCount := RowsSeen*ButtonsPerRow;
{ Do we have to scroll down to see the item? }
while Index >= (HiddenCount + VisibleCount) do
begin
ScrollPosChanged(scLineDown, 0);
HiddenCount := FHiddenItems*ButtonsPerRow;
end;
end;
end;
end;
procedure TbsSkinButtonGroup.CMHintShow(var Message: TCMHintShow);
var
ItemIndex: Integer;
begin
Message.Result := 1; { Don't show the hint }
if Message.HintInfo.HintControl = Self then
begin
ItemIndex := IndexOfButtonAt(Message.HintInfo.CursorPos.X, Message.HintInfo.CursorPos.Y);
if (ItemIndex >= 0) and (ItemIndex < Items.Count) then
begin
{ Only show the hint if the item's text is truncated }
if Items[ItemIndex].Hint <> '' then
Message.HintInfo.HintStr := Items[ItemIndex].Hint
else
begin
// corbin - finish..
// Canvas.TextRect(TextRect, Items[ItemIndex].Caption, [tfEndEllipsis]);
Message.HintInfo.HintStr := Items[ItemIndex].Caption;
end;
if (Items[ItemIndex].ActionLink <> nil) then
Items[ItemIndex].ActionLink.DoShowHint(Message.HintInfo.HintStr);
Message.HintInfo.CursorRect := GetButtonRect(ItemIndex);
Message.Result := 0; { Show the hint }
end;
end;
end;
procedure TbsSkinButtonGroup.Assign(Source: TPersistent);
begin
if Source is TbsSkinButtonGroup then
begin
Items := TbsSkinButtonGroup(Source).Items;
ButtonHeight := TbsSkinButtonGroup(Source).ButtonHeight;
ButtonWidth := TbsSkinButtonGroup(Source).ButtonWidth;
ButtonOptions := TbsSkinButtonGroup(Source).ButtonOptions;
end
else
inherited;
end;
procedure TbsSkinButtonGroup.SetInsertionPoints(const InsertionIndex: Integer);
begin
if FInsertTop <> InsertionIndex then
begin
RemoveInsertionPoints;
if CalcButtonsPerRow = 1 then
begin
FInsertTop := InsertionIndex;
FInsertBottom := InsertionIndex - 1;
end
else
begin
{ More than one button per row, so use Left/Right separators }
FInsertLeft := InsertionIndex;
FInsertRight := InsertionIndex - 1;
end;
UpdateButton(FInsertTop);
UpdateButton(FInsertLeft);
UpdateButton(FInsertBottom);
UpdateButton(FInsertRight);
UpdateWindow(Handle);
end;
end;
procedure TbsSkinButtonGroup.DoEndDrag(Target: TObject; X, Y: Integer);
begin
inherited;
FDragIndex := -1;
RemoveInsertionPoints;
end;
procedure TbsSkinButtonGroup.SetDragIndex(const Value: Integer);
begin
FDragIndex := Value;
FDragStarted := True;
end;
function TbsSkinButtonGroup.DoMouseWheelDown(Shift: TShiftState;
MousePos: TPoint): Boolean;
begin
Result := inherited DoMouseWheelDown(Shift, MousePos);
if not Result then
begin
UpdateButton(FHotIndex);
FHotIndex := -1;
Result := True;
if (FScrollBarMax > 0) and (Shift = []) then
ScrollPosChanged(scLineDown, 0)
else if (FScrollBarMax > 0) and (ssCtrl in Shift) then
ScrollPosChanged(scPageDown, 0)
{ else if ssShift in Shift then
begin
NextButton := GetNextButton(SelectedItem, True);
if NextButton <> nil then
SelectedItem := NextButton;
end;
}
end;
end;
function TbsSkinButtonGroup.DoMouseWheelUp(Shift: TShiftState;
MousePos: TPoint): Boolean;
begin
Result := inherited DoMouseWheelUp(Shift, MousePos);
if not Result then
begin
UpdateButton(FHotIndex);
FHotIndex := -1;
Result := True;
if (FScrollBarMax > 0) and (Shift = []) then
ScrollPosChanged(scLineUp, 0)
else if (FScrollBarMax > 0) and (ssCtrl in Shift) then
ScrollPosChanged(scPageUp, 0)
{ else if ssShift in Shift then
begin
NextButton := GetNextButton(SelectedItem, False);
if NextButton <> nil then
SelectedItem := NextButton;
end;
}
end;
end;
{ TbsGrpButtonItem }
function TbsGrpButtonItem.GetButtonGroup: TbsSkinButtonGroup;
begin
Result := Collection.ButtonGroup;
end;
function TbsGrpButtonItem.GetCollection: TbsGrpButtonItems;
begin
Result := TbsGrpButtonItems(inherited Collection);
end;
function TbsGrpButtonItem.GetNotifyTarget: TComponent;
begin
Result := TComponent(ButtonGroup);
end;
procedure TbsGrpButtonItem.ScrollIntoView;
begin
TbsGrpButtonItems(Collection).FButtonGroup.ScrollIntoView(Index);
end;
procedure TbsGrpButtonItem.SetCollection(const Value: TbsGrpButtonItems);
begin
inherited Collection := Value;
end;
{ TbsGrpButtonItems }
function TbsGrpButtonItems.Add: TbsGrpButtonItem;
begin
Result := TbsGrpButtonItem(inherited Add);
end;
function TbsGrpButtonItems.AddItem(Item: TbsGrpButtonItem;
Index: Integer): TbsGrpButtonItem;
begin
if (Item = nil) and (FButtonGroup <> nil) then
Result := FButtonGroup.CreateButton
else
Result := Item;
if Assigned(Result) then
begin
Result.Collection := Self;
if Index < 0 then
Index := Count - 1;
Result.Index := Index;
end;
end;
procedure TbsGrpButtonItems.BeginUpdate;
begin
if UpdateCount = 0 then
if FButtonGroup.ItemIndex <> -1 then
FOriginalID := Items[FButtonGroup.ItemIndex].ID
else
FOriginalID := -1;
inherited;
end;
constructor TbsGrpButtonItems.Create(const ButtonGroup: TbsSkinButtonGroup);
begin
if ButtonGroup <> nil then
inherited Create(ButtonGroup.GetButtonClass)
else
inherited Create(TbsGrpButtonItem);
FButtonGroup := ButtonGroup;
FOriginalID := -1;
end;
function TbsGrpButtonItems.GetItem(Index: Integer): TbsGrpButtonItem;
begin
Result := TbsGrpButtonItem(inherited GetItem(Index));
end;
function TbsGrpButtonItems.GetOwner: TPersistent;
begin
Result := FButtonGroup;
end;
function TbsGrpButtonItems.Insert(Index: Integer): TbsGrpButtonItem;
begin
Result := AddItem(nil, Index);
end;
procedure TbsGrpButtonItems.SetItem(Index: Integer; const Value: TbsGrpButtonItem);
begin
inherited SetItem(Index, Value);
end;
procedure TbsGrpButtonItems.Update(Item: TCollectionItem);
var
AItem: TCollectionItem;
begin
if (UpdateCount = 0) and (not FButtonGroup.FIgnoreUpdate) then
begin
if Item <> nil then
FButtonGroup.UpdateButton(Item.Index)
else
begin
if (FOriginalID <> -1) then
AItem := FindItemID(FOriginalID)
else
AItem := nil;
if AItem = nil then
begin
FButtonGroup.FItemIndex := -1;
FButtonGroup.FFocusIndex := -1;
end
else if bsgboGroupStyle in FButtonGroup.ButtonOptions then
FButtonGroup.FItemIndex := AItem.Index;
FButtonGroup.Resize;
FButtonGroup.UpdateAllButtons;
end;
end;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -