unit SLHColorPicker; {$IFDEF FPC} {$MODE DELPHI} {$ENDIF} interface {$I mxs.inc} uses {$IFDEF FPC} LCLIntf, LCLType, LMessages, {$ELSE} Windows, Messages, {$ENDIF} SysUtils, Classes, Controls, Graphics, Forms, RGBHSLUtils, mbTrackBarPicker, SLColorPicker, HColorPicker, Menus, {$IFDEF DELPHI_7_UP} Themes, {$ENDIF} HTMLColors, mbBasicPicker; type TSLHColorPicker = class(TmbBasicPicker) private FOnChange: TNotifyEvent; FSLPicker: TSLColorPicker; FHPicker: THColorPicker; FSelectedColor: TColor; FHValue, FSValue, FLValue: integer; FRValue, FGValue, FBValue: integer; FSLHint, FHHint: string; FSLMenu, FHMenu: TPopupMenu; FSLCursor, FHCursor: TCursor; PBack: TBitmap; function GetManual: boolean; procedure SelectColor(c: TColor); procedure SetH(v: integer); procedure SetS(v: integer); procedure SetL(v: integer); procedure SetR(v: integer); procedure SetG(v: integer); procedure SetB(v: integer); procedure SetHHint(h: string); procedure SetSLHint(h: string); procedure SetSLMenu(m: TPopupMenu); procedure SetHMenu(m: TPopupMenu); procedure SetHCursor(c: TCursor); procedure SetSLCursor(c: TCursor); procedure HPickerChange(Sender: TObject); procedure SLPickerChange(Sender: TObject); protected procedure CreateWnd; override; procedure DoChange; procedure DoMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); procedure Paint; override; procedure PaintParentBack; override; procedure Resize; override; procedure WMSetFocus(var Message: {$IFDEF FPC}TLMSetFocus{$ELSE}TWMSetFocus{$ENDIF}); message {$IFDEF FPC}LM_SETFOCUS{$ELSE}WM_SETFOCUS{$ENDIF}; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; function GetColorUnderCursor: TColor; function GetHexColorUnderCursor: string; function GetSelectedHexColor: string; property ColorUnderCursor: TColor read GetColorUnderCursor; property HValue: integer read FHValue write SetH default 0; property SValue: integer read FSValue write SetS default 240; property LValue: integer read FLValue write SetL default 120; property RValue: integer read FRValue write SetR default 255; property GValue: integer read FGValue write SetG default 0; property BValue: integer read FBValue write SetB default 0; property Manual: boolean read GetManual; published property SelectedColor: TColor read FSelectedColor write SelectColor default clRed; property HPickerPopupMenu: TPopupMenu read FHMenu write SetHMenu; property SLPickerPopupMenu: TPopupMenu read FSLMenu write SetSLMenu; property HPickerHintFormat: string read FHHint write SetHHint; property SLPickerHintFormat: string read FSLHint write SetSLHint; property HPickerCursor: TCursor read FHCursor write SetHCursor default crDefault; property SLPickerCursor: TCursor read FSLCursor write SetSLCursor default crDefault; property TabStop default true; property ShowHint; property ParentShowHint; property Anchors; property Align; property Visible; property Enabled; property TabOrder; property Color; property ParentColor default true; {$IFDEF DELPHI_7_UP}{$IFDEF DELPHI} property ParentBackground default true; {$ENDIF}{$ENDIF} property OnChange: TNotifyEvent read FOnChange write FOnChange; property OnMouseMove; end; implementation const WSL = 255; HSL = 255; WH = 40; DIST = 2; VDELTA = 8; {TSLHColorPicker} constructor TSLHColorPicker.Create(AOwner: TComponent); begin inherited; ControlStyle := ControlStyle - [csAcceptsControls] + [csOpaque]; DoubleBuffered := true; PBack := TBitmap.Create; PBack.PixelFormat := pf32bit; ParentColor := true; {$IFDEF DELPHI_7_UP}{$IFDEF DELPHI} ParentBackground := true; {$ENDIF}{$ENDIF} {$IFDEF DELPHI} Width := 297; Height := 271; {$ELSE} SetInitialBounds(0, 0, WSL + DIST + WH, HSL + 2*VDELTA); {$ENDIF} TabStop := true; FSelectedColor := clRed; FHPicker := THColorPicker.Create(Self); InsertControl(FHPicker); FHCursor := crDefault; FSLCursor := crDefault; // Hue picker with FHPicker do begin Layout := lyVertical; // put before setting width and height {$IFDEF DELPHI} Left := 257; Top := 0; Width := 40; Height := 271; {$ELSE} SetInitialBounds(WSL + DIST, 0, WH, HSL + 2*VDELTA); {$ENDIF} // Anchors := [akTop, akRight, akBottom]; Visible := true; Layout := lyVertical; ArrowPlacement := spBoth; NewArrowStyle := true; OnChange := HPickerChange; OnMouseMove := DoMouseMove; end; // Saturation-Lightness picker FSLPicker := TSLColorPicker.Create(Self); InsertControl(FSLPicker); with FSLPicker do begin {$IFDEF DELPHI} Left := 0; Top := DELTA; Width := 255; Height := self.Height - 2 * VDELTA; {$ELSE} SetInitialBounds(0, VDELTA, WSL, HSL); {$ENDIF} //Anchors := [akLeft, akRight, akTop, akBottom]; Visible := true; SelectedColor := clRed; OnChange := SLPickerChange; OnMouseMove := DoMouseMove; end; FHValue := 0; FSValue := 255; FLValue := 255; FRValue := 255; FGValue := 0; FBValue := 0; FHHint := 'Hue: %h'; FSLHint := 'S: %hslS L: %l'#13'Hex: %hex'; end; destructor TSLHColorPicker.Destroy; begin PBack.Free; FHPicker.Free; FSLPicker.Free; inherited Destroy; end; procedure TSLHColorPicker.HPickerChange(Sender: TObject); begin FSLPicker.Hue := FHPicker.Hue; DoChange; end; procedure TSLHColorPicker.SLPickerChange(Sender: TObject); begin FSelectedColor := FSLPicker.SelectedColor; DoChange; end; procedure TSLHColorPicker.DoChange; begin FHValue := FHPicker.Hue; FSValue := FSLPicker.Saturation; FLValue := FSLPicker.Luminance; FRValue := GetRValue(FSLPicker.SelectedColor); FGValue := GetGValue(FSLPicker.SelectedColor); FBValue := GetBValue(FSLPicker.SelectedColor); if Assigned(FOnChange) then FOnChange(Self); end; procedure TSLHColorPicker.SelectColor(c: TColor); begin FSelectedColor := c; FHPicker.Hue := GetHValue(c); FSLPicker.SelectedColor := c; end; procedure TSLHColorPicker.SetH(v: integer); begin FHValue := v; FSLPicker.Hue := v; FHPicker.Hue := v; end; procedure TSLHColorPicker.SetS(v: integer); begin FSValue := v; FSLPicker.Saturation := v; end; procedure TSLHColorPicker.SetL(v: integer); begin FLValue := v; FSLPicker.Luminance := v; end; procedure TSLHColorPicker.SetR(v: integer); begin FRValue := v; SelectColor(RGB(FRValue, FGValue, FBValue)); end; procedure TSLHColorPicker.SetG(v: integer); begin FGValue := v; SelectColor(RGB(FRValue, FGValue, FBValue)); end; procedure TSLHColorPicker.SetB(v: integer); begin FBValue := v; SelectColor(RGB(FRValue, FGValue, FBValue)); end; function TSLHColorPicker.GetSelectedHexColor: string; begin Result := ColorToHex(FSelectedColor); end; procedure TSLHColorPicker.SetHHint(h: string); begin FHHint := h; FHPicker.HintFormat := h; end; procedure TSLHColorPicker.SetSLHint(h: string); begin FSLHint := h; FSLPicker.HintFormat := h; end; procedure TSLHColorPicker.SetSLMenu(m: TPopupMenu); begin FSLMenu := m; FSLPicker.PopupMenu := m; end; procedure TSLHColorPicker.SetHMenu(m: TPopupMenu); begin FHMenu := m; FHPicker.PopupMenu := m; end; procedure TSLHColorPicker.DoMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin if Assigned(OnMouseMove) then OnMouseMove(Self, Shift, x, y); inherited; end; function TSLHColorPicker.GetColorUnderCursor: TColor; begin Result := FSLPicker.GetColorUnderCursor; end; function TSLHColorPicker.GetHexColorUnderCursor: string; begin Result := FSLPicker.GetHexColorUnderCursor; end; procedure TSLHColorPicker.SetHCursor(c: TCursor); begin FHCursor := c; FHPicker.Cursor := c; end; procedure TSLHColorPicker.SetSLCursor(c: TCursor); begin FSLCursor := c; FSLPicker.Cursor := c; end; procedure TSLHColorPicker.WMSetFocus( var Message: {$IFDEF FPC}TLMSetFocus{$ELSE}TWMSetFocus{$ENDIF} ); begin FHPicker.SetFocus; Message.Result := 1; end; function TSLHColorPicker.GetManual:boolean; begin Result := FHPicker.Manual or FSLPicker.Manual; end; procedure TSLHColorPicker.Resize; begin inherited; PaintParentBack; if (FSLPicker = nil) or (FHPicker = nil) then exit; FSLPicker.Width := Width - FHPicker.Width - DIST; FSLPicker.Height := Height - 2*VDELTA; FHPicker.Left := Width - FHPicker.Width; FHPicker.Height := Height; end; procedure TSLHColorPicker.PaintParentBack; begin if PBack = nil then begin PBack := TBitmap.Create; PBack.PixelFormat := pf32bit; end; PBack.Width := Width; PBack.Height := Height; PaintParentBack(PBack); end; procedure TSLHColorPicker.Paint; begin PaintParentBack; Canvas.Draw(0, 0, PBack); end; procedure TSLHColorPicker.CreateWnd; begin inherited; PaintParentBack; end; end.