📄 jvqlistcomb.pas
字号:
//=== { TJvImageItems } ======================================================
constructor TJvImageItems.Create(AOwner: TPersistent);
begin
inherited Create(AOwner, TJvImageItem);
end;
function TJvImageItems.Add: TJvImageItem;
begin
Result := TJvImageItem(inherited Add);
while FStrings.Count < Count do
FStrings.Add('');
end;
function TJvImageItems.Add(const Text: string): Integer;
var
Item: TJvImageItem;
begin
Item := Add;
Item.Text := Text;
Result := Item.Index;
end;
function TJvImageItems.Insert(Index: Integer): TJvImageItem;
begin
Result := TJvImageItem(inherited Insert(Index));;
end;
procedure TJvImageItems.Insert(Index: Integer; const Text: string);
begin
Insert(Index).Text := Text;
end;
procedure TJvImageItems.Move(CurIndex, NewIndex: Integer);
var
Item, NewItem: TJvImageItem;
ItemText: string;
ItemObject: TObject;
begin
if NewIndex < 0 then
NewIndex := 0;
if NewIndex > Count then
NewIndex := Count;
if CurIndex <> NewIndex then
begin
BeginUpdate;
try
while FStrings.Count < Count do
FStrings.Add('');
{ Save object data }
ItemText := FStrings.Strings[CurIndex];
ItemObject := FStrings.Objects[CurIndex];
Item := TJvImageItem.Create(nil);
try
Item.FNoTextAssign := True;
Item.Assign(Items[CurIndex]);
{ Delete item }
Delete(CurIndex);
{ Add new item on NewIndex }
if NewIndex < Count then
NewItem := Insert(NewIndex)
else
NewItem := Add;
{ restore data except property Text which is linked to FStrings[] }
NewItem.FNoTextAssign := True;
try
NewItem.Assign(Item);
finally
NewItem.FNoTextAssign := False;
end;
{ restore property Text }
NewItem.Text := ItemText;
while FStrings.Count < Count do
FStrings.Add('');
FStrings.Objects[NewIndex] := ItemObject;
finally
Item.Free;
end;
finally
EndUpdate;
end;
Changed;
end;
end;
procedure TJvImageItems.Assign(Source: TPersistent);
var
I: Integer;
begin
if Source is TJvImageItems then
begin
BeginUpdate;
try
Clear;
for I := 0 to TJvImageItems(Source).Count - 1 do
Add.Assign(TJvImageItems(Source)[I]);
finally
EndUpdate;
end;
end
else
if Source is TStrings then
begin
BeginUpdate;
try
Clear;
for I := 0 to TStrings(Source).Count - 1 do
Add.Text := TStrings(Source)[I];
if FStrings <> nil then
FStrings.Assign(Source);
finally
EndUpdate;
end;
end
else
inherited Assign(Source);
end;
function TJvImageItems.GetItems(Index: Integer): TJvImageItem;
begin
Result := TJvImageItem(inherited Items[Index])
end;
procedure TJvImageItems.SetItems(Index: Integer; const Value: TJvImageItem);
begin
inherited Items[Index] := Value;
end;
procedure TJvImageItems.Update(Item: TCollectionItem);
var
W: TPersistent;
Obj: IJvResetItemHeight;
begin
if UpdateCount <> 0 then
Exit;
inherited Update(Item);
W := GetOwner;
if Supports(W, IJvResetItemHeight, Obj) then
Obj.ResetItemHeight
else
if W is TWinControl then
TWinControl(W).Invalidate;
end;
//=== { TJvImageComboBox } ===================================================
constructor TJvImageComboBox.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FItems := TJvImageItems.Create(Self);
FItems.FStrings := inherited Items;
FImageWidth := 0;
FImageHeight := 0;
FImageList := nil;
FDefaultIndent := 0;
FButtonFrame := False;
Style := csOwnerDrawVariable;
Color := clWindow;
FColorHighlight := clHighlight;
FColorHighlightText := clHighlightText;
FChangeLink := TChangeLink.Create;
FChangeLink.OnChange := ImageListChange;
end;
destructor TJvImageComboBox.Destroy;
begin
FItems.Free;
FChangeLink.Free;
inherited Destroy;
end;
procedure TJvImageComboBox.ImageListChange(Sender: TObject);
begin
// Invalidate;
end;
procedure TJvImageComboBox.SetImageList(Value: TCustomImageList);
begin
if FImageList <> Value then
begin
if FImageList <> nil then
FImageList.UnRegisterChanges(FChangeLink);
FImageList := Value;
if FImageList <> nil then
FImageList.RegisterChanges(FChangeLink);
{ if Assigned(FImageList) then
begin
FWidth := FImageList.Width;
FHeight := FImageList.Height;
end
else
begin
FWidth := 0;
FHeight := 0;
end; }
ResetItemHeight;
RecreateWnd;
end;
end;
procedure TJvImageComboBox.CreateWnd;
begin
inherited CreateWnd;
SetDroppedWidth(FDroppedWidth);
end;
procedure TJvImageComboBox.RecreateWnd;
begin
inherited RecreateWnd;
SetDroppedWidth(FDroppedWidth);
end;
procedure TJvImageComboBox.Notification(AComponent: TComponent; Operation: TOperation);
begin
inherited Notification(AComponent, Operation);
if (Operation = opRemove) and (AComponent = FImageList) then
FImageList := nil;
end;
function TJvImageComboBox.DrawItem(Index: Integer; R: TRect; State: TOwnerDrawState): Boolean;
var
Offset, Tmp: Integer;
TmpCol: TColor;
TmpR, OrigR: TRect;
SavedColor: TColor;
begin
Result := True; // Handled
if csDestroying in ComponentState then
Exit;
if odSelected in State then
begin
Canvas.Brush.Color := FColorHighlight;
Canvas.Font.Color := FColorHighlightText;
end;
SavedColor := Canvas.Font.Color;
Canvas.Font.Assign(Items[Index].Font);
if odSelected in State then
begin
Canvas.Brush.Color := FColorHighlight;
Canvas.Font.Color := FColorHighlightText;
end;
if State <> [] then
Canvas.Font.Color := SavedColor;
OrigR := R;
with Canvas do
begin
TmpCol := Brush.Color;
Brush.Color := Color;
FillRect(R);
Brush.Color := TmpCol;
if not (odComboBoxEdit in State) or IndentSelected then // (p3) don't draw indentation for edit item unless explicitly told to do so
R.Left := R.Left + Items[Index].Indent;
if not Items[Index].Glyph.Empty then
begin
Offset := ((R.Bottom - R.Top) - GetImageHeight(Index)) div 2;
Canvas.Draw(R.Left + 2, R.Top + Offset, Items[Index].Glyph);
if FButtonFrame then
begin
TmpR := Rect(R.Left, R.Top, R.Left + FImageList.Width + 4, R.Top + FImageList.Height + 4);
DrawBtnFrame(Canvas, FButtonStyle, Color, not ((odFocused in State) and
not (odComboBoxEdit in State)), TmpR);
end;
Inc(R.Left, GetImageWidth(Index) + 8);
OrigR.Left := R.Left;
end
else
if Assigned(FImageList) then
begin
Tmp := Items[Index].ImageIndex;
// R.Left := R.Left + Items[Index].Indent;
Offset := ((R.Bottom - R.Top) - GetImageHeight(Index)) div 2;
FImageList.Draw(Canvas, R.Left + 2, R.Top + Offset, Tmp);
if FButtonFrame then
begin
TmpR := Rect(R.Left, R.Top, R.Left + FImageList.Width + 4, R.Top + FImageList.Height + 4);
DrawBtnFrame(Canvas, FButtonStyle, Color, not ((Tmp in [0..FImageList.Count - 1]) and (odFocused in State) and
not (odComboBoxEdit in State)), TmpR);
end;
Inc(R.Left, GetImageWidth(Index) + 8);
OrigR.Left := R.Left;
end;
R.Right := R.Left + TextWidth(Items[Index].Text);
InflateRect(R, 2, -1);
if Length(Items[Index].Text) > 0 then
begin
Inc(R.Right,2);
FillRect(R);
Inc(R.Left, 2);
DrawText(Canvas, Items[Index].Text, Length(Items[Index].Text), R,
DT_SINGLELINE or DT_NOPREFIX or DT_VCENTER);
Dec(R.Left, 2);
if (odSelected in State) and (Color <> FColorHighlight) then
DrawFocusRect(R);
end
else
begin
FillRect(OrigR);
if (odSelected in State) and (Color <> FColorHighlight) then
DrawFocusRect(OrigR);
end;
end;
end;
procedure TJvImageComboBox.MeasureItem(Control: TWinControl; Item: QClxListBoxItemH;
var Height, Width: Integer);
begin
Height := Max(GetItemHeight(Font) + 4, FImageList.Height + (Ord(ButtonFrame) * 4));
end;
procedure TJvImageComboBox.SetParent(const AParent: TWidgetControl);
begin
inherited SetParent(AParent);
ResetItemHeight;
end;
procedure TJvImageComboBox.SetColorHighlight(Value: TColor);
begin
if FColorHighlight <> Value then
begin
FColorHighlight := Value;
Invalidate;
end;
end;
procedure TJvImageComboBox.SetColorHighlightText(Value: TColor);
begin
if FColorHighlightText <> Value then
begin
FColorHighlightText := Value;
Invalidate;
end;
end;
function TJvImageComboBox.GetDroppedWidth: Integer;
begin
HandleNeeded;
Result := QWidget_width(QCombobox_listBox(Handle));
end;
procedure TJvImageComboBox.SetDroppedWidth(Value: Integer);
begin
HandleNeeded;
QWidget_setFixedWidth(QCombobox_listBox(Handle), Value);
FDroppedWidth := GetDroppedWidth;
end;
procedure TJvImageComboBox.FontChanged;
begin
inherited FontChanged;
if not (csRecreating in ControlState) then
ResetItemHeight;
end;
procedure TJvImageComboBox.ResetItemHeight;
var
MaxImageHeight: Integer;
I: Integer;
begin
MaxImageHeight := GetImageHeight(-1);
for I := 0 to FItems.Count-1 do
begin
if GetImageHeight(I) > MaxImageHeight then
MaxImageHeight := GetImageHeight(I);
end;
ItemHeight := Max(GetItemHeight(Font) + 4, MaxImageHeight + Ord(ButtonFrame) * 4);
end;
procedure TJvImageComboBox.Change;
begin
if Assigned(FOnChange) then
FOnChange(Self);
end;
procedure TJvImageComboBox.EnabledChanged;
const
EnableColors: array [Boolean] of TColor = (clBtnFace, clWindow);
begin
inherited EnabledChanged;
Color := EnableColors[Enabled];
end;
procedure TJvImageComboBox.SetDefaultIndent(const Value: Integer);
begin
if FDefaultIndent <> Value then
begin
FDefaultIndent := Value;
Invalidate;
end;
end;
procedure TJvImageComboBox.SetItems(const Value: TJvImageItems);
begin
FItems.Assign(Value);
FItems.Update(nil);
end;
procedure TJvImageComboBox.SetIndentSelected(const Value: Boolean);
begin
if FIndentSelected <> Value then
begin
FIndentSelected := Value;
Invalidate;
end;
end;
function TJvImageComboBox.GetImageWidth(Index: Integer): Integer;
begin
if (Index > -1) and not Items[Index].Glyph.Empty then
Result := Items[Index].Glyph.Width
else
if Assigned(FImageList) then
Result := FImageList.Width
else
Result := FImageWidth;
end;
function TJvImageComboBox.GetImageHeight(Index: Integer): Integer;
begin
if (Index > -1) and not Items[Index].Glyph.Empty then
Result := Items[Index].Glyph.Height
else
if Assigned(FImageList) then
Result := FImageList.Height
else
Result := FImageHeight;
end;
//=== { TJvImageListBox } ====================================================
constructor TJvImageListBox.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
// ControlStyle := ControlStyle + [csAcceptsControls];
SetBounds(0, 0, 121, 97);
FItems := TJvImageItems.Create(Self);
FItems.FStrings := inherited Items;
Color := clWindow;
FColorHighlight := clHighlight;
FColorHighlightText := clHighlightText;
FImageWidth := 0;
FImageHeight := 0;
FAlignment := taLeftJustify;
FButtonFrame := False;
Style := lbOwnerDrawFixed;
FChangeLink := TChangeLink.Create;
FChangeLink.OnChange := ImageListChange;
end;
destructor TJvImageListBox.Destroy;
begin
FItems.Free;
FChangeLink.Free;
inherited Destroy;
end;
procedure TJvImageListBox.ImageListChange;
begin
// Invalidate;
end;
procedure TJvImageListBox.SetImageList(Value: TCustomImageList);
begin
if FImageList <> Value then
begin
if FImageList <> nil then
FImageList.UnRegisterChanges(FChangeLink);
FImageList := Value;
if FImageList <> nil then
FImageList.RegisterChanges(FChangeLink);
{ if Assigned(FImageList) then
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -