gtkshedit.pp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586
  1. {
  2. GTK implementation for SHEdit
  3. Copyright (C) 1999-2000 by Sebastian Guenther ([email protected])
  4. See the file COPYING.FPC, included in this distribution,
  5. for details about the copyright.
  6. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  9. }
  10. unit GtkSHEdit;
  11. interface
  12. {$MODE objfpc}
  13. {$H+}
  14. uses
  15. SysUtils, Classes,
  16. GDK, GTK,
  17. doc_text, SHEdit;
  18. const
  19. colBlack = $000000;
  20. colDarkBlue = $000080;
  21. colBlue = $0000ff;
  22. colDarkGreen = $008000;
  23. colGreen = $00ff00;
  24. colDarkCyan = $008080;
  25. colCyan = $00ffff;
  26. colBrown = $800000;
  27. colRed = $ff0000;
  28. colDarkMagenta = $800080;
  29. colMagenta = $ff00ff;
  30. colDarkYellow = $808000;
  31. colYellow = $ffff00;
  32. colGray = $808080;
  33. colGrey = colGray;
  34. colLightGray = $c0c0c0;
  35. colLightGrey = colLightGray;
  36. colWhite = $ffffff;
  37. colInvalid = $ff000000;
  38. colDefault = $ffffffff;
  39. type
  40. TSHFontStyle = (fsNormal, fsBold, fsItalics, fsBoldItalics);
  41. TSHStyle = record
  42. Name: String[32];
  43. Color, Background: LongWord;
  44. FontStyle: TSHFontStyle;
  45. end;
  46. TSHStyleArray = array[1..255] of TSHStyle; // Notice the 1!
  47. PSHStyleArray = ^TSHStyleArray;
  48. {This class is a kind of widget class which implements the ISHWidget
  49. interface for drawing syntax highlighted text}
  50. TGtkSHWidget = class(ISHWidget)
  51. protected
  52. SHStyles: PSHStyleArray;
  53. SHStyleCount: Integer; // # of currently registered styles
  54. shWhitespace: Integer;
  55. CurGCColor: LongWord;
  56. hadj, vadj: PGtkAdjustment;
  57. PaintBox: PGtkWidget;
  58. FEdit: TSHTextEdit;
  59. LeftIndent: Integer;
  60. CharW, CharH: Integer;
  61. Font: array[TSHFontStyle] of PGdkFont; // Fonts for content drawing
  62. gc: PGdkGC;
  63. GdkWnd: PGdkWindow;
  64. procedure SetGCColor(AColor: LongWord);
  65. // ISHWidget Implemenation:
  66. procedure InvalidateRect(x, y, w, h: Integer); override;
  67. // Drawing
  68. procedure ClearRect(x, y, w, h: Integer); override;
  69. procedure DrawTextLine(x1, x2, y: Integer; s: PChar); override;
  70. // Cursor
  71. procedure ShowCursor(x, y: Integer); override;
  72. procedure HideCursor(x, y: Integer); override;
  73. // Scrolling support
  74. function GetHorzPos: Integer; override;
  75. procedure SetHorzPos(x: Integer); override;
  76. function GetVertPos: Integer; override;
  77. procedure SetVertPos(y: Integer); override;
  78. function GetPageWidth: Integer; override;
  79. function GetPageHeight: Integer; override;
  80. function GetLineWidth: Integer; override;
  81. procedure SetLineWidth(count: Integer); override;
  82. function GetLineCount: Integer; override;
  83. procedure SetLineCount(count: Integer); override;
  84. // Clipboard support
  85. function GetClipboard: String; override;
  86. procedure SetClipboard(Content: String); override;
  87. public
  88. Widget: PGtkWidget; // this is the outer editor widget
  89. constructor Create(ADoc: TTextDoc; AEditClass: TSHTextEditClass);
  90. destructor Destroy; override;
  91. procedure SetFocus;
  92. function AddSHStyle(AName: String; AColor, ABackground: LongWord;
  93. AStyle: TSHFontStyle): Integer;
  94. property Edit: TSHTextEdit read FEdit;
  95. end;
  96. implementation
  97. var
  98. InternalClipboardContent: String;
  99. {*****************************************************************************
  100. GTK/GDK Callbacks
  101. *****************************************************************************}
  102. procedure TGtkSHWidget_Expose(GtkWidget: PGtkWidget; event: PGdkEventExpose;
  103. widget: TGtkSHWidget); cdecl;
  104. var
  105. x, y, w, h: Integer;
  106. begin
  107. x := (event^.area.x - widget.LeftIndent) div widget.CharW;
  108. y := event^.area.y div widget.CharH;
  109. w := (event^.area.x + event^.area.width + widget.CharW - 1) div widget.CharW - x;
  110. h := (event^.area.y + event^.area.height + widget.CharH - 1) div widget.CharH - y;
  111. // WriteLn(Format('Expose(%d/%d, %dx%d) for %s', [x, y, w, h, FEdit.ClassName]));
  112. widget.GdkWnd := widget.PaintBox^.window;
  113. widget.GC := gdk_gc_new(widget.GdkWnd);
  114. widget.CurGCColor := 0; // Reset color, because we have a new GC!
  115. gdk_gc_copy(widget.GC, PGtkStyle(widget.PaintBox^.thestyle)^.
  116. fg_gc[widget.PaintBox^.state]);
  117. widget.FEdit.AdjustCursorToRange;
  118. widget.FEdit.DrawContent(x, y, w, h);
  119. end;
  120. function TGtkSHWidget_KeyPressed(GtkWidget: PGtkWidget; Event: PGdkEventKey;
  121. widget: TGtkSHWidget): Integer; cdecl;
  122. var
  123. KeyState,
  124. KeyCode: LongWord;
  125. KeyMods: TShiftState;
  126. begin
  127. Result := 1;
  128. case Event^.KeyVal of
  129. GDK_Return : KeyCode:=13;
  130. GDK_KP_Insert : KeyCode:=GDK_Insert;
  131. GDK_KP_Home : KeyCode:=GDK_Home;
  132. GDK_KP_Left : KeyCode:=GDK_Left;
  133. GDK_KP_Up : KeyCode:=GDK_Up;
  134. GDK_KP_Right : KeyCode:=GDK_Right;
  135. GDK_KP_Down : KeyCode:=GDK_Down;
  136. GDK_KP_Page_Up : KeyCode:=GDK_Page_Up;
  137. GDK_KP_Page_Down : KeyCode:=GDK_Page_Down;
  138. GDK_KP_End : KeyCode:=GDK_End;
  139. GDK_Scroll_Lock,
  140. GDK_Num_Lock,
  141. GDK_Shift_L..GDK_Hyper_R :
  142. begin
  143. // Don't let modifier keys trough as normal keys
  144. // *** This doesn't work reliably! (sg)
  145. exit;
  146. end;
  147. else
  148. KeyCode:=Event^.KeyVal;
  149. end;
  150. KeyState:=Event^.State;
  151. // WriteLn('KeyCode ', KeyCode,' keystate ',KeyState);
  152. // Calculate the Key modifiers (shiftstate)
  153. KeyMods := [];
  154. if (KeyState and 1) <> 0 then KeyMods := KeyMods + [ssShift];
  155. if (KeyState and 2) <> 0 then KeyMods := KeyMods + [ssCaps];
  156. if (KeyState and 4) <> 0 then KeyMods := KeyMods + [ssCtrl];
  157. if (KeyState and 8) <> 0 then KeyMods := KeyMods + [ssAlt];
  158. if (KeyState and $10) <> 0 then KeyMods := KeyMods + [ssNum];
  159. if (KeyState and $40) <> 0 then KeyMods := KeyMods + [ssSuper];
  160. if (KeyState and $80) <> 0 then KeyMods := KeyMods + [ssScroll];
  161. if (KeyState and $100) <> 0 then KeyMods := KeyMods + [ssLeft];
  162. if (KeyState and $200) <> 0 then KeyMods := KeyMods + [ssMiddle];
  163. if (KeyState and $400) <> 0 then KeyMods := KeyMods + [ssRight];
  164. if (KeyState and $2000) <> 0 then KeyMods := KeyMods + [ssAltGr];
  165. widget.FEdit.KeyPressed(KeyCode,KeyMods);
  166. end;
  167. function TGtkSHWidget_ButtonPressEvent(GtkWidget: PGtkWidget;
  168. event: PGdkEventButton; widget: TGtkSHWidget): Integer; cdecl;
  169. begin
  170. widget.FEdit.CursorX := Round((event^.x - widget.LeftIndent) / widget.CharW);
  171. widget.FEdit.CursorY := Trunc(event^.y) div widget.CharH;
  172. widget.SetFocus;
  173. Result := 1;
  174. end;
  175. function TGtkSHWidget_FocusInEvent(GtkWidget: PGtkWidget;
  176. event: PGdkEventFocus; widget: TGtkSHWidget): Integer; cdecl;
  177. begin
  178. // Writeln('focus in');
  179. widget.FEdit.FocusIn;
  180. result:=1;
  181. end;
  182. function TGtkSHWidget_FocusOutEvent(GtkWidget: PGtkWidget; event: PGdkEventFocus; widget: TGtkSHWidget): Integer; cdecl;
  183. begin
  184. // Writeln('focus out');
  185. widget.FEdit.FocusOut;
  186. result:=1;
  187. end;
  188. {*****************************************************************************
  189. TGtkSHWidget
  190. *****************************************************************************}
  191. constructor TGtkSHWidget.Create(ADoc: TTextDoc; AEditClass: TSHTextEditClass);
  192. var
  193. lfd: String; // Logical font descriptor
  194. i: Integer;
  195. begin
  196. inherited Create;
  197. // Create fonts
  198. for i := 0 to 3 do begin
  199. lfd := '-*-courier-';
  200. if (i and 1) <> 0 then lfd := lfd + 'bold'
  201. else lfd := lfd + 'medium';
  202. lfd := lfd + '-';
  203. if (i and 2) <> 0 then lfd := lfd + 'i'
  204. else lfd := lfd + 'r';
  205. lfd := lfd + '-normal--14-*-*-*-*-*-iso8859-1';
  206. Font[TSHFontStyle(i)] := gdk_font_load(PChar(lfd));
  207. end;
  208. CharW := gdk_char_width(Font[fsBold], ' ');
  209. CharH := 14 {=FontHeight} + 3; // *** find better way to determine max. cell height
  210. LeftIndent := CharW;
  211. // Create scrolled window and drawing area
  212. hadj := PGtkAdjustment(gtk_adjustment_new(0, 0, 200, 1, 10, 100));
  213. vadj := PGtkAdjustment(gtk_adjustment_new(0, 0, 200, 1, 10, 100));
  214. Widget := gtk_scrolled_window_new(hadj, vadj);
  215. PaintBox := gtk_drawing_area_new;
  216. gtk_scrolled_window_add_with_viewport(PGtkScrolledWindow(Widget), PaintBox);
  217. gtk_widget_show(PaintBox);
  218. gtk_widget_set_flags(PGtkWidget(PaintBox),GTK_CAN_FOCUS);
  219. gtk_signal_connect(PGtkObject(PaintBox), 'expose-event',
  220. GTK_SIGNAL_FUNC(@TGtkSHWidget_Expose), self);
  221. gtk_signal_connect_after(PGtkObject(PaintBox), 'key-press-event',
  222. GTK_SIGNAL_FUNC(@TGtkSHWidget_Keypressed), self);
  223. gtk_signal_connect(PGtkObject(PaintBox), 'button-press-event',
  224. GTK_SIGNAL_FUNC(@TGtkSHWidget_ButtonPressEvent), self);
  225. gtk_signal_connect_after(PGtkObject(PaintBox), 'focus-in-event',
  226. GTK_SIGNAL_FUNC(@TGtkSHWidget_FocusInEvent), self);
  227. gtk_signal_connect_after(PGtkObject(PaintBox), 'focus-out-event',
  228. GTK_SIGNAL_FUNC(@TGtkSHWidget_FocusOutEvent), self);
  229. gtk_widget_set_events(PGtkWidget(Paintbox),
  230. GDK_EXPOSURE_MASK or GDK_KEY_PRESS_MASK or GDK_KEY_RELEASE_MASK or
  231. GDK_BUTTON_PRESS_MASK or GDK_ENTER_NOTIFY_MASK or GDK_LEAVE_NOTIFY_MASK);
  232. gtk_widget_show(Widget);
  233. FEdit := AEditClass.Create(ADoc, Self);
  234. shWhitespace := AddSHStyle('Whitespace', colBlack, colWhite, fsNormal);
  235. FEdit.shDefault := AddSHStyle('Default', colBlack, colWhite, fsNormal);
  236. FEdit.shSelected := AddSHStyle('Selected', colWhite, colDarkBlue, fsNormal);
  237. { Install keys }
  238. FEdit.AddKeyDef(@FEdit.CursorUp, selClear, 'Cursor up', GDK_Up, []);
  239. FEdit.AddKeyDef(@FEdit.CursorDown, selClear, 'Cursor down', GDK_Down, []);
  240. FEdit.AddKeyDef(@FEdit.CursorLeft, selClear, 'Cursor left', GDK_Left, []);
  241. FEdit.AddKeyDef(@FEdit.CursorRight, selClear, 'Cursor right', GDK_Right, []);
  242. FEdit.AddKeyDef(@FEdit.CursorHome, selClear, 'Cursor Home', GDK_Home, []);
  243. FEdit.AddKeyDef(@FEdit.CursorEnd, selClear, 'Cursor Home', GDK_End, []);
  244. FEdit.AddKeyDef(@FEdit.CursorPageUp, selClear, 'Cursor PageUp', GDK_Page_Up, []);
  245. FEdit.AddKeyDef(@FEdit.CursorPageDown, selClear, 'Cursor PageDown', GDK_Page_Down, []);
  246. FEdit.AddKeyDef(@FEdit.CursorDocBegin, selClear, 'Cursor Document Start', GDK_Page_Up, [ssCtrl]);
  247. FEdit.AddKeyDef(@FEdit.CursorDocEnd, selClear, 'Cursor Document End', GDK_Page_Down, [ssCtrl]);
  248. FEdit.AddKeyDef(@FEdit.CursorUp, selExtend, 'Selection up', GDK_Up, [ssShift]);
  249. FEdit.AddKeyDef(@FEdit.CursorDown, selExtend, 'Selection down', GDK_Down, [ssShift]);
  250. FEdit.AddKeyDef(@FEdit.CursorLeft, selExtend, 'Selection left', GDK_Left, [ssShift]);
  251. FEdit.AddKeyDef(@FEdit.CursorRight, selExtend, 'Selection right', GDK_Right, [ssShift]);
  252. FEdit.AddKeyDef(@FEdit.CursorHome, selExtend, 'Selection Home', GDK_Home, [ssShift]);
  253. FEdit.AddKeyDef(@FEdit.CursorEnd, selExtend, 'Selection Home', GDK_End, [ssShift]);
  254. FEdit.AddKeyDef(@FEdit.CursorPageUp, selExtend, 'Selection PageUp', GDK_Page_Up, [ssShift]);
  255. FEdit.AddKeyDef(@FEdit.CursorPageDown, selExtend, 'Selection PageDown', GDK_Page_Down, [ssShift]);
  256. FEdit.AddKeyDef(@FEdit.CursorDocBegin, selExtend, 'Selection Document Start', GDK_Page_Up, [ssCtrl,ssShift]);
  257. FEdit.AddKeyDef(@FEdit.CursorDocEnd, selExtend, 'Selection Document End', GDK_Page_Down, [ssCtrl,ssShift]);
  258. FEdit.AddKeyDef(@FEdit.ToggleOverwriteMode, selNothing, 'Toggle overwrite mode', GDK_Insert, []);
  259. FEdit.AddKeyDef(@FEdit.EditDelLeft, selClear, 'Delete char left of cursor', GDK_Backspace, []);
  260. FEdit.AddKeyDef(@FEdit.EditDelRight, selClear, 'Delete char right of cursor', GDK_Delete_Key, []);
  261. FEdit.AddKeyDef(@FEdit.EditDelLine, selClear, 'Delete current line', Ord('Y'), [ssCtrl]);
  262. FEdit.AddKeyDef(@FEdit.EditDelLine, selClear, 'Delete current line', Ord('y'), [ssCtrl]);
  263. FEdit.AddKeyDef(@FEdit.EditUndo, selClear, 'Undo last action', GDK_Backspace, [ssAlt]);
  264. FEdit.AddKeyDef(@FEdit.EditRedo, selClear, 'Redo last undone action', GDK_Backspace, [ssShift, ssAlt]);
  265. end;
  266. destructor TGtkSHWidget.Destroy;
  267. begin
  268. FreeMem(SHStyles);
  269. FEdit.Free;
  270. inherited Destroy;
  271. end;
  272. function TGtkSHWidget.AddSHStyle(AName: String; AColor, ABackground: LongWord; AStyle: TSHFontStyle): Integer;
  273. begin
  274. ReAllocMem(SHStyles, SizeOf(TSHStyle) * (SHStyleCount + 1));
  275. Inc(SHStyleCount);
  276. SHStyles^[SHStyleCount].Name := AName;
  277. SHStyles^[SHStyleCount].Color := AColor;
  278. SHStyles^[SHStyleCount].Background := ABackground;
  279. SHStyles^[SHStyleCount].FontStyle := AStyle;
  280. Result := SHStyleCount;
  281. end;
  282. procedure TGtkSHWidget.SetGCColor(AColor: LongWord);
  283. var
  284. c: TGdkColor;
  285. begin
  286. if AColor <> CurGCColor then begin
  287. c.pixel := 0;
  288. c.red := (((AColor shr 16) and 255) * 65535) div 255;
  289. c.green := (((AColor shr 8) and 255) * 65535) div 255;
  290. c.blue := ((AColor and 255) * 65535) div 255;
  291. gdk_colormap_alloc_color(gdk_colormap_get_system, @c, False, True);
  292. gdk_gc_set_foreground(gc, @c);
  293. CurGCColor := AColor;
  294. end;
  295. end;
  296. procedure TGtkSHWidget.ClearRect(x, y, w, h: Integer);
  297. begin
  298. SetGCColor(SHStyles^[shWhitespace].Background);
  299. gdk_draw_rectangle(PGdkDrawable(GdkWnd), GC, 1,
  300. x * CharW + LeftIndent, y * CharH, w * CharW, h * CharH);
  301. end;
  302. procedure TGtkSHWidget.InvalidateRect(x, y, w, h: Integer);
  303. var
  304. r : TGdkRectangle;
  305. begin
  306. r.x := x * CharW + LeftIndent;
  307. r.y := y * CharH;
  308. r.Width := w * CharW;
  309. r.Height := h * CharH;
  310. gtk_widget_draw(PGtkWidget(PaintBox), @r);
  311. end;
  312. procedure TGtkSHWidget.DrawTextLine(x1, x2, y: Integer; s: PChar);
  313. var
  314. CurColor: LongWord;
  315. CurX1, CurX2: Integer;
  316. procedure DoErase;
  317. begin
  318. SetGCColor(CurColor);
  319. if CurX1 < x1 then
  320. CurX1 := x1;
  321. if CurX2 > CurX1 then begin
  322. gdk_draw_rectangle(PGdkDrawable(GdkWnd), GC, 1,
  323. CurX1 * CharW + LeftIndent, y * CharH, (CurX2 - CurX1) * CharW, CharH);
  324. end;
  325. CurX1 := CurX2;
  326. end;
  327. var
  328. RequestedColor: Integer;
  329. NewColor: LongWord;
  330. hs : PChar;
  331. begin
  332. // Erase the (potentially multi-coloured) background
  333. hs := s;
  334. CurColor := SHStyles^[shWhitespace].Background;
  335. CurX1 := 0;
  336. CurX2 := 0;
  337. while (hs[0] <> #0) and (CurX2 <= x2) do begin
  338. case hs[0] of
  339. LF_Escape: begin
  340. NewColor := SHStyles^[Ord(hs[1])].Background;
  341. if NewColor = colDefault then
  342. NewColor := SHStyles^[shWhitespace].Background;
  343. if NewColor <> CurColor then begin
  344. DoErase;
  345. CurColor := NewColor;
  346. end;
  347. Inc(hs, 2);
  348. end;
  349. #9: begin
  350. repeat
  351. Inc(CurX2);
  352. until (CurX2 and 7) = 0;
  353. Inc(hs);
  354. end;
  355. else begin
  356. Inc(hs);
  357. Inc(CurX2);
  358. end;
  359. end;
  360. end;
  361. CurX2 := x2;
  362. DoErase;
  363. // Draw text line
  364. RequestedColor := shWhitespace;
  365. CurX1 := 0;
  366. while s[0] <> #0 do
  367. case s[0] of
  368. LF_Escape: begin
  369. RequestedColor := Ord(s[1]);
  370. Inc(s, 2);
  371. end;
  372. #9: begin
  373. repeat
  374. Inc(CurX1);
  375. until (CurX1 and 7) = 0;
  376. Inc(s);
  377. end;
  378. ' ': begin
  379. Inc(s);
  380. Inc(CurX1);
  381. end;
  382. else begin
  383. if (CurX1 >= x1) and (CurX1 <= x2) then begin
  384. SetGCColor(SHStyles^[RequestedColor].Color);
  385. gdk_draw_text(PGdkDrawable(GdkWnd),
  386. Font[SHStyles^[RequestedColor].FontStyle], GC,
  387. CurX1 * CharW + LeftIndent, (y + 1) * CharH - 3, s, 1);
  388. end;
  389. Inc(s);
  390. Inc(CurX1);
  391. end;
  392. end;
  393. end;
  394. procedure TGtkSHWidget.SetFocus;
  395. begin
  396. gtk_window_set_focus(PGtkWindow(gtk_widget_get_toplevel(Paintbox)),Paintbox);
  397. end;
  398. procedure TGtkSHWidget.ShowCursor(x, y: Integer);
  399. begin
  400. // writeln('Showcursor ',x,',',y);
  401. if assigned(GdkWnd) then
  402. begin
  403. SetGCColor(colBlack);
  404. gdk_draw_rectangle(PGdkDrawable(GdkWnd), GC, 1, x*CharW + LeftIndent, y*CharH, 2, CharH);
  405. end;
  406. end;
  407. procedure TGtkSHWidget.HideCursor(x, y: Integer);
  408. var
  409. r : TGdkRectangle;
  410. begin
  411. // writeln('Hidecursor ',x,',',y);
  412. r.x := x * CharW + LeftIndent;
  413. r.y := y * CharH;
  414. r.Width := 2;
  415. r.Height := CharH;
  416. gtk_widget_draw(PGtkWidget(PaintBox), @r);
  417. end;
  418. function TGtkSHWidget.GetLineWidth: Integer;
  419. begin
  420. Result := (Trunc(hadj^.upper)-LeftIndent) div CharW;
  421. end;
  422. procedure TGtkSHWidget.SetLineWidth(count: Integer);
  423. begin
  424. hadj^.upper := count * CharW + LeftIndent;
  425. gtk_adjustment_changed(hadj);
  426. gtk_widget_set_usize(PaintBox, Trunc(hadj^.upper), Trunc(vadj^.upper));
  427. end;
  428. function TGtkSHWidget.GetLineCount: Integer;
  429. begin
  430. Result := Trunc(vadj^.upper) div CharH;
  431. end;
  432. procedure TGtkSHWidget.SetLineCount(count: Integer);
  433. begin
  434. vadj^.upper := (count+1) * CharH;
  435. gtk_adjustment_changed(vadj);
  436. gtk_widget_set_usize(PaintBox, Trunc(hadj^.upper), Trunc(vadj^.upper));
  437. end;
  438. function TGtkSHWidget.GetClipboard: String;
  439. begin
  440. Result := InternalClipboardContent;
  441. end;
  442. procedure TGtkSHWidget.SetClipboard(Content: String);
  443. begin
  444. InternalClipboardContent := Content;
  445. end;
  446. function TGtkSHWidget.GetHorzPos: Integer;
  447. begin
  448. Result := Trunc(hadj^.value);
  449. if Result>0 then
  450. Result:=(Result-LeftIndent) div CharW;
  451. end;
  452. procedure TGtkSHWidget.SetHorzPos(x: Integer);
  453. begin
  454. if x>0 then
  455. x:=x*CharW+LeftIndent;
  456. gtk_adjustment_set_value(hadj, x);
  457. end;
  458. function TGtkSHWidget.GetVertPos: Integer;
  459. begin
  460. Result := (Trunc(vadj^.value)+CharH-1) div CharH;
  461. end;
  462. procedure TGtkSHWidget.SetVertPos(y: Integer);
  463. begin
  464. gtk_adjustment_set_value(vadj, y*CharH);
  465. end;
  466. function TGtkSHWidget.GetPageWidth: Integer;
  467. begin
  468. Result := Trunc(hadj^.page_size) div CharW;
  469. end;
  470. function TGtkSHWidget.GetPageHeight: Integer;
  471. begin
  472. Result := Trunc(vadj^.page_size) div CharH;
  473. end;
  474. end.