- added themeservices for gtk

- gtk2 themeservices is descendant of gtk themeservices now

git-svn-id: trunk@11224 -
This commit is contained in:
paul 2007-05-30 06:45:30 +00:00
parent 630a91fda3
commit 219599ff13
5 changed files with 371 additions and 221 deletions

1
.gitattributes vendored
View File

@ -2582,6 +2582,7 @@ lcl/interfaces/gtk/gtkpagecallback.inc svneol=native#text/pascal
lcl/interfaces/gtk/gtkprivatewidget.inc svneol=native#text/plain lcl/interfaces/gtk/gtkprivatewidget.inc svneol=native#text/plain
lcl/interfaces/gtk/gtkproc.inc svneol=native#text/pascal lcl/interfaces/gtk/gtkproc.inc svneol=native#text/pascal
lcl/interfaces/gtk/gtkproc.pp svneol=native#text/pascal lcl/interfaces/gtk/gtkproc.pp svneol=native#text/pascal
lcl/interfaces/gtk/gtkthemes.pas svneol=native#text/pascal
lcl/interfaces/gtk/gtkwinapi.inc svneol=native#text/pascal lcl/interfaces/gtk/gtkwinapi.inc svneol=native#text/pascal
lcl/interfaces/gtk/gtkwinapih.inc svneol=native#text/pascal lcl/interfaces/gtk/gtkwinapih.inc svneol=native#text/pascal
lcl/interfaces/gtk/gtkwinapiwindow.pp svneol=native#text/pascal lcl/interfaces/gtk/gtkwinapiwindow.pp svneol=native#text/pascal

View File

@ -71,7 +71,7 @@ uses
// LCL // LCL
ExtDlgs, Dialogs, Controls, Forms, LCLStrConsts, LMessages, ExtDlgs, Dialogs, Controls, Forms, LCLStrConsts, LMessages,
LCLProc, LCLIntf, LCLType, DynHashArray, GraphType, GraphMath, LCLProc, LCLIntf, LCLType, DynHashArray, GraphType, GraphMath,
Graphics, Menus, Maps, Graphics, Menus, Maps, Themes,
// widgetset // widgetset
GtkFontCache, gtkDef, GtkProc, gtkMsgQueue, GtkExtra, gtkWSPrivate, WSLCLClasses; GtkFontCache, gtkDef, GtkProc, gtkMsgQueue, GtkExtra, gtkWSPrivate, WSLCLClasses;
@ -123,6 +123,7 @@ type
FExtUTF8OutCacheSize: integer; FExtUTF8OutCacheSize: integer;
FGlobalCursor: HCursor; FGlobalCursor: HCursor;
function CreateThemeServices: TThemeServices; override;
public public
procedure InitStockItems; virtual; procedure InitStockItems; virtual;
procedure FreeStockItems; virtual; procedure FreeStockItems; virtual;
@ -366,6 +367,7 @@ uses
GtkWSSpin, GtkWSSpin,
GtkWSStdCtrls, GtkWSStdCtrls,
// GtkWSToolwin, // GtkWSToolwin,
GtkThemes,
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
Buttons, StdCtrls, PairSplitter, Buttons, StdCtrls, PairSplitter,
GTKWinApiWindow, ComCtrls, CListBox, Calendar, Arrow, Spin, CommCtrl, GTKWinApiWindow, ComCtrls, CListBox, Calendar, Arrow, Spin, CommCtrl,

View File

@ -1466,6 +1466,11 @@ begin
//gtk_main_quit; //gtk_main_quit;
end; end;
function TGTKWidgetSet.CreateThemeServices: TThemeServices;
begin
Result := TGtkThemeServices.Create;
end;
Procedure TGtkWidgetSet.InitStockItems; Procedure TGtkWidgetSet.InitStockItems;
var var
LogBrush: TLogBrush; LogBrush: TLogBrush;

View File

