Skip to content

Commit 031239e

Browse files
committed
Update color picker to use ImageBoxZoomPanel
1 parent 1ea0f21 commit 031239e

File tree

3 files changed

+156
-136
lines changed

3 files changed

+156
-136
lines changed

Source/ide/simba.ide_colorpicker.pas

Lines changed: 145 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -10,110 +10,120 @@
1010
interface
1111

1212
uses
13-
classes, sysutils, forms, controls, graphics, dialogs, extctrls, stdctrls,
14-
simba.component_imageboxzoom, simba.base, simba.vartype_box;
13+
Classes, SysUtils, Forms, Controls, Graphics, ExtCtrls,
14+
simba.base,
15+
simba.ide_events,
16+
simba.component_imageboxzoom;
1517

1618
type
17-
TSimbaColorPickerHint = class(THintWindow)
18-
protected
19-
procedure Paint; override;
20-
public
21-
Zoom: TSimbaImageBoxZoom;
22-
Info: TLabel;
23-
24-
constructor Create(AOwner: TComponent); override;
25-
end;
26-
2719
TSimbaColorPicker = class(TObject)
28-
protected
20+
private
2921
FForm: TForm;
30-
FColor: TColor;
31-
FPoint: TPoint;
32-
FHint: TSimbaColorPickerHint;
22+
FHint: THintWindow;
3323
FImage: TImage;
3424
FPicked: Boolean;
3525
FImageX, FImageY: Integer;
36-
FWindow: TWindowHandle;
37-
38-
procedure FormClosed(Sender: TObject; var CloseAction: TCloseAction);
39-
procedure HintKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
26+
FPoint: TPoint;
27+
FColor: TColor;
28+
FWindowSelection: TWindowHandle;
4029

41-
procedure ImageMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
42-
procedure ImageMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
30+
procedure DoFormClosed(Sender: TObject; var CloseAction: TCloseAction);
31+
procedure DoHintKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
32+
procedure DoImageMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
33+
procedure DoImageMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
4334
public
44-
function Pick(out X, Y: Integer; out Color: TColor): Boolean;
35+
constructor Create;
36+
destructor Destroy; override;
4537

46-
constructor Create(Window: TWindowHandle); reintroduce;
38+
procedure Pick;
4739
end;
4840

49-
function ShowColorPicker(Window: TWindowHandle; out X, Y: Integer; out Color: TColor): Boolean;
41+
var
42+
SimbaColorPicker: TSimbaColorPicker;
5043

5144
implementation
5245

5346
uses
47+
ATCanvasPrimitives,
5448
LCLType,
49+
simba.initializations,
50+
simba.dialog,
5551
simba.image,
52+
simba.colormath,
53+
simba.ide_maintoolbar,
54+
simba.ide_vars,
5655
simba.vartype_windowhandle,
57-
simba.form_colorpickhistory,
58-
simba.colormath;
56+
simba.vartype_box,
57+
simba.component_theme,
58+
simba.form_colorpickhistory;
5959

60-
function ShowColorPicker(Window: TWindowHandle; out X, Y: Integer; out Color: TColor): Boolean;
61-
begin
62-
with TSimbaColorPicker.Create(Window) do
63-
try
64-
Result := Pick(X, Y, Color);
65-
if Result then
66-
begin
67-
SimbaColorPickHistoryForm.Add(TPoint.Create(X, Y), Color, True);
68-
SimbaColorPickHistoryForm.MakeVisible();
69-
end;
70-
finally
71-
Free();
60+
type
61+
TSimbaColorPickerHint = class(THintWindow)
62+
protected
63+
function DoHintTextMeasure(Sender: TObject): String;
64+
function DoHintText(Sender: TObject; AColor: TColor; X, Y: Integer): String;
65+
66+
procedure Paint; override;
67+
public
68+
Zoom: TSimbaImageBoxZoomPanel;
69+
70+
constructor Create(AOwner: TComponent); override;
7271
end;
72+
73+
function TSimbaColorPickerHint.DoHintTextMeasure(Sender: TObject): String;
74+
begin
75+
Result := 'Position: 12345, 12345';
76+
end;
77+
78+
function TSimbaColorPickerHint.DoHintText(Sender: TObject; AColor: TColor; X, Y: Integer): String;
79+
begin
80+
Result := 'Color: ' + ColorToStr(AColor) + LineEnding + 'Position: ' + IntToStr(X) + ', ' + IntToStr(Y);
7381
end;
7482

