ColorPalette: Add new properties "PickMode" and "PickShift" to select when and by which mouse button the color is selected. Some reorganisation of code. Update demo.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@4279 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2015-08-20 21:02:08 +00:00
parent 77c582dda8
commit 7f5584ad24
4 changed files with 182 additions and 53 deletions

View File

@ -52,6 +52,15 @@ uses
type type
TPickMode = (
pmDefault, // Select color at mouse-down, ColorPick event at mouse-up if at same pos
pmImproved, // Select color and ColorPick event at mouse-down
pmContinuous // Select color at mouse-down and mouse-move, ColorPick event at mouse-up
);
TPickShiftEnum = (ssLeft, ssRight, ssMiddle);
TPickShift = set of TPickShiftEnum;
TColorMouseEvent = procedure (Sender: TObject; AColor: TColor; Shift: TShiftState) of object; TColorMouseEvent = procedure (Sender: TObject; AColor: TColor; Shift: TShiftState) of object;
{ TCustomColorPalette } { TCustomColorPalette }
@ -65,7 +74,13 @@ type
FOnColorPick: TColorMouseEvent; FOnColorPick: TColorMouseEvent;
FRows: Integer; FRows: Integer;
FColors: TList; FColors: TList;
MX, MY: integer; FPickedColor: TColor;
FPickMode: TPickMode;
FPickShift: TPickShift;
FMousePt: TPoint;
FMouseIndex: Integer;
FPrevMouseIndex: Integer;
FStoredShift: TShiftState;
function GetColorCount: Integer; function GetColorCount: Integer;
function GetColors(Index: Integer): TColor; function GetColors(Index: Integer): TColor;
procedure SetButtonHeight(const AValue: Integer); procedure SetButtonHeight(const AValue: Integer);
@ -73,17 +88,21 @@ type
procedure SetColors(Index: Integer; const AValue: TColor); procedure SetColors(Index: Integer; const AValue: TColor);
procedure SetCols(AValue: Integer); procedure SetCols(AValue: Integer);
protected protected
procedure MouseDown(Button: TMouseButton; Shift:TShiftState; X, Y:Integer); override;
procedure MouseMove(Shift:TShiftState; X, Y:Integer); override;
procedure MouseUp(Button: TMouseButton; Shift:TShiftState; X, Y:Integer); override;
procedure ColorPick(AColor: TColor; Shift: TShiftState); dynamic; procedure ColorPick(AColor: TColor; Shift: TShiftState); dynamic;
procedure ColorMouseMove(AColor: TColor; Shift: TShiftState); dynamic; procedure ColorMouseMove(AColor: TColor; Shift: TShiftState); dynamic;
procedure DoAddColor(AColor: TColor); virtual; procedure DoAddColor(AColor: TColor); virtual;
procedure DoDeleteColor(AIndex: Integer); virtual; procedure DoDeleteColor(AIndex: Integer); virtual;
function IsCorrectShift(Shift: TShiftState): Boolean;
procedure MouseDown(Button: TMouseButton; Shift:TShiftState; X, Y:Integer); override;
procedure MouseMove(Shift:TShiftState; X, Y:Integer); override;
procedure MouseUp(Button: TMouseButton; Shift:TShiftState; X, Y:Integer); override;
procedure UpdateSize; virtual; procedure UpdateSize; virtual;
property ButtonWidth: Integer read FButtonWidth write SetButtonWidth;
property ButtonHeight: Integer read FButtonHeight write SetButtonHeight;
property ColumnCount: Integer read FCols write SetCols;
property PickMode: TPickMode read FPickMode write FPickMode default pmDefault;
property PickShift: TPickShift read FPickShift write FPickShift default [ssLeft];
public public
PickedColor: TColor;
PickShift: TShiftState;
constructor Create(TheOwner: TComponent); override; constructor Create(TheOwner: TComponent); override;
destructor Destroy; override; destructor Destroy; override;
procedure Paint; override; procedure Paint; override;
@ -93,12 +112,10 @@ type
procedure LoadPalette(const FileName: String); procedure LoadPalette(const FileName: String);
procedure SavePalette(const FileName: String); procedure SavePalette(const FileName: String);
property ButtonWidth: Integer read FButtonWidth write SetButtonWidth;
property ButtonHeight: Integer read FButtonHeight write SetButtonHeight;
property Colors[Index: Integer]: TColor read GetColors write SetColors; property Colors[Index: Integer]: TColor read GetColors write SetColors;
property ColorCount: Integer read GetColorCount; property ColorCount: Integer read GetColorCount;
property ColumnCount: Integer read FCols write SetCols; property PickedColor: TColor read FPickedColor;
property OnColorPick: TColorMouseEvent read FOnColorPick write FOnColorPick; property OnColorPick: TColorMouseEvent read FOnColorPick write FOnColorPick;
property OnColorMouseMove: TColorMouseEvent read FOnColorMouseMove write FOnColorMouseMove; property OnColorMouseMove: TColorMouseEvent read FOnColorMouseMove write FOnColorMouseMove;
@ -123,6 +140,8 @@ type
property Hint; property Hint;
property ParentColor; property ParentColor;
property ParentShowHint; property ParentShowHint;
property PickMode;
property PickShift;
property PopupMenu; property PopupMenu;
property ShowHint; property ShowHint;
property Visible; property Visible;
@ -180,6 +199,7 @@ end;
procedure TCustomColorPalette.SetColors(Index: Integer; const AValue: TColor); procedure TCustomColorPalette.SetColors(Index: Integer; const AValue: TColor);
begin begin
FColors.Items[Index] := Pointer(AValue); FColors.Items[Index] := Pointer(AValue);
Invalidate;
end; end;
procedure TCustomColorPalette.SetCols(AValue: Integer); procedure TCustomColorPalette.SetCols(AValue: Integer);
@ -205,27 +225,49 @@ procedure TCustomColorPalette.MouseDown(Button: TMouseButton;
begin begin
inherited; inherited;
MX := X; FMousePt.X := X;
MY := Y; FMousePt.Y := Y;
X := X div FButtonWidth; X := X div FButtonWidth;
Y := Y div FButtonHeight; Y := Y div FButtonHeight;
if X + Y * FCols < 0 then FMouseIndex := X + Y * FCols;
FPrevMouseIndex := FMouseIndex;
if FMouseIndex < 0 then
Exit; Exit;
if X + Y * FCols < FColors.Count then if (FMouseIndex < FColors.Count) then
begin begin
PickedColor := GetColors(X + Y * FCols); FPickedColor := GetColors(FMouseIndex);
PickShift := Shift; FStoredShift := Shift; // store for usage by pmDefault at MouseUp
if FPickMode <> pmDefault then
ColorPick(FPickedColor, Shift);
end; end;
end; end;
procedure TCustomColorPalette.MouseUp(Button: TMouseButton; procedure TCustomColorPalette.MouseUp(Button: TMouseButton;
Shift: TShiftState; X, Y: Integer); Shift: TShiftState; X, Y: Integer);
begin begin
if (PickedColor <> clNone) and (MX = X) and (MY = Y) then case FPickMode of
ColorPick(PickedColor, PickShift); pmDefault:
if (FMousePt.X = X) and (FMousePt.Y = Y) then
ColorPick(FPickedColor, FStoredShift);
pmImproved, pmContinuous:
begin
X := X div FButtonWidth;
Y := Y div FButtonHeight;
FMouseIndex := X + Y * FCols;
if (FMouseIndex >= 0) and (FMouseIndex < FColors.Count) and
(FMouseIndex <> FPrevMouseIndex) then
begin
FPickedColor := GetColors(FMouseIndex);
ColorPick(FPickedColor, Shift);
end;
end;
end;
FPrevMouseIndex := -1;
inherited; inherited;
end; end;
@ -238,23 +280,44 @@ begin
X := X div FButtonWidth; X := X div FButtonWidth;
Y := Y div FButtonHeight; Y := Y div FButtonHeight;
if X + Y * FCols < 0 then FMouseIndex := X + Y * FCols;
Exit; if (FMouseIndex >= 0) and (FMouseIndex < FColors.Count) and
if X + Y * FCols < FColors.Count then (FMouseIndex <> FPrevMouseIndex) then
begin begin
C := GetColors(X + Y * FCols); C := GetColors(FMouseIndex);
if C <> clNone then ColorMouseMove(C, Shift); if C <> clNone then
ColorMouseMove(C, Shift);
if FPickMode = pmContinuous then begin
FPickedColor := GetColors(FMouseIndex);
ColorPick(FPickedColor, Shift);
end;
end; end;
FPrevMouseIndex := FMouseIndex;
end;
function TCustomColorPalette.IsCorrectShift(Shift: TShiftState): Boolean;
var
ss: TShiftState;
begin
Result := True;
if (ssLeft in FPickShift) and (Classes.ssLeft in Shift) then exit;
if (ssRight in FPickShift) and (Classes.ssRight in Shift) then exit;
if (ssMiddle in FPickShift) and (Classes.ssMiddle in Shift) then exit;
Result := false;
end; end;
procedure TCustomColorPalette.ColorPick(AColor: TColor; Shift: TShiftState); procedure TCustomColorPalette.ColorPick(AColor: TColor; Shift: TShiftState);
begin begin
if Assigned(FOnColorPick) then FOnColorPick(Self, AColor, Shift); if IsCorrectShift(Shift) and Assigned(FOnColorPick) then
FOnColorPick(Self, AColor, Shift);
end; end;
procedure TCustomColorPalette.ColorMouseMove(AColor: TColor; Shift: TShiftState); procedure TCustomColorPalette.ColorMouseMove(AColor: TColor; Shift: TShiftState);
begin begin
if Assigned(FOnColorMouseMove) then FOnColorMouseMove(Self, AColor, Shift); if IsCorrectShift(Shift) and Assigned(FOnColorMouseMove) then
FOnColorMouseMove(Self, AColor, Shift);
end; end;
constructor TCustomColorPalette.Create(TheOwner: TComponent); constructor TCustomColorPalette.Create(TheOwner: TComponent);
@ -264,6 +327,8 @@ begin
FColors := TList.Create; FColors := TList.Create;
FButtonWidth := 12; FButtonWidth := 12;
FButtonHeight := 12; FButtonHeight := 12;
FPrevMouseIndex := -1;
FPickShift := [ssLeft];
ControlStyle := ControlStyle + [csFixedWidth, csFixedHeight]; ControlStyle := ControlStyle + [csFixedWidth, csFixedHeight];
FCols := 8; FCols := 8;

View File

@ -9,6 +9,7 @@
<Title Value="project1"/> <Title Value="project1"/>
<ResourceType Value="res"/> <ResourceType Value="res"/>
<UseXPManifest Value="True"/> <UseXPManifest Value="True"/>
<Icon Value="0"/>
</General> </General>
<i18n> <i18n>
<EnableI18N LFM="False"/> <EnableI18N LFM="False"/>

View File

@ -1,7 +1,7 @@
object MainForm: TMainForm object MainForm: TMainForm
Left = 522 Left = 358
Height = 502 Height = 502
Top = 211 Top = 179
Width = 455 Width = 455
Caption = 'MainForm' Caption = 'MainForm'
ClientHeight = 502 ClientHeight = 502
@ -17,8 +17,10 @@ object MainForm: TMainForm
ButtonWidth = 16 ButtonWidth = 16
ButtonHeight = 16 ButtonHeight = 16
ColumnCount = 8 ColumnCount = 8
PickShift = [ssLeft, ssMiddle]
PopupMenu = PalettePopupMenu PopupMenu = PalettePopupMenu
OnColorPick = ColorPaletteColorPick OnColorPick = ColorPaletteColorPick
OnDblClick = ColorPaletteDblClick
OnMouseDown = ColorPaletteMouseDown OnMouseDown = ColorPaletteMouseDown
end end
object Panel1: TPanel object Panel1: TPanel
@ -35,7 +37,7 @@ object MainForm: TMainForm
Left = 10 Left = 10
Height = 29 Height = 29
Top = 13 Top = 13
Width = 69 Width = 63
end end
object LblInfo: TLabel object LblInfo: TLabel
Left = 12 Left = 12
@ -50,11 +52,11 @@ object MainForm: TMainForm
WordWrap = True WordWrap = True
end end
object BtnEditColor: TButton object BtnEditColor: TButton
Left = 91 Left = 83
Height = 19 Height = 19
Hint = 'Edit current color' Hint = 'Edit current color'
Top = 13 Top = 13
Width = 56 Width = 64
Caption = 'Edit' Caption = 'Edit'
OnClick = BtnEditColorClick OnClick = BtnEditColorClick
TabOrder = 0 TabOrder = 0
@ -62,7 +64,7 @@ object MainForm: TMainForm
object BtnLoadRndPalette: TButton object BtnLoadRndPalette: TButton
Left = 10 Left = 10
Height = 25 Height = 25
Top = 188 Top = 190
Width = 137 Width = 137
Caption = 'Load random palette' Caption = 'Load random palette'
Enabled = False Enabled = False
@ -99,7 +101,7 @@ object MainForm: TMainForm
object BtnDeleteCurrent: TButton object BtnDeleteCurrent: TButton
Left = 10 Left = 10
Height = 25 Height = 25
Top = 314 Top = 311
Width = 137 Width = 137
Caption = 'Delete color #0' Caption = 'Delete color #0'
OnClick = BtnDeleteCurrentClick OnClick = BtnDeleteCurrentClick
@ -108,10 +110,9 @@ object MainForm: TMainForm
object BtnLoadDefaultPal1: TButton object BtnLoadDefaultPal1: TButton
Left = 10 Left = 10
Height = 25 Height = 25
Top = 227 Top = 228
Width = 137 Width = 137
Caption = 'Save palette...' Caption = 'Save palette...'
OnClick = BtnLoadDefaultPal1Click
TabOrder = 6 TabOrder = 6
end end
object LblPaletteSize: TLabel object LblPaletteSize: TLabel
@ -140,6 +141,32 @@ object MainForm: TMainForm
Caption = 'Column count:' Caption = 'Column count:'
ParentColor = False ParentColor = False
end end
object CbPickMode: TComboBox
Left = 12
Height = 23
Hint = 'Defines when the picked color is determined and when the OnPickColor event is generated:'#13#10#13#10'pmDefault: '#13#10' Color selection at mouse-down, OnPickColor event at mouse-up if at same location'#13#10#13#10'pmImproved:'#13#10' Color selection and OnPickColor event at mouse-down'#13#10#13#10'pmContinuous:'#13#10' Color selection and OnPickColor event while mouse is down'
Top = 376
Width = 135
ItemHeight = 15
ItemIndex = 0
Items.Strings = (
'default'
'improved'
'continuous'
)
OnSelect = CbPickModeSelect
Style = csDropDownList
TabOrder = 8
Text = 'default'
end
object LblPickMode: TLabel
Left = 12
Height = 15
Top = 355
Width = 56
Caption = 'Pick mode'
ParentColor = False
end
end end
object Bevel1: TBevel object Bevel1: TBevel
Left = 160 Left = 160

View File

@ -23,6 +23,8 @@ type
BtnEditColor: TButton; BtnEditColor: TButton;
ColorDialog: TColorDialog; ColorDialog: TColorDialog;
ColorPalette: TColorPalette; ColorPalette: TColorPalette;
CbPickMode: TComboBox;
LblPickMode: TLabel;
LblPaletteSize: TLabel; LblPaletteSize: TLabel;
EdColCount: TSpinEdit; EdColCount: TSpinEdit;
Label2: TLabel; Label2: TLabel;
@ -33,14 +35,15 @@ type
Panel1: TPanel; Panel1: TPanel;
SaveDialog: TSaveDialog; SaveDialog: TSaveDialog;
curColor: TShape; curColor: TShape;
procedure BtnDeleteCurrentClick(Sender: TObject);
procedure BtnLoadDefaultPal1Click(Sender: TObject);
procedure BtnLoadRndPaletteClick(Sender: TObject);
procedure BtnCreateRndPaletteClick(Sender: TObject);
procedure BtnAddColorClick(Sender: TObject); procedure BtnAddColorClick(Sender: TObject);
procedure BtnCreateRndPaletteClick(Sender: TObject);
procedure BtnDeleteCurrentClick(Sender: TObject);
procedure BtnLoadDefaultPalClick(Sender: TObject); procedure BtnLoadDefaultPalClick(Sender: TObject);
procedure BtnLoadRndPaletteClick(Sender: TObject);
procedure CbPickModeSelect(Sender: TObject);
procedure ColorPaletteColorPick(Sender: TObject; AColor: TColor; procedure ColorPaletteColorPick(Sender: TObject; AColor: TColor;
Shift: TShiftState); Shift: TShiftState);
procedure ColorPaletteDblClick(Sender: TObject);
procedure ColorPaletteMouseDown(Sender: TObject; Button: TMouseButton; procedure ColorPaletteMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer); Shift: TShiftState; X, Y: Integer);
procedure EdColCountChange(Sender: TObject); procedure EdColCountChange(Sender: TObject);
@ -53,6 +56,7 @@ type
curIndex: integer; curIndex: integer;
procedure EditCurColor; procedure EditCurColor;
procedure SetLabel(ATitle: string; AColor: TColor); procedure SetLabel(ATitle: string; AColor: TColor);
procedure UpdateColorCountInfo;
procedure UpdatePalette; procedure UpdatePalette;
public public
{ public declarations } { public declarations }
@ -72,7 +76,7 @@ procedure TMainForm.BtnAddColorClick(Sender: TObject);
begin begin
if ColorDialog.Execute then if ColorDialog.Execute then
ColorPalette.AddColor(ColorDialog.Color); ColorPalette.AddColor(ColorDialog.Color);
LblPaletteSize.caption := IntToStr(ColorPalette.ColorCount) + ' colors available'; LblPaletteSize.Caption := IntToStr(ColorPalette.ColorCount) + ' colors available';
end; end;
procedure TMainForm.BtnCreateRndPaletteClick(Sender: TObject); procedure TMainForm.BtnCreateRndPaletteClick(Sender: TObject);
@ -108,6 +112,9 @@ begin
DeleteColor(curIndex); DeleteColor(curIndex);
if curIndex = ColorCount then dec(curIndex); if curIndex = ColorCount then dec(curIndex);
curColor.Brush.Color := Colors[curIndex] ; curColor.Brush.Color := Colors[curIndex] ;
if Colors[curIndex] = clNone then
curColor.Brush.Style := bsClear else
curColor.Brush.Style := bsSolid;
LblPaletteSize.Caption := IntToStr(ColorCount) + ' colors available'; LblPaletteSize.Caption := IntToStr(ColorCount) + ' colors available';
SetLabel('Current', ColorPalette.Colors[curIndex]); SetLabel('Current', ColorPalette.Colors[curIndex]);
end; end;
@ -126,15 +133,6 @@ begin
EdColCount.Value := ColorPalette.ColumnCount; EdColCount.Value := ColorPalette.ColumnCount;
end; end;
procedure TMainForm.BtnLoadDefaultPal1Click(Sender: TObject);
begin
Showmessage('???');
SaveDialog.FileName := 'random_palette.pal';
SaveDialog.InitialDir := ExtractFileDir(ParamStr(0));
if SaveDialog.Execute then
ColorPalette.SavePalette(SaveDialog.FileName);
end;
procedure TMainForm.BtnLoadRndPaletteClick(Sender: TObject); procedure TMainForm.BtnLoadRndPaletteClick(Sender: TObject);
begin begin
ColorPalette.LoadPalette('random_palette.pal'); ColorPalette.LoadPalette('random_palette.pal');
@ -150,13 +148,41 @@ begin
UpdatePalette; UpdatePalette;
end; end;
procedure TMainForm.CbPickModeSelect(Sender: TObject);
begin
ColorPalette.PickMode := TPickMode(CbPickMode.ItemIndex);
end;
procedure TMainForm.ColorPaletteColorPick(Sender: TObject; AColor: TColor; procedure TMainForm.ColorPaletteColorPick(Sender: TObject; AColor: TColor;
Shift: TShiftState); Shift: TShiftState);
begin begin
curColor.Brush.Color := ColorPalette.PickedColor; curColor.Brush.Color := ColorPalette.PickedColor;
if ColorPalette.Colors[curIndex] = clNone then
curColor.Brush.Style := bsClear else
curColor.Brush.Style := bsSolid;
SetLabel('PickedColor', ColorPalette.PickedColor); SetLabel('PickedColor', ColorPalette.PickedColor);
end; end;
procedure TMainForm.ColorPaletteDblClick(Sender: TObject);
begin
with ColorDialog do
begin
Color := ColorPalette.Colors[curIndex];
if Execute then
begin
ColorPalette.Colors[curIndex] := Color;
curColor.Brush.Color := Color;
curColor.Brush.Style := bsSolid;
SetLabel('Current', Color);
with BtnEditColor do
begin
Caption := 'Edit';
Hint := 'Edit current color';
end;
end;
end;
end;
procedure TMainForm.ColorPaletteMouseDown(Sender: TObject; Button: TMouseButton; procedure TMainForm.ColorPaletteMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer); Shift: TShiftState; X, Y: Integer);
begin begin
@ -180,12 +206,14 @@ begin
with ColorDialog do with ColorDialog do
begin begin
Color := curColor.Brush.color; Color := curColor.Brush.color;
if Execute then if Execute then begin
curColor.Brush.Color := Color; curColor.Brush.Color := Color;
curColor.Brush.Style := bsSolid;
end;
end; end;
if curColor.Brush.Color <> ColorPalette.PickedColor then if curColor.Brush.Color <> ColorPalette.PickedColor then
begin begin
BtnEditColor.caption := 'Update'; BtnEditColor.caption := 'Update >';
BtnEditColor.hint := 'Update palette'; BtnEditColor.hint := 'Update palette';
SetLabel('New color', curColor.Brush.Color); SetLabel('New color', curColor.Brush.Color);
end; end;
@ -195,9 +223,13 @@ procedure TMainForm.FormCreate(Sender: TObject);
begin begin
Caption := 'TColorPalette Demo'; Caption := 'TColorPalette Demo';
curIndex := 0; curIndex := 0;
curColor.brush.color := ColorPalette.Colors[0]; curColor.Brush.Color := ColorPalette.Colors[0];
SetLabel('Current', ColorPalette.Colors[curIndex]); SetLabel('Current', ColorPalette.Colors[curIndex]);
LblPaletteSize.Caption := IntToStr(ColorPalette.ColorCount) + ' colors available'; UpdateColorCountInfo;
{ ColorPalette.PickShift must contain ssRight in order to be able to select
colors for the context menu. Use object inspector, or use this code: }
ColorPalette.PickShift := [ssLeft, ssRight];
end; end;
procedure TMainForm.MnuDeletePickedColorClick(Sender: TObject); procedure TMainForm.MnuDeletePickedColorClick(Sender: TObject);
@ -220,10 +252,14 @@ begin
); );
end; end;
procedure TMainForm.UpdateColorCountInfo;
begin
LblPaletteSize.Caption := IntToStr(ColorPalette.ColorCount) + ' colors available';
end;
procedure TMainForm.UpdatePalette; procedure TMainForm.UpdatePalette;
begin begin
ColorPalette.Colors[curIndex] := curColor.Brush.Color; ColorPalette.Colors[curIndex] := curColor.Brush.Color;
ColorPalette.Refresh;
SetLabel('Current', ColorPalette.Colors[curIndex]); SetLabel('Current', ColorPalette.Colors[curIndex]);
with BtnEditColor do with BtnEditColor do
begin begin