kolmck/Addons/ToGrush.pas

538 lines
16 KiB
ObjectPascal
Raw Normal View History

unit ToGRush;
interface
//{$DEFINE TOGRUSH_AUTO_DISIMAGES} // add this symbol to provide 256 gray images
// based on original ones for Disabled state
// of toolbar buttons
//{$DEFINE TOGRUSH_AUTO_DIS_EQ} // RGB channels of the same level while TOGRUSH_AUTO_DISIMAGES
//{$DEFINE TOGRUSH_DROPBTN2} // Drop button will be placed right to the button
// having property DropDown, not in the button
//{$DEFINE TOGRUSH_NO_AUTO_SIZE_BTNS} // not use AutoSize for buttons
// (sensible only in a case, when only images are in the toolbar)
uses Windows, KOL, KOLGRushControls;
function NewButton( AParent: PControl; const Caption: KOLString ): PControl;
function NewCheckbox( AParent: PControl; const Caption: KOLString ): PControl;
function NewRadiobox( AParent: PControl; const Caption: KOLString ): PControl;
function NewPanel( AParent: PControl; EdgeStyle: TEdgeStyle ): PControl;
function NewSplitter( AParent: PControl; MinSizePrev, MinSizeNext: Integer ): PControl;
function NewSplitterEx( AParent: PControl; MinSizePrev, MinSizeNext: Integer;
EdgeStyle: TEdgeStyle ): PControl;
function NewToolbar( AParent: PControl; Align: TControlAlign; Options: TToolbarOptions;
Bitmap: HBitmap; const Buttons: array of PChar;
const BtnImgIdxArray: array of Integer ) : PControl;
function ToolbarButtonRect( Toolbar: PControl; BtnID: Integer ): TRect;
procedure ToolbarSetTooltips( Toolbar: PControl; BtnID1st: Integer; const Tooltips: array of PKOLChar );
function ToolbarButtonEnabled( Toolbar: PControl; BtnID: Integer ): Boolean;
procedure EnableToolbarButton( Toolbar: PControl; BtnID: Integer; Enable: Boolean );
function ToolbarButtonVisible( Toolbar: PControl; BtnID: Integer ): Boolean;
procedure ShowHideToolbarButton( Toolbar: PControl; BtnID: Integer; Show: Boolean );
function NewProgressbar( AParent: PControl ): PControl;
function NewProgressbarEx( AParent: PControl; Options: TProgressbarOptions ): PControl;
implementation
const
IS_DRDWN = 16;
type
PControl_ = ^TControl_;
TControl_ = object( TControl )
end;
////////////////////////////////////////////////////////////////////////////////
// BUTTON, CHECK, RADIO CHECK
////////////////////////////////////////////////////////////////////////////////
function NewButton( AParent: PControl; const Caption: KOLString ): PControl;
begin
Result := Pointer( NewGRushButton( AParent, Caption ).SetSize( 64, 22 ) );
PControl_( Result ).fIsButton := TRUE;
end;
function NewCheckbox( AParent: PControl; const Caption: KOLString ): PControl;
begin
Result := Pointer( NewGRushCheckBox( AParent, Caption ).SetSize( 64, 22 ) );
end;
function NewRadiobox( AParent: PControl; const Caption: KOLString ): PControl;
begin
Result := Pointer( NewGRushRadioBox( AParent, Caption ).SetSize( 64, 22 ) );
end;
////////////////////////////////////////////////////////////////////////////////
// PANEL
////////////////////////////////////////////////////////////////////////////////
function NewPanel( AParent: PControl; EdgeStyle: TEdgeStyle ): PControl;
begin
if EdgeStyle = esTransparent then
begin
Result := KOL.NewPanel( AParent, esNone ).SetSize( 64, 64 );
Result.Transparent := TRUE;
end
else
Result := Pointer( NewGRushPanel( AParent ) );
end;
////////////////////////////////////////////////////////////////////////////////
// SPLITTER
////////////////////////////////////////////////////////////////////////////////
function NewSplitter( AParent: PControl; MinSizePrev, MinSizeNext: Integer ): PControl;
begin
Result := Pointer( NewGRushSplitter( AParent, MinSizePrev, MinSizeNext ) );
Result.Transparent := TRUE;
end;
function NewSplitterEx( AParent: PControl; MinSizePrev, MinSizeNext: Integer;
EdgeStyle: TEdgeStyle ): PControl;
begin
Result := Pointer( NewGRushSplitter( AParent, MinSizePrev, MinSizeNext ) );
Result.Transparent := TRUE;
end;
////////////////////////////////////////////////////////////////////////////////
// TOOL BAR
////////////////////////////////////////////////////////////////////////////////
type
TTBButtonEvent = packed Record
BtnID: DWORD;
Event: TOnToolbarButtonClick;
end;
PTBButtonEvent = ^TTBButtonEvent;
procedure ToGR_ClickToolbarBtn( Dummy, Sender: PControl );
var D: DWORD;
Idx: Integer;
IsCheck, Checked: Boolean;
Toolbar: PControl_;
EventRec: PTBButtonEvent;
begin
D := GetProp( Sender.Handle, 'GRBTN' );
Idx := LoWord( D );
IsCheck := HiWord( D ) and 2 <> 0;
Checked := HiWord( D ) and 4 <> 0;
if IsCheck then
begin
Checked := not Checked;
D := D xor $40000;
SetProp( Sender.Handle, 'GRBTN', D );
PGrushControl( Sender ).Checked := Checked;
end;
Toolbar := Pointer( Sender.Parent );
if Assigned( Toolbar.fTBEvents ) and
(Toolbar.fTBevents.Count > Idx) then
begin
EventRec := Toolbar.fTBevents.Items[ Idx ];
if Assigned( EventRec.Event ) then
EventRec.Event( Toolbar, EventRec.BtnID );
end
else
if Assigned( Toolbar.fOnClick ) then
begin
Toolbar.fOnClick( Toolbar );
end;
end;
procedure ToGR_ClickToolbarBtnDD( Dummy, Sender: PControl );
var D: DWORD;
Idx: Integer;
Toolbar: PControl_;
EventRec: PTBButtonEvent;
begin
D := GetProp( Sender.Handle, 'GRBTN' );
Idx := LoWord( D );
Toolbar := Pointer( Sender.Parent );
{$IFDEF TOGRUSH_DROPBTN2}
{$ELSE}
Toolbar := Pointer( Toolbar.Parent );
{$ENDIF}
Toolbar.fCurItem := Idx;
Toolbar.fCurIndex := Idx;
Toolbar.fDropped := TRUE;
if Assigned( Toolbar.fTBevents ) and
(Toolbar.fTBevents.Count > Idx) then
begin
EventRec := Toolbar.fTBevents.Items[ Idx ];
Toolbar.fCurItem := EventRec.BtnID;
end;
if Assigned( Toolbar.OnTBDropDown ) then
begin
Toolbar.OnTBDropDown( Toolbar );
end
else
if Assigned( Toolbar.fOnClick ) then
begin
Toolbar.fOnClick( Toolbar );
end;
Toolbar.fDropped := FALSE;
end;
procedure Provide_DIS_images( var B: PBitmap );
var B2: PBitmap;
y, y_to, x, c: Integer;
Src, Dst: PRGBQuad;
first_pixel: Boolean;
Transp: DWORD;
begin
if (B =nil) or B.Empty then Exit;
B2 := NewDIBBitmap( B.Width, B.Height * 2, pf32bit );
TRY
B.Draw( B2.Canvas.Handle, 0, 0 );
y_to := B.Height;
first_pixel := TRUE;
Transp := 0;
for y := 0 to B.Height-1 do
begin
Src := B2.ScanLine[ y ];
Dst := B2.ScanLine[ y_to ];
for x := 0 to B2.Width-1 do
begin
if first_pixel then
Transp := PDWORD( Src )^ and $FFFFFF;
first_pixel := FALSE;
if PDWORD( Src )^ and $FFFFFF = Transp then
PDWORD( Dst )^ := Transp
else
begin
{$IFDEF TOGRUSH_AUTO_DIS_BAL}
c := (Src.rgbRed * 64 + Src.rgbGreen * 128 + Src.rgbBlue * (128 + 64))
div 256;
{$ELSE}
c := (Src.rgbRed * 64 + Src.rgbGreen * 64 + Src.rgbBlue * 64)
div 100;
{$ENDIF}
if c > 255 then c := 255;
Dst.rgbBlue := c;
Dst.rgbGreen := c;
Dst.rgbRed := c;
end;
inc( Src );
inc( Dst );
end;
inc( y_to );
end;
FINALLY
B.Assign( B2 );
B2.Free;
END;
end;
var DrDownBmp: PBitmap;
function NewToolbar( AParent: PControl; Align: TControlAlign; Options: TToolbarOptions;
Bitmap: HBitmap; const Buttons: array of PChar;
const BtnImgIdxArray: array of Integer ) : PControl;
var i, BtnID: Integer;
B, B2: PGRushControl;
C: String;
IsSep: Boolean;
IsDropDown: Boolean;
IsCheck, Checked, IsRadio: Boolean;
Idx: Integer;
D: DWORD;
imgW, imgH, W, H: Integer;
Bmp: PBitmap;
DD_dst: PByte;
y: Integer;
ES: TEdgeStyle;
const DD_img: array[ 0..6 ] of Byte = ( $0, $F8, $F8, $70, $70, $20, $20 );
begin
if Align = caNone then Align := caTop;
H := 0;
imgW := 0;
imgH := 0;
Bmp := nil;
if Bitmap <> 0 then
begin
Bmp := NewBitmap( 0, 0 );
Bmp.Handle := Bitmap;
imgH := Bmp.Height;
imgW := imgH;
H := Bmp.Height + 12;
//Bmp.PixelFormat := pf32bit;
//Bmp.SaveToFile( GetStartDir + 'test_toolbar1.bmp' );
{$IFDEF TOGRUSH_AUTO_DISIMAGES}
Provide_DIS_images( Bmp );
{$ENDIF}
end;
ES := esNone;
if [tboTransparent, tboFlat] * Options <> [] then
ES := esTransparent;
Result := Pointer( NewPanel( AParent, ES ).SetSize( 0, H ).SetAlign(Align) );
//if Bmp <> nil then Result.Add2AutoFree( Bmp );
Idx := -1;
for i := 0 to High( Buttons ) do
begin
C := Buttons[ i ];
IsSep := C = '-';
IsDropDown := FALSE;
IsCheck := FALSE;
Checked := FALSE;
BtnID := i; //ToolbarsIDcmd; inc( ToolbarsIDcmd );
if IsSep then C := ''
else
begin
Inc( Idx );
IsDropDown := (C <> '') and (C[ 1 ] = '^');
if IsDropDown then Delete( C, 1, 1 );
IsCheck := (C <> '') and (C[ 1 ] in [ '+', '-' ]);
if IsCheck then
begin
Checked := C[ 1 ] = '+';
Delete( C, 1, 1 );
IsRadio := (C <> '') and (C[ 1 ] = '!');
if IsRadio then Delete( C, 1, 1 );
end;
end;
if Trim( C ) = '' then C := '';
if IsSep then
NewPanel( Result, esTransparent ).SetSize( 6, 0 ).SetAlign( caLeft )
else
begin
if C = '' then
begin
W := 32;
if H <> 0 then W := H;
end
else
begin
W := 64;
end;
B := Pointer( NewButton( Result, C ).SetSize( W, 0 ).SetAlign( caLeft ) );
{$IFDEF USE_NAMES}
//B.Name := 'TB' + Int2Str( Idx+1 );
{$ENDIF USE_NAMES}
B.Tabstop := FALSE;
B.LikeSpeedButton;
B.Transparent := TRUE;
if IsSep then B.Enabled := FALSE;
if B.GetWindowHandle <> 0 then
begin
D := i or Integer( IsSep ) shl 16
or Integer( IsCheck ) shl 17
or Integer( Checked ) shl 18
or Integer( IsDropDown ) shl 19
;
SetProp( B.Handle, 'GRBTN', D );
end;
SetProp( B.Handle, 'BTNID', BtnID );
B.OnClick := TOnEvent( MakeMethod( nil, @ ToGR_ClickToolbarBtn ) );
if Bmp <> nil then
begin
B.All_GlyphItemX := idx;
B.All_GlyphItemY := 0;
B.All_GlyphBitmap := Bmp;
B.All_GlyphWidth := ImgW;
B.All_GlyphHeight := ImgH;
//B.All_GlyphAttached := TRUE;
{$IFDEF TOGRUSH_AUTO_DISIMAGES}
B.Dis_GlyphItemX := idx;
B.Dis_GlyphItemY := 1;
B.All_GlyphBitmap := Bmp;
B.All_GlyphWidth := ImgW;
B.All_GlyphHeight := ImgH;
{$ENDIF}
if not IsDropDown and (C = '') then
B.All_GlyphHAlign := haCenter;
end;
{$IFNDEF TOGRUSH_NO_AUTO_SIZE_BTNS}
B.fCommandActions.aAutoSzX := 10 + ImgW;
if ImgW > 0 then inc( B.fCommandActions.aAutoSzX, 5 );
if IsDropDown then inc( B.fCommandActions.aAutoSzX, 10 );
B.AutoSize( TRUE );
{$ENDIF}
if IsDropDown then
begin
{$IFDEF TOGRUSH_DROPBTN2}
B2 := Pointer( NewButton( Result, C ).SetSize( 5 + 8, 0 ).SetAlign( caLeft ) );
{$ELSE}
//B.AutoSize( FALSE );
//B.Width := W + 13;
B.All_TextHAlign := haLeft;
B.Border := 2;
B2 := Pointer( NewButton( B, C ).SetSize( 5 + 8, 0 ).SetAlign( caRight ) );
{$ENDIF}
{$IFDEF USE_NAMES}
//B2.Name := 'TB_dd' + Int2Str( Idx+1 );
{$ENDIF USE_NAMES}
B2.Tabstop := FALSE;
B2.LikeSpeedButton;
B2.Transparent := TRUE;
PGrushControl( B2 ).All_BorderWidth := 0;
PGrushControl( B2 ).Over_BorderWidth := 1;
if B2.GetWindowHandle <> 0 then
begin
D := i or Integer( IsSep ) shl 16
or Integer( IsCheck ) shl 17
or Integer( Checked ) shl 18
or Integer( IsDropDown ) shl 19
or IS_DRDWN shl 16;
SetProp( B2.Handle, 'GRBTN', D );
end;
B2.OnClick := TOnEvent( MakeMethod( nil, @ ToGR_ClickToolbarBtnDD ) );
if DrDownBmp = nil then
begin
DrDownBmp := NewDIBBitmap( 5, High( DD_img )+1, pf1bit );
DrDownBmp.DIBPalEntries[ 0 ] := $686868;
DrDownBmp.DIBPalEntries[ 1 ] := $FFFFFF;
for y := 0 to High( DD_img ) do
begin
DD_dst := DrDownBmp.ScanLine[ y ];
DD_dst^ := not DD_img[ y ];
end;
//B2.All_GlyphItemX := 0;
//B.All_GlyphItemY := 0;
B2.All_GlyphBitmap := DrDownBmp;
DrDownBmp.RefDec;
end
else
begin
B2.All_GlyphBitmap := DrDownBmp;
end;
B2.All_GlyphWidth := 5;
B2.All_GlyphHeight := High( DD_img )+1;
B2.All_GlyphHAlign := haCenter;
B2.All_GlyphVAlign := vaBottom;
end;
end;
end;
if Bmp <> nil then
begin
Bmp.Free;
end;
end;
function ToolbarButtonRect( Toolbar: PControl; BtnID: Integer ): TRect;
var i: Integer;
B: PControl;
begin
for i := 0 to Toolbar.ChildCount-1 do
begin
B := Toolbar.Children[ i ];
if (B.GetWindowHandle <> 0) and
(Integer( GetProp( B.Handle, 'BTNID' ) ) = BtnID) then
begin
Result := B.BoundsRect;
Exit;
end;
end;
Result := MakeRect( 0, 0, 0, 0 );
end;
procedure ToolbarSetTooltips( Toolbar: PControl; BtnID1st: Integer; const Tooltips: array of PKOLChar );
{$IFDEF USE_MHTOOLTIP}
var i, j: Integer;
B: PControl;
found: Boolean;
{$ENDIF}
begin
Toolbar.TBSetTooltips( BtnID1st, Tooltips );
{$IFDEF USE_MHTOOLTIP}
found := FALSE;
j := 0;
if BtnID1st < 0 then BtnID1st := 0;
for i := 0 to Toolbar.ChildCount-1 do
begin
if j > High( Tooltips ) then break;
B := Toolbar.Children[ i ];
//if not B.IsButton then continue;
if HiWord( GetProp( B.Handle, 'GRBTN' ) ) and IS_DRDWN <> 0 then
continue;
if found or (Integer( GetProp( B.Handle, 'BTNID' ) ) = BtnID1st) then
begin
found := TRUE;
if Trim( Tooltips[ j ] ) <> '' then
NewHint( B ).Text := Tooltips[ j ];
inc( BtnID1st );
inc( j );
end;
end;
{$ENDIF USE_MHTOOLTIP}
end;
function ToolbarButtonEnabled( Toolbar: PControl; BtnID: Integer ): Boolean;
var i: Integer;
B: PControl;
begin
for i := 0 to Toolbar.ChildCount-1 do
begin
B := Toolbar.Children[ i ];
if (B.GetWindowHandle <> 0) and
(Integer( GetProp( B.Handle, 'BTNID' ) ) = BtnID) then
begin
Result := B.Enabled;
Exit;
end;
end;
Result := FALSE;
end;
procedure EnableToolbarButton( Toolbar: PControl; BtnID: Integer; Enable: Boolean );
var i: Integer;
B: PControl;
begin
for i := 0 to Toolbar.ChildCount-1 do
begin
B := Toolbar.Children[ i ];
if (B.GetWindowHandle <> 0) and
(Integer( GetProp( B.Handle, 'BTNID' ) ) = BtnID) then
begin
B.Enabled := Enable;
Exit;
end;
end;
end;
function ToolbarButtonVisible( Toolbar: PControl; BtnID: Integer ): Boolean;
var i: Integer;
B: PControl;
begin
for i := 0 to Toolbar.ChildCount-1 do
begin
B := Toolbar.Children[ i ];
if (B.GetWindowHandle <> 0) and
(Integer( GetProp( B.Handle, 'BTNID' ) ) = BtnID) then
begin
Result := B.Visible;
Exit;
end;
end;
Result := FALSE;
end;
procedure ShowHideToolbarButton( Toolbar: PControl; BtnID: Integer; Show: Boolean );
var i: Integer;
B: PControl;
begin
for i := 0 to Toolbar.ChildCount-1 do
begin
B := Toolbar.Children[ i ];
if (B.GetWindowHandle <> 0) and
(Integer( GetProp( B.Handle, 'BTNID' ) ) = BtnID) then
begin
B.Visible := Show;
Exit;
end;
end;
end;
////////////////////////////////////////////////////////////////////////////////
// PROGRESS BAR
////////////////////////////////////////////////////////////////////////////////
function NewProgressbar( AParent: PControl ): PControl;
begin
Result := Pointer( NewGRushProgressBar( AParent ).SetSize( 300, 20 ) );
end;
function NewProgressbarEx( AParent: PControl; Options: TProgressbarOptions ): PControl;
begin
Result := NewProgressbar( AParent );
end;
end.