1 2 3 4{ $Id$} 5{ 6 ***************************************************************************** 7 * GtkWSStdCtrls.pp * 8 * ---------------- * 9 * * 10 * * 11 ***************************************************************************** 12 13 ***************************************************************************** 14 This file is part of the Lazarus Component Library (LCL) 15 16 See the file COPYING.modifiedLGPL.txt, included in this distribution, 17 for details about the license. 18 ***************************************************************************** 19} 20unit GtkWSStdCtrls; 21 22{$mode objfpc}{$H+} 23 24interface 25 26uses 27 Classes, SysUtils, Math, 28 LCLType, LMessages, LCLProc, Controls, Graphics, StdCtrls, Forms, 29 {$IFDEF gtk2} 30 glib2, gdk2pixbuf, gdk2, gtk2, Pango, Gtk2WSPrivate, 31 {$ELSE} 32 glib, gdk, gtk, gdkpixbuf, 33 GtkFontCache, Gtk1WSPrivate, 34 {$ENDIF} 35 InterfaceBase, WSStdCtrls, WSLCLClasses, WSProc, WSControls, 36 GtkInt, GtkDef, GTKWinApiWindow, GtkGlobals, GtkProc, GtkExtra, GtkWSPrivate; 37 38 39type 40 41 { TGtkWSScrollBar } 42 43 TGtkWSScrollBar = class(TWSScrollBar) 44 protected 45 class procedure SetCallbacks(const AGtkWidget: PGtkWidget; const AWidgetInfo: PWidgetInfo); virtual; 46 published 47 class function CreateHandle(const AWinControl: TWinControl; const AParams: TCreateParams): TLCLIntfHandle; override; 48 class procedure SetParams(const AScrollBar: TCustomScrollBar); override; 49 end; 50 51 { TGtkWSCustomGroupBox } 52 53 TGtkWSCustomGroupBox = class(TWSCustomGroupBox) 54 protected 55 class procedure SetCallbacks(const AGtkWidget: PGtkWidget; const AWidgetInfo: PWidgetInfo); virtual; 56 published 57 {$ifdef gtk1} 58 class function CreateHandle(const AWinControl: TWinControl; const AParams: TCreateParams): TLCLIntfHandle; override; 59 class procedure GetPreferredSize(const AWinControl: TWinControl; 60 var PreferredWidth, PreferredHeight: integer; 61 WithThemeSpace: Boolean); override; 62 class procedure SetText(const AWinControl: TWinControl; const AText: string); override; 63 {$endif} 64 end; 65 66 { TGtkWSGroupBox } 67 68 TGtkWSGroupBox = class(TWSGroupBox) 69 published 70 end; 71 72 { TGtkWSCustomComboBox } 73 74 TGtkWSCustomComboBox = class(TWSCustomComboBox) 75 published 76 {$IFDEF GTK1} 77 class procedure SetCallbacks(const AGtkWidget: PGtkWidget; const AWidgetInfo: PWidgetInfo); virtual; 78 class function CreateHandle(const AWinControl: TWinControl; const AParams: TCreateParams): TLCLIntfHandle; override; 79 class function GetDroppedDown(const ACustomComboBox: TCustomComboBox): Boolean; override; 80 class function GetSelStart(const ACustomComboBox: TCustomComboBox): integer; override; 81 class function GetSelLength(const ACustomComboBox: TCustomComboBox): integer; override; 82 class function GetItemIndex(const ACustomComboBox: TCustomComboBox): integer; override; 83 class function GetMaxLength(const ACustomComboBox: TCustomComboBox): integer; override; 84 class function GetText(const AWinControl: TWinControl; var AText: String): Boolean; override; 85 86 class procedure SetArrowKeysTraverseList(const ACustomComboBox: TCustomComboBox; 87 NewTraverseList: boolean); override; 88 class procedure SetDroppedDown(const ACustomComboBox: TCustomComboBox; ADroppedDown: Boolean); override; 89 class procedure SetSelStart(const ACustomComboBox: TCustomComboBox; NewStart: integer); override; 90 class procedure SetSelLength(const ACustomComboBox: TCustomComboBox; NewLength: integer); override; 91 class procedure SetItemIndex(const ACustomComboBox: TCustomComboBox; NewIndex: integer); override; 92 class procedure SetMaxLength(const ACustomComboBox: TCustomComboBox; NewLength: integer); override; 93 class procedure SetStyle(const ACustomComboBox: TCustomComboBox; NewStyle: TComboBoxStyle); override; 94 class procedure SetText(const AWinControl: TWinControl; const AText: String); override; 95 96 class function GetItems(const ACustomComboBox: TCustomComboBox): TStrings; override; 97 class procedure Sort(const ACustomComboBox: TCustomComboBox; AList: TStrings; IsSorted: boolean); override; 98 class procedure SetColor(const AWinControl: TWinControl); override; 99 class procedure SetFont(const AWinControl: TWinControl; const AFont: TFont); override; 100 {$ENDIF} 101 end; 102 103 { TGtkWSComboBox } 104 105 TGtkWSComboBox = class(TWSComboBox) 106 published 107 end; 108 109 { TGtkWSCustomListBox } 110 111 TGtkWSCustomListBox = class(TWSCustomListBox) 112 published 113 {$IFDEF GTK1} 114 class function CreateHandle(const AWinControl: TWinControl; const AParams: TCreateParams): TLCLIntfHandle; override; 115 class function GetIndexAtXY(const ACustomListBox: TCustomListBox; X, Y: integer): integer; override; 116 class function GetItemIndex(const ACustomListBox: TCustomListBox): integer; override; 117 class function GetItemRect(const ACustomListBox: TCustomListBox; Index: integer; var ARect: TRect): boolean; override; 118 class function GetSelCount(const ACustomListBox: TCustomListBox): integer; override; 119 class function GetSelected(const ACustomListBox: TCustomListBox; const AIndex: integer): boolean; override; 120 class function GetStrings(const ACustomListBox: TCustomListBox): TStrings; override; 121 class function GetTopIndex(const ACustomListBox: TCustomListBox): integer; override; 122 123 class procedure SelectItem(const ACustomListBox: TCustomListBox; AIndex: integer; ASelected: boolean); override; 124 class procedure SetBorder(const ACustomListBox: TCustomListBox); override; 125 class procedure SetItemIndex(const ACustomListBox: TCustomListBox; const AIndex: integer); override; 126 class procedure SetSelectionMode(const ACustomListBox: TCustomListBox; const AExtendedSelect, AMultiSelect: boolean); override; 127 class procedure SetSorted(const ACustomListBox: TCustomListBox; AList: TStrings; ASorted: boolean); override; 128 class procedure SetTopIndex(const ACustomListBox: TCustomListBox; const NewTopIndex: integer); override; 129 class procedure SetColor(const AWinControl: TWinControl); override; 130 class procedure SetFont(const AWinControl: TWinControl; const AFont: TFont); override; 131 {$ENDIF} 132 end; 133 134 { TGtkWSListBox } 135 136 TGtkWSListBox = class(TWSListBox) 137 published 138 end; 139 140 { TGtkWSCustomEdit } 141 142 TGtkWSCustomEdit = class(TWSCustomEdit) 143 published 144 class procedure SetCallbacks(const AGtkWidget: PGtkWidget; const AWidgetInfo: PWidgetInfo); virtual; 145 class function CreateHandle(const AWinControl: TWinControl; const AParams: TCreateParams): TLCLIntfHandle; override; 146 class function GetSelStart(const ACustomEdit: TCustomEdit): integer; override; 147 class function GetSelLength(const ACustomEdit: TCustomEdit): integer; override; 148 149 class procedure SetCharCase(const ACustomEdit: TCustomEdit; NewCase: TEditCharCase); override; 150 class procedure SetEchoMode(const ACustomEdit: TCustomEdit; NewMode: TEchoMode); override; 151 class procedure SetMaxLength(const ACustomEdit: TCustomEdit; NewLength: integer); override; 152 class procedure SetPasswordChar(const ACustomEdit: TCustomEdit; NewChar: char); override; 153 class procedure SetReadOnly(const ACustomEdit: TCustomEdit; NewReadOnly: boolean); override; 154 class procedure SetSelStart(const ACustomEdit: TCustomEdit; NewStart: integer); override; 155 class procedure SetSelLength(const ACustomEdit: TCustomEdit; NewLength: integer); override; 156 class procedure SetText(const AWinControl: TWinControl; const AText: string); override; 157 158 class procedure GetPreferredSize(const AWinControl: TWinControl; 159 var PreferredWidth, PreferredHeight: integer; 160 WithThemeSpace: Boolean); override; 161 class procedure SetColor(const AWinControl: TWinControl); override; 162 end; 163 164 { TGtkWSCustomMemo } 165 166 TGtkWSCustomMemo = class(TWSCustomMemo) 167 published 168 {$ifdef GTK1} 169 class procedure SetCallbacks(const AGtkWidget: PGtkWidget; const AWidgetInfo: PWidgetInfo); virtual; 170 class function CreateHandle(const AWinControl: TWinControl; 171 const AParams: TCreateParams): TLCLIntfHandle; override; 172 class procedure AppendText(const ACustomMemo: TCustomMemo; 173 const AText: string); override; 174 class function GetStrings(const ACustomMemo: TCustomMemo): TStrings; override; 175 class procedure SetEchoMode(const ACustomEdit: TCustomEdit; 176 NewMode: TEchoMode); override; 177 class procedure SetMaxLength(const ACustomEdit: TCustomEdit; 178 NewLength: integer); override; 179 class procedure SetPasswordChar(const ACustomEdit: TCustomEdit; 180 NewChar: char); override; 181 class procedure SetReadOnly(const ACustomEdit: TCustomEdit; 182 NewReadOnly: boolean); override; 183 class procedure SetScrollbars(const ACustomMemo: TCustomMemo; 184 const NewScrollbars: TScrollStyle); override; 185 class procedure SetWordWrap(const ACustomMemo: TCustomMemo; 186 const NewWordWrap: boolean); override; 187 class procedure SetColor(const AWinControl: TWinControl); override; 188 class procedure SetFont(const AWinControl: TWinControl; const AFont: TFont); override; 189 {$endif} 190 end; 191 192 { TGtkWSEdit } 193 194 TGtkWSEdit = class(TWSEdit) 195 published 196 end; 197 198 { TGtkWSMemo } 199 200 TGtkWSMemo = class(TWSMemo) 201 published 202 end; 203 204 { TGtkWSCustomStaticText } 205 206 TGtkWSCustomStaticText = class(TWSCustomStaticText) 207 protected 208 class function GetLabelWidget(AFrame: PGtkFrame): PGtkLabel; 209 class function GetBoxWidget(AFrame: PGtkFrame): PGtkEventBox; 210 published 211 class function CreateHandle(const AWinControl: TWinControl; const AParams: TCreateParams): TLCLIntfHandle; override; 212 class procedure SetAlignment(const ACustomStaticText: TCustomStaticText; 213 const NewAlignment: TAlignment); override; 214 class procedure GetPreferredSize(const AWinControl: TWinControl; 215 var PreferredWidth, PreferredHeight: integer; 216 WithThemeSpace: Boolean); override; 217 class function GetText(const AWinControl: TWinControl; var AText: String): Boolean; override; 218 class procedure SetCallbacks(const AGtkWidget: PGtkWidget; const AWidgetInfo: PWidgetInfo); 219 class procedure SetColor(const AWinControl: TWinControl); override; 220 class procedure SetFont(const AWinControl: TWinControl; const AFont: TFont); override; 221 class procedure SetStaticBorderStyle(const ACustomStaticText: TCustomStaticText; const NewBorderStyle: TStaticBorderStyle); override; 222 class procedure SetText(const AWinControl: TWinControl; const AText: String); override; 223 end; 224 225 { TGtkWSStaticText } 226 227 TGtkWSStaticText = class(TWSStaticText) 228 published 229 end; 230 231 { TGtkWSButtonControl } 232 233 TGtkWSButtonControl = class(TWSButtonControl) 234 published 235 end; 236 237 { TGtkWSButton } 238 239 TGtkWSButton = class(TWSButton) 240 public 241 {SetCallbacks is made public so that it can be called from 242 TGtkWSBitBtn.CreateHandle. 243 TODO: move it to TGtkPrivateButton} 244 class procedure SetCallbacks(const AGtkWidget: PGtkWidget; const AWidgetInfo: PWidgetInfo); virtual; 245 published 246 {$ifdef Gtk1} 247 class function CreateHandle(const AWinControl: TWinControl; const AParams: TCreateParams): TLCLIntfHandle; override; 248 class procedure GetPreferredSize(const AWinControl: TWinControl; 249 var PreferredWidth, PreferredHeight: integer; 250 WithThemeSpace: Boolean); override; 251 class function GetText(const AWinControl: TWinControl; var AText: String): Boolean; override; 252 253 class procedure SetColor(const AWinControl: TWinControl); override; 254 class procedure SetFont(const AWinControl: TWinControl; const AFont: TFont); override; 255 class procedure SetDefault(const AButton: TCustomButton; ADefault: Boolean); override; 256 class procedure SetShortcut(const AButton: TCustomButton; const ShortCutK1, ShortCutK2: TShortcut); override; 257 class procedure SetText(const AWinControl: TWinControl; const AText: String); override; 258 {$endif Gtk1} 259 end; 260 261 { TGtkWSCustomCheckBox } 262 263 TGtkWSCustomCheckBox = class(TWSCustomCheckBox) 264 protected 265 class procedure SetCallbacks(const AGtkWidget: PGtkWidget; const AWidgetInfo: PWidgetInfo); virtual; 266 published 267 {$IFDEF GTK1} 268 class function CreateHandle(const AWinControl: TWinControl; const AParams: TCreateParams): TLCLIntfHandle; override; 269 class function RetrieveState(const ACustomCheckBox: TCustomCheckBox): TCheckBoxState; override; 270 class procedure SetShortCut(const ACustomCheckBox: TCustomCheckBox; const ShortCutK1, ShortCutK2: TShortCut); override; 271 class procedure SetState(const ACB: TCustomCheckBox; const ANewState: TCheckBoxState); override; 272 class procedure GetPreferredSize(const AWinControl: TWinControl; 273 var PreferredWidth, PreferredHeight: integer; 274 WithThemeSpace: Boolean); override; 275 class procedure SetFont(const AWinControl: TWinControl; const AFont: TFont); override; 276 {$ENDIF} 277 end; 278 279 { TGtkWSCheckBox } 280 281 TGtkWSCheckBox = class(TWSCheckBox) 282 published 283 end; 284 285 { TGtkWSToggleBox } 286 287 TGtkWSToggleBox = class(TWSToggleBox) 288 published 289 class function CreateHandle(const AWinControl: TWinControl; const AParams: TCreateParams): TLCLIntfHandle; override; 290 end; 291 292 { TGtkWSRadioButton } 293 294 TGtkWSRadioButton = class(TWSRadioButton) 295 published 296 class function CreateHandle(const AWinControl: TWinControl; const AParams: TCreateParams): TLCLIntfHandle; override; 297 end; 298 299function WidgetGetSelStart(const Widget: PGtkWidget): integer; 300procedure WidgetSetSelLength(const Widget: PGtkWidget; NewLength: integer); 301 302{$ifdef gtk1} 303{$I gtk1memostringsh.inc} 304{$endif} 305 306implementation 307 308uses 309 GtkWSControls; 310 311const 312 StaticBorderShadowMap: array[TStaticBorderStyle] of TGtkShadowType = 313 ( 314 GTK_SHADOW_NONE, 315 GTK_SHADOW_ETCHED_IN, 316 GTK_SHADOW_IN 317 ); 318 319{$ifdef gtk1} 320{$I gtk1memostrings.inc} 321{$endif} 322 323{ helper routines } 324 325 326 327function WidgetGetSelStart(const Widget: PGtkWidget): integer; 328begin 329 if Widget <> nil then 330 begin 331 if PGtkOldEditable(Widget)^.selection_start_pos 332 < PGtkOldEditable(Widget)^.selection_end_pos 333 then 334 Result:= PGtkOldEditable(Widget)^.selection_start_pos 335 else 336 Result:= PGtkOldEditable(Widget)^.current_pos;// selection_end_pos 337 end else 338 Result:= 0; 339end; 340 341procedure WidgetSetSelLength(const Widget: PGtkWidget; NewLength: integer); 342begin 343 if Widget<>nil then 344 begin 345 gtk_editable_select_region(PGtkOldEditable(Widget), 346 gtk_editable_get_position(PGtkOldEditable(Widget)), 347 gtk_editable_get_position(PGtkOldEditable(Widget)) + NewLength); 348 end; 349end; 350 351{ TGtkWSScrollBar } 352 353class procedure TGtkWSScrollBar.SetCallbacks(const AGtkWidget: PGtkWidget; 354 const AWidgetInfo: PWidgetInfo); 355begin 356 TGtkWSWinControl.SetCallbacks(PGtkObject(AGtkWidget), TComponent(AWidgetInfo^.LCLObject)); 357 358 if TScrollBar(AWidgetInfo^.LCLObject).Kind = sbHorizontal then 359 TGtkWidgetset(Widgetset).SetCallback(LM_HSCROLL, PGtkObject(AGtkWidget), AWidgetInfo^.LCLObject) 360 else 361 TGtkWidgetset(Widgetset).SetCallback(LM_VSCROLL, PGtkObject(AGtkWidget), AWidgetInfo^.LCLObject); 362end; 363 364class function TGtkWSScrollBar.CreateHandle(const AWinControl: TWinControl; 365 const AParams: TCreateParams): TLCLIntfHandle; 366var 367 Adjustment: PGtkAdjustment; 368 Widget: PGtkWidget; 369 WidgetInfo: PWidgetInfo; 370begin 371 with TScrollBar(AWinControl) do 372 begin 373 Adjustment := PgtkAdjustment( 374 gtk_adjustment_new(1, Min, Max, SmallChange, LargeChange, 375 Pagesize)); 376 377 if (Kind = sbHorizontal) then 378 Widget := gtk_hscrollbar_new(Adjustment) 379 else 380 Widget := gtk_vscrollbar_new(Adjustment); 381 end; 382 gtk_object_set_data(PGTKObject(Adjustment), odnScrollBar, Widget); 383 384 Result := TLCLIntfHandle(PtrUInt(Widget)); 385 {$IFDEF DebugLCLComponents} 386 DebugGtkWidgets.MarkCreated(Widget, dbgsName(AWinControl)); 387 {$ENDIF} 388 WidgetInfo := CreateWidgetInfo(Pointer(Result), AWinControl, AParams); 389 Set_RC_Name(AWinControl, Widget); 390 SetCallbacks(Widget, WidgetInfo); 391end; 392 393class procedure TGtkWSScrollBar.SetParams(const AScrollBar: TCustomScrollBar); 394var 395 Adjustment: PGtkAdjustment; 396begin 397 with AScrollBar do 398 begin 399 //set properties for the range 400 Adjustment := gtk_range_get_adjustment (GTK_RANGE(Pointer(Handle))); 401 Adjustment^.lower := Min; 402 Adjustment^.Upper := Max; 403 Adjustment^.Value := Position; 404 Adjustment^.step_increment := SmallChange; 405 Adjustment^.page_increment := LargeChange; 406 end; 407end; 408 409{ TGtkWSCustomListBox } 410 411{$IFDEF GTK1} 412 413class function TGtkWSCustomListBox.CreateHandle(const AWinControl: TWinControl; 414 const AParams: TCreateParams): TLCLIntfHandle; 415var 416 Widget: PGtkWidget; 417 WidgetInfo: PWidgetInfo; 418 ScrolledWnd: PGtkScrolledWindow absolute Widget; 419 ListBox: TCustomListBox absolute AWinControl; 420 List: Pointer; 421begin 422 Widget := gtk_scrolled_window_new(nil, nil); 423 GTK_WIDGET_UNSET_FLAGS(ScrolledWnd^.hscrollbar, GTK_CAN_FOCUS); 424 GTK_WIDGET_UNSET_FLAGS(ScrolledWnd^.vscrollbar, GTK_CAN_FOCUS); 425 gtk_scrolled_window_set_policy(ScrolledWnd, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); 426 gtk_widget_show(Widget); 427 428 List := gtk_list_new; 429 gtk_scrolled_window_add_with_viewport(ScrolledWnd, List); 430 gtk_container_set_focus_vadjustment(List, 431 gtk_scrolled_window_get_vadjustment(ScrolledWnd)); 432 gtk_container_set_focus_hadjustment(PGtkContainer(List), 433 gtk_scrolled_window_get_hadjustment(ScrolledWnd)); 434 gtk_widget_show(List); 435 436 WidgetInfo := CreateWidgetInfo(Widget, AWinControl, AParams); 437 SetMainWidget(Widget, List); 438 WidgetInfo^.CoreWidget := List; 439 440 TGtkWidgetSet(WidgetSet).SetSelectionMode(AWinControl, Widget, 441 ListBox.MultiSelect, ListBox.ExtendedSelect); 442 443 Result := TLCLIntfHandle(PtrUInt(Widget)); 444 {$IFDEF DebugLCLComponents} 445 DebugGtkWidgets.MarkCreated(Widget, dbgsName(AWinControl)); 446 {$ENDIF} 447 Set_RC_Name(AWinControl, Widget); 448 449 TGtkPrivateListClass(WSPrivate).SetCallbacks(Widget, WidgetInfo); 450end; 451 452class function TGtkWSCustomListBox.GetIndexAtXY( 453 const ACustomListBox: TCustomListBox; X, Y: integer): integer; 454var 455 ScrolledWindow: PGtkScrolledWindow; 456 VertAdj: PGTKAdjustment; 457 AdjValue: integer; 458 ListWidget: PGtkList; 459 AWidget: PGtkWidget; 460 GListItem: PGList; 461 ListItemWidget: PGtkWidget; 462begin 463 Result:=-1; 464 465 if ACustomListBox.FCompStyle in [csListBox, csCheckListBox] then 466 begin 467 AWidget:=PGtkWidget(ACustomListBox.Handle); 468 ListWidget:=PGtkList(GetWidgetInfo(AWidget, True)^.CoreWidget); 469 ScrolledWindow:=PGtkScrolledWindow(AWidget); 470 VertAdj:=gtk_scrolled_window_get_vadjustment(ScrolledWindow); 471 if VertAdj=nil then 472 AdjValue:=y 473 else 474 AdjValue:=RoundToInt(VertAdj^.value)+y; 475 GListItem:=ListWidget^.children; 476 while GListItem<>nil do begin 477 inc(Result); 478 ListItemWidget:=PGtkWidget(GListItem^.data); 479 dec(AdjValue,ListItemWidget^.Allocation.Height); 480 if AdjValue<0 then exit; 481 GListItem:=GListItem^.next; 482 end; 483 Result:=-1; 484 end; 485end; 486 487class function TGtkWSCustomListBox.GetItemIndex(const ACustomListBox: TCustomListBox 488 ): integer; 489var 490 Widget: PGtkWidget;// pointer to gtk-widget 491 GList : pGList; // Only used for listboxes, replace with widget!!!!! 492 Handle: HWND; 493begin 494 Handle := ACustomListBox.Handle; 495 {!$IFdef GTK1} 496 if Handle<>0 then 497 begin 498 Widget := nil; 499 if Widget = nil then 500 begin 501 GList:= PGtkList(GetWidgetInfo(Pointer(Handle), True)^. 502 CoreWidget)^.selection; 503 if GList <> nil then 504 Widget:= PGtkWidget(GList^.data); 505 end; 506 if Widget = nil then 507 Result:= -1 508 else 509 Result:= gtk_list_child_position(PGtkList( 510 GetWidgetInfo(Pointer(Handle), True)^. 511 CoreWidget), Widget); 512 end 513 else 514 Result:=-1; 515 {!$EndIf} 516end; 517 518class function TGtkWSCustomListBox.GetItemRect( 519 const ACustomListBox: TCustomListBox; Index: integer; var ARect: TRect 520 ): boolean; 521var 522 ScrolledWindow: PGtkScrolledWindow; 523 VertAdj: PGTKAdjustment; 524 AdjValue: integer; 525 ListWidget: PGtkList; 526 AWidget: PGtkWidget; 527 GListItem: PGList; 528 ListItemWidget: PGtkWidget; 529begin 530 Result:=false; 531 FillChar(ARect,SizeOf(ARect),0); 532 533 if ACustomListBox.FCompStyle in [csListBox, csCheckListBox] then 534 begin 535 AWidget:=PGtkWidget(ACustomListBox.Handle); 536 ListWidget:=PGtkList(GetWidgetInfo(AWidget, True)^.CoreWidget); 537 ScrolledWindow:=PGtkScrolledWindow(AWidget); 538 VertAdj:=gtk_scrolled_window_get_vadjustment(ScrolledWindow); 539 540 if VertAdj=nil then 541 AdjValue:=0 542 else 543 AdjValue:= (-RoundToInt(VertAdj^.value)); 544 545 GListItem:=ListWidget^.children; 546 while GListItem<>nil do 547 begin 548 ListItemWidget:=PGtkWidget(GListItem^.data); 549 if Index=0 then 550 begin 551 ARect.Left:=0; 552 ARect.Top:=AdjValue; 553 ARect.Right:=ListItemWidget^.Allocation.Width; 554 ARect.Bottom:=ARect.Top+ListItemWidget^.Allocation.Height; 555 Result:=true; 556 exit; 557 end; 558 inc(AdjValue,ListItemWidget^.Allocation.Height); 559 dec(Index); 560 GListItem:=GListItem^.next; 561 end; 562 end; 563end; 564 565class function TGtkWSCustomListBox.GetSelCount(const ACustomListBox: TCustomListBox 566 ): integer; 567var 568 Handle: HWND; 569begin 570 Handle := ACustomListBox.Handle; 571 572 Result := g_list_length(PGtkList(GetWidgetInfo(Pointer(Handle), 573 True)^.CoreWidget)^.selection); 574end; 575 576class function TGtkWSCustomListBox.GetSelected(const ACustomListBox: TCustomListBox; 577 const AIndex: integer): boolean; 578var 579 Handle: HWND; 580 Widget : PGtkWidget; // pointer to gtk-widget (local use when neccessary) 581 //GList : pGList; // Only used for listboxes, replace with widget!!!!! 582 ListItem : PGtkListItem;// currently only used for listboxes 583begin 584 Result := false; { assume: nothing found } 585 Handle := ACustomListBox.Handle; 586 587 { Get the child in question of that index } 588 Widget:=GetWidgetInfo(Pointer(Handle),True)^.CoreWidget; 589 ListItem:= g_list_nth_data(PGtkList(Widget)^.children, AIndex); 590 if (ListItem<>nil) 591 and (g_list_index(PGtkList(Widget)^.selection, ListItem)>=0) 592 then Result:=true 593 594 //if CompareText(ACustomListBox.Name,'LBProperties')=0 then 595 // debugln('TGtkWSCustomListBox.GetSelected ',DbgSName(ACustomListBox),' Index=',dbgs(AIndex),' Selected=',dbgs(Result)); 596end; 597 598class function TGtkWSCustomListBox.GetStrings(const ACustomListBox: TCustomListBox 599 ): TStrings; 600var 601 Widget: PGtkWidget;// pointer to gtk-widget 602 Handle: HWND; 603begin 604 Handle := ACustomListBox.Handle; 605 606 Widget := GetWidgetInfo(Pointer(Handle), True)^.CoreWidget; 607 Result := TGtkListStringList.Create(PGtkList(Widget), 608 ACustomListBox, ACustomListBox.fCompStyle = csCheckListBox); 609 if ACustomListBox is TCustomListBox then 610 TGtkListStringList(Result).Sorted := ACustomListBox.Sorted; 611end; 612 613class function TGtkWSCustomListBox.GetTopIndex(const ACustomListBox: TCustomListBox): integer; 614begin 615 Result := GetIndexAtXY(ACustomListBox, 0, 0); 616end; 617 618class procedure TGtkWSCustomListBox.SelectItem(const ACustomListBox: TCustomListBox; 619 AIndex: integer; ASelected: boolean); 620var 621 Widget: PGtkWidget;// pointer to gtk-widget (local use when neccessary) 622 Handle: HWND; 623begin 624 //if CompareText(ACustomListBox.Name,'LBProperties')=0 then 625 // debugln('TGtkWSCustomListBox.SelectItem ',DbgSName(ACustomListBox),' Index=',dbgs(AIndex),' Selected=',dbgs(ASelected)); 626 Handle := ACustomListBox.Handle; 627 628 Widget := GetWidgetInfo(Pointer(Handle), True)^.CoreWidget; 629 if ASelected then gtk_list_select_item(PGtkList(Widget), AIndex) 630 else gtk_list_unselect_item(PGtkList(Widget), AIndex); 631end; 632 633class procedure TGtkWSCustomListBox.SetBorder(const ACustomListBox: TCustomListBox); 634var 635 Handle: HWND; 636 Widget: PGtkWidget;// pointer to gtk-widget 637begin 638 Handle := ACustomListBox.Handle; 639 Widget:= PGtkWidget(PGtkBin(Handle)^.child); 640 gtk_viewport_set_shadow_type(PGtkViewPort(Widget), BorderStyleShadowMap[ACustomListBox.BorderStyle]); 641end; 642 643class procedure TGtkWSCustomListBox.SetItemIndex(const ACustomListBox: TCustomListBox; 644 const AIndex: integer); 645var 646 Handle: HWND; 647 Widget: PGtkWidget; 648begin 649 //if CompareText(ACustomListBox.Name,'LBProperties')=0 then 650 // debugln('TGtkWSCustomListBox.SetItemIndex ',DbgSName(ACustomListBox),' Index=',dbgs(AIndex)); 651 Handle := ACustomListBox.Handle; 652 if Handle<>0 then 653 begin 654 LockOnChange(PGtkObject(Handle),+1); 655 Widget:=GetWidgetInfo(Pointer(Handle),True)^.CoreWidget; 656 657 if AIndex >= 0 then 658 gtk_list_select_item(PGtkList(Widget), AIndex) 659 else 660 gtk_list_unselect_all(PGtkList(Widget)); 661 662 LockOnChange(PGtkObject(Handle),-1); 663 end; 664end; 665 666class procedure TGtkWSCustomListBox.SetSelectionMode( 667 const ACustomListBox: TCustomListBox; 668 const AExtendedSelect, AMultiSelect: boolean); 669begin 670 //if CompareText(ACustomListBox.Name,'LBProperties')=0 then 671 // debugln('TGtkWSCustomListBox.SetSelectionMode ',DbgSName(ACustomListBox)); 672 TGtkWidgetSet(WidgetSet).SetSelectionMode(ACustomListBox, 673 PGtkWidget(ACustomListBox.Handle), AMultiSelect, AExtendedSelect); 674end; 675 676class procedure TGtkWSCustomListBox.SetSorted(const ACustomListBox: TCustomListBox; 677 AList: TStrings; ASorted: boolean); 678begin 679 //if CompareText(ACustomListBox.Name,'LBProperties')=0 then 680 // debugln('TGtkWSCustomListBox.SetSorted ',DbgSName(ACustomListBox)); 681 if AList is TGtkListStringList then 682 TGtkListStringList(AList).Sorted := ASorted 683 else 684 raise Exception.Create(''); 685end; 686 687class procedure TGtkWSCustomListBox.SetTopIndex( 688 const ACustomListBox: TCustomListBox; const NewTopIndex: integer); 689var 690 ScrolledWindow: PGtkScrolledWindow; 691 VertAdj: PGTKAdjustment; 692 AdjValue, MaxAdjValue: integer; 693 ListWidget: PGtkList; 694 AWidget: PGtkWidget; 695 GListItem: PGList; 696 ListItemWidget: PGtkWidget; 697 i: Integer; 698 requisition: TGtkRequisition; 699begin 700 //if CompareText(ACustomListBox.Name,'LBProperties')=0 then 701 // debugln('TGtkWSCustomListBox.SetTopIndex ',DbgSName(ACustomListBox)); 702 AWidget:=PGtkWidget(ACustomListBox.Handle); 703 ListWidget:=PGtkList(GetWidgetInfo(AWidget, True)^.CoreWidget); 704 ScrolledWindow:=PGtkScrolledWindow(AWidget); 705 AdjValue:=0; 706 GListItem:=ListWidget^.children; 707 i:=0; 708 while GListItem<>nil do begin 709 ListItemWidget:=PGtkWidget(GListItem^.data); 710 if i>=NewTopIndex then break; 711 if ListItemWidget<>nil then begin 712 gtk_widget_size_request(ListItemWidget,@requisition); 713 inc(AdjValue,requisition.height); 714 end; 715 //DebugLn(['TGtkWSCustomListBox.SetTopIndex ',i,' AdjValue=',AdjValue,' Flags=',WidgetFlagsToString(ListItemWidget)]); 716 inc(i); 717 GListItem:=GListItem^.next; 718 end; 719 VertAdj:=gtk_scrolled_window_get_vadjustment(ScrolledWindow); 720 MaxAdjValue:=RoundToInt(VertAdj^.upper); 721 if AdjValue>MaxAdjValue then AdjValue:=MaxAdjValue; 722 //DebugLn(['TGtkWSCustomListBox.SetTopIndex AdjValue=',AdjValue,' VertAdj^.upper=',VertAdj^.upper,' VertAdj^.page_size=',VertAdj^.page_size]); 723 gtk_adjustment_set_value(VertAdj,AdjValue); 724end; 725 726class procedure TGtkWSCustomListBox.SetColor(const AWinControl: TWinControl); 727var 728 AWidget, ListWidget: PGTKWidget; 729begin 730 if not WSCheckHandleAllocated(AWinControl, 'SetColor') then Exit; 731 AWidget := PGtkWidget(AWinControl.Handle); 732 ListWidget := GetWidgetInfo(AWidget, True)^.CoreWidget; 733 GtkWidgetSet.SetWidgetColor(ListWidget, AWinControl.Font.Color, 734 AWinControl.Color, 735 [GTK_STATE_NORMAL,GTK_STATE_ACTIVE,GTK_STATE_PRELIGHT,GTK_STATE_SELECTED, 736 GTK_STYLE_BASE]); 737end; 738 739class procedure TGtkWSCustomListBox.SetFont(const AWinControl: TWinControl; 740 const AFont: TFont); 741var 742 Widget: PGtkWidget; 743 GList: PGList; 744 ChildWidget: PGTKLabel; 745begin 746 if not AWinControl.HandleAllocated then exit; 747 748 { Get the selections } 749 Widget := GetWidgetInfo(Pointer(AWinControl.Handle))^.CoreWidget; 750 GList := PGtkList(Widget)^.children; 751 while Assigned(GList) do 752 begin 753 // DebugLn('TGtkWSCustomListBox.SetFont for item ',PGTKLabel(PGtkBin(GList^.data)^.child)^.thelabel); 754 ChildWidget := PGTKLabel(PGtkBin(GList^.data)^.child); 755 756 GtkWidgetSet.SetWidgetColor(PGtkWidget(ChildWidget), AFont.Color, clNone, 757 [GTK_STATE_NORMAL,GTK_STATE_ACTIVE,GTK_STATE_PRELIGHT,GTK_STATE_SELECTED]); 758 GtkWidgetSet.SetWidgetFont(PGtkWidget(ChildWidget), AFont); 759 GList := GList^.Next; 760 end; 761end; 762 763{$ENDIF} 764 765 766{ TGtkWSCustomComboBox } 767 768{$IFDEF GTK1} 769 770function gtkComboBoxChanged(Widget: PGtkWidget; Info: PWidgetInfo): GBoolean; cdecl; 771var 772 Mess : TLMessage; 773 GtkComboWidget: PGtkCombo; 774 GtkListWidget: PGtkList; 775 LCLIndex: PInteger; 776 GtkIndex: Integer; 777begin 778 Result := CallBackDefaultReturn; 779 780 if ComponentIsDestroyingHandle(TWinControl(Info^.LCLObject)) or 781 (Info^.ChangeLock > 0) or 782 (gtk_signal_n_emissions_by_name(PGtkObject(widget), 'changed') > 1) or 783 (GTK_WIDGET_VISIBLE(PGtkCombo(Info^.CoreWidget)^.popwin)) then exit; 784 785 {$IFDEF EventTrace} 786 EventTrace('changed', Info^.LCLObject); 787 {$ENDIF} 788 789 FillChar(Mess, SizeOf(Mess), 0); 790 Mess.Msg := LM_CHANGED; 791 DeliverMessage(Info^.LCLObject, Mess); 792 793 GtkComboWidget := PGtkCombo(Info^.CoreWidget); 794 GtkListWidget := PGtkList(GtkComboWidget^.list); 795 LCLIndex := PInteger(Info^.UserData); 796 797 //Check if an item is selected 798 if (GtkListWidget^.selection <> nil) then 799 begin 800 GtkIndex := gtk_list_child_position(GtkListWidget, 801 PGtkWidget(GtkListWidget^.selection^.data)); 802 //If the selected item index changed send a LM_SELCHANGE msg 803 if LCLIndex^ <> GtkIndex then 804 begin 805 gtk_list_set_selection_mode(GtkListWidget, GTK_SELECTION_BROWSE); 806 LCLIndex^ := GtkIndex; 807 Mess.Msg := LM_SELCHANGE; 808 DeliverMessage(Info^.LCLObject, Mess); 809 end; 810 end 811 else 812 begin 813 LCLIndex^ := -1; 814 gtk_list_set_selection_mode(GtkListWidget, GTK_SELECTION_SINGLE); 815 end; 816end; 817 818class function TGtkWSCustomComboBox.GetDroppedDown( 819 const ACustomComboBox: TCustomComboBox): Boolean; 820var 821 ComboWidget: PGtkCombo; 822begin 823 if not WSCheckHandleAllocated(ACustomComboBox, 'GetDroppedDown') then 824 Exit(False); 825 ComboWidget:=PGtkCombo(ACustomComboBox.Handle); 826 Result := GTK_WIDGET_VISIBLE(ComboWidget^.popwin); 827end; 828 829class procedure TGtkWSCustomComboBox.SetDroppedDown( 830 const ACustomComboBox: TCustomComboBox; ADroppedDown: Boolean); 831 832 procedure gtk_combo_get_pos(combo : PGtkCombo; var x : gint; var y : gint; 833 var height : gint; var width : gint); 834 var 835 popwin : PGtkbin; 836 widget : PGtkWidget; 837 popup : PGtkScrolledwindow; 838 real_height : gint; 839 list_requisition : PGtkRequisition; 840 show_hscroll : gboolean; 841 show_vscroll : gboolean; 842 avail_height : gint; 843 min_height : gint; 844 alloc_width : gint; 845 work_height : gint; 846 old_height : gint; 847 old_width : gint; 848 okay_to_exit : boolean; 849 const 850 EMPTY_LIST_HEIGHT = 15; 851 begin 852 show_hscroll := False; 853 show_vscroll := False; 854 855 widget := GTK_WIDGET(combo); 856 popup := GTK_SCROLLED_WINDOW (combo^.popup); 857 popwin := GTK_BIN (combo^.popwin); 858 859 gdk_window_get_origin (combo^.entry^.window, @x, @y); 860 861 real_height := MIN (combo^.entry^.requisition.height, 862 combo^.entry^.allocation.height); 863 y := y + real_height; 864 865 avail_height := gdk_screen_height () - y; 866 867 New(list_requisition); 868 if combo^.list<>nil then begin 869 gtk_widget_size_request (combo^.list, list_requisition); 870 end else begin 871 list_requisition^.height:=1; 872 list_requisition^.width:=1; 873 end; 874 875 min_height := MIN (list_requisition^.height,popup^.vscrollbar^.requisition.height); 876 if GTK_LIST (combo^.list)^.children = nil then 877 list_requisition^.height := list_requisition^.height + EMPTY_LIST_HEIGHT; 878 879 alloc_width := (cardinal(widget^.allocation.width) - 880 2 * cardinal(gtk_widget_get_xthickness(gtk_bin_get_child(popwin))) - 881 2 * border_width(GTK_CONTAINER (gtk_bin_get_child(popwin))^) - 882 2 * border_width(GTK_CONTAINER (combo^.popup)^) - 883 2 * border_width(GTK_CONTAINER (gtk_bin_get_child(PGTKBin(popup)))^) - 884 2 * cardinal(gtk_widget_get_xthickness(gtk_bin_get_child(PGTKBin(popup))))); 885 886 work_height := (2 * cardinal(gtk_widget_get_ythickness(gtk_bin_get_child(popwin))) + 887 2 * border_width(GTK_CONTAINER (gtk_bin_get_child(popwin))^) + 888 2 * border_width(GTK_CONTAINER (combo^.popup)^) + 889 2 * border_width(GTK_CONTAINER (gtk_bin_get_child(PGTKBin(popup)))^) + 890 2 * cardinal(gtk_widget_get_xthickness(gtk_bin_get_child(PGTKBin(popup))))); 891 892 repeat 893 okay_to_exit := True; 894 old_width := alloc_width; 895 old_height := work_height; 896 897 if ((not show_hscroll) and (alloc_width < list_requisition^.width)) then 898 begin 899 work_height := work_height + popup^.hscrollbar^.requisition.height + 900 GTK_SCROLLED_WINDOW_CLASS(gtk_object_get_class(combo^.popup))^.scrollbar_spacing; 901 show_hscroll := TRUE; 902 okay_to_exit := False; 903 end; 904 if ((not show_vscroll) and (work_height + list_requisition^.height > avail_height)) then 905 begin 906 if ((work_height + min_height > avail_height) and (y - real_height > avail_height)) then 907 begin 908 y := y - (work_height + list_requisition^.height + real_height); 909 break; 910 end; 911 alloc_width := alloc_width - 912 popup^.vscrollbar^.requisition.width + 913 GTK_SCROLLED_WINDOW_CLASS(gtk_object_get_class(combo^.popup))^.scrollbar_spacing; 914 show_vscroll := TRUE; 915 okay_to_exit := False; 916 end; 917 until ((old_width <> alloc_width) or (old_height <> work_height) or okay_to_exit); 918 919 width := widget^.allocation.width; 920 if (show_vscroll) then 921 height := avail_height 922 else 923 height := work_height + list_requisition^.height; 924 if (x < 0) then 925 x := 0; 926 927 Dispose(list_requisition); 928 end; 929 930var 931 ComboWidget: PGtkCombo; 932 height, width, x, y : gint; 933 old_width, old_height : gint; 934begin 935 if not WSCheckHandleAllocated(ACustomComboBox, 'SetDroppedDown') then Exit; 936 ComboWidget:=PGtkCombo(ACustomComboBox.Handle); 937 if ADroppedDown<>GTK_WIDGET_VISIBLE(ComboWidget^.popwin) then begin 938 if ADroppedDown then begin 939 old_width := ComboWidget^.popwin^.allocation.width; 940 old_height := ComboWidget^.popwin^.allocation.height; 941 gtk_combo_get_pos(ComboWidget,x,y,height,width); 942 if ((old_width <> width) or (old_height <> height)) then 943 begin 944 gtk_widget_hide (GTK_SCROLLED_WINDOW(ComboWidget^.popup)^.hscrollbar); 945 gtk_widget_hide (GTK_SCROLLED_WINDOW(ComboWidget^.popup)^.vscrollbar); 946 end; 947 gtk_widget_set_uposition (comboWidget^.popwin,x, y); 948 gtk_widget_set_usize(ComboWidget^.popwin,width ,height); 949 gtk_widget_realize(ComboWidget^.popwin); 950 951 {$IFDEF DebugGDKTraps} 952 BeginGDKErrorTrap; 953 {$ENDIF} 954 gdk_window_resize(ComboWidget^.popwin^.window,width,height); 955 {$IFDEF DebugGDKTraps} 956 EndGDKErrorTrap; 957 {$ENDIF} 958 959 gtk_widget_show (ComboWidget^.popwin); 960 gtk_widget_grab_focus(ComboWidget^.popwin); 961 end else 962 gtk_widget_hide (ComboWidget^.popwin); 963 end; 964end; 965 966class procedure TGtkWSCustomComboBox.SetCallbacks(const AGtkWidget: PGtkWidget; 967 const AWidgetInfo: PWidgetInfo); 968begin 969 TGtkWSWinControl.SetCallbacks(PGtkObject(AGtkWidget), TComponent(AWidgetInfo^.LCLObject)); 970 with TGtkWidgetset(Widgetset) do 971 begin 972 //gtk1 and gtk2 have different 'changed' event handlers 973 g_signal_connect(PGtkObject(PGtkCombo(AGtkWidget)^.entry), 974 'changed', TGTKSignalFunc(@gtkComboBoxChanged), AWidgetInfo); 975 g_signal_connect(PGtkObject(PGtkCombo(AGtkWidget)^.popwin), 976 'hide', TGTKSignalFunc(@gtkComboBoxChanged), AWidgetInfo); 977 SetCallback(LM_COMMAND, PGtkObject(AGtkWidget), AWidgetInfo^.LCLObject); 978 end; 979end; 980 981class function TGtkWSCustomComboBox.CreateHandle(const AWinControl: TWinControl; const AParams: TCreateParams): TLCLIntfHandle; 982var 983 ComboBox: TComboBox absolute AWinControl; 984 Widget: PGtkWidget; 985 WidgetInfo: PWidgetInfo; 986 ComboWidget: PGtkCombo absolute Widget; 987 988 ItemList: TGtkListStringList; 989 GtkList: PGtkList; 990 Allocation: TGtkAllocation; 991 LCLIndex: PInteger; 992begin 993 Widget := gtk_combo_new(); 994 995 SetMainWidget(Widget, ComboWidget^.entry); 996 SetMainWidget(Widget, ComboWidget^.button); 997 998 gtk_combo_disable_activate(ComboWidget); 999 gtk_combo_set_case_sensitive(ComboWidget, GdkTrue); 1000 1001 GtkList:=PGtkList(ComboWidget^.List); 1002 1003 // Items 1004 ItemList:= TGtkListStringList.Create(GtkList, ComboBox, False); 1005 gtk_object_set_data(PGtkObject(Widget), GtkListItemLCLListTag, ItemList); 1006 ItemList.Assign(ComboBox.Items); 1007 ItemList.Sorted:= ComboBox.Sorted; 1008 1009 WidgetInfo := CreateWidgetInfo(Widget, AWinControl, AParams); 1010 New(LCLIndex); 1011 WidgetInfo^.UserData := LCLIndex; 1012 WidgetInfo^.DataOwner := True; 1013 1014 // ItemIndex 1015 1016 // Switching the selection mode is necessary to avoid the following problems: 1017 // - The first added item is automatically selected when mode is "BROWSE" 1018 // - Is not possible to select the previous selected item if mode is "BROWSE" 1019 // and current index is -1 1020 // - The item is deselected after a second click if mode is "SINGLE" 1021 // - The OnSelect event could be fired after add the first item when mode is 1022 // "BROWSE". Since LM_SELCHANGE is sent in 'changed' event now, no problem. 1023 // So basically the mode is set to BROWSE when a item is selected and 1024 // "SINGLE" when there's no item selected 1025 if ComboBox.ItemIndex >= 0 then 1026 begin 1027 gtk_list_set_selection_mode(GtkList, GTK_SELECTION_BROWSE); 1028 gtk_list_select_item(GtkList, ComboBox.ItemIndex); 1029 LCLIndex^ := ComboBox.ItemIndex; 1030 end 1031 else 1032 begin 1033 gtk_list_set_selection_mode(GtkList, GTK_SELECTION_SINGLE); 1034 LCLIndex^ := -1; 1035 end; 1036 1037 // MaxLength 1038 gtk_entry_set_max_length(PGtkEntry(ComboWidget^.entry),guint16(ComboBox.MaxLength)); 1039 1040 {$IFDEF DebugLCLComponents} 1041 DebugGtkWidgets.MarkCreated(Widget, dbgsName(AWinControl)); 1042 {$ENDIF} 1043 Result := THandle(PtrUInt(Widget)); 1044 1045 1046 Allocation.X := AParams.X; 1047 Allocation.Y := AParams.Y; 1048 Allocation.Width := AParams.Width; 1049 Allocation.Height := AParams.Height; 1050 gtk_widget_size_allocate(Widget, @Allocation); 1051 1052 Set_RC_Name(AWinControl, Widget); 1053 SetCallbacks(Widget, WidgetInfo); 1054end; 1055 1056class function TGtkWSCustomComboBox.GetSelStart( 1057 const ACustomComboBox: TCustomComboBox): integer; 1058begin 1059 Result := WidgetGetSelStart(PGtkWidget(PGtkCombo(ACustomComboBox.Handle 1060 )^.entry)); 1061end; 1062 1063class function TGtkWSCustomComboBox.GetSelLength( 1064 const ACustomComboBox: TCustomComboBox): integer; 1065begin 1066 with PGtkOldEditable(PGtkCombo(ACustomComboBox.Handle)^.entry)^ do begin 1067 Result:= Abs(integer(selection_end_pos)-integer(selection_start_pos)); 1068 end; 1069end; 1070 1071class function TGtkWSCustomComboBox.GetText(const AWinControl: TWinControl; 1072 var AText: String): Boolean; 1073begin 1074 //DebugLn('TGtkWSCustomComboBox.GetText ',DbgSName(ACustomComboBox),' ',GetWidgetDebugReport(PGtkWidget(ACustomComboBox.Handle))); 1075 AText := gtk_entry_get_text(PGtkEntry(PGtkCombo(AWinControl.Handle)^.entry)); 1076 //if AWinControl.Name='FileExtensionsComboBox' then 1077 // DebugLn('TGtkWSCustomComboBox.GetText ',DbgSName(AWinControl),' ',GetWidgetDebugReport(PGtkWidget(AWinControl.Handle)),' AText="',AText,'"'); 1078 Result:=true; 1079end; 1080 1081class function TGtkWSCustomComboBox.GetItemIndex( 1082 const ACustomComboBox: TCustomComboBox): integer; 1083var 1084 ListWidget: PGtkList; 1085begin 1086 //DebugLn('TGtkWSCustomComboBox.GetItemIndex ',DbgSName(ACustomComboBox),' ',GetWidgetDebugReport(PGtkWidget(ACustomComboBox.Handle))); 1087 ListWidget := PGtkList(PGtkCombo(ACustomComboBox.Handle)^.list); 1088 if ListWidget^.selection <> nil then 1089 Result := gtk_list_child_position(ListWidget, ListWidget^.selection^.data) 1090 else 1091 Result := -1; 1092end; 1093 1094class function TGtkWSCustomComboBox.GetMaxLength( 1095 const ACustomComboBox: TCustomComboBox): integer; 1096begin 1097 Result:= PGtkEntry(PGtkCombo(ACustomComboBox.Handle)^.entry)^.text_max_length; 1098end; 1099 1100class procedure TGtkWSCustomComboBox.SetArrowKeysTraverseList( 1101 const ACustomComboBox: TCustomComboBox; 1102 NewTraverseList: boolean); 1103var 1104 GtkCombo: PGtkCombo; 1105begin 1106 GtkCombo := GTK_COMBO(Pointer(ACustomComboBox.Handle)); 1107 if ACustomComboBox.ArrowKeysTraverseList then 1108 begin 1109 gtk_combo_set_use_arrows(GtkCombo,GdkTrue); 1110 end else 1111 begin 1112 gtk_combo_set_use_arrows(GtkCombo,GdkFalse); 1113 end; 1114end; 1115 1116class procedure TGtkWSCustomComboBox.SetSelStart( 1117 const ACustomComboBox: TCustomComboBox; NewStart: integer); 1118begin 1119 if NewStart < 0 then NewStart := 0; // prevent SegFault in gtk 1120 gtk_editable_set_position( 1121 PGtkOldEditable(PGtkCombo(ACustomComboBox.Handle)^.entry), NewStart); 1122end; 1123 1124class procedure TGtkWSCustomComboBox.SetSelLength( 1125 const ACustomComboBox: TCustomComboBox; NewLength: integer); 1126begin 1127 WidgetSetSelLength(PGtkCombo(ACustomComboBox.Handle)^.entry, NewLength); 1128end; 1129 1130class procedure TGtkWSCustomComboBox.SetItemIndex( 1131 const ACustomComboBox: TCustomComboBox; NewIndex: integer); 1132var 1133 ComboWidget: PGtkCombo; 1134 WidgetInfo: PWidgetInfo; 1135begin 1136 ComboWidget := PGtkCombo(ACustomComboBox.Handle); 1137 WidgetInfo := GetWidgetInfo(ComboWidget); 1138 //Store the LCLIndex 1139 PInteger(WidgetInfo^.UserData)^ := NewIndex; 1140 //Avoid calling OnChange/OnSelect events 1141 Inc(WidgetInfo^.ChangeLock); 1142 //gtk_list_select_item does not update the list when Index is -1 1143 if NewIndex > -1 then 1144 begin 1145 gtk_list_set_selection_mode(PGtkList(ComboWidget^.list), 1146 GTK_SELECTION_BROWSE); 1147 gtk_list_select_item(PGtkList(ComboWidget^.list), NewIndex); 1148 end 1149 else 1150 begin 1151 gtk_list_set_selection_mode(PGtkList(ComboWidget^.list), 1152 GTK_SELECTION_SINGLE); 1153 gtk_entry_set_text(PGtkEntry(ComboWidget^.entry), ''); 1154 end; 1155 Dec(WidgetInfo^.ChangeLock); 1156end; 1157 1158class procedure TGtkWSCustomComboBox.SetMaxLength( 1159 const ACustomComboBox: TCustomComboBox; NewLength: integer); 1160begin 1161 gtk_entry_set_max_length(PGtkEntry(PGtkCombo(ACustomComboBox.Handle)^.entry), 1162 guint16(NewLength)); 1163end; 1164 1165class procedure TGtkWSCustomComboBox.SetStyle( 1166 const ACustomComboBox: TCustomComboBox; NewStyle: TComboBoxStyle); 1167var 1168 GtkCombo: PGtkCombo; 1169begin 1170 GtkCombo := GTK_COMBO(Pointer(ACustomComboBox.Handle)); 1171 if not ACustomComboBox.Style.HasEditBox then 1172 begin 1173 // do not set ok_if_empty = true, otherwise it can hang focus 1174 gtk_combo_set_value_in_list(GtkCombo,GdkTrue,GdkTrue); 1175 gtk_combo_set_use_arrows_always(GtkCombo,GdkTrue); 1176 gtk_combo_set_case_sensitive(GtkCombo,GdkFalse); 1177 end 1178 else 1179 begin 1180 // do not set ok_if_empty = true, otherwise it can hang focus 1181 gtk_combo_set_value_in_list(GtkCombo,GdkFalse,GdkTrue); 1182 gtk_combo_set_use_arrows_always(GtkCombo,GdkFalse); 1183 gtk_combo_set_case_sensitive(GtkCombo,GdkTrue); 1184 end; 1185end; 1186 1187class procedure TGtkWSCustomComboBox.SetText(const AWinControl: TWinControl; 1188 const AText: String); 1189var 1190 ComboControl: TCustomComboBox absolute AWinControl; 1191 ComboWidget: PGtkCombo; 1192 WidgetInfo: PWidgetInfo; 1193 i: Integer; 1194begin 1195 if ComboControl.ReadOnly then 1196 begin 1197 i := ComboControl.Items.IndexOf(AText); 1198 TGtkWSCustomComboBox.SetItemIndex(ComboControl, i); 1199 end 1200 else 1201 begin 1202 ComboWidget := PGtkCombo(AWinControl.Handle); 1203 WidgetInfo := GetWidgetInfo(ComboWidget); 1204 // lock combobox, so that no OnChange event is not fired 1205 Inc(WidgetInfo^.ChangeLock); 1206 // set text 1207 // The String > PChar conversion ensures at least a null terminated string 1208 gtk_entry_set_text(PGtkEntry(ComboWidget^.entry), PChar(AText)); 1209 // unlock combobox 1210 Dec(WidgetInfo^.ChangeLock); 1211 end; 1212end; 1213 1214class function TGtkWSCustomComboBox.GetItems( 1215 const ACustomComboBox: TCustomComboBox): TStrings; 1216begin 1217 Result := TStrings(gtk_object_get_data(PGtkObject(ACustomComboBox.Handle), 1218 GtkListItemLCLListTag)); 1219end; 1220 1221class procedure TGtkWSCustomComboBox.Sort(const ACustomComboBox: TCustomComboBox; 1222 AList: TStrings; IsSorted: boolean); 1223begin 1224 TGtkListStringList(AList).Sorted := IsSorted; 1225end; 1226 1227class procedure TGtkWSCustomComboBox.SetColor(const AWinControl: TWinControl); 1228var 1229 AWidget, EntryWidget: PGTKWidget; 1230begin 1231 if not WSCheckHandleAllocated(AWinControl, 'SetColor') then Exit; 1232 AWidget := PGtkWidget(AWinControl.Handle); 1233 EntryWidget := PGtkCombo(AWidget)^.entry; 1234 GtkWidgetSet.SetWidgetColor(EntryWidget, AWinControl.Font.Color, AWinControl.Color, 1235 [GTK_STATE_NORMAL,GTK_STATE_ACTIVE,GTK_STATE_PRELIGHT,GTK_STATE_SELECTED,GTK_STYLE_BASE]); 1236end; 1237 1238class procedure TGtkWSCustomComboBox.SetFont(const AWinControl: TWinControl; 1239 const AFont: TFont); 1240var 1241 AWidget: PGTKWidget; 1242 EntryWidget: PGtkWidget; 1243begin 1244 if not AWinControl.HandleAllocated then exit; 1245 1246 AWidget := PGtkWidget(AWinControl.Handle); 1247 EntryWidget := PGtkCombo(AWidget)^.entry; 1248 1249 if EntryWidget<>nil then 1250 begin 1251 GtkWidgetSet.SetWidgetColor(EntryWidget, AFont.Color, clNone, 1252 [GTK_STATE_NORMAL,GTK_STATE_ACTIVE,GTK_STATE_PRELIGHT,GTK_STATE_SELECTED]); 1253 GtkWidgetSet.SetWidgetFont(EntryWidget, AFont); 1254 end; 1255end; 1256{$ENDIF} 1257 1258{ TGtkWSCustomEdit } 1259 1260class procedure TGtkWSCustomEdit.SetCallbacks(const AGtkWidget: PGtkWidget; 1261 const AWidgetInfo: PWidgetInfo); 1262begin 1263 TGtkWSWinControl.SetCallbacks(PGtkObject(AGtkWidget), TComponent(AWidgetInfo^.LCLObject)); 1264 1265 with TGtkWidgetset(Widgetset) do 1266 begin 1267 SetCallback(LM_CHANGED, PGtkObject(AGtkWidget), AWidgetInfo^.LCLObject); 1268 SetCallback(LM_ACTIVATE, PGtkObject(AGtkWidget), AWidgetInfo^.LCLObject); 1269 SetCallback(LM_CUT, PGtkObject(AGtkWidget), AWidgetInfo^.LCLObject); 1270 SetCallback(LM_COPY, PGtkObject(AGtkWidget), AWidgetInfo^.LCLObject); 1271 SetCallback(LM_PASTE, PGtkObject(AGtkWidget), AWidgetInfo^.LCLObject); 1272 end; 1273end; 1274 1275class function TGtkWSCustomEdit.CreateHandle(const AWinControl: TWinControl; 1276 const AParams: TCreateParams): TLCLIntfHandle; 1277var 1278 Widget: PGtkWidget; // ptr to the newly created GtkWidget 1279 WidgetInfo: PWidgetInfo; 1280begin 1281 Widget := gtk_entry_new(); 1282 gtk_editable_set_editable(PGtkEditable(Widget), not TCustomEdit(AWinControl).ReadOnly); 1283 gtk_widget_show_all(Widget); 1284 Result := TLCLIntfHandle(PtrUInt(Widget)); 1285 {$IFDEF DebugLCLComponents} 1286 DebugGtkWidgets.MarkCreated(Widget, dbgsName(AWinControl)); 1287 {$ENDIF} 1288 if Result = 0 then 1289 Exit; 1290 WidgetInfo := CreateWidgetInfo(Pointer(Result), AWinControl, AParams); 1291 Set_RC_Name(AWinControl, Widget); 1292 SetCallbacks(Widget, WidgetInfo); 1293end; 1294 1295class function TGtkWSCustomEdit.GetSelStart(const ACustomEdit: TCustomEdit): integer; 1296begin 1297 Result := WidgetGetSelStart(GetWidgetInfo(Pointer(ACustomEdit.Handle), 1298 true)^.CoreWidget); 1299end; 1300 1301class function TGtkWSCustomEdit.GetSelLength(const ACustomEdit: TCustomEdit): integer; 1302begin 1303 with PGtkOldEditable(GetWidgetInfo(Pointer(ACustomEdit.Handle), true)^. 1304 CoreWidget)^ do 1305 begin 1306 Result:=Abs(integer(selection_end_pos)-integer(selection_start_pos)); 1307 end; 1308end; 1309 1310class procedure TGtkWSCustomEdit.SetCharCase(const ACustomEdit: TCustomEdit; 1311 NewCase: TEditCharCase); 1312begin 1313 // TODO: implement me! 1314end; 1315 1316class procedure TGtkWSCustomEdit.SetEchoMode(const ACustomEdit: TCustomEdit; 1317 NewMode: TEchoMode); 1318begin 1319 // XXX TODO: GTK 1.x does not support EchoMode emNone. 1320 // This will have to be coded around, but not a priority 1321 SetPasswordChar(ACustomEdit, ACustomEdit.PasswordChar); 1322end; 1323 1324class procedure TGtkWSCustomEdit.SetMaxLength(const ACustomEdit: TCustomEdit; 1325 NewLength: integer); 1326var 1327 Widget: PGtkWidget; 1328begin 1329 Widget:=PGtkWidget(ACustomEdit.Handle); 1330 if GtkWidgetIsA(Widget, GTK_TYPE_ENTRY) then 1331 gtk_entry_set_max_length(GTK_ENTRY(Widget), guint16(NewLength)); 1332end; 1333 1334class procedure TGtkWSCustomEdit.SetPasswordChar(const ACustomEdit: TCustomEdit; 1335 NewChar: char); 1336var 1337 Widget: PGtkWidget; 1338begin 1339 Widget:=PGtkWidget(ACustomEdit.Handle); 1340 if GtkWidgetIsA(Widget, GTK_TYPE_ENTRY) then 1341 gtk_entry_set_visibility(GTK_ENTRY(Widget), 1342 (ACustomEdit.EchoMode = emNormal) and (NewChar = #0)); 1343end; 1344 1345class procedure TGtkWSCustomEdit.SetReadOnly(const ACustomEdit: TCustomEdit; 1346 NewReadOnly: boolean); 1347var 1348 Widget: PGtkWidget; 1349begin 1350 Widget := PGtkWidget(ACustomEdit.Handle); 1351 if GtkWidgetIsA(Widget, GTK_TYPE_ENTRY) then 1352 gtk_entry_set_editable(GTK_ENTRY(Widget), not NewReadOnly); 1353end; 1354 1355class procedure TGtkWSCustomEdit.SetSelStart(const ACustomEdit: TCustomEdit; 1356 NewStart: integer); 1357var 1358 Widget: PGtkWidget; 1359 MaxPos: Integer; 1360begin 1361 Widget:=GetWidgetInfo(Pointer(ACustomEdit.Handle), true)^.CoreWidget; 1362 if WidgetGetSelStart(Widget)=NewStart then exit; 1363 // sometimes the gtk freezes the memo, changes something and emits the change 1364 // event. Then the LCL gets notified and wants to react: force thaw (unfreeze) 1365 if GTK_IS_TEXT(Widget) then 1366 begin 1367 gtk_text_thaw(PGtkText(Widget)); 1368 MaxPos := gtk_text_get_length(PGtkText(Widget)); 1369 end 1370 else 1371 if GTK_IS_ENTRY(Widget) then 1372 MaxPos := PGtkEntry(Widget)^.text_length 1373 else 1374 MaxPos := 0; 1375 gtk_editable_set_position(PGtkOldEditable(Widget), Min(NewStart, MaxPos)); 1376 WidgetSetSelLength(Widget,0); // Setting the selection start should cancel any selection 1377end; 1378 1379class procedure TGtkWSCustomEdit.SetSelLength(const ACustomEdit: TCustomEdit; 1380 NewLength: integer); 1381begin 1382 WidgetSetSelLength(GetWidgetInfo(Pointer(ACustomEdit.Handle),true)^.CoreWidget, 1383 NewLength); 1384end; 1385 1386class procedure TGtkWSCustomEdit.SetText(const AWinControl: TWinControl; 1387 const AText: string); 1388var 1389 Widget: PGtkWidget; 1390 Mess : TLMessage; 1391begin 1392 if not WSCheckHandleAllocated(AWinControl, 'SetText') then 1393 Exit; 1394 {$IFDEF VerboseTWinControlRealText} 1395 DebugLn(['TGtkWSCustomEdit.SetText START ',DbgSName(AWinControl),' AText="',AText,'"']); 1396 {$ENDIF} 1397 Widget:=PGtkWidget(AWinControl.Handle); 1398 // some gtk2 versions fire the change event twice 1399 // lock the event and send the message afterwards 1400 // see bug http://bugs.freepascal.org/view.php?id=14615 1401 LockOnChange(PgtkObject(Widget), +1); 1402 try 1403 gtk_entry_set_text(PGtkEntry(Widget), PChar(AText)); 1404 finally 1405 LockOnChange(PgtkObject(Widget), -1); 1406 end; 1407 {$IFDEF VerboseTWinControlRealText} 1408 DebugLn(['TGtkWSCustomEdit.SetText SEND TEXTCHANGED message ',DbgSName(AWinControl),' New="',gtk_entry_get_text(PGtkEntry(AWinControl.Handle)),'"']); 1409 {$ENDIF} 1410 FillByte(Mess,SizeOf(Mess),0); 1411 Mess.Msg := CM_TEXTCHANGED; 1412 DeliverMessage(AWinControl, Mess); 1413 1414 {$IFDEF VerboseTWinControlRealText} 1415 DebugLn(['TGtkWSCustomEdit.SetText END ',DbgSName(AWinControl),' New="',gtk_entry_get_text(PGtkEntry(AWinControl.Handle)),'"']); 1416 {$ENDIF} 1417end; 1418 1419class procedure TGtkWSCustomEdit.GetPreferredSize(const AWinControl: TWinControl; 1420 var PreferredWidth, PreferredHeight: integer; WithThemeSpace: Boolean); 1421begin 1422 GetGTKDefaultWidgetSize(AWinControl,PreferredWidth,PreferredHeight, 1423 WithThemeSpace); 1424 //debugln('TGtkWSCustomEdit.GetPreferredSize ',DbgSName(AWinControl),' PreferredWidth=',dbgs(PreferredWidth),' PreferredHeight=',dbgs(PreferredHeight)); 1425end; 1426 1427class procedure TGtkWSCustomEdit.SetColor(const AWinControl: TWinControl); 1428var 1429 AWidget: PGTKWidget; 1430begin 1431 if not WSCheckHandleAllocated(AWinControl, 'SetColor') then Exit; 1432 AWidget := PGtkWidget(AWinControl.Handle); 1433 // don't change selected state 1434 GtkWidgetSet.SetWidgetColor(AWidget, clNone, AWinControl.Color, 1435 [GTK_STATE_NORMAL, GTK_STYLE_BASE]); 1436end; 1437 1438{ TGtkWSCustomStaticText } 1439 1440class function TGtkWSCustomStaticText.GetLabelWidget(AFrame: PGtkFrame): PGtkLabel; 1441begin 1442 {$IFDEF GTK2} 1443 Result := PGtkLabel(PGtkBin(GetBoxWidget(AFrame))^.child); 1444 {$ELSE} 1445 Result := PGtkLabel(GetBoxWidget(AFrame)^.bin.child); 1446 {$ENDIF} 1447end; 1448 1449class function TGtkWSCustomStaticText.GetBoxWidget(AFrame: PGtkFrame): PGtkEventBox; 1450begin 1451 {$IFDEF GTK2} 1452 Result := PGtkEventBox(PGtkBin(AFrame)^.child); 1453 {$ELSE} 1454 Result := PGtkEventBox(AFrame^.bin.Child); 1455 {$ENDIF} 1456end; 1457 1458class function TGtkWSCustomStaticText.CreateHandle( 1459 const AWinControl: TWinControl; const AParams: TCreateParams 1460 ): TLCLIntfHandle; 1461var 1462 AStaticText: TCustomStaticText; 1463 WidgetInfo: PWidgetInfo; 1464 Allocation: TGTKAllocation; 1465 EventBox, LblWidget: PGtkWidget; 1466begin 1467 // TStaticText control is a Text area with frame around. Both Text and Area around 1468 // text can have their own color 1469 1470 // To implement that in gtk we need: 1471 // 1. GtkLabel to handle Text 1472 // 2. GtkEventBox to draw color area around GtkLabel (since GtkLabel have no window) 1473 // 3. GtkFrame to draw frame around Text area 1474 // GtkFrame is our main widget - it is container and it contains GtkEventBox 1475 // GtkEventBox is also containter and it contains GtkLabel 1476 1477 AStaticText := AWinControl as TCustomStaticText; 1478 Result := TLCLIntfHandle(PtrUInt(gtk_frame_new(nil))); // frame is the main container - to decorate label 1479 if Result = 0 then Exit; 1480 1481 gtk_frame_set_shadow_type(PGtkFrame(Result), StaticBorderShadowMap[AStaticText.BorderStyle]); 1482 1483 EventBox := gtk_event_box_new; // our area 1484 LblWidget := gtk_label_new(PChar(TCustomStaticText(AWinControl).Caption)); // our text widget 1485 gtk_container_add(PGtkContainer(EventBox), LblWidget); 1486 SetLabelAlignment(PGtkLabel(LblWidget), AStaticText.Alignment); 1487 gtk_widget_show(LblWidget); 1488 gtk_widget_show(EventBox); 1489 gtk_container_add(PGtkContainer(Result), EventBox); 1490 1491 {$IFDEF DebugLCLComponents} 1492 DebugGtkWidgets.MarkCreated(Pointer(Result), dbgsName(AWinControl)); 1493 {$ENDIF} 1494 1495 WidgetInfo := CreateWidgetInfo(Pointer(Result), AStaticText, AParams); 1496 WidgetInfo^.CoreWidget := EventBox; 1497 gtk_object_set_data(PGtkObject(EventBox), 'widgetinfo', WidgetInfo); 1498 1499 Allocation.X := AParams.X; 1500 Allocation.Y := AParams.Y; 1501 Allocation.Width := AParams.Width; 1502 Allocation.Height := AParams.Height; 1503 gtk_widget_size_allocate(PGtkWidget(Result), @Allocation); 1504 1505 Set_RC_Name(AWinControl, PGtkWidget(Result)); 1506 SetCallbacks(PGtkWidget(Result), WidgetInfo); 1507end; 1508 1509class procedure TGtkWSCustomStaticText.SetAlignment(const ACustomStaticText: TCustomStaticText; 1510 const NewAlignment: TAlignment); 1511var 1512 LblWidget: PGtkLabel; 1513begin 1514 if not WSCheckHandleAllocated(ACustomStaticText, 'SetAlignment') 1515 then Exit; 1516 1517 LblWidget := GetLabelWidget(PGtkFrame(ACustomStaticText.Handle)); 1518 SetLabelAlignment(LblWidget, NewAlignment); 1519end; 1520 1521class procedure TGtkWSCustomStaticText.GetPreferredSize(const AWinControl: TWinControl; 1522 var PreferredWidth, PreferredHeight: integer; WithThemeSpace: Boolean); 1523begin 1524 GetGTKDefaultWidgetSize(AWinControl, PreferredWidth, PreferredHeight, 1525 WithThemeSpace); 1526 //debugln('TGtkWSCustomStaticText.GetPreferredSize ',DbgSName(AWinControl),' PreferredWidth=',dbgs(PreferredWidth),' PreferredHeight=',dbgs(PreferredHeight)); 1527end; 1528 1529class function TGtkWSCustomStaticText.GetText(const AWinControl: TWinControl; 1530 var AText: String): Boolean; 1531begin 1532 // The text is static, so let the LCL fallback to FCaption 1533 Result := False; 1534end; 1535 1536class procedure TGtkWSCustomStaticText.SetText(const AWinControl: TWinControl; 1537 const AText: String); 1538var 1539 FrameWidget: PGtkFrame; 1540 LblWidget: PGtkLabel; 1541 DC: HDC; 1542 ALabel: PChar; 1543begin 1544 if not WSCheckHandleAllocated(AWincontrol, 'SetText') 1545 then Exit; 1546 1547 FrameWidget := PGtkFrame(AWinControl.Handle); 1548 LblWidget := GetLabelWidget(FrameWidget); 1549 1550 if TStaticText(AWinControl).ShowAccelChar then 1551 begin 1552 DC := Widgetset.GetDC(HWND(PtrUInt(LblWidget))); 1553 ALabel := TGtkWidgetSet(WidgetSet).ForceLineBreaks( 1554 DC, PChar(AText), TStaticText(AWinControl).Width, false); 1555 Widgetset.DeleteDC(DC); 1556 GtkWidgetSet.SetLabelCaption(LblWidget, ALabel 1557 {$IFDEF Gtk1}, AWinControl, PGtkWidget(FrameWidget), 'grab_focus'{$ENDIF}); 1558 StrDispose(ALabel); 1559 end else 1560 begin 1561 gtk_label_set_text(LblWidget, PChar(AText)); 1562 gtk_label_set_pattern(LblWidget, nil); 1563 end; 1564end; 1565 1566class procedure TGtkWSCustomStaticText.SetStaticBorderStyle( 1567 const ACustomStaticText: TCustomStaticText; 1568 const NewBorderStyle: TStaticBorderStyle); 1569begin 1570 if not WSCheckHandleAllocated(ACustomStaticText, 'SetStaticBorderStyle') 1571 then Exit; 1572 gtk_frame_set_shadow_type(PGtkFrame(ACustomStaticText.Handle), StaticBorderShadowMap[NewBorderStyle]); 1573end; 1574 1575class procedure TGtkWSCustomStaticText.SetCallbacks( 1576 const AGtkWidget: PGtkWidget; const AWidgetInfo: PWidgetInfo); 1577begin 1578 TGtkWSWinControl.SetCallbacks(PGtkObject(AGtkWidget), TComponent(AWidgetInfo^.LCLObject)); 1579 1580 SignalConnect(AGtkWidget, 'grab_focus', @gtkActivateCB, AWidgetInfo); 1581end; 1582 1583class procedure TGtkWSCustomStaticText.SetColor(const AWinControl: TWinControl); 1584begin 1585 if not WSCheckHandleAllocated(AWinControl, 'SetColor') then Exit; 1586 1587 GtkWidgetSet.SetWidgetColor(PGtkWidget(GetBoxWidget(PGtkFrame(AWinControl.Handle))), 1588 clNone, AWinControl.Color, 1589 [GTK_STATE_NORMAL,GTK_STATE_ACTIVE, 1590 GTK_STATE_PRELIGHT,GTK_STATE_SELECTED]); 1591end; 1592 1593class procedure TGtkWSCustomStaticText.SetFont(const AWinControl: TWinControl; 1594 const AFont: TFont); 1595var 1596 Widget: PGtkWidget; 1597begin 1598 if not WSCheckHandleAllocated(AWinControl, 'SetFont') 1599 then Exit; 1600 1601 Widget := PGtkWidget(GetLabelWidget(PGtkFrame(AWinControl.Handle))); 1602 1603 GtkWidgetSet.SetWidgetColor(Widget, AFont.Color, clNone, 1604 [GTK_STATE_NORMAL,GTK_STATE_ACTIVE,GTK_STATE_PRELIGHT,GTK_STATE_SELECTED]); 1605 GtkWidgetSet.SetWidgetFont(Widget, AFont); 1606end; 1607 1608{ TGtkWSButton } 1609 1610function GtkWSButton_Clicked(AWidget: PGtkWidget; AInfo: PWidgetInfo): GBoolean; cdecl; 1611var 1612 Msg: TLMessage; 1613begin 1614 Result := CallBackDefaultReturn; 1615 if AInfo^.ChangeLock > 0 then Exit; 1616 Msg.Msg := LM_CLICKED; 1617 Result := DeliverMessage(AInfo^.LCLObject, Msg) = 0; 1618end; 1619 1620class procedure TGtkWSButton.SetCallbacks(const AGtkWidget: PGtkWidget; 1621 const AWidgetInfo: PWidgetInfo); 1622begin 1623 TGtkWSWinControl.SetCallbacks(PGtkObject(AGtkWidget), TComponent(AWidgetInfo^.LCLObject)); 1624 SignalConnect(AGtkWidget, 'clicked', @GtkWSButton_Clicked, AWidgetInfo); 1625end; 1626 1627{$IFDEF Gtk1} 1628 1629class function TGtkWSButton.CreateHandle(const AWinControl: TWinControl; 1630 const AParams: TCreateParams): TLCLIntfHandle; 1631var 1632 Button: TCustomButton; 1633 WidgetInfo: PWidgetInfo; 1634 Allocation: TGTKAllocation; 1635begin 1636 Button := AWinControl as TCustomButton; 1637 Result := TLCLIntfHandle(PtrUInt(gtk_button_new_with_label('button'))); 1638 if Result = 0 then Exit; 1639 {$IFDEF DebugLCLComponents} 1640 DebugGtkWidgets.MarkCreated(Pointer(Result),'button'); 1641 {$ENDIF} 1642 1643 WidgetInfo := CreateWidgetInfo(Pointer(Result), Button, AParams); 1644 1645 Allocation.X := AParams.X; 1646 Allocation.Y := AParams.Y; 1647 Allocation.Width := AParams.Width; 1648 Allocation.Height := AParams.Height; 1649 gtk_widget_size_allocate(PGtkWidget(Result), @Allocation); 1650 1651 Set_RC_Name(AWinControl, PGtkWidget(Result)); 1652 SetCallbacks(PGtkWidget(Result), WidgetInfo); 1653end; 1654 1655class function TGtkWSButton.GetText(const AWinControl: TWinControl; var AText: String): Boolean; 1656begin 1657 // The button text is static, so let the LCL fallback to FCaption 1658 Result := False; 1659end; 1660 1661class procedure TGtkWSButton.SetDefault(const AButton: TCustomButton; ADefault: Boolean); 1662begin 1663 if not WSCheckHandleAllocated(AButton, 'SetDefault') 1664 then Exit; 1665 1666 if ADefault 1667 and (GTK_WIDGET_CAN_DEFAULT(pgtkwidget(AButton.Handle))) then 1668 //gtk_widget_grab_default(pgtkwidget(handle)) 1669 else begin 1670 {DebugLn('LM_BTNDEFAULT_CHANGED ',TCustomButton(Sender).Name,':',Sender.ClassName,' widget can not grab default ', 1671 ' visible=',GTK_WIDGET_VISIBLE(PGtkWidget(Handle)), 1672 ' realized=',GTK_WIDGET_REALIZED(PGtkWidget(Handle)), 1673 ' mapped=',GTK_WIDGET_MAPPED(PGtkWidget(Handle)), 1674 '');} 1675 // gtk_widget_Draw_Default(pgtkwidget(Handle)); //this isn't right but I'm not sure what to call 1676 end; 1677end; 1678 1679class procedure TGtkWSButton.SetShortcut(const AButton: TCustomButton; const ShortCutK1, ShortCutK2: TShortcut); 1680begin 1681 if not WSCheckHandleAllocated(AButton, 'SetShortcut') 1682 then Exit; 1683 1684 {$IFDEF Gtk1} 1685 Accelerate(AButton, PGtkWidget(AButton.Handle), ShortCutK1, 'clicked'); 1686 {$ENDIF} 1687 // gtk2: shortcuts are handled by the LCL 1688end; 1689 1690class procedure TGtkWSButton.SetText(const AWinControl: TWinControl; const AText: String); 1691var 1692 BtnWidget: PGtkButton; 1693 LblWidget: PGtkLabel; 1694begin 1695 if not WSCheckHandleAllocated(AWincontrol, 'SetText') 1696 then Exit; 1697 1698 BtnWidget := PGtkButton(AWinControl.Handle); 1699 {$IFDEF GTK2} 1700 LblWidget := PGtkLabel(PGtkBin(BtnWidget)^.Child); 1701 {$ELSE} 1702 LblWidget := PGtkLabel(BtnWidget^.Child); 1703 {$ENDIF} 1704 1705 if LblWidget = nil 1706 then begin 1707 //DebugLn(Format('trace: [WARNING] Button %s(%s) has no label', [AWinControl.Name, AWinControl.ClassName])); 1708 LblWidget := PGtkLabel(gtk_label_new('')); 1709 gtk_container_add(PGtkContainer(BtnWidget), PGtkWidget(LblWidget)); 1710 end; 1711 1712 GtkWidgetSet.SetLabelCaption(LblWidget, AText 1713 {$IFDEF Gtk1}, AWinControl,PGtkWidget(BtnWidget), 'clicked'{$ENDIF}); 1714end; 1715 1716class procedure TGtkWSButton.SetColor(const AWinControl: TWinControl); 1717var 1718 Widget: PGTKWidget; 1719begin 1720 if not WSCheckHandleAllocated(AWinControl, 'SetColor') then Exit; 1721 Widget := PGtkWidget(AWinControl.Handle); 1722 GtkWidgetSet.SetWidgetColor(Widget, clNone, AWinControl.Color, 1723 [GTK_STATE_NORMAL,GTK_STATE_ACTIVE,GTK_STATE_PRELIGHT,GTK_STATE_SELECTED]); 1724end; 1725 1726class procedure TGtkWSButton.SetFont(const AWinControl: TWinControl; 1727 const AFont: TFont); 1728var 1729 Widget: PGTKWidget; 1730 LblWidget: PGtkWidget; 1731begin 1732 if not AWinControl.HandleAllocated then exit; 1733 1734 Widget:= PGtkWidget(AWinControl.Handle); 1735 LblWidget := (pGtkBin(Widget)^.Child); 1736 1737 if LblWidget <> nil then 1738 begin 1739 GtkWidgetSet.SetWidgetColor(LblWidget, AFont.Color, clNone, 1740 [GTK_STATE_NORMAL,GTK_STATE_ACTIVE,GTK_STATE_PRELIGHT,GTK_STATE_SELECTED]); 1741 GtkWidgetSet.SetWidgetFont(LblWidget, AFont); 1742 end; 1743end; 1744 1745class procedure TGtkWSButton.GetPreferredSize(const AWinControl: TWinControl; 1746 var PreferredWidth, PreferredHeight: integer; WithThemeSpace: Boolean); 1747begin 1748 GetGTKDefaultWidgetSize(AWinControl,PreferredWidth,PreferredHeight, 1749 WithThemeSpace); 1750 //debugln('TGtkWSButton.GetPreferredSize ',DbgSName(AWinControl),' PreferredWidth=',dbgs(PreferredWidth),' PreferredHeight=',dbgs(PreferredHeight)); 1751end; 1752 1753{$ENDIF Gtk1} 1754 1755{ TGtkWSCustomCheckBox } 1756 1757class procedure TGtkWSCustomCheckBox.SetCallbacks(const AGtkWidget: PGtkWidget; const AWidgetInfo: PWidgetInfo); 1758begin 1759 TGtkWSWinControl.SetCallbacks(PGtkObject(AGtkWidget), TComponent(AWidgetInfo^.LCLObject)); 1760 TGtkWidgetset(WidgetSet).SetCallback(LM_CHANGED, PGtkObject(AGtkWidget), AWidgetInfo^.LCLObject); 1761end; 1762 1763{$IFDEF Gtk1} 1764 1765class function TGtkWSCustomCheckBox.CreateHandle( 1766 const AWinControl: TWinControl; const AParams: TCreateParams 1767 ): TLCLIntfHandle; 1768var 1769 Widget: PGtkWidget; 1770 WidgetInfo: PWidgetInfo; 1771 Allocation: TGTKAllocation; 1772begin 1773 Widget := gtk_check_button_new_with_label(AParams.Caption); 1774 {$IFDEF DebugLCLComponents} 1775 DebugGtkWidgets.MarkCreated(Widget, dbgsName(AWinControl)); 1776 {$ENDIF} 1777 Result := THandle(PtrUInt(Widget)); 1778 WidgetInfo := CreateWidgetInfo(Pointer(Result), AWinControl, AParams); 1779 1780 Allocation.X := AParams.X; 1781 Allocation.Y := AParams.Y; 1782 Allocation.Width := AParams.Width; 1783 Allocation.Height := AParams.Height; 1784 gtk_widget_size_allocate(PGtkWidget(Result), @Allocation); 1785 1786 Set_RC_Name(AWinControl, PGtkWidget(Result)); 1787 SetCallbacks(PGtkWidget(Result), WidgetInfo); 1788end; 1789 1790class function TGtkWSCustomCheckBox.RetrieveState( 1791 const ACustomCheckBox: TCustomCheckBox): TCheckBoxState; 1792var 1793 ToggleButton: PGtkToggleButton; 1794begin 1795 ToggleButton:=PGtkToggleButton(ACustomCheckBox.Handle); 1796 if (gtk_object_get_data(PgtkObject(ToggleButton),'Grayed')<>nil) then 1797 Result:=cbGrayed 1798 else if gtk_toggle_button_get_active(ToggleButton) then 1799 Result := cbChecked 1800 else 1801 Result := cbUnChecked; 1802end; 1803 1804class procedure TGtkWSCustomCheckBox.SetShortCut( 1805 const ACustomCheckBox: TCustomCheckBox; const ShortCutK1, ShortCutK2: TShortCut); 1806begin 1807 Accelerate(ACustomCheckBox, PGtkWidget(ACustomCheckBox.Handle), ShortCutK1, 1808 'activate_item'); 1809end; 1810 1811class procedure TGtkWSCustomCheckBox.SetState(const ACB: TCustomCheckBox; 1812 const ANewState: TCheckBoxState); 1813var 1814 GtkObject: PGtkObject; 1815begin 1816 if not WSCheckHandleAllocated(ACB, 'SetState') 1817 then Exit; 1818 1819 GtkObject := PGtkObject(ACB.Handle); 1820 LockOnChange(GtkObject,1); 1821 if ANewState=cbGrayed then 1822 gtk_object_set_data(GtkObject, 'Grayed', GtkObject) 1823 else 1824 gtk_object_set_data(GtkObject, 'Grayed', nil); 1825 gtk_toggle_button_set_active(PGtkToggleButton(GtkObject), ANewState = cbChecked); 1826 LockOnChange(GtkObject,-1); 1827end; 1828 1829class procedure TGtkWSCustomCheckBox.GetPreferredSize(const AWinControl: TWinControl; 1830 var PreferredWidth, PreferredHeight: integer; WithThemeSpace: Boolean); 1831begin 1832 GetGTKDefaultWidgetSize(AWinControl,PreferredWidth,PreferredHeight, 1833 WithThemeSpace); 1834 //debugln('TGtkWSCustomCheckBox.GetPreferredSize ',DbgSName(AWinControl),' PreferredWidth=',dbgs(PreferredWidth),' PreferredHeight=',dbgs(PreferredHeight)); 1835end; 1836 1837class procedure TGtkWSCustomCheckBox.SetFont(const AWinControl: TWinControl; 1838 const AFont: TFont); 1839var 1840 Widget: PGTKWidget; 1841 LblWidget: PGtkWidget; 1842begin 1843 if not AWinControl.HandleAllocated then exit; 1844 1845 Widget:= PGtkWidget(AWinControl.Handle); 1846 LblWidget := (pGtkBin(Widget)^.Child); 1847 1848 if LblWidget<>nil then 1849 begin 1850 GtkWidgetSet.SetWidgetColor(LblWidget, AFont.Color, clNone, 1851 [GTK_STATE_NORMAL,GTK_STATE_ACTIVE,GTK_STATE_PRELIGHT,GTK_STATE_SELECTED]); 1852 GtkWidgetSet.SetWidgetFont(LblWidget, AFont); 1853 end; 1854end; 1855 1856{$ENDIF} 1857 1858{ TGtkWSCustomMemo } 1859 1860{$ifdef GTK1} 1861 1862class procedure TGtkWSCustomMemo.SetCallbacks(const AGtkWidget: PGtkWidget; 1863 const AWidgetInfo: PWidgetInfo); 1864begin 1865 TGtkWSWinControl.SetCallbacks(PGtkObject(AGtkWidget), TComponent(AWidgetInfo^.LCLObject)); 1866 with TGtkWidgetset(Widgetset) do 1867 begin 1868 SetCallback(LM_CHANGED, PGtkObject(AGtkWidget), AWidgetInfo^.LCLObject); 1869 SetCallback(LM_ACTIVATE, PGtkObject(AGtkWidget), AWidgetInfo^.LCLObject); 1870 SetCallback(LM_CUT, PGtkObject(AGtkWidget), AWidgetInfo^.LCLObject); 1871 SetCallback(LM_COPY, PGtkObject(AGtkWidget), AWidgetInfo^.LCLObject); 1872 SetCallback(LM_PASTE, PGtkObject(AGtkWidget), AWidgetInfo^.LCLObject); 1873 end; 1874end; 1875 1876class function TGtkWSCustomMemo.CreateHandle(const AWinControl: TWinControl; 1877 const AParams: TCreateParams): TLCLIntfHandle; 1878var 1879 P: Pointer; 1880 TempWidget: PGtkWidget; 1881 WidgetInfo: PWidgetInfo; 1882begin 1883 P := gtk_scrolled_window_new(nil, nil); 1884 TempWidget := gtk_text_new(nil, nil); 1885 gtk_container_add(p, TempWidget); 1886 1887 GTK_WIDGET_UNSET_FLAGS(PGtkScrolledWindow(p)^.hscrollbar, GTK_CAN_FOCUS); 1888 GTK_WIDGET_UNSET_FLAGS(PGtkScrolledWindow(p)^.vscrollbar, GTK_CAN_FOCUS); 1889 gtk_scrolled_window_set_policy(PGtkScrolledWindow(p), 1890 GTK_POLICY_AUTOMATIC, 1891 GTK_POLICY_AUTOMATIC); 1892 gtk_text_set_adjustments(PGtkText(TempWidget), 1893 gtk_scrolled_window_get_hadjustment(PGtkScrolledWindow(p)), 1894 gtk_scrolled_window_get_vadjustment(PGtkScrolledWindow(p))); 1895 1896 WidgetInfo := CreateWidgetInfo(P, AWinControl, AParams); 1897 SetMainWidget(p, TempWidget); 1898 WidgetInfo^.CoreWidget := TempWidget; 1899 1900 gtk_text_set_editable (PGtkText(TempWidget), not TCustomMemo(AWinControl).ReadOnly); 1901 if TCustomMemo(AWinControl).WordWrap then 1902 gtk_text_set_line_wrap(PGtkText(TempWidget), GdkTrue) 1903 else 1904 gtk_text_set_line_wrap(PGtkText(TempWidget), GdkFalse); 1905 gtk_text_set_word_wrap(PGtkText(TempWidget), GdkTrue); 1906 1907 gtk_widget_show_all(P); 1908 1909 {$IFDEF DebugLCLComponents} 1910 DebugGtkWidgets.MarkCreated(P,dbgsName(AWinControl)); 1911 {$ENDIF} 1912 Result := TLCLIntfHandle(PtrUInt(P)); 1913 //DebugLn(['TGtkWSCustomMemo.CreateHandle ']); 1914 Set_RC_Name(AWinControl, P); 1915 SetCallbacks(P, WidgetInfo); 1916end; 1917 1918class procedure TGtkWSCustomMemo.AppendText(const ACustomMemo: TCustomMemo; 1919 const AText: string); 1920var 1921 Widget: PGtkWidget; 1922 CurMemoLen: gint; 1923begin 1924 if Length(AText) = 0 then 1925 exit; 1926 1927 Widget:=GetWidgetInfo(Pointer(ACustomMemo.Handle), true)^.CoreWidget; 1928 gtk_text_freeze(PGtkText(Widget)); 1929 CurMemoLen := gtk_text_get_length(PGtkText(Widget)); 1930 //debugln('TGtkWSCustomMemo.AppendText "',AText,'" CurMemoLen=',dbgs(CurMemoLen)); 1931 gtk_editable_insert_text(PGtkOldEditable(Widget), PChar(AText), Length(AText), 1932 @CurMemoLen); 1933 //debugln('TGtkWSCustomMemo.AppendText B CurMemoLen=',dbgs(CurMemoLen)); 1934 gtk_text_thaw(PGtkText(Widget)); 1935end; 1936 1937class function TGtkWSCustomMemo.GetStrings(const ACustomMemo: TCustomMemo): TStrings; 1938var 1939Widget: PGtkText; 1940begin 1941 Widget:=PGtkText(GetWidgetInfo(Pointer(ACustomMemo.Handle), true)^.CoreWidget); 1942 Result:=TGtkMemoStrings.Create(Widget, ACustomMemo); 1943end; 1944 1945class procedure TGtkWSCustomMemo.SetEchoMode(const ACustomEdit: TCustomEdit; 1946 NewMode: TEchoMode); 1947begin 1948 // no password char in memo 1949end; 1950 1951class procedure TGtkWSCustomMemo.SetMaxLength(const ACustomEdit: TCustomEdit; 1952 NewLength: integer); 1953var 1954 ImplWidget: PGtkWidget; 1955 i: integer; 1956begin 1957 if (ACustomEdit.MaxLength > 0) then 1958 begin 1959 ImplWidget := GetWidgetInfo(PGtkWidget(ACustomEdit.Handle), true)^.CoreWidget; 1960 i := gtk_text_get_length(GTK_TEXT(ImplWidget)); 1961 if i > ACustomEdit.MaxLength then 1962 gtk_editable_delete_text(PGtkOldEditable(ImplWidget), 1963 ACustomEdit.MaxLength, i); 1964 end; 1965end; 1966 1967class procedure TGtkWSCustomMemo.SetPasswordChar(const ACustomEdit: TCustomEdit; 1968 NewChar: char); 1969begin 1970 // no password char in memo 1971end; 1972 1973class procedure TGtkWSCustomMemo.SetReadOnly(const ACustomEdit: TCustomEdit; 1974 NewReadOnly: boolean); 1975var 1976 ImplWidget : PGtkWidget; 1977begin 1978 ImplWidget:= GetWidgetInfo(PGtkWidget(ACustomEdit.Handle), true)^.CoreWidget; 1979 gtk_text_set_editable (GTK_TEXT(ImplWidget), not ACustomEdit.ReadOnly); 1980end; 1981 1982class procedure TGtkWSCustomMemo.SetColor(const AWinControl: TWinControl); 1983var 1984 AWidget: PGTKWidget; 1985begin 1986 if not WSCheckHandleAllocated(AWinControl, 'SetColor') then Exit; 1987 AWidget := PGtkWidget(AWinControl.Handle); 1988 AWidget := GetWidgetInfo(AWidget, true)^.CoreWidget; 1989 GtkWidgetSet.SetWidgetColor(AWidget, clNone, AWinControl.Color, 1990 [GTK_STATE_NORMAL, GTK_STATE_ACTIVE, GTK_STATE_PRELIGHT, GTK_STATE_SELECTED, 1991 GTK_STYLE_BASE]); 1992end; 1993 1994class procedure TGtkWSCustomMemo.SetFont(const AWinControl: TWinControl; 1995 const AFont: TFont); 1996var 1997 AWidget: PGTKWidget; 1998begin 1999 if not AWinControl.HandleAllocated then exit; 2000 2001 AWidget:= PGtkWidget(AWinControl.Handle); 2002 AWidget:= GetWidgetInfo(AWidget, true)^.CoreWidget; 2003 2004 if AWidget<>nil then begin 2005 GtkWidgetSet.SetWidgetColor(AWidget, AFont.Color, clNone, 2006 [GTK_STATE_NORMAL,GTK_STATE_ACTIVE,GTK_STATE_PRELIGHT,GTK_STATE_SELECTED, 2007 GTK_STYLE_TEXT]); 2008 GtkWidgetSet.SetWidgetFont(AWidget, AFont); 2009 end; 2010end; 2011 2012class procedure TGtkWSCustomMemo.SetScrollbars(const ACustomMemo: TCustomMemo; 2013 const NewScrollbars: TScrollStyle); 2014var 2015 wHandle: HWND; 2016begin 2017 wHandle := ACustomMemo.Handle; 2018 case ACustomMemo.Scrollbars of 2019 ssHorizontal: gtk_scrolled_window_set_policy( 2020 GTK_SCROLLED_WINDOW(wHandle), 2021 GTK_POLICY_ALWAYS, GTK_POLICY_NEVER); 2022 ssVertical: gtk_scrolled_window_set_policy( 2023 GTK_SCROLLED_WINDOW(wHandle), 2024 GTK_POLICY_NEVER, GTK_POLICY_ALWAYS); 2025 ssBoth: gtk_scrolled_window_set_policy( 2026 GTK_SCROLLED_WINDOW(wHandle), 2027 GTK_POLICY_ALWAYS, GTK_POLICY_ALWAYS); 2028 ssAutoHorizontal: gtk_scrolled_window_set_policy( 2029 GTK_SCROLLED_WINDOW(wHandle), 2030 GTK_POLICY_AUTOMATIC, GTK_POLICY_NEVER); 2031 ssAutoVertical: gtk_scrolled_window_set_policy( 2032 GTK_SCROLLED_WINDOW(wHandle), 2033 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); 2034 ssAutoBoth: gtk_scrolled_window_set_policy( 2035 GTK_SCROLLED_WINDOW(wHandle), 2036 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); 2037 else 2038 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(wHandle), 2039 GTK_POLICY_NEVER, GTK_POLICY_NEVER); 2040 end; 2041end; 2042 2043class procedure TGtkWSCustomMemo.SetWordWrap(const ACustomMemo: TCustomMemo; 2044 const NewWordWrap: boolean); 2045var 2046 ImplWidget : PGtkWidget; 2047begin 2048 ImplWidget:= GetWidgetInfo(PGtkWidget(ACustomMemo.Handle), true)^.CoreWidget; 2049 gtk_text_freeze(PGtkText(ImplWidget)); 2050 if ACustomMemo.WordWrap then 2051 gtk_text_set_line_wrap(GTK_TEXT(ImplWidget), GdkTrue) 2052 else 2053 gtk_text_set_line_wrap(GTK_TEXT(ImplWidget), GdkFalse); 2054 gtk_text_set_word_wrap(GTK_TEXT(ImplWidget), GdkTrue); 2055 gtk_text_thaw(PGtkText(ImplWidget)); 2056end; 2057 2058{$endif} 2059 2060{ TGtkWSCustomGroupBox } 2061 2062class procedure TGtkWSCustomGroupBox.SetCallbacks(const AGtkWidget: PGtkWidget; 2063 const AWidgetInfo: PWidgetInfo); 2064begin 2065 TGtkWSWinControl.SetCallbacks(PGtkObject(AGtkWidget), TComponent(AWidgetInfo^.LCLObject)); 2066end; 2067 2068{$ifdef gtk1} 2069class function TGtkWSCustomGroupBox.CreateHandle( 2070 const AWinControl: TWinControl; const AParams: TCreateParams): TLCLIntfHandle; 2071var 2072 TempWidget: PGTKWidget; // pointer to gtk-widget (local use when neccessary) 2073 p : pointer; // ptr to the newly created GtkWidget 2074 Allocation: TGTKAllocation; 2075 WidgetInfo: PWidgetInfo; 2076begin 2077 if AParams.Caption <> '' then 2078 P := gtk_frame_new(AParams.Caption) 2079 else 2080 P := gtk_frame_new(nil); 2081 WidgetInfo := CreateWidgetInfo(P, AWinControl, AParams); 2082 TempWidget := CreateFixedClientWidget; 2083 gtk_container_add(GTK_CONTAINER(p), TempWidget); 2084 WidgetInfo^.ClientWidget := TempWidget; 2085 WidgetInfo^.CoreWidget := TempWidget; 2086 gtk_object_set_data(PGtkObject(TempWidget), 'widgetinfo', WidgetInfo); 2087 gtk_widget_show(TempWidget); 2088 gtk_widget_show(P); 2089 2090 Result := TLCLIntfHandle(PtrUInt(P)); 2091 2092 Allocation.X := AParams.X; 2093 Allocation.Y := AParams.Y; 2094 Allocation.Width := AParams.Width; 2095 Allocation.Height := AParams.Height; 2096 gtk_widget_size_allocate(P, @Allocation); 2097 2098 Set_RC_Name(AWinControl, P); 2099 SetCallbacks(P, WidgetInfo); 2100end; 2101 2102class procedure TGtkWSCustomGroupBox.GetPreferredSize(const AWinControl: TWinControl; 2103 var PreferredWidth, PreferredHeight: integer; WithThemeSpace: Boolean); 2104var 2105 Widget: PGtkWidget; 2106 border_width: Integer; 2107begin 2108 Widget := PGtkWidget(AWinControl.Handle); 2109 2110 PreferredWidth := (gtk_widget_get_xthickness(Widget)) * 2 2111 +PGtkFrame(Widget)^.label_width; 2112 PreferredHeight := Max(gtk_widget_get_ythickness(Widget), 2113 PGtkFrame(Widget)^.label_height) 2114 + gtk_widget_get_ythickness(Widget); 2115 2116 if WithThemeSpace then begin 2117 border_width:=(PGtkContainer(Widget)^.flag0 and bm_TGtkContainer_border_width) 2118 shr bp_TGtkContainer_border_width; 2119 inc(PreferredWidth, border_width); 2120 inc(PreferredHeight,2*border_width); 2121 end; 2122end; 2123 2124class procedure TGtkWSCustomGroupBox.SetText(const AWinControl: TWinControl; 2125 const AText: string); 2126begin 2127 if not WSCheckHandleAllocated(AWinControl, 'SetText') then Exit; 2128 if AText <> '' then 2129 gtk_frame_set_label(PGtkFrame(AWinControl.Handle), PChar(AText)) 2130 else 2131 gtk_frame_set_label(PGtkFrame(AWinControl.Handle), nil); 2132end; 2133{$endif} 2134 2135{ TGtkWSRadioButton } 2136 2137class function TGtkWSRadioButton.CreateHandle(const AWinControl: TWinControl; 2138 const AParams: TCreateParams): TLCLIntfHandle; 2139var 2140 Widget, TempWidget: PGtkWidget; 2141 LabelWidget: PGtkLabel; 2142 TempInt: Integer; 2143 WidgetInfo: PWidgetInfo; 2144 Allocation: TGTKAllocation; 2145begin 2146 with TRadioButton(AWinControl) do 2147 begin 2148 // Look for our parent's control and use the first radio we find for grouping 2149 TempWidget := nil; 2150 if (Parent <> nil) then 2151 begin 2152 for TempInt := 0 to Parent.ControlCount - 1 do 2153 begin 2154 if (Parent.Controls[TempInt] is TRadioButton) and 2155 TWinControl(Parent.Controls[TempInt]).HandleAllocated then 2156 begin 2157 TempWidget := PGtkWidget(TWinControl(Parent.Controls[TempInt]).Handle); 2158 Break; 2159 end; 2160 end; 2161 end; 2162 2163 if TempWidget <> nil then 2164 Widget := gtk_radio_button_new_with_label(PGtkRadioButton(TempWidget)^.group,'') 2165 else 2166 Widget := gtk_radio_button_new_with_label(nil, ''); 2167 2168 LabelWidget := PGtkLabel(gtk_bin_get_child(PGtkBin(@PGTKToggleButton(Widget)^.Button))); 2169 GtkWidgetSet.SetLabelCaption(LabelWidget, AParams.Caption 2170 {$IFDEF Gtk1}, AWinControl, Widget, 'clicked'{$ENDIF}); 2171 end; 2172 2173 {$IFDEF DebugLCLComponents} 2174 DebugGtkWidgets.MarkCreated(Widget, dbgsName(AWinControl)); 2175 {$ENDIF} 2176 Result := THandle(PtrUInt(Widget)); 2177 WidgetInfo := CreateWidgetInfo(Pointer(Result), AWinControl, AParams); 2178 2179 Allocation.X := AParams.X; 2180 Allocation.Y := AParams.Y; 2181 Allocation.Width := AParams.Width; 2182 Allocation.Height := AParams.Height; 2183 gtk_widget_size_allocate(Widget, @Allocation); 2184 2185 Set_RC_Name(AWinControl, Widget); 2186 TGtkWSCustomCheckBox.SetCallbacks(Widget, WidgetInfo); 2187end; 2188 2189{ TGtkWSToggleBox } 2190 2191class function TGtkWSToggleBox.CreateHandle(const AWinControl: TWinControl; 2192 const AParams: TCreateParams): TLCLIntfHandle; 2193var 2194 Widget: PGtkWidget; 2195 WidgetInfo: PWidgetInfo; 2196 Allocation: TGTKAllocation; 2197begin 2198 Widget := gtk_toggle_button_new_with_label(AParams.Caption); 2199 {$IFDEF DebugLCLComponents} 2200 DebugGtkWidgets.MarkCreated(Widget, dbgsName(AWinControl)); 2201 {$ENDIF} 2202 Result := THandle(PtrUInt(Widget)); 2203 WidgetInfo := CreateWidgetInfo(Pointer(Result), AWinControl, AParams); 2204 2205 Allocation.X := AParams.X; 2206 Allocation.Y := AParams.Y; 2207 Allocation.Width := AParams.Width; 2208 Allocation.Height := AParams.Height; 2209 gtk_widget_size_allocate(Widget, @Allocation); 2210 2211 Set_RC_Name(AWinControl, Widget); 2212 TGtkWSCustomCheckBox.SetCallbacks(Widget, WidgetInfo); 2213end; 2214 2215end. 2216