Gtk2: implemented TListView.OwnerDraw.Part of issue #25149

git-svn-id: trunk@43122 -
This commit is contained in:
zeljko 2013-10-06 12:39:22 +00:00
parent ed57fc41d6
commit 8a567bd42b
2 changed files with 55 additions and 16 deletions

View File

@ -160,6 +160,7 @@ var
TmpDC1, TmpDC1,
TmpDC2: HDC; TmpDC2: HDC;
SkipDefaultPaint: Boolean; SkipDefaultPaint: Boolean;
OwnerDrawnListView: Boolean;
begin begin
{DebugLn(['LCLIntfCellRenderer_Render cell=',dbgs(cell), {DebugLn(['LCLIntfCellRenderer_Render cell=',dbgs(cell),
' ',GetWidgetDebugReport(Widget),' ', ' ',GetWidgetDebugReport(Widget),' ',
@ -174,9 +175,12 @@ begin
(AWinControl.FCompStyle = csListView) then (AWinControl.FCompStyle = csListView) then
ColumnIndex := 0; ColumnIndex := 0;
OwnerDrawnListView := False;
if ColumnIndex > -1 then // listview if ColumnIndex > -1 then // listview
begin begin
OwnerDrawnListView := TCustomListViewAccess(AWinControl).OwnerDraw and
(TCustomListViewAccess(AWinControl).ViewStyle = vsReport);
AreaRect := Bounds(background_area^.x, background_area^.y, AreaRect := Bounds(background_area^.x, background_area^.y,
background_area^.Width, background_area^.Height); background_area^.Width, background_area^.Height);
@ -207,7 +211,8 @@ begin
begin begin
GTK2WidgetSet.ReleaseDC(HWnd({%H-}PtrUInt(Widget)),TmpDC1); GTK2WidgetSet.ReleaseDC(HWnd({%H-}PtrUInt(Widget)),TmpDC1);
TCustomListViewAccess(AWinControl).Canvas.Handle := TmpDC2; TCustomListViewAccess(AWinControl).Canvas.Handle := TmpDC2;
Exit; if not OwnerDrawnListView then
Exit;
end; end;
end; end;
@ -227,8 +232,11 @@ begin
end; end;
// do default draw only if we are not customdrawn. // do default draw only if we are not customdrawn.
if (ColumnIndex > -1) or ((ColumnIndex < 0) and (AWinControl = nil)) then if (ColumnIndex > -1) or ((ColumnIndex < 0) and (AWinControl = nil)) then
CellClass^.DefaultGtkRender(cell, Window, Widget, background_area, cell_area, begin
expose_area, flags); if not OwnerDrawnListView then
CellClass^.DefaultGtkRender(cell, Window, Widget, background_area, cell_area,
expose_area, flags);
end;
if ColumnIndex < 0 then // is a listbox or combobox if ColumnIndex < 0 then // is a listbox or combobox
begin begin
@ -279,28 +287,55 @@ begin
TCustomListViewAccess(AWinControl).Canvas.Handle := TmpDC2; TCustomListViewAccess(AWinControl).Canvas.Handle := TmpDC2;
GTK2WidgetSet.ReleaseDC(HWnd({%H-}PtrUInt(Widget)),TmpDC1); GTK2WidgetSet.ReleaseDC(HWnd({%H-}PtrUInt(Widget)),TmpDC1);
Exit; if not OwnerDrawnListView then
Exit;
end; end;
// ListBox and ComboBox // ListBox and ComboBox
// create message and deliverFillChar(Msg,SizeOf(Msg),0); // create message and deliverFillChar(Msg,SizeOf(Msg),0);
Msg.Msg:=LM_DrawListItem; if OwnerDrawnListView then
begin
// we are TListView (GtkTreeView) with OwnerDraw + vsReport
Msg.Msg := CN_DRAWITEM;
// collect state flags
State := [];
if (flags and GTK_CELL_RENDERER_SELECTED)>0 then
Include(State, odSelected);
if not GTK_WIDGET_SENSITIVE(Widget) then
Include(State, odInactive);
if GTK_WIDGET_HAS_DEFAULT(Widget) then
Include(State, odDefault);
if (flags and GTK_CELL_RENDERER_FOCUSED) <> 0 then
Include(State, odFocused);
AreaRect := Bounds(expose_area^.x, expose_area^.y,
expose_area^.Width, expose_area^.Height);
if gtk_tree_view_get_headers_visible(PGtkTreeView(Widget)) then
begin
inc(AreaRect.Top, background_area^.height);
inc(AreaRect.Bottom, background_area^.height);
end;
end else
Msg.Msg:=LM_DrawListItem;
New(Msg.DrawListItemStruct); New(Msg.DrawListItemStruct);
try try
FillChar(Msg.DrawListItemStruct^,SizeOf(TDrawListItemStruct),0); FillChar(Msg.DrawListItemStruct^,SizeOf(TDrawListItemStruct),0);
with Msg.DrawListItemStruct^ do begin with Msg.DrawListItemStruct^ do
begin
ItemID:=UINT(ItemIndex); ItemID:=UINT(ItemIndex);
Area:=AreaRect; Area:=AreaRect;
//DebugLn(['LCLIntfCellRenderer_Render Widget=',GetWidgetDebugReport(Widget^.parent),' Area=',dbgs(Area)]); // DebugLn(['LCLIntfCellRenderer_Render Widget=',GetWidgetDebugReport(Widget^.parent),' Area=',dbgs(Area)]);
DCWidget:=Widget; DCWidget:=Widget;
if (DCWidget^.parent<>nil) if (DCWidget^.parent<>nil) and
and (GtkWidgetIsA(DCWidget^.parent,gtk_menu_item_get_type)) then begin (GtkWidgetIsA(DCWidget^.parent,gtk_menu_item_get_type)) then
begin
// the Widget is a sub widget of a menu item // the Widget is a sub widget of a menu item
// -> allow the LCL to paint over the whole menu item // -> allow the LCL to paint over the whole menu item
DCWidget:=DCWidget^.parent; DCWidget := DCWidget^.parent;
Area:=Rect(0,0,DCWidget^.allocation.width,DCWidget^.allocation.height); Area:=Rect(0,0,DCWidget^.allocation.width,DCWidget^.allocation.height);
end; end;
DC:=GTK2WidgetSet.CreateDCForWidget(DCWidget,Window,false); DC := GTK2WidgetSet.CreateDCForWidget(DCWidget,Window,false);
ItemState:=State; ItemState:=State;
end; end;
DeliverMessage(AWinControl, Msg); DeliverMessage(AWinControl, Msg);

View File

@ -532,9 +532,13 @@ begin
if GTK_IS_ICON_VIEW(MainView) then if GTK_IS_ICON_VIEW(MainView) then
gtk_icon_view_set_selection_mode(PGtkIconView(MainView), BoolToSelectionMode[AIsSet]); gtk_icon_view_set_selection_mode(PGtkIconView(MainView), BoolToSelectionMode[AIsSet]);
end; end;
lvpOwnerDraw: begin lvpOwnerDraw:
// TODO: implement begin
// use custom images/widgets ? // It must send CN_DRAWITEM with ItemID and proper rect of item
// then LCL does all other stuff. Note that OwnerDraw should work only
// in case of vsReport, according to embarcadero docs.
// http://docwiki.embarcadero.com/Libraries/XE4/en/Vcl.ComCtrls.TCustomListView.OnDrawItem
// NOTE: this is automatically handled by cell renderer (Gtk2CellRenderer).
end; end;
lvpReadOnly: begin lvpReadOnly: begin
// TODO: implement inline editor ? // TODO: implement inline editor ?
@ -1071,7 +1075,7 @@ begin
if GTK_IS_TREE_VIEW(MainView) then if GTK_IS_TREE_VIEW(MainView) then
begin begin
Column := gtk_tree_view_get_column(PGtkTreeView(MainView), ASubItem); Column := gtk_tree_view_get_column(PGtkTreeView(MainView), ASubItem);
gtk_tree_view_get_cell_area(PGtkTreeView(MainView), Path, Column, @ItemRect); gtk_tree_view_get_cell_area(PGtkTreeView(MainView), Path, Column, @ItemRect);
if gtk_tree_view_get_headers_visible(PGtkTreeView(MainView)) then if gtk_tree_view_get_headers_visible(PGtkTreeView(MainView)) then
begin begin
gtk_tree_view_column_cell_get_size(gtk_tree_view_get_column(PGtkTreeView(MainView), 0), gtk_tree_view_column_cell_get_size(gtk_tree_view_get_column(PGtkTreeView(MainView), 0),