@ -0,0 +1,359 @@
unit GtkThemes;
{$mode objfpc}{$H+}
interface
uses
// rtl
Types, Classes, SysUtils,
// os
{$ifdef gtk1}
glib, gdk, gtk,
{$else}
glib2, gdk2, gtk2, Pango,
{$endif}
// lcl
InterfaceBase, LCLType, LCLProc, LCLIntf, Graphics, Themes, TmSchema,
// widgetset
gtkdef, gtkint, gtkproc;
type
TGtkPainterType =
(
gptNone,
gptDefault,
gptHLine,
gptVLine,
gptShadow,
gptBox,
gptFlatBox,
gptCheck,
gptOption,
gptTab,
// gptSlider,
gptHandle
// gptExpander,
// gptResizeGrip
);
TGtkStyleParams = record
Style : PGtkStyle; // paint style
Painter : TGtkPainterType; // type of paint handler
Widget : PGtkWidget; // widget
Window : PGdkWindow; // paint window
Origin : TPoint; // offset
State : TGtkStateType; // Style state
Shadow : TGtkShadowType; // Shadow
Detail : String; // Detail (button, checkbox, ...)
Orientation: TGtkOrientation; // Orientation (horizontal/vertical)
IsHot : Boolean;
end;
{ TGtk1ThemeServices }
TGtkThemeServices = class(TThemeServices)
private
protected
function GdkRectFromRect(R: TRect): TGdkRectangle;
function GetGtkStyleParams(DC: HDC; Details: TThemedElementDetails): TGtkStyleParams; virtual;
function InitThemes: Boolean; override;
function UseThemes: Boolean; override;
function ThemedControlsEnabled: Boolean; override;
procedure InternalDrawParentBackground(Window: HWND; Target: HDC; Bounds: PRect); override;
public
procedure DrawElement(DC: HDC; Details: TThemedElementDetails; const R: TRect; ClipRect: PRect); override;
procedure DrawIcon(DC: HDC; Details: TThemedElementDetails; const R: TRect; himl: HIMAGELIST; Index: Integer); override;
procedure DrawText(DC: HDC; Details: TThemedElementDetails; const S: WideString; R: TRect; Flags, Flags2: Cardinal); override;
function ContentRect(DC: HDC; Details: TThemedElementDetails; BoundingRect: TRect): TRect; override;
function HasTransparentParts(Details: TThemedElementDetails): Boolean; override;
end;
const
// most common maps
GtkButtonMap: array[0..6] of TGtkStateType =
(
{ filter ? } GTK_STATE_NORMAL,
{ normal } GTK_STATE_NORMAL,
{ hot } GTK_STATE_PRELIGHT,
{ pressed } GTK_STATE_ACTIVE,
{ disabled } GTK_STATE_INSENSITIVE,
{ defaulted/checked } GTK_STATE_ACTIVE,
{ hot + checked } GTK_STATE_INSENSITIVE // PRELIGHT IS TOO LIGHT
);
implementation
{ TGtkThemeServices }
function TGtkThemeServices.GdkRectFromRect(R: TRect): TGdkRectangle;
begin
with Result, R do
begin
x := Left;
y := Top;
width := Right-Left;
height := Bottom-Top;
end;
end;
function TGtkThemeServices.GetGtkStyleParams(DC: HDC;
Details: TThemedElementDetails): TGtkStyleParams;
var
ClientWidget: PGtkWidget;
begin
Result.Style := nil;
if GTKWidgetSet.IsValidDC(DC) then
with TDeviceContext(DC) do
begin
Result.Widget := DCWidget;
ClientWidget := GetFixedWidget(Result.Widget);
if ClientWidget <> nil then
Result.Widget := ClientWidget;
Result.Window := Drawable;
Result.Origin := GetDCOffset(TDeviceContext(DC));
Result.Style := gtk_widget_get_style(Result.Widget);
if Result.Style = nil then
Result.Style := gtk_widget_get_default_style();
Result.Painter := gptDefault;
Result.State := GTK_STATE_NORMAL;
Result.Detail := '';
Result.Shadow := GTK_SHADOW_NONE;
Result.IsHot := False;
case Details.Element of
teButton, teHeader:
begin
case Details.Part of
BP_PUSHBUTTON:
begin
Result.State := GtkButtonMap[Details.State];
if Details.State = PBS_PRESSED then
Result.Shadow := GTK_SHADOW_IN
else
Result.Shadow := GTK_SHADOW_OUT;
Result.IsHot:= Result.State = GTK_STATE_PRELIGHT;
Result.Detail := 'button';
Result.Painter := gptBox;
end;
end;
end;
teToolBar:
begin
case Details.Part of
TP_BUTTON:
begin
Result.State := GtkButtonMap[Details.State];
if Details.State in [TS_PRESSED, TS_CHECKED, TS_HOTCHECKED] then
Result.Shadow := GTK_SHADOW_IN
else
if Details.State in [TS_HOT] then
Result.Shadow := GTK_SHADOW_ETCHED_IN
else
Result.Shadow := GTK_SHADOW_NONE;
Result.IsHot := Details.State in [TS_HOT, TS_HOTCHECKED];
Result.Detail := 'togglebutton';
if Result.Shadow = GTK_SHADOW_NONE then
Result.Painter := gptNone
else
Result.Painter := gptBox;
end;
end;
end;
teRebar:
begin
case Details.Part of
RP_GRIPPER, RP_GRIPPERVERT:
begin
Result.State := GTK_STATE_NORMAL;
Result.Shadow := GTK_SHADOW_OUT;
if Details.Part = RP_GRIPPER then
Result.Detail := 'hpaned'
else
Result.Detail := 'vpaned';
Result.Painter := gptBox;
end;
RP_BAND:
begin
Result.State := GtkButtonMap[Details.State];
Result.Shadow := GTK_SHADOW_NONE;
Result.Detail := 'paned';
Result.Painter := gptFlatBox;
end;
end;
end;
end;
end;
end;
function TGtkThemeServices.InitThemes: Boolean;
begin
Result := True;
end;
function TGtkThemeServices.UseThemes: Boolean;
begin
Result := True;
end;
function TGtkThemeServices.ThemedControlsEnabled: Boolean;
begin
Result := True;
end;
function TGtkThemeServices.ContentRect(DC: HDC;
Details: TThemedElementDetails; BoundingRect: TRect): TRect;
var
StyleParams: TGtkStyleParams;
begin
Result := BoundingRect;
StyleParams := GetGtkStyleParams(DC, Details);
if StyleParams.Style <> nil then
InflateRect(Result, -1, -1);
end;
procedure TGtkThemeServices.DrawElement(DC: HDC;
Details: TThemedElementDetails; const R: TRect; ClipRect: PRect);
var
ClipArea: TGdkRectangle;
p_ClipArea: PGdkRectangle;
StyleParams: TGtkStyleParams;
R1: TRect;
begin
StyleParams := GetGtkStyleParams(DC, Details);
if StyleParams.Style <> nil then
begin
if ClipRect <> nil then
begin
ClipArea := GdkRectFromRect(ClipRect^);
inc(ClipArea.x, StyleParams.Origin.x);
inc(ClipArea.y, StyleParams.Origin.y);
p_ClipArea := @ClipArea;
end
else
p_ClipArea := nil;
with StyleParams do
begin
R1 := R;
if IsHot then
begin
// todo: draw rectanle with selected state
{gtk_paint_box(
Style, Window,
GTK_STATE_SELECTED, Shadow,
p_ClipArea, Widget, PChar(Detail),
R1.Left + Origin.x, R1.Top + Origin.y,
R1.Right - R1.Left, R1.Bottom - R1.Top);
inflateRect(R1, -1, -1);
}
end;
case Painter of
gptBox,
gptDefault: gtk_paint_box(
Style, Window,
State, Shadow,
p_ClipArea, Widget, PChar(Detail),
R1.Left + Origin.x, R1.Top + Origin.y,
R1.Right - R1.Left, R1.Bottom - R1.Top);
gptHLine : gtk_paint_hline(
Style, Window,
State, p_ClipArea,
Widget, PChar(Detail),
R1.Left + Origin.x, R1.Right + Origin.x, R1.Top + Origin.y);
gptVLine : gtk_paint_vline(
Style, Window,
State, p_ClipArea,
Widget, PChar(Detail),
R1.Top + Origin.y, R1.Bottom + Origin.y, R1.Left + Origin.x);
gptShadow : gtk_paint_shadow(
Style, Window,
State, Shadow,
p_ClipArea, Widget, PChar(Detail),
R1.Left + Origin.x, R1.Top + Origin.y,
R1.Right - R1.Left, R1.Bottom - R1.Top);
gptFlatBox: gtk_paint_flat_box(
Style, Window,
State, Shadow,
p_ClipArea, Widget, PChar(Detail),
R1.Left + Origin.x, R1.Top + Origin.y,
R1.Right - R1.Left, R1.Bottom - R1.Top);
gptCheck : gtk_paint_check(
Style, Window,
State, Shadow,
p_ClipArea, Widget, PChar(Detail),
R1.Left + Origin.x, R1.Top + Origin.y,
R1.Right - R1.Left, R1.Bottom - R1.Top);
gptOption : gtk_paint_option(
Style, Window,
State, Shadow,
p_ClipArea, Widget, PChar(Detail),
R1.Left + Origin.x, R1.Top + Origin.y,
R1.Right - R1.Left, R1.Bottom - R1.Top);
gptTab : gtk_paint_tab(
Style, Window,
State, Shadow,
p_ClipArea, Widget, PChar(Detail),
R1.Left + Origin.x, R1.Top + Origin.y,
R1.Right - R1.Left, R1.Bottom - R1.Top);
gptHandle : gtk_paint_handle(
Style, Window,
State, Shadow,
p_ClipArea, Widget, PChar(Detail),
R1.Left + Origin.x, R1.Top + Origin.y,
R1.Right - R1.Left, R1.Bottom - R1.Top,
Orientation);
end;
end;
end;
end;
procedure TGtkThemeServices.DrawIcon(DC: HDC;
Details: TThemedElementDetails; const R: TRect; himl: HIMAGELIST;
Index: Integer);
begin
end;
function TGtkThemeServices.HasTransparentParts(Details: TThemedElementDetails): Boolean;
begin
Result := True; // ?
end;
procedure TGtkThemeServices.InternalDrawParentBackground(Window: HWND;
Target: HDC; Bounds: PRect);
begin
// ?
end;
procedure TGtkThemeServices.DrawText(DC: HDC; Details: TThemedElementDetails;
const S: WideString; R: TRect; Flags, Flags2: Cardinal);
var
StyleParams: TGtkStyleParams;
P: PChar;
tmpRect: TRect;
begin
StyleParams := GetGtkStyleParams(DC, Details);
if StyleParams.Style <> nil then
with StyleParams do
begin
P := PChar(String(S));
tmpRect := R;
Widgetset.DrawText(DC, P, Length(S), tmpRect, Flags);
// TODO: parse flags
//gtk_draw_string(Style, Window, State, R.Left + Origin.x, R.Top + Origin.y, P);
end;
end;
end.