7583
procedure TSimbaColorPickerHint.Paint;
7684
begin
77-
Canvas.Pen.Color := clBlack;
78-
Canvas.Brush.Color := clForm;
79-
Canvas.Rectangle(ClientRect);
85+
inherited Paint;
8086

81-
inherited Paint();
87+
Canvas.Pen.Color := ColorBlendHalf(SimbaComponentTheme.ColorFrame, SimbaComponentTheme.ColorLine);
88+
Canvas.Frame(ClientRect);
8289
end;
8390

8491
constructor TSimbaColorPickerHint.Create(AOwner: TComponent);
8592
begin
8693
inherited Create(AOwner);
8794

95+
Color := SimbaComponentTheme.ColorFrame;
96+
Font.Color := SimbaComponentTheme.ColorFont;
97+
8898
BorderStyle := bsNone;
8999
AutoSize := True;
90100

91-
Zoom := TSimbaImageBoxZoom.Create(Self);
101+
Zoom := TSimbaImageBoxZoomPanel.Create(Self);
92102
Zoom.Parent := Self;
93-
Zoom.Align := alLeft;
94-
Zoom.SetZoom(4, 5);
103+
Zoom.Align := alClient;
104+
Zoom.OnGetTextMeasure := @DoHintTextMeasure;
105+
Zoom.OnGetText := @DoHintText;
95106
Zoom.BorderSpacing.Around := 10;
96-
97-
Info := TLabel.Create(Self);
98-
Info.Parent := Self;
99-
Info.Font.Color := clBlack;
100-
Info.BorderSpacing.Right := 10;
101-
Info.AnchorToNeighbour(akLeft, 10, Zoom);
102-
Info.AnchorVerticalCenterTo(Zoom);
107+
Zoom.FrameColor := ColorBlendHalf(SimbaComponentTheme.ColorFrame, SimbaComponentTheme.ColorLine);
103108
end;
104109

105-
procedure TSimbaColorPicker.FormClosed(Sender: TObject; var CloseAction: TCloseAction);
110+
procedure TSimbaColorPicker.DoFormClosed(Sender: TObject; var CloseAction: TCloseAction);
106111
begin
107112
if FPicked then
108113
begin
109-
FPoint := FWindow.GetRelativeCursorPos();
110-
FColor := FImage.Picture.Bitmap.Canvas.Pixels[FImageX, FImageY];
114+
DebugLn([EDebugLn.FOCUS], 'Color picked: %s at (%d, %d)', [ColorToStr(FColor), FPoint.X, FPoint.Y]);
115+
116+
SimbaColorPickHistoryForm.Add(FPoint, FColor, True);
117+
SimbaColorPickHistoryForm.MakeVisible();
111118
end;
112119

113-
CloseAction := caFree;
120+
FHint.Close();
121+
FImage.Picture.Clear(); // Free up mem
122+
123+
CloseAction := caHide;
114124
end;
115125

