diff options
Diffstat (limited to 'libgtk_kylix')
| -rw-r--r-- | libgtk_kylix/GTKControls.pas | 38 | ||||
| -rw-r--r-- | libgtk_kylix/GTKDialogs.pas | 5 | ||||
| -rw-r--r-- | libgtk_kylix/GTKForms.pas | 109 | ||||
| -rw-r--r-- | libgtk_kylix/GTKStdCtrls.pas | 19 | ||||
| -rw-r--r-- | libgtk_kylix/GTKUtils.pas | 138 | ||||
| -rw-r--r-- | libgtk_kylix/GTKView.pas | 457 |
6 files changed, 444 insertions, 322 deletions
diff --git a/libgtk_kylix/GTKControls.pas b/libgtk_kylix/GTKControls.pas index 4729266..502e1b9 100644 --- a/libgtk_kylix/GTKControls.pas +++ b/libgtk_kylix/GTKControls.pas @@ -82,6 +82,7 @@ type FOnDblClick: TGDKMouseEvent; FOnExpose: TGDKExposeEvent; FOnMouseMove: TGDKMouseEvent; + FCSSProvider: PGtkCssProvider; function GetWidth: Integer; function GetHeight: Integer; function GetLeft: Integer; @@ -141,6 +142,7 @@ type procedure Invalidate; function GetData(Key: string): Pointer; procedure SetData(Key: string; Value: Pointer); + procedure ApplyCustomCSS(Stylesheet: string); published property Width: Integer read GetWidth write SetWidth; property Height: Integer read GetHeight write SetHeight; @@ -301,14 +303,16 @@ begin FOnMouseMove := nil; FOnMouseDown := nil; FOnMouseUp := nil; + FCSSProvider := nil; end; destructor TGTKControl.Destroy; begin - try + if Assigned(FCSSProvider) then g_object_unref(PGObject(FCSSProvider)); +// try // SetParent(nil); // if Assigned(FWidget) {and GTK_IS_WIDGET(FWidget)} then gtk_widget_destroy(PGtkWidget(FWidget)); - except end; +// except end; inherited Destroy; end; @@ -381,6 +385,7 @@ end; function TGTKControl.GetLeft: Integer; var A: TGtkAllocation; begin + A.x := 0; gtk_widget_get_allocation(FWidget, @A); Result := A.x; end; @@ -388,6 +393,7 @@ end; function TGTKControl.GetTop: Integer; var A: TGtkAllocation; begin + A.y := 0; gtk_widget_get_allocation(FWidget, @A); Result := A.y; end; @@ -776,6 +782,32 @@ begin gtk_widget_set_margin_bottom(FWidget, Value); end; +procedure TGTKControl.ApplyCustomCSS(Stylesheet: string); +var provider: PGtkCssProvider; + error: PGError; +begin + error := nil; + // No stylesheet previously attached and asked to reset, nothing to do + if not Assigned(FCSSProvider) and (Length(Stylesheet) < 1) then Exit; + // Create new stylesheet provider + if not Assigned(FCSSProvider) then begin + FCSSProvider := gtk_css_provider_new(); + gtk_style_context_add_provider(gtk_widget_get_style_context(FWidget), PGtkStyleProvider(FCSSProvider), G_MAXUINT32); + end; + // Asked to clear the stylesheets + if Length(Stylesheet) < 1 then begin + gtk_style_context_remove_provider(gtk_widget_get_style_context(FWidget), PGtkStyleProvider(FCSSProvider)); + g_object_unref(PGObject(FCSSProvider)); + FCSSProvider := nil; + end else begin + // Apply the stylesheet + if not gtk_css_provider_load_from_data(FCSSProvider, PChar(Stylesheet), -1, @Error) then begin + g_log(PChar('tuxcmd'), [G_LOG_LEVEL_WARNING], 'Failed to parse CSS stylesheet "%s": %s', [PChar(Stylesheet), Error^.message]); + g_error_free(error); + Exit; + end; + end; +end; (********************************************************************************************************************************) (********************************************************************************************************************************) @@ -812,7 +844,7 @@ end; function TGTKContainer.GetChildrenCount: integer; var List: PGList; begin - List := LAZGLIB2.PGList(gtk_container_get_children(PGtkContainer(FWidget))); + List := gtk_container_get_children(PGtkContainer(FWidget)); Result := g_list_length(List); g_list_free(List); end; diff --git a/libgtk_kylix/GTKDialogs.pas b/libgtk_kylix/GTKDialogs.pas index dfbe1b2..ff8a0b0 100644 --- a/libgtk_kylix/GTKDialogs.pas +++ b/libgtk_kylix/GTKDialogs.pas @@ -135,7 +135,7 @@ end; function TGTKColorButton.GetColor: string; var c: TGdkRGBA; begin - FillChar(c, sizeof(TGdkRGBA), 0); + Initialize(c); gtk_color_chooser_get_rgba(PGtkColorChooser(FWidget), @c); Result := string(gdk_rgba_to_string(@c)); end; @@ -149,7 +149,8 @@ end; procedure TGTKColorButton.SetDefaultColor; begin - gtk_color_chooser_set_rgba(PGtkColorChooser(FWidget), nil); + // No way to reset the widget to an empty state, just set grey + SetColor('#EEEEEE'); end; (********************************************************************************************************************************) diff --git a/libgtk_kylix/GTKForms.pas b/libgtk_kylix/GTKForms.pas index b1467db..0dc1691 100644 --- a/libgtk_kylix/GTKForms.pas +++ b/libgtk_kylix/GTKForms.pas @@ -70,6 +70,9 @@ type // Some basic types FOnShow: TNotifyEvent; FCaption: string; FOnDestroy: TNotifyEvent; + FDeleteEventSignalHandlerID: gulong; + FSizeAllocateSignalHandlerID: gulong; + FShowSignalHandlerID: gulong; function GetWindowPosition: TWindowPosition; function GetResizeable: boolean; function GetWindowTypeHint: TGDKWindowTypeHint; @@ -88,6 +91,7 @@ type // Some basic types procedure SetWidth(Value: integer); procedure SetHeight(Value: integer); procedure SetDefault(Value: TGTKControl); + procedure ConnectDefaultSignals; protected procedure DoClose(var Action: TCloseAction); dynamic; property Visible write SetVisible default False; @@ -182,7 +186,7 @@ type // Some basic types destructor Destroy; override; procedure ControlDestroyed(Control: TGTKControl); procedure CreateForm(InstanceClass: TComponentClass; var Reference); - procedure HandleException(Sender: TObject); +// procedure HandleException(Sender: TObject); procedure HandleMessage; procedure HookSynchronizeWakeup; procedure Initialize; @@ -192,7 +196,7 @@ type // Some basic types Default: TMessageButton = mbNone; Escape: TMessageButton = mbNone): TMessageButton; overload; procedure ProcessMessages; procedure Run; - procedure ShowException(E: Exception); +// procedure ShowException(E: Exception); procedure Terminate; procedure UnhookSynchronizeWakeup; property MainForm: TCustomGTKForm read FMainForm; @@ -207,8 +211,6 @@ type // Some basic types var Application: TGTKApplication; Screen: TGDKScreen; - Argc: Integer; - Argv: PPChar; function GetParentForm(Control: TGTKControl): TCustomGTKForm; @@ -286,6 +288,9 @@ begin FOnClose := nil; FOnCloseQuery := nil; FOnDestroy := nil; + FDeleteEventSignalHandlerID := 0; + FSizeAllocateSignalHandlerID := 0; + FShowSignalHandlerID := 0; FCaption := ''; FAccelGroup := gtk_accel_group_new; Screen.AddForm(Self); @@ -293,15 +298,22 @@ end; destructor TCustomGTKForm.Destroy; begin - try - Screen.RemoveForm(Self); - if Assigned(FOnDestroy) then FOnDestroy(Self); - except - end; + Screen.RemoveForm(Self); + if Assigned(FOnDestroy) then FOnDestroy(Self); +// if FDeleteEventSignalHandlerID > 0 then g_signal_handler_disconnect(PGObject(FWidget), FDeleteEventSignalHandlerID); +// if FSizeAllocateSignalHandlerID > 0 then g_signal_handler_disconnect(PGObject(FWidget), FSizeAllocateSignalHandlerID); +// if FShowSignalHandlerID > 0 then g_signal_handler_disconnect(PGObject(FWidget), FShowSignalHandlerID); if not Application.Terminated then gtk_widget_destroy(FWidget); inherited Destroy; end; +procedure TCustomGTKForm.ConnectDefaultSignals; +begin + FDeleteEventSignalHandlerID := g_signal_connect_data(PGObject(FWidget), 'delete-event', TGCallback(@TCustomGTKForm_delete_event), Self, nil, G_CONNECT_DEFAULT); + FSizeAllocateSignalHandlerID := g_signal_connect_data(PGObject(FWidget), 'size-allocate', TGCallback(@TCustomGTKForm_size_allocate), Self, nil, G_CONNECT_DEFAULT); + FShowSignalHandlerID := g_signal_connect_data(PGObject(FWidget), 'show', TGCallback(@TCustomGTKForm_show), Self, nil, G_CONNECT_DEFAULT); +end; + procedure TCustomGTKForm.SetVisible(Value: Boolean); begin inherited Visible := Value; @@ -339,7 +351,7 @@ end; procedure TCustomGTKForm.Release; begin -// SetParent(nil); + SetParent(nil); // if Assigned(FWidget) and GTK_IS_WIDGET(FWidget) then gtk_widget_destroy(PGtkWidget(FWidget)); end; @@ -407,6 +419,7 @@ end; function TCustomGTKForm.GetWindowState: TGDKWindowState; begin + if gtk_window_is_maximized(PGtkWindow(FWidget)) then Result := wsMaximized else Result := TGDKWindowState(gdk_window_get_state(PGdkWindow(FWidget^.window))); end; @@ -514,48 +527,31 @@ begin inherited Create(AOwner); FMainForm := nil; FMainFormSet := False; - if not Assigned(Classes.ApplicationHandleException) then +{ if not Assigned(Classes.ApplicationHandleException) then Classes.ApplicationHandleException := @HandleException; if not Assigned(Classes.ApplicationShowException) then - Classes.ApplicationShowException := @ShowException; + Classes.ApplicationShowException := @ShowException;} CreateHandle; HookSynchronizeWakeup; FThreadID := 0; end; -procedure my_g_thread_init(vtable:Pointer);cdecl;external 'libgthread-2.0.so' name 'g_thread_init'; - procedure TGTKApplication.CreateHandle; -var - I: Integer; - Temp: string; +var argc: gint; + argv: PPgchar; + i: Integer; begin - Argc := ParamCount + 1; - Argv := AllocMem((Argc + 1) * SizeOf(PChar)); - for I := 0 to Argc - 1 do - begin - Temp := ParamStr(I); - {$R-} - PCharArray(Argv^)[I] := AllocMem(Length(Temp)+1); - StrCopy(PCharArray(Argv^)[I], PChar(Temp)); - {$R+} - end; - {$R-} - PCharArray(Argv^)[Argc] := nil; - {$R+} - - // Init threads - my_g_thread_init(nil); - - (* ATTENTION: do not call gdk_threads_init(), it causes deadlocks and we don't really need it *) -// gdk_threads_init; + argc := ParamCount; + argv := g_malloc0(argc * sizeof(Pointer)); + for i := 0 to argc - 1 do + argv[i] := g_strdup(PChar(ParamStr(i))); // Initialize the widget set gtk_init(@argc, @argv); -{ if not gtk_init_check(@argc, @argv) then begin - WriteLn('Unable to initialize GTK+ interface. Make sure you have correctly installed all of GTK libraries and have set a valid X server in the DISPLAY variable.'); - Halt(1); - end; } + + for i := 0 to argc - 1 do + g_free(argv[i]); + g_free(argv); end; destructor TGTKApplication.Destroy; @@ -565,31 +561,34 @@ var P: TNotifyEvent; E: TExceptionEvent; begin - UnhookSynchronizeWakeup; +{ UnhookSynchronizeWakeup; P := @HandleException; if @P = @Classes.ApplicationHandleException then Classes.ApplicationHandleException := nil; E := @ShowException; if @E = @Classes.ApplicationShowException then Classes.ApplicationShowException := nil; +} inherited Destroy; end; procedure TGTKApplication.HookSynchronizeWakeup; begin - if not Assigned(Classes.WakeMainThread) then - Classes.WakeMainThread := WakeMainThread; +{ if not Assigned(Classes.WakeMainThread) then + Classes.WakeMainThread := WakeMainThread; } end; procedure TGTKApplication.UnhookSynchronizeWakeup; var P: TNotifyEvent; begin - P := WakeMainThread; +{ P := WakeMainThread; if @P = @Classes.WakeMainThread then Classes.WakeMainThread := nil; +} end; +{ procedure TGTKApplication.HandleException(Sender: TObject); begin if ExceptObject is Exception then @@ -602,6 +601,7 @@ begin end else SysUtils.ShowException(ExceptObject, ExceptAddr); end; +} procedure TGTKApplication.CreateForm(InstanceClass: TComponentClass; var Reference); var @@ -662,11 +662,13 @@ function __pthread_self: __pthread_t; cdecl; external 'libpthread.so.0' name 'pt procedure TGTKApplication.Run; begin - repeat + gtk_main(); + +{ repeat try // gdk_threads_enter; - FThreadID := __pthread_self; - gtk_main; + FThreadID := __pthread_self(); + gtk_main(); // gdk_threads_leave; except on E : Exception do @@ -677,6 +679,7 @@ begin end else HandleException(E); end; until Terminated; + } end; function TGTKApplication_MessageBox_key_press_event(widget: PGtkWidget; event: PGdkEventKey; user_data : gpointer): gboolean; cdecl; @@ -709,7 +712,7 @@ begin Result := Escape; Exit; end; - Dialog := gtk_message_dialog_new(ParentWindow, [GTK_DIALOG_MODAL, GTK_DIALOG_DESTROY_WITH_PARENT], TMessageStyleID[Integer(Style)], + Dialog := gtk_message_dialog_new_with_markup(ParentWindow, [GTK_DIALOG_MODAL, GTK_DIALOG_DESTROY_WITH_PARENT], TMessageStyleID[Integer(Style)], GTK_BUTTONS_NONE, '%s', [PChar(Text)]); for i := 1 to NumMessageButtons do if TMessageButton(i - 1) in Buttons @@ -721,6 +724,7 @@ begin gtk_widget_destroy(Dialog); end; +{ procedure TGTKApplication.ShowException(E: Exception); var Msg: string; begin @@ -728,6 +732,7 @@ begin if (Msg <> '') and (AnsiLastChar(Msg) = '.') then Delete(Msg, Length(Msg), 1); MessageBox(Format('An unhandled exception has occured: '#10' %s'#10#10'It is strongly recommended to save your data and quit the application.', [Msg]), [mbOk], mbError); end; +} procedure TGTKApplication.Terminate; begin @@ -751,13 +756,11 @@ begin inherited Create(AOwner); FWidget := gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_add_accel_group(PGtkWindow(FWidget), FAccelGroup); - g_signal_connect_data(PGObject(FWidget), 'delete-event', TGCallback(@TCustomGTKForm_delete_event), Self, nil, G_CONNECT_DEFAULT); - g_signal_connect_data(PGObject(FWidget), 'size-allocate', TGCallback(@TCustomGTKForm_size_allocate), Self, nil, G_CONNECT_DEFAULT); - g_signal_connect_data(PGObject(FWidget), 'show', TGCallback(@TCustomGTKForm_show), Self, nil, G_CONNECT_DEFAULT); Visible := False; SetResizeable(True); FormCreate(Self); if Visible then Show; + ConnectDefaultSignals; end; procedure TGTKForm.Hide; @@ -784,9 +787,6 @@ begin if Assigned(AOwner) and (AOwner is TCustomGTKForm) then SetTransientFor(AOwner as TCustomGTKForm); FOnResponse := nil; gtk_window_add_accel_group(PGtkWindow(FWidget), FAccelGroup); - g_signal_connect_data(PGObject(FWidget), 'delete-event', TGCallback(@TCustomGTKForm_delete_event), Self, nil, G_CONNECT_DEFAULT); - g_signal_connect_data(PGObject(FWidget), 'show', TGCallback(@TCustomGTKForm_show), Self, nil, G_CONNECT_DEFAULT); - g_signal_connect_data(PGObject(FWidget), 'response', TGCallback(@TGTKDialog_response_event), Self, nil, G_CONNECT_DEFAULT); ClientArea := TGTKVBox.CreateLinked(Self, gtk_dialog_get_content_area(PGtkDialog(FWidget))); ActionArea := TGTKHBox.CreateLinked(Self, gtk_dialog_get_action_area(PGtkDialog(FWidget))); FButtons := []; @@ -794,6 +794,7 @@ begin SetResizeable(True); FormCreate(Self); if Visible then Show; + ConnectDefaultSignals; end; function TGTKDialog.Run: TMessageButton; diff --git a/libgtk_kylix/GTKStdCtrls.pas b/libgtk_kylix/GTKStdCtrls.pas index 2bca3bb..7f73594 100644 --- a/libgtk_kylix/GTKStdCtrls.pas +++ b/libgtk_kylix/GTKStdCtrls.pas @@ -23,7 +23,7 @@ unit GTKStdCtrls; interface -uses lazglib2, lazgobject2, lazgtk3, Classes, GTKControls, GTKConsts; +uses lazglib2, lazgobject2, lazgtk3, Classes, GTKControls, GTKPixbuf, GTKConsts; type @@ -32,12 +32,14 @@ type TGTKButton = class(TGTKBin) private FOnClick: TNotifyEvent; + FImage: PGtkWidget; function GetCaption: string; function GetUseUnderline: boolean; function GetBorderStyle: TGTKBorderStyle; procedure SetCaption(Value: string); procedure SetUseUnderline(Value: boolean); procedure SetBorderStyle(Value: TGTKBorderStyle); + procedure SetIcon(Value: TGDKPixbuf); public constructor Create(AOwner: TComponent); override; constructor CreateFromIconName(AOwner: TComponent; const IconName: string); @@ -47,6 +49,7 @@ type property OnClick: TNotifyEvent read FOnClick write FOnClick; property UseUnderline: boolean read GetUseUnderline write SetUseUnderline; property BorderStyle: TGTKBorderStyle read GetBorderStyle write SetBorderStyle; + property Icon: TGDKPixbuf write SetIcon; end; (****************************************** TGTKLABEL **************************************************************************) @@ -302,6 +305,20 @@ begin gtk_button_set_relief(PGtkButton(FWidget), TGtkReliefStyle(Value)); end; +procedure TGTKButton.SetIcon(Value: TGDKPixbuf); +begin + if Assigned(Value) then begin + if Assigned(FImage) then g_object_unref(PGObject(FImage)); + FImage := gtk_image_new_from_pixbuf(Value.FPixbuf); + gtk_button_set_image(PGtkButton(FWidget), FImage); + gtk_button_set_always_show_image(PGtkButton(FWidget), True); + end else begin + gtk_button_set_image(PGtkButton(FWidget), nil); + g_object_unref(PGObject(FImage)); + FImage := nil; + end; +end; + (********************************************************************************************************************************) (********************************************************************************************************************************) constructor TGTKLabel.Create(AOwner: TComponent); diff --git a/libgtk_kylix/GTKUtils.pas b/libgtk_kylix/GTKUtils.pas index c1b662e..1b3e7e8 100644 --- a/libgtk_kylix/GTKUtils.pas +++ b/libgtk_kylix/GTKUtils.pas @@ -32,27 +32,35 @@ function AllocateColor(R, G, B: Word): TGDKColor; overload; *) function KeyValToUnicode(const Key: word): guint32; function UnicodeToKeyVal(const UnicodeVal: guint32): word; -(* -function GetDefaultForegroundColor(State: integer): PGdkColor; overload; -function GetDefaultForegroundColor(Widget: TGTKControl; State: integer): PGdkColor; overload; -function GetDefaultBackgroundColor(State: integer): PGdkColor; overload; -function GetDefaultBackgroundColor(Widget: TGTKControl; State: integer): PGdkColor; overload; -function GetDefaultBaseColor(State: integer): PGdkColor; overload; -function GetDefaultBaseColor(Widget: TGTKControl; State: integer): PGdkColor; overload; -function GetDefaultTextColor(State: integer): PGdkColor; overload; -function GetDefaultTextColor(Widget: TGTKControl; State: integer): PGdkColor; overload; +{ +function GetDefaultForegroundColor(State: TGtkStateFlags): PGdkRGBA; overload; +function GetDefaultForegroundColor(Widget: TGTKControl; State: TGtkStateFlags): PGdkRGBA; overload; +} +function GetDefaultBackgroundColor(Widget: TGTKControl; State: TGtkStateFlags): PGdkRGBA; overload; +{ +function GetDefaultBaseColor(State: TGtkStateFlags): PGdkRGBA; overload; +function GetDefaultBaseColor(Widget: TGTKControl; State: TGtkStateFlags): PGdkRGBA; overload; +} +// Returns newly allocated PGdkRGBA +function GetDefaultTextColor(Widget: TGTKControl; State: TGtkStateFlags): PGdkRGBA; +{ function GDKColorToPGdkRGBA(Color: TGDKColor): PGdkRGBA; -function PGdkRGBAToGDKColor(Color: PGdkRGBA): TGDKColor; -function GDKColorToString(Color: TGDKColor): string; -function StringToGDKColor(Str: string; var Color: TGDKColor): boolean; -*) +function PGdkRGBAToGDKColor(Color: PGdkRGBA): TGDKColor;} + +function GDKRGBAToString(Color: PGdkRGBA): string; +function StringToGDKRGBA(Str: string): PGdkRGBA; + function ValidateColorString(const Color: string): boolean; +function PangoFontDescToCSS(const PangoFontDesc: string): string; + (********************************************************************************************************************************) implementation +uses lazpango1; + (********************************************************************************************************************************) (* function AllocateColor(Widget: PGtkWidget; R, G, B: Word): PGdkColor; @@ -89,7 +97,7 @@ end; (********************************************************************************************************************************) (* -function GetDefaultForegroundColor(State: integer): PGdkColor; +function GetDefaultForegroundColor(State: TGtkStateFlags): PGdkRGBA; var Widget: PGtkWidget; Style: PGtkStyle; begin @@ -99,7 +107,7 @@ begin gtk_widget_destroy(Widget); end; -function GetDefaultForegroundColor(Widget: TGTKControl; State: integer): PGdkColor; +function GetDefaultForegroundColor(Widget: TGTKControl; State: TGtkStateFlags): PGdkRGBA; var Style: PGtkStyle; begin Style := gtk_rc_get_style(Widget.FWidget); @@ -108,28 +116,20 @@ end; *) (********************************************************************************************************************************) -(* -function GetDefaultBackgroundColor(State: integer): PGdkColor; -var Widget: PGtkWidget; - Style: PGtkStyle; -begin - Widget := gtk_window_new(GTK_WINDOW_TOPLEVEL); - Style := gtk_rc_get_style(Widget); - Result := @(Style^.bg[State]); - gtk_widget_destroy(Widget); -end; -function GetDefaultBackgroundColor(Widget: TGTKControl; State: integer): PGdkColor; -var Style: PGtkStyle; +function GetDefaultBackgroundColor(Widget: TGTKControl; State: TGtkStateFlags): PGdkRGBA; +var StyleContext: PGtkStyleContext; + Value: PGdkRGBA; begin - Style := gtk_rc_get_style(Widget.FWidget); - Result := @(Style^.bg[State]); + Value := nil; + StyleContext := gtk_widget_get_style_context(Widget.FWidget); + gtk_style_context_get(StyleContext, State, [GTK_STYLE_PROPERTY_BACKGROUND_COLOR, @Value, nil]); + Result := Value; end; -*) (********************************************************************************************************************************) (* -function GetDefaultBaseColor(State: integer): PGdkColor; +function GetDefaultBaseColor(State: TGtkStateFlags): PGdkRGBA; var Widget: PGtkWidget; Style: PGtkStyle; begin @@ -139,7 +139,7 @@ begin gtk_widget_destroy(Widget); end; -function GetDefaultBaseColor(Widget: TGTKControl; State: integer): PGdkColor; +function GetDefaultBaseColor(Widget: TGTKControl; State: TGtkStateFlags): PGdkRGBA; var Style: PGtkStyle; begin Style := gtk_rc_get_style(Widget.FWidget); @@ -148,24 +148,17 @@ end; *) (********************************************************************************************************************************) -(* -function GetDefaultTextColor(State: integer): PGdkColor; -var Widget: PGtkWidget; - Style: PGtkStyle; -begin - Widget := gtk_window_new(GTK_WINDOW_TOPLEVEL); - Style := gtk_rc_get_style(Widget); - Result := @(Style^.text[State]); - gtk_widget_destroy(Widget); -end; -function GetDefaultTextColor(Widget: TGTKControl; State: integer): PGdkColor; -var Style: PGtkStyle; +function GetDefaultTextColor(Widget: TGTKControl; State: TGtkStateFlags): PGdkRGBA; +var StyleContext: PGtkStyleContext; + Value: PGdkRGBA; begin - Style := gtk_rc_get_style(Widget.FWidget); - Result := @(Style^.text[State]); + Value := nil; + StyleContext := gtk_widget_get_style_context(Widget.FWidget); + gtk_style_context_get(StyleContext, State, [GTK_STYLE_PROPERTY_COLOR, @Value, nil]); + Result := Value; end; -*) + (********************************************************************************************************************************) (* @@ -218,6 +211,26 @@ end; *) (********************************************************************************************************************************) +function GDKRGBAToString(Color: PGdkRGBA): string; +begin + Result := ''; + if Assigned(Color) then Result := String(gdk_rgba_to_string(Color)); +end; + +function StringToGDKRGBA(Str: string): PGdkRGBA; +var Value: TGdkRGBA; +begin + if Length(Str) < 1 then begin + Result := nil; + Exit; + end; + Initialize(Value); + if gdk_rgba_parse(@Value, PChar(Str)) then Result := gdk_rgba_copy(@Value) + else begin + g_log(PChar('tuxcmd'), [G_LOG_LEVEL_WARNING], 'Failed to parse color string "%s"', [PChar(Str)]); + Result := nil; + end; +end; function ValidateColorString(const Color: string): boolean; var rgba: TGdkRGBA; @@ -225,4 +238,35 @@ begin Result := gdk_rgba_parse(@rgba, PChar(Color)); end; +(********************************************************************************************************************************) + +function PangoFontDescToCSS(const PangoFontDesc: string): string; +var font_desc: PPangoFontDescription; + s: string; + val: Pgchar; + size: gint; +begin + s := ''; + font_desc := pango_font_description_from_string(PChar(PangoFontDesc)); + if not Assigned(font_desc) then begin + Result := ''; + Exit; + end; + val := pango_font_description_get_family(font_desc); + if Assigned(val) then s := s + 'font-family: ' + string(val) + '; '; + size := pango_font_description_get_size(font_desc); + if size > 0 then begin + if pango_font_description_get_size_is_absolute(font_desc) + then s := s + 'font-size: ' + IntToStr(size) + 'px; ' + else s := s + 'font-size: ' + IntToStr(Trunc(pango_units_to_double(size))) + 'pt; '; + end; + case pango_font_description_get_style(font_desc) of + PANGO_STYLE_NORMAL: ; + PANGO_STYLE_OBLIQUE: s := s + 'font-style: oblique; '; + PANGO_STYLE_ITALIC: s := s + 'font-style: italic; '; + end; + pango_font_description_free(font_desc); + Result := s; +end; + end. diff --git a/libgtk_kylix/GTKView.pas b/libgtk_kylix/GTKView.pas index b971e7d..1ac742b 100644 --- a/libgtk_kylix/GTKView.pas +++ b/libgtk_kylix/GTKView.pas @@ -210,6 +210,7 @@ type function GetSearchColumn: integer; function GetSortColumnID: integer; function GetSortOrder: TGTKTreeViewSortOrder; + function GetFixedHeightMode: boolean; procedure SetSelectionMode(Value: TGTKSelectionMode); procedure SetShowHeaders(Value: boolean); procedure SetRulesHint(Value: boolean); @@ -218,6 +219,7 @@ type procedure SetSearchColumn(Value: integer); procedure SetSortColumnID(Value: integer); procedure SetSortOrder(Value: TGTKTreeViewSortOrder); + procedure SetFixedHeightMode(Value: boolean); protected public FSelection: PGtkTreeSelection; @@ -244,6 +246,7 @@ type property CellDataFunc: TGTKCellDataFunc read FCellDataFunc write FCellDataFunc; property FromSortedCoversionFunc: TGTKSortCoversionFunc read FFromSortedConvFunc write FFromSortedConvFunc; property ToSortedCoversionFunc: TGTKSortCoversionFunc read FToSortedConvFunc write FToSortedConvFunc; + property FixedHeightMode: boolean read GetFixedHeightMode write SetFixedHeightMode; end; (****************************************** TGTKLISTVIEW ************************************************************************) @@ -255,6 +258,9 @@ type FSortable: boolean; FCompareFunc: TGTKTreeViewCompareFunc; FOnColumnsChanged: TNotifyEvent; + FChangedSignalHandlerID: gulong; + FRowActivatedSignalHandlerID: gulong; + FColumnsChangedSignalHandlerID: gulong; protected FListItems: TGTKListItems; procedure Recreate; @@ -291,6 +297,7 @@ begin FOnSelectionChanged := nil; FToSortedConvFunc := nil; FFromSortedConvFunc := nil; + FSelection := nil; end; destructor TGTKView.Destroy; @@ -388,6 +395,16 @@ begin gtk_tree_sortable_set_sort_column_id(PGtkTreeSortable(FTreeModelSort), Value, TGtkSortType(GetSortOrder)); end; +function TGTKView.GetFixedHeightMode: boolean; +begin + Result := gtk_tree_view_get_fixed_height_mode(PGtkTreeView(FWidget)); +end; + +procedure TGTKView.SetFixedHeightMode(Value: boolean); +begin + gtk_tree_view_set_fixed_height_mode(PGtkTreeView(FWidget), Value); +end; + procedure TGTKView.ConvertChildToPath(var Path: PGtkTreePath); var NewPath: PGtkTreePath; begin @@ -471,6 +488,9 @@ end; constructor TGTKListView.Create(AOwner: TComponent); begin inherited Create(AOwner); + FChangedSignalHandlerID := 0; + FRowActivatedSignalHandlerID := 0; + FColumnsChangedSignalHandlerID := 0; FListItems := TGTKListItems.Create(Self); FSortable := False; FCompareFunc := nil; @@ -479,6 +499,9 @@ end; destructor TGTKListView.Destroy; begin +// if FChangedSignalHandlerID > 0 then g_signal_handler_disconnect(PGObject(FSelection), FChangedSignalHandlerID); +// if FRowActivatedSignalHandlerID > 0 then g_signal_handler_disconnect(PGObject(FWidget), FRowActivatedSignalHandlerID); +// if FColumnsChangedSignalHandlerID > 0 then g_signal_handler_disconnect(PGObject(FWidget), FColumnsChangedSignalHandlerID); FListItems.Free; inherited Destroy; end; @@ -517,9 +540,9 @@ begin FWidget := gtk_tree_view_new_with_model(PGtkTreeModel(FTreeModelSort)); end; FSelection := gtk_tree_view_get_selection(PGtkTreeView(FWidget)); - g_signal_connect_data(PGObject(FSelection), 'changed', TGCallback(@TGTKListView_changed), Self, nil, G_CONNECT_DEFAULT); - g_signal_connect_data(PGObject(FWidget), 'row-activated', TGCallback(@TGTKListView_row_activated), Self, nil, G_CONNECT_DEFAULT); - g_signal_connect_data(PGObject(FWidget), 'columns-changed', TGCallback(@TGTKListView_columns_changed), Self, nil, [G_CONNECT_AFTER]); + FChangedSignalHandlerID := g_signal_connect_data(PGObject(FSelection), 'changed', TGCallback(@TGTKListView_changed), Self, nil, G_CONNECT_DEFAULT); + FRowActivatedSignalHandlerID := g_signal_connect_data(PGObject(FWidget), 'row-activated', TGCallback(@TGTKListView_row_activated), Self, nil, G_CONNECT_DEFAULT); + FColumnsChangedSignalHandlerID := g_signal_connect_data(PGObject(FWidget), 'columns-changed', TGCallback(@TGTKListView_columns_changed), Self, nil, [G_CONNECT_AFTER]); FTreeModel := gtk_tree_view_get_model(PGtkTreeView(FWidget)); Show; end; @@ -663,7 +686,7 @@ end; function TGTKListItems.GetItem(Index: longint): TGTKListItem; begin Result := TGTKListItem(FList[Index]); - Result.FIndex := Index; +// Result.FIndex := Index; end; procedure TGTKListItems.SetItem(Index: longint; Value: TGTKListItem); @@ -672,11 +695,12 @@ begin end; function TGTKListItems.Add: TGTKListItem; +var Item: TGTKListItem; begin - Result := TGTKListItem.Create(Self); - Result.FIndex := GetCount; -// Insert(GetCount, Result); - Append(Result); + Item := TGTKListItem.Create(Self); + Item.FIndex := GetCount; + Append(Item); + Result := Item; end; function TGTKListItems.GetCount: longint; @@ -691,16 +715,17 @@ begin end; procedure TGTKListItems.Delete(Index: longint); -var x: pointer; +var x: TGTKListItem; Iter: TGtkTreeIter; begin - x := FList[Index]; + Initialize(Iter); + x := TGTKListItem(FList[Index]); if gtk_tree_model_get_iter_from_string(PGtkTreeModel(FStore), @Iter, PChar(IntToStr(Index))) then begin // (FOwner as TGTKView).CovertSortableIter(Iter); gtk_list_store_remove(FStore, @Iter); - end; + end else writeln(' iter invalid!!!'); FList.Delete(Index); - TObject(x).Free; + x.Free; end; procedure TGTKListItems.Insert(Index: longint; Item: TGTKListItem); @@ -713,12 +738,217 @@ end; procedure TGTKListItems.Append(Item: TGTKListItem); var Iter: TGtkTreeIter; begin + Initialize(Iter); FList.Add(Item); gtk_list_store_append(FStore, @Iter); end; (********************************************************************************************************************************) (********************************************************************************************************************************) +constructor TGTKListItem.Create(AOwner: TComponent); +begin + inherited Create(AOwner); + FOwner := AOwner; + FData := nil; +end; + +destructor TGTKListItem.Destroy; +begin + inherited Destroy; +end; + +function TGTKListItem.AsString(Index: longint): string; +var Iter: TGtkTreeIter; + Val: Pgchar; +begin + Result := ''; + Val := nil; + if gtk_tree_model_get_iter_from_string(PGtkTreeModel((FOwner as TGTKListItems).FStore), @Iter, PChar(IntToStr(FIndex))) then + begin + gtk_tree_model_get(PGtkTreeModel((FOwner as TGTKListItems).FStore), @Iter, [Index, @Val, -1]); + if Assigned(Val) then Result := String(Val); + end; +end; + +function TGTKListItem.AsInteger(Index: longint): integer; +var Iter: TGtkTreeIter; + Val: glong; +begin + Result := 0; + Val := 0; + if gtk_tree_model_get_iter_from_string(PGtkTreeModel((FOwner as TGTKListItems).FStore), @Iter, PChar(IntToStr(FIndex))) then + begin + gtk_tree_model_get(PGtkTreeModel((FOwner as TGTKListItems).FStore), @Iter, [Index, @Val, -1]); + Result := Val; + end; +end; + +function TGTKListItem.AsPointer(Index: longint): pointer; +var Iter: TGtkTreeIter; + Val: Pointer; +begin + Result := nil; + Val := nil; + if gtk_tree_model_get_iter_from_string(PGtkTreeModel((FOwner as TGTKListItems).FStore), @Iter, PChar(IntToStr(FIndex))) then + begin + gtk_tree_model_get(PGtkTreeModel((FOwner as TGTKListItems).FStore), @Iter, [Index, @Val, -1]); + Result := Val; + end; +end; + +function TGTKListItem.AsBoolean(Index: longint): boolean; +var Iter: TGtkTreeIter; + Val: gboolean; +begin + Result := False; + Val := False; + if gtk_tree_model_get_iter_from_string(PGtkTreeModel((FOwner as TGTKListItems).FStore), @Iter, PChar(IntToStr(FIndex))) then + begin + gtk_tree_model_get(PGtkTreeModel((FOwner as TGTKListItems).FStore), @Iter, [Index, @Val, -1]); + Result := Val; + end; +end; + +procedure TGTKListItem.SetValue(Index: longint; Value: string); +var Iter: TGtkTreeIter; +begin + if gtk_tree_model_get_iter_from_string(PGtkTreeModel((FOwner as TGTKListItems).FStore), @Iter, PChar(IntToStr(FIndex))) + then gtk_list_store_set((FOwner as TGTKListItems).FStore, @Iter, [Index, PChar(Value), -1]); +end; + +procedure TGTKListItem.SetValue(Index: longint; Value: integer); +var Iter: TGtkTreeIter; +begin + if gtk_tree_model_get_iter_from_string(PGtkTreeModel((FOwner as TGTKListItems).FStore), @Iter, PChar(IntToStr(FIndex))) + then gtk_list_store_set((FOwner as TGTKListItems).FStore, @Iter, [Index, glong(Value), -1]); +end; + +procedure TGTKListItem.SetValue(Index: longint; Value: pointer); +var Iter: TGtkTreeIter; +begin + if gtk_tree_model_get_iter_from_string(PGtkTreeModel((FOwner as TGTKListItems).FStore), @Iter, PChar(IntToStr(FIndex))) + then gtk_list_store_set((FOwner as TGTKListItems).FStore, @Iter, [Index, gpointer(Value), -1]); +end; + +procedure TGTKListItem.SetValue(Index: longint; Value: boolean); +var Iter: TGtkTreeIter; +begin + if gtk_tree_model_get_iter_from_string(PGtkTreeModel((FOwner as TGTKListItems).FStore), @Iter, PChar(IntToStr(FIndex))) + then gtk_list_store_set((FOwner as TGTKListItems).FStore, @Iter, [Index, gboolean(Value), -1]); +end; + +function TGTKListItem.GetSelected: boolean; +var Iter: TGtkTreeIter; +begin + Result := False; + if gtk_tree_model_get_iter_from_string(PGtkTreeModel((FOwner as TGTKListItems).FStore), @Iter, PChar(IntToStr(FIndex))) then begin +// ((FOwner as TGTKListItems).FOwner as TGTKView).ConvertSortableIter(Iter); + Result := gtk_tree_selection_iter_is_selected(((FOwner as TGTKListItems).FOwner as TGTKView).FSelection, @Iter); + end; +end; + +procedure TGTKListItem.SetSelected(Value: boolean); +var Iter, NewIter: TGtkTreeIter; +begin + try + if gtk_tree_model_get_iter_from_string(PGtkTreeModel((FOwner as TGTKListItems).FStore), @Iter, PChar(IntToStr(FIndex))) then begin + if Assigned(((FOwner as TGTKListItems).FOwner as TGTKView).FTreeModelSort) then begin + gtk_tree_model_sort_convert_child_iter_to_iter(((FOwner as TGTKListItems).FOwner as TGTKView).FTreeModelSort, @NewIter, @Iter); + Iter := NewIter; + end; + if Value then gtk_tree_selection_select_iter(((FOwner as TGTKListItems).FOwner as TGTKView).FSelection, @Iter) + else gtk_tree_selection_unselect_iter(((FOwner as TGTKListItems).FOwner as TGTKView).FSelection, @Iter); + end; + except end; +end; + +procedure TGTKListItem.SetCursor(const FocusColumnNo: integer; const StartEditing, UseAlignment: boolean; const AlignX, AlignY: Double); +var Path: PGtkTreePath; + Column: PGtkTreeViewColumn; +// Renderer: PGtkCellRenderer; + i : integer; +begin + Path := gtk_tree_path_new_from_string(PChar(IntToStr(FIndex))); + if not Assigned(Path) then Exit; + ((FOwner as TGTKListItems).FOwner as TGTKView).ConvertChildToPath(Path); + if not Assigned(Path) then Exit; + + Column := ((FOwner as TGTKListItems).FOwner as TGTKView).Columns[FocusColumnNo].FColumn; +// Renderer := ((FOwner as TGTKListItems).FOwner as TGTKView).Columns[FocusColumnNo].FRenderer; + + gtk_tree_view_set_cursor(PGtkTreeView(((FOwner as TGTKListItems).FOwner as TGTKView).FWidget), Path, Column, StartEditing); +// gtk_tree_view_set_cursor(PGtkTreeView(((FOwner as TGTKListItems).FOwner as TGTKView).FWidget), Path, Column, StartEditing); +// gtk_tree_view_set_cursor_on_cell(PGtkTreeView(((FOwner as TGTKListItems).FOwner as TGTKView).FWidget), Path, Column, Renderer, StartEditing); + gtk_tree_view_scroll_to_cell(PGtkTreeView(((FOwner as TGTKListItems).FOwner as TGTKView).FWidget), Path, nil, UseAlignment, AlignX, AlignY); + + gtk_tree_path_free(Path); +end; + +procedure TGTKListItem.StartEditing(ColumnNo: integer); +var CellEditable: PGtkCellEditable; + Path: PGtkTreePath; + Column: PGtkTreeViewColumn; + BackgroundRect, CellRect: TGdkRectangle; +begin + Path := gtk_tree_path_new_from_string(PChar(IntToStr(FIndex))); + if not Assigned(Path) then Exit; + ((FOwner as TGTKListItems).FOwner as TGTKView).ConvertChildToPath(Path); + if not Assigned(Path) then Exit; + Column := ((FOwner as TGTKListItems).FOwner as TGTKView).Columns[ColumnNo].FColumn; + gtk_tree_view_get_background_area(PGtkTreeView(((FOwner as TGTKListItems).FOwner as TGTKView).FWidget), Path, Column, @BackgroundRect); + gtk_tree_view_get_cell_area(PGtkTreeView(((FOwner as TGTKListItems).FOwner as TGTKView).FWidget), Path, Column, @CellRect); + + gtk_tree_view_column_focus_cell(Column, ((FOwner as TGTKListItems).FOwner as TGTKView).Columns[ColumnNo].FRenderer); + CellEditable := gtk_cell_renderer_start_editing(((FOwner as TGTKListItems).FOwner as TGTKView).Columns[ColumnNo].FRenderer, + nil, ((FOwner as TGTKListItems).FOwner as TGTKView).FWidget, PChar(PChar(IntToStr(FIndex))), + @BackgroundRect, @CellRect, []); + gtk_widget_show(PGtkWidget(CellEditable)); +// gtk_cell_editable_start_editing(CellEditable, nil); + + + gtk_tree_path_free(Path); +end; + +procedure TGTKListItem.RedrawRow; +var Rect, BackgroundRect: TGdkRectangle; + Path: PGtkTreePath; + Column: PGtkTreeViewColumn; +begin +Exit; + Path := gtk_tree_path_new_from_string(PChar(IntToStr(FIndex))); + if not Assigned(Path) then Exit; + ((FOwner as TGTKListItems).FOwner as TGTKView).ConvertChildToPath(Path); + if not Assigned(Path) then Exit; + Column := ((FOwner as TGTKListItems).FOwner as TGTKView).Columns[0].FColumn; + gtk_tree_view_get_background_area(PGtkTreeView(((FOwner as TGTKListItems).FOwner as TGTKView).FWidget), Path, Column, @BackgroundRect); + + Rect.x := 0; + Rect.width := gtk_widget_get_allocated_width(((FOwner as TGTKListItems).FOwner as TGTKView).FWidget); + Rect.y := BackgroundRect.y; + Rect.height := BackgroundRect.height; + gdk_window_invalidate_rect(gtk_tree_view_get_bin_window(PGtkTreeView(((FOwner as TGTKListItems).FOwner as TGTKView).FWidget)), @Rect, True); + + gtk_tree_path_free(Path); +end; + +function TGTKListItem.IsVisible: boolean; +var CellRect, VisibleRect: TGdkRectangle; + Path: PGtkTreePath; +begin + Result := False; + Exit; + gtk_tree_view_get_visible_rect(PGtkTreeView(((FOwner as TGTKListItems).FOwner as TGTKView).FWidget), @VisibleRect); + Path := gtk_tree_path_new_from_string(PChar(IntToStr(FIndex))); + if not Assigned(Path) then Exit; + ((FOwner as TGTKListItems).FOwner as TGTKView).ConvertChildToPath(Path); + if not Assigned(Path) then Exit; + gtk_tree_view_get_background_area(PGtkTreeView(((FOwner as TGTKListItems).FOwner as TGTKView).FWidget), Path, nil, @CellRect); + gtk_tree_path_free(Path); + Result := (CellRect.y > VisibleRect.y) and (CellRect.y + CellRect.height < VisibleRect.y + VisibleRect.height); +end; + +(********************************************************************************************************************************) +(********************************************************************************************************************************) constructor TGTKTreeViewColumns.Create(AOwner: TComponent); begin inherited Create(AOwner); @@ -1108,209 +1338,6 @@ begin g_object_set_property(PGObject(FPixbufRenderer), PChar(AProperty), @AValue); end; -(********************************************************************************************************************************) -(********************************************************************************************************************************) -constructor TGTKListItem.Create(AOwner: TComponent); -begin - inherited Create(AOwner); - FOwner := AOwner; - FData := nil; -end; - -destructor TGTKListItem.Destroy; -begin - inherited Destroy; -end; - -function TGTKListItem.AsString(Index: longint): string; -var Iter: TGtkTreeIter; - AValue: TGValue; -begin - Result := ''; - if gtk_tree_model_get_iter_from_string(PGtkTreeModel((FOwner as TGTKListItems).FStore), @Iter, PChar(IntToStr(FIndex))) then - begin - AValue.g_type := 0; - gtk_tree_model_get_value(PGtkTreeModel((FOwner as TGTKListItems).FStore), @Iter, Index, @AValue); - Result := String(AValue.data[0].v_pointer); - end; -end; - -function TGTKListItem.AsInteger(Index: longint): integer; -var Iter: TGtkTreeIter; - AValue: TGValue; -begin - Result := 0; - if gtk_tree_model_get_iter_from_string(PGtkTreeModel((FOwner as TGTKListItems).FStore), @Iter, PChar(IntToStr(FIndex))) then - begin - AValue.g_type := 0; - gtk_tree_model_get_value(PGtkTreeModel((FOwner as TGTKListItems).FStore), @Iter, Index, @AValue); - Result := AValue.data[0].v_long; - end; -end; - -function TGTKListItem.AsPointer(Index: longint): pointer; -var Iter: TGtkTreeIter; - AValue: TGValue; -begin - Result := nil; - if gtk_tree_model_get_iter_from_string(PGtkTreeModel((FOwner as TGTKListItems).FStore), @Iter, PChar(IntToStr(FIndex))) then - begin - AValue.g_type := 0; - gtk_tree_model_get_value(PGtkTreeModel((FOwner as TGTKListItems).FStore), @Iter, Index, @AValue); - Result := AValue.data[0].v_pointer; - end; -end; - -function TGTKListItem.AsBoolean(Index: longint): boolean; -var Iter: TGtkTreeIter; - AValue: TGValue; -begin - Result := False; - if gtk_tree_model_get_iter_from_string(PGtkTreeModel((FOwner as TGTKListItems).FStore), @Iter, PChar(IntToStr(FIndex))) then - begin - AValue.g_type := 0; - gtk_tree_model_get_value(PGtkTreeModel((FOwner as TGTKListItems).FStore), @Iter, Index, @AValue); - Result := boolean(AValue.data[0].v_int); - end; -end; - -procedure TGTKListItem.SetValue(Index: longint; Value: string); -var Iter: TGtkTreeIter; -begin - if gtk_tree_model_get_iter_from_string(PGtkTreeModel((FOwner as TGTKListItems).FStore), @Iter, PChar(IntToStr(FIndex))) - then gtk_list_store_set((FOwner as TGTKListItems).FStore, @Iter, [Index, PChar(Value), -1]); -end; - -procedure TGTKListItem.SetValue(Index: longint; Value: integer); -var Iter: TGtkTreeIter; -begin - if gtk_tree_model_get_iter_from_string(PGtkTreeModel((FOwner as TGTKListItems).FStore), @Iter, PChar(IntToStr(FIndex))) - then gtk_list_store_set((FOwner as TGTKListItems).FStore, @Iter, [Index, Value, -1]); -end; - -procedure TGTKListItem.SetValue(Index: longint; Value: pointer); -var Iter: TGtkTreeIter; -begin - if gtk_tree_model_get_iter_from_string(PGtkTreeModel((FOwner as TGTKListItems).FStore), @Iter, PChar(IntToStr(FIndex))) - then gtk_list_store_set((FOwner as TGTKListItems).FStore, @Iter, [Index, Value, -1]); -end; - -procedure TGTKListItem.SetValue(Index: longint; Value: boolean); -var Iter: TGtkTreeIter; -begin - if gtk_tree_model_get_iter_from_string(PGtkTreeModel((FOwner as TGTKListItems).FStore), @Iter, PChar(IntToStr(FIndex))) - then gtk_list_store_set((FOwner as TGTKListItems).FStore, @Iter, [Index, Value, -1]); -end; - -function TGTKListItem.GetSelected: boolean; -var Iter: TGtkTreeIter; -begin - Result := False; - if gtk_tree_model_get_iter_from_string(PGtkTreeModel((FOwner as TGTKListItems).FStore), @Iter, PChar(IntToStr(FIndex))) then begin -// ((FOwner as TGTKListItems).FOwner as TGTKView).ConvertSortableIter(Iter); - Result := gtk_tree_selection_iter_is_selected(((FOwner as TGTKListItems).FOwner as TGTKView).FSelection, @Iter); - end; -end; - -procedure TGTKListItem.SetSelected(Value: boolean); -var Iter, NewIter: TGtkTreeIter; -begin - try - if gtk_tree_model_get_iter_from_string(PGtkTreeModel((FOwner as TGTKListItems).FStore), @Iter, PChar(IntToStr(FIndex))) then begin - if Assigned(((FOwner as TGTKListItems).FOwner as TGTKView).FTreeModelSort) then begin - gtk_tree_model_sort_convert_child_iter_to_iter(((FOwner as TGTKListItems).FOwner as TGTKView).FTreeModelSort, @NewIter, @Iter); - Iter := NewIter; - end; - if Value then gtk_tree_selection_select_iter(((FOwner as TGTKListItems).FOwner as TGTKView).FSelection, @Iter) - else gtk_tree_selection_unselect_iter(((FOwner as TGTKListItems).FOwner as TGTKView).FSelection, @Iter); - end; - except end; -end; - -procedure TGTKListItem.SetCursor(const FocusColumnNo: integer; const StartEditing, UseAlignment: boolean; const AlignX, AlignY: Double); -var Path: PGtkTreePath; - Column: PGtkTreeViewColumn; -// Renderer: PGtkCellRenderer; - i : integer; -begin - Path := gtk_tree_path_new_from_string(PChar(IntToStr(FIndex))); - if not Assigned(Path) then Exit; - ((FOwner as TGTKListItems).FOwner as TGTKView).ConvertChildToPath(Path); - if not Assigned(Path) then Exit; - - Column := ((FOwner as TGTKListItems).FOwner as TGTKView).Columns[FocusColumnNo].FColumn; -// Renderer := ((FOwner as TGTKListItems).FOwner as TGTKView).Columns[FocusColumnNo].FRenderer; - - for i := 1 to 2 do gtk_main_iteration_do(False); // This ugly piece of code HAVE TO BE HERE due some focus-related problems in GtkTreeView - gtk_tree_view_set_cursor(PGtkTreeView(((FOwner as TGTKListItems).FOwner as TGTKView).FWidget), Path, Column, StartEditing); -// gtk_tree_view_set_cursor(PGtkTreeView(((FOwner as TGTKListItems).FOwner as TGTKView).FWidget), Path, Column, StartEditing); -// gtk_tree_view_set_cursor_on_cell(PGtkTreeView(((FOwner as TGTKListItems).FOwner as TGTKView).FWidget), Path, Column, Renderer, StartEditing); - gtk_tree_view_scroll_to_cell(PGtkTreeView(((FOwner as TGTKListItems).FOwner as TGTKView).FWidget), Path, nil, UseAlignment, AlignX, AlignY); - - gtk_tree_path_free(Path); -end; - -procedure TGTKListItem.StartEditing(ColumnNo: integer); -var CellEditable: PGtkCellEditable; - Path: PGtkTreePath; - Column: PGtkTreeViewColumn; - BackgroundRect, CellRect: TGdkRectangle; -begin - Path := gtk_tree_path_new_from_string(PChar(IntToStr(FIndex))); - if not Assigned(Path) then Exit; - ((FOwner as TGTKListItems).FOwner as TGTKView).ConvertChildToPath(Path); - if not Assigned(Path) then Exit; - Column := ((FOwner as TGTKListItems).FOwner as TGTKView).Columns[ColumnNo].FColumn; - gtk_tree_view_get_background_area(PGtkTreeView(((FOwner as TGTKListItems).FOwner as TGTKView).FWidget), Path, Column, @BackgroundRect); - gtk_tree_view_get_cell_area(PGtkTreeView(((FOwner as TGTKListItems).FOwner as TGTKView).FWidget), Path, Column, @CellRect); - - gtk_tree_view_column_focus_cell(Column, ((FOwner as TGTKListItems).FOwner as TGTKView).Columns[ColumnNo].FRenderer); - CellEditable := gtk_cell_renderer_start_editing(((FOwner as TGTKListItems).FOwner as TGTKView).Columns[ColumnNo].FRenderer, - nil, ((FOwner as TGTKListItems).FOwner as TGTKView).FWidget, PChar(PChar(IntToStr(FIndex))), - @BackgroundRect, @CellRect, []); - gtk_widget_show(PGtkWidget(CellEditable)); -// gtk_cell_editable_start_editing(CellEditable, nil); - - - gtk_tree_path_free(Path); -end; - -procedure TGTKListItem.RedrawRow; -var Rect, BackgroundRect: TGdkRectangle; - Path: PGtkTreePath; - Column: PGtkTreeViewColumn; -begin - Path := gtk_tree_path_new_from_string(PChar(IntToStr(FIndex))); - if not Assigned(Path) then Exit; - ((FOwner as TGTKListItems).FOwner as TGTKView).ConvertChildToPath(Path); - if not Assigned(Path) then Exit; - Column := ((FOwner as TGTKListItems).FOwner as TGTKView).Columns[0].FColumn; - gtk_tree_view_get_background_area(PGtkTreeView(((FOwner as TGTKListItems).FOwner as TGTKView).FWidget), Path, Column, @BackgroundRect); - - Rect.x := 0; - Rect.width := gtk_widget_get_allocated_width(((FOwner as TGTKListItems).FOwner as TGTKView).FWidget); - Rect.y := BackgroundRect.y; - Rect.height := BackgroundRect.height; - gdk_window_invalidate_rect(gtk_tree_view_get_bin_window(PGtkTreeView(((FOwner as TGTKListItems).FOwner as TGTKView).FWidget)), @Rect, True); - - gtk_tree_path_free(Path); -end; - -function TGTKListItem.IsVisible: boolean; -var CellRect, VisibleRect: TGdkRectangle; - Path: PGtkTreePath; -begin - Result := False; - gtk_tree_view_get_visible_rect(PGtkTreeView(((FOwner as TGTKListItems).FOwner as TGTKView).FWidget), @VisibleRect); - Path := gtk_tree_path_new_from_string(PChar(IntToStr(FIndex))); - if not Assigned(Path) then Exit; - ((FOwner as TGTKListItems).FOwner as TGTKView).ConvertChildToPath(Path); - if not Assigned(Path) then Exit; - gtk_tree_view_get_background_area(PGtkTreeView(((FOwner as TGTKListItems).FOwner as TGTKView).FWidget), Path, nil, @CellRect); - gtk_tree_path_free(Path); - Result := (CellRect.y > VisibleRect.y) and (CellRect.y + CellRect.height < VisibleRect.y + VisibleRect.height); -end; - (********************************************************************************************************************************) (********************************************************************************************************************************) |