View File

@ -12,90 +12,22 @@ uses
// lcl // lcl
LCLType, LCLProc, LCLIntf, Graphics, Themes, TmSchema, LCLType, LCLProc, LCLIntf, Graphics, Themes, TmSchema,
// widgetset // widgetset
gtkdef, gtk2int, gtkproc; GtkDef, Gtk2Int, GtkProc, GtkThemes;
type type
TGtkPainterType =
(
gptNone,
gptDefault,
gptHLine,
gptVLine,
gptShadow,
gptBox,
gptFlatBox,
gptCheck,
gptOption,
gptTab,
// gptSlider,
gptHandle
// gptExpander,
// gptResizeGrip
);
TGtkStyleParams = record
Style : PGtkStyle; // paint style
Painter : TGtkPainterType; // type of paint handler
Widget : PGtkWidget; // widget
Window : PGdkWindow; // paint window
Origin : TPoint; // offset
State : TGtkStateType; // Style state
Shadow : TGtkShadowType; // Shadow
Detail : String; // Detail (button, checkbox, ...)
Orientation: TGtkOrientation; // Orientation (horizontal/vertical)
IsHot : Boolean;
end;
{ TGtk2ThemeServices } { TGtk2ThemeServices }
TGtk2ThemeServices = class(TThemeServices) TGtk2ThemeServices = class(TGtkThemeServices)
private
protected protected
function GdkRectFromRect(R: TRect): TGdkRectangle; function GetGtkStyleParams(DC: HDC; Details: TThemedElementDetails): TGtkStyleParams; override;
function GetGtkStyleParams(DC: HDC; Details: TThemedElementDetails): TGtkStyleParams;
function InitThemes: Boolean; override;
function UseThemes: Boolean; override;
function ThemedControlsEnabled: Boolean; override;
procedure InternalDrawParentBackground(Window: HWND; Target: HDC; Bounds: PRect); override;
public public
procedure DrawElement(DC: HDC; Details: TThemedElementDetails; const R: TRect; ClipRect: PRect); override;
procedure DrawIcon(DC: HDC; Details: TThemedElementDetails; const R: TRect; himl: HIMAGELIST; Index: Integer); override;
procedure DrawText(DC: HDC; Details: TThemedElementDetails; const S: WideString; R: TRect; Flags, Flags2: Cardinal); override;
function ContentRect(DC: HDC; Details: TThemedElementDetails; BoundingRect: TRect): TRect; override; function ContentRect(DC: HDC; Details: TThemedElementDetails; BoundingRect: TRect): TRect; override;
function HasTransparentParts(Details: TThemedElementDetails): Boolean; override;
end; end;
implementation implementation
const
// most common maps
GtkButtonMap: array[0..6] of TGtkStateType =
(
{ filter ? } GTK_STATE_NORMAL,
{ normal } GTK_STATE_NORMAL,
{ hot } GTK_STATE_PRELIGHT,
{ pressed } GTK_STATE_ACTIVE,
{ disabled } GTK_STATE_INSENSITIVE,
{ defaulted/checked } GTK_STATE_ACTIVE,
{ hot + checked } GTK_STATE_INSENSITIVE // PRELIGHT IS TOO LIGHT
);
{ TGtk2ThemeServices } { TGtk2ThemeServices }
function TGtk2ThemeServices.GdkRectFromRect(R: TRect): TGdkRectangle;
begin
with Result, R do
begin
x := Left;
y := Top;
width := Right-Left;
height := Bottom-Top;
end;
end;
function TGtk2ThemeServices.GetGtkStyleParams(DC: HDC; function TGtk2ThemeServices.GetGtkStyleParams(DC: HDC;
Details: TThemedElementDetails): TGtkStyleParams; Details: TThemedElementDetails): TGtkStyleParams;
var var
@ -192,21 +124,6 @@ begin
end; end;
end; end;
function TGtk2ThemeServices.InitThemes: Boolean;
begin
Result := True;
end;
function TGtk2ThemeServices.UseThemes: Boolean;
begin
Result := True;
end;
function TGtk2ThemeServices.ThemedControlsEnabled: Boolean;
begin
Result := True;
end;
function TGtk2ThemeServices.ContentRect(DC: HDC; function TGtk2ThemeServices.ContentRect(DC: HDC;
Details: TThemedElementDetails; BoundingRect: TRect): TRect; Details: TThemedElementDetails; BoundingRect: TRect): TRect;
var var
@ -220,139 +137,5 @@ begin
-StyleParams.Style^.ythickness); -StyleParams.Style^.ythickness);
end; end;
procedure TGtk2ThemeServices.DrawElement(DC: HDC;
Details: TThemedElementDetails; const R: TRect; ClipRect: PRect);
var
ClipArea: TGdkRectangle;
p_ClipArea: PGdkRectangle;
StyleParams: TGtkStyleParams;
R1: TRect;
begin
StyleParams := GetGtkStyleParams(DC, Details);
if StyleParams.Style <> nil then
begin
if ClipRect <> nil then
begin
ClipArea := GdkRectFromRect(ClipRect^);
inc(ClipArea.x, StyleParams.Origin.x);
inc(ClipArea.y, StyleParams.Origin.y);
p_ClipArea := @ClipArea;
end
else
p_ClipArea := nil;
with StyleParams do
begin
R1 := R;
if IsHot then
begin
// todo: draw rectanle with selected state
{gtk_paint_box(
Style, Window,
GTK_STATE_SELECTED, Shadow,
p_ClipArea, Widget, PChar(Detail),
R1.Left + Origin.x, R1.Top + Origin.y,
R1.Right - R1.Left, R1.Bottom - R1.Top);
inflateRect(R1, -1, -1);
}
end;
case Painter of
gptBox,
gptDefault: gtk_paint_box(
Style, Window,
State, Shadow,
p_ClipArea, Widget, PChar(Detail),
R1.Left + Origin.x, R1.Top + Origin.y,
R1.Right - R1.Left, R1.Bottom - R1.Top);
gptHLine : gtk_paint_hline(
Style, Window,
State, p_ClipArea,
Widget, PChar(Detail),
R1.Left + Origin.x, R1.Right + Origin.x, R1.Top + Origin.y);
gptVLine : gtk_paint_vline(
Style, Window,
State, p_ClipArea,
Widget, PChar(Detail),
R1.Top + Origin.y, R1.Bottom + Origin.y, R1.Left + Origin.x);
gptShadow : gtk_paint_shadow(
Style, Window,
State, Shadow,
p_ClipArea, Widget, PChar(Detail),
R1.Left + Origin.x, R1.Top + Origin.y,
R1.Right - R1.Left, R1.Bottom - R1.Top);
gptFlatBox: gtk_paint_flat_box(
Style, Window,
State, Shadow,
p_ClipArea, Widget, PChar(Detail),
R1.Left + Origin.x, R1.Top + Origin.y,
R1.Right - R1.Left, R1.Bottom - R1.Top);
gptCheck : gtk_paint_check(
Style, Window,
State, Shadow,
p_ClipArea, Widget, PChar(Detail),
R1.Left + Origin.x, R1.Top + Origin.y,
R1.Right - R1.Left, R1.Bottom - R1.Top);
gptOption : gtk_paint_option(
Style, Window,
State, Shadow,
p_ClipArea, Widget, PChar(Detail),
R1.Left + Origin.x, R1.Top + Origin.y,
R1.Right - R1.Left, R1.Bottom - R1.Top);
gptTab : gtk_paint_tab(
Style, Window,
State, Shadow,
p_ClipArea, Widget, PChar(Detail),
R1.Left + Origin.x, R1.Top + Origin.y,
R1.Right - R1.Left, R1.Bottom - R1.Top);
gptHandle : gtk_paint_handle(
Style, Window,
State, Shadow,
p_ClipArea, Widget, PChar(Detail),
R1.Left + Origin.x, R1.Top + Origin.y,
R1.Right - R1.Left, R1.Bottom - R1.Top,
Orientation);
end;
end;
end;
end;
procedure TGtk2ThemeServices.DrawIcon(DC: HDC;
Details: TThemedElementDetails; const R: TRect; himl: HIMAGELIST;
Index: Integer);
begin
end;
function TGtk2ThemeServices.HasTransparentParts(Details: TThemedElementDetails): Boolean;
begin
Result := True; // ?
end;
procedure TGtk2ThemeServices.InternalDrawParentBackground(Window: HWND;
Target: HDC; Bounds: PRect);
begin
// ?
end;
procedure TGtk2ThemeServices.DrawText(DC: HDC; Details: TThemedElementDetails;
const S: WideString; R: TRect; Flags, Flags2: Cardinal);
var
StyleParams: TGtkStyleParams;
P: PChar;
tmpRect: TRect;
begin
StyleParams := GetGtkStyleParams(DC, Details);
if StyleParams.Style <> nil then
with StyleParams do
begin
P := PChar(String(S));
tmpRect := R;
Gtk2Widgetset.DrawText(DC, P, Length(S), tmpRect, Flags);
// TODO: parse flags
//gtk_draw_string(Style, Window, State, R.Left + Origin.x, R.Top + Origin.y, P);
end;
end;
end. end.