116-
procedure TSimbaColorPicker.HintKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
126+
procedure TSimbaColorPicker.DoHintKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
117127
begin
118128
case Key of
119129
VK_UP: Mouse.CursorPos := Mouse.CursorPos + TPoint.Create(0, -1);
@@ -132,101 +142,116 @@ procedure TSimbaColorPicker.HintKeyDown(Sender: TObject; var Key: Word; Shift: T
132142
Key := VK_UNKNOWN;
133143
end;
134144

135-
procedure TSimbaColorPicker.ImageMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
145+
procedure TSimbaColorPicker.DoImageMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
136146
begin
137147
FImageX := X;
138148
FImageY := Y;
139149

140-
FPoint := FWindow.GetRelativeCursorPos();
141-
150+
FPoint := FWindowSelection.GetRelativeCursorPos();
151+
FColor := FImage.Picture.Bitmap.Canvas.Pixels[X, Y];
142152
with FImage.ClientToScreen(TPoint.Create(X + 25, Y - (FHint.Height div 2))) do
143153
begin
144154
FHint.Left := X;
145155
FHint.Top := Y;
146156
end;
147157

148-
FHint.Zoom.Move(TImage(Sender).Canvas, X, Y);
149-
FHint.Info.Caption := 'Color: ' + ColorToStr(FImage.Picture.Bitmap.Canvas.Pixels[X, Y]) + LineEnding +
150-
'Position: ' + IntToStr(FPoint.X) + ', ' + IntToStr(FPoint.Y);
158+
TSimbaColorPickerHint(FHint).Zoom.Move(TImage(Sender).Canvas, X, Y);
151159
end;
152160

153-
procedure TSimbaColorPicker.ImageMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
161+
procedure TSimbaColorPicker.DoImageMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
154162
begin
155163
FPicked := True;
156164

157165
FForm.Close();
158166
end;
159167

160-
function TSimbaColorPicker.Pick(out X, Y: Integer; out Color: TColor): Boolean;
168+
procedure TSimbaColorPicker.Pick;
169+
var
170+
DesktopWindow: TWindowHandle;
171+
DesktopBounds: TBox;
172+
DesktopImage: TSimbaImage;
161173
begin
162-
FForm.ShowOnTop();
174+
DesktopImage := nil;
163175

164-
FHint.Show();
165-
FHint.BringToFront();
176+
try
177+
if (FForm = nil) then // only create form when actually needed
178+
begin
179+
FForm := TForm.CreateNew(nil);
180+
FForm.BorderStyle := bsNone;
181+
FForm.OnClose := @DoFormClosed;
182+
183+
FImage := TImage.Create(FForm);
184+
FImage.Parent := FForm;
185+
FImage.Align := alClient;
186+
FImage.Cursor := crCross;
187+
FImage.OnMouseUp := @DoImageMouseUp;
188+
FImage.OnMouseMove := @DoImageMouseMove;
189+
190+
FHint := TSimbaColorPickerHint.Create(FForm);
191+
FHint.OnKeyDown := @DoHintKeyDown;
192+
end;
166193

167-
while FForm.Showing do
168-
begin
169-
Application.ProcessMessages();
194+
DesktopWindow := GetDesktopWindow();
195+
DesktopBounds := DesktopWindow.GetBounds();
196+
DesktopImage := TSimbaImage.CreateFromWindow(DesktopWindow);
170197

171-
Sleep(25);
172-
end;
198+
FWindowSelection := SimbaIDEVars.WindowSelection.EnsureValid();
173199

174-
Result := FPicked;
175-
if FPicked then
176-
begin
177-
X := FPoint.X;
178-
Y := FPoint.Y;
179-
Color := FColor;
180-
end;
181-
end;
200+
FForm.Left := DesktopBounds.X1;
201+
FForm.Top := DesktopBounds.Y1;
202+
FForm.Width := DesktopBounds.Width;
203+
FForm.Height := DesktopBounds.Height;
182204

183-
constructor TSimbaColorPicker.Create(Window: TWindowHandle);
184-
var
185-
DesktopWindow: TWindowHandle;
186-
DesktopBounds: TBox;
187-
Temp: TSimbaImage;
188-
begin
189-
inherited Create();
205+
FImage.Picture.Bitmap := DesktopImage.ToLazBitmap();
190206

191-
DesktopWindow := GetDesktopWindow();
192-
DesktopBounds := DesktopWindow.GetBounds();
207+
FForm.ShowOnTop();
208+
FHint.Show();
209+
FHint.BringToFront();
193210

194-
FWindow := Window;
195-
if (FWindow = 0) or (not FWindow.IsValid()) then
196-
FWindow := GetDesktopWindow();
211+
while FForm.Showing do
212+
begin
213+
Application.ProcessMessages();
197214

198-
FForm := TForm.CreateNew(nil);
199-
with FForm do
200-
begin
201-
Left := DesktopBounds.X1;
202-
Top := DesktopBounds.Y1;
203-
Width := DesktopBounds.Width;
204-
Height := DesktopBounds.Height;
215+
Sleep(25);
216+
end;
217+
except
218+
on E: Exception do
219+
begin
220+
ShowErrorDialog('Color Picker', 'Exception occurred while picking color %s', [E.Message]);
221+
if (FForm <> nil) then
222+
FForm.Close();
223+
end;
224+
end;
205225

206-
BorderStyle := bsNone;
226+
if (DesktopImage <> nil) then
227+
FreeAndNil(DesktopImage);
228+
end;
207229

208-
OnClose := @FormClosed;
209-
end;
230+
constructor TSimbaColorPicker.Create;
231+
begin
232+
inherited Create();
233+
end;
210234

211-
FImage := TImage.Create(FForm);
212-
with FImage do
213-
begin
214-
Parent := FForm;
215-
Align := alClient;
216-
Cursor := crCross;
235+
destructor TSimbaColorPicker.Destroy;
236+
begin
237+
if (FForm <> nil) then
238+
FreeAndNil(FForm);
217239

218-
OnMouseUp := @ImageMouseUp;
219-
OnMouseMove := @ImageMouseMove;
240+
inherited Destroy();
241+
end;
220242

221-
Temp := TSimbaImage.CreateFromWindow(DesktopWindow);
222-
Picture.Bitmap := Temp.ToLazBitmap;
223-
Temp.Free();
224-
end;
243+
procedure DoCreate;
244+
begin
245+
SimbaColorPicker := TSimbaColorPicker.Create();
246+
end;
225247

226-
FHint := TSimbaColorPickerHint.Create(FForm);
227-
FHint.OnKeyDown := @HintKeyDown;
228-
FHint.Show();
248+
procedure DoDestroy;
249+
begin
250+
FreeAndNil(SimbaColorPicker);
229251
end;
230252

231-
end.
253+
initialization
254+
SimbaInitialization_Add(ESimbaInit.IDE_BEFORE_SHOW, @DoCreate, 'SimbaColorPicker');
255+
SimbaInitialization_Add(ESimbaInit.IDE_DESTROY, @DoDestroy, 'SimbaColorPicker');
232256

257+
end.

Source/ide/simba.ide_maintoolbar.pas

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -190,21 +190,8 @@ procedure TSimbaMainToolBar.DoClickPackageButton(Sender: TObject);
190190
end;
191191

192192
procedure TSimbaMainToolBar.DoClickColorPicker(Sender: TObject);
193-
var
194-
X, Y: Integer;
195-
Color: TColor;
196193
begin
197-
try
198-
if ShowColorPicker(FWindowSelection, X, Y, Color) then
199-
begin
200-
DebugLn([EDebugLn.FOCUS], 'Color picked: %d at (%d, %d)', [Color, X, Y]);
201-
202-
SimbaIDEEvents.Notify(SimbaIDEEvent.COLOR_PICKED, Self);
203-
end;
204-
except
205-
on E: Exception do
206-
ShowMessage('Exception while picking color: ' + E.Message);
207-
end;
194+
SimbaColorPicker.Pick();
208195
end;
209196

210197
procedure TSimbaMainToolBar.DoClickAreaSelector(Sender: TObject);

0 commit comments

Comments
 (0)