buttonrow.pp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461
  1. {
  2. This file is part of the fpgtk package
  3. Copyright (c) 1999-2000 by Michael van Canney, Sebastian Guenther
  4. Button row (bar)
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. {$mode objfpc}{$h+}
  12. unit ButtonRow;
  13. interface
  14. {$IFDEF FPC_DOTTEDUNITS}
  15. uses System.Classes, Api.Gtk1.Glib, Api.Gtk1.Gtk, Api.Gtk1.Gdk, Fpgtk;
  16. {$ELSE FPC_DOTTEDUNITS}
  17. uses classes, glib, gtk, gdk, FPgtk;
  18. {$ENDIF FPC_DOTTEDUNITS}
  19. type
  20. TRefreshProc = procedure (Selected:TCollectionItem; NeedFocus:boolean) of object;
  21. TCalcIconFunc = procedure (Item:TCollectionItem; var Pixmap:PGdkPixMap; var mask:PGdkBitmap) of object;
  22. TButtonRow = class (TFPGtkToolbar)
  23. private
  24. FMFirst, FMPrev, FMNext, FMLast,
  25. FMCopy, FMAdd, FMDelete, FMUp, FMDown : TFPGtkMenuItem;
  26. FCopy, FAdd, FDelete, FUp, FDown : TFPGtkWidget;
  27. ICopy, IUp, IDown, IDelete, IAdd : TFPgtkPixmap;
  28. FCollection : TCollection;
  29. FList : TFPgtkCList;
  30. FRefreshProc : TRefreshProc;
  31. FCalcIconFunc : TCalcIconFunc;
  32. FSelectIndex : integer;
  33. FNeedFocus : boolean;
  34. FTitle : AnsiString;
  35. AccelGroup : PGtkAccelGroup;
  36. procedure SetTitle (Value : AnsiString);
  37. procedure CreatePixmaps;
  38. procedure NewSelection (Sender : TFPgtkObject; row,column:integer;
  39. event:PGdkEventButton; data : pointer);
  40. procedure ClickedAdd (Sender : TFPgtkObject; data : pointer);
  41. procedure ClickedCopy (Sender : TFPgtkObject; data : pointer);
  42. procedure ClickedDelete (Sender : TFPgtkObject; data : pointer);
  43. procedure ClickedUp (Sender : TFPgtkObject; data : pointer);
  44. procedure ClickedDown (Sender : TFPgtkObject; data : pointer);
  45. procedure ClickedFirst (Sender : TFPgtkObject; data : pointer);
  46. procedure ClickedPrevious (Sender : TFPgtkObject; data : pointer);
  47. procedure ClickedNext (Sender : TFPgtkObject; data : pointer);
  48. procedure ClickedLast (Sender : TFPgtkObject; data : pointer);
  49. procedure CheckSensitive (index : integer);
  50. procedure FillList;
  51. public
  52. constructor create;
  53. procedure Configure (TheList : TFPgtkCList;
  54. CalcIconFunc : TCalcIconFunc;
  55. RefreshProc : TRefreshProc;
  56. TheSubMenu : TFPgtkMenuShell;
  57. AG : PGtkAccelGroup;
  58. Mods : TGdkModifierType);
  59. procedure ChangeCollection (ACollection : TCollection);
  60. function CurrentItem : TCollectionItem;
  61. property SelectedRow : integer read FSelectIndex;
  62. property Title : AnsiString read FTitle write SetTitle;
  63. end;
  64. implementation
  65. {$IFDEF FPC_DOTTEDUNITS}
  66. uses Xpms, Gtkdeftexts, Fpgtkext;
  67. {$ELSE FPC_DOTTEDUNITS}
  68. uses XPMs, GtkDefTexts, FPgtkExt;
  69. {$ENDIF FPC_DOTTEDUNITS}
  70. var
  71. DefAdd, DefCopy, DefDel, DefUp, DefDown : PGdkPixmap;
  72. DefAddM, DefCopyM, DefDelM, DefUpM, DefDownM : PGdkBitmap;
  73. { TButtonRow }
  74. procedure TButtonRow.SetTitle (Value : AnsiString);
  75. begin
  76. FTitle := Value + ': ';
  77. end;
  78. procedure TButtonRow.CreatePixmaps;
  79. begin
  80. IAdd := TFPgtkPixmap.Create;
  81. ICopy := TFPgtkPixmap.Create;
  82. IDelete := TFPgtkPixmap.Create;
  83. IUp := TFPgtkPixmap.Create;
  84. IDown := TFPgtkPixmap.Create;
  85. if assigned (DefAdd) then
  86. begin
  87. IAdd.SetPixmap (DefAdd, DefAddM);
  88. ICopy.SetPixmap (DefCopy, DefCopyM);
  89. IDelete.SetPixmap (DefDel, DefDelM);
  90. IUp.SetPixmap (DefUp, DefUpM);
  91. IDown.SetPixmap (DefDown, DefDownM);
  92. end
  93. else
  94. begin
  95. IAdd.LoadFromArray (XPMEditAdd);
  96. ICopy.LoadFromArray (XPMEditCopy);
  97. IDelete.LoadFromArray (XPMEditDelete);
  98. IUp.LoadFromArray (XPMEditUp);
  99. IDown.LoadFromArray (XPMEditDown);
  100. IAdd.GetPixmap (DefAdd, DefAddM);
  101. ICopy.GetPixmap (DefCopy, DefCopyM);
  102. IDelete.GetPixmap (DefDel, DefDelM);
  103. IUp.GetPixmap (DefUp, DefUpM);
  104. IDown.GetPixmap (DefDown, DefDownM);
  105. end;
  106. end;
  107. constructor TButtonRow.create;
  108. begin
  109. inherited;
  110. // Create the Pixmaps
  111. CreatePixMaps;
  112. // Configure the toolbar
  113. ButtonRelief := Gtk_Relief_None;
  114. // Create the buttons with the pixmaps
  115. FAdd := AppendItem ('',RemoveUnderscore(smAdd),'',IAdd, @ClickedAdd, nil);
  116. FAdd.Sensitive := False;
  117. FCopy := AppendItem ('',RemoveUnderscore(smCopy),'',ICopy, @ClickedCopy, nil);
  118. FCopy.Sensitive := False;
  119. FDelete := AppendItem ('',RemoveUnderscore(smDelete),'',IDelete, @ClickedDelete, nil);
  120. FDelete.Sensitive := False;
  121. AppendSpace;
  122. FUp := AppendItem ('',RemoveUnderscore(smUp),'',IUp, @ClickedUp, nil);
  123. FUp.Sensitive := False;
  124. FDown := AppendItem ('',RemoveUnderscore(smDown),'',IDown, @ClickedDown, nil);
  125. FDown.Sensitive := False;
  126. end;
  127. procedure TButtonRow.Configure (TheList : TFPgtkCList;
  128. CalcIconFunc : TCalcIconFunc;
  129. RefreshProc : TRefreshProc;
  130. TheSubMenu : TFPgtkMenuShell;
  131. AG : PGtkAccelGroup;
  132. Mods : TGdkModifierType);
  133. function MyKeyDef (Key : guint) : PAccelKeyDef;
  134. begin
  135. if Mods = 0 then
  136. result := nil
  137. else
  138. result := MakeAccelKeyDef (AG, Key, Mods);
  139. end;
  140. begin
  141. FList := TheList;
  142. FCollection := nil;
  143. FRefreshProc := RefreshProc;
  144. FCalcIconFunc := CalcIconFunc;
  145. with FList do
  146. begin
  147. SelectionMode := Gtk_Selection_Browse;
  148. ConnectSelectRow (@NewSelection, nil);
  149. SetColumnAutoResize (0, true);
  150. if assigned (FCalcIconFunc) then
  151. SetColumnAutoResize (1, true);
  152. end;
  153. with TheSubMenu do
  154. begin
  155. FMAdd := NewMenuItem (smAdd, '', '', MyKeyDef (gdk_A), @ClickedAdd, nil);
  156. FMDelete := NewMenuItem (smDelete, '', '', MyKeyDef (gdk_D), @ClickedDelete, nil);
  157. FMCopy := NewMenuItem (smCopy, '', '', MyKeyDef (gdk_C), @ClickedCopy, nil);
  158. FMUp := NewMenuItem (smUp, '', '', MyKeyDef (gdk_U), @ClickedUp, nil);
  159. FMDown := NewMenuItem (smDown, '', '', MyKeyDef (gdk_O), @ClickedDown, nil);
  160. FMFirst := NewMenuItem (smFirst, '', '', MyKeyDef (gdk_F), @ClickedFirst, nil);
  161. FMLast := NewMenuItem (smLast, '', '', MyKeyDef (gdk_L), @ClickedLast, nil);
  162. FMPrev := NewMenuItem (smPrevious, '', '', MyKeyDef (gdk_P), @ClickedPrevious, nil);
  163. FMNext := NewMenuItem (smNext, '', '', MyKeyDef (gdk_N), @ClickedNext, nil);
  164. Add (FMAdd);
  165. Add (FMCopy);
  166. Add (FMDelete);
  167. Add (NewLine);
  168. Add (FMUp);
  169. Add (FMDown);
  170. Add (NewLine);
  171. Add (FMFirst);
  172. Add (FMPrev);
  173. Add (FMNext);
  174. Add (FMLast);
  175. end;
  176. CheckSensitive (-1);
  177. end;
  178. procedure TButtonRow.FillList;
  179. var r : integer;
  180. pm : PGdkPixMap;
  181. m : PGdkBitmap;
  182. begin
  183. FList.Freeze;
  184. try
  185. FList.Clear;
  186. if assigned (FCollection) and (FCollection.Count > 0) then
  187. with FCollection do
  188. begin
  189. if assigned (FCalcIconFunc) then
  190. for r := 0 to count-1 do
  191. begin
  192. FCalcIconFunc (Items[r], pm, m);
  193. FList.Append (['',Items[r].Displayname]);
  194. FList.SetPixmap (r, 0, pm, m);
  195. end
  196. else
  197. for r := 0 to count-1 do
  198. begin
  199. FList.Append (Items[r].Displayname, '~');
  200. end;
  201. end
  202. else
  203. begin
  204. FSelectIndex := -1;
  205. if assigned (FRefreshProc) then
  206. FRefreshProc (nil, false);
  207. end;
  208. finally
  209. FList.Thaw;
  210. end;
  211. end;
  212. procedure TButtonRow.ChangeCollection (ACollection : TCollection);
  213. begin
  214. {$IFDEF debug}
  215. writeln (FTitle, 'ChangeCollection');
  216. {$ENDIF}
  217. FCollection := ACollection;
  218. FillList;
  219. if assigned(FCollection) and (FCollection.count > 0) then
  220. CheckSensitive (0)
  221. else
  222. CheckSensitive (-1);
  223. {$IFDEF debug}
  224. writeln (FTitle, 'ChangeCollection End');
  225. {$ENDIF}
  226. end;
  227. procedure TButtonRow.NewSelection (Sender : TFPgtkObject; row,column:integer;
  228. event:PGdkEventButton; data:pointer);
  229. begin
  230. {$IFDEF debug}
  231. writeln (FTitle, 'NewSelection');
  232. {$ENDIF}
  233. if row >= 0 then
  234. begin
  235. FSelectIndex := row;
  236. CheckSensitive (row);
  237. if assigned (FRefreshProc) then
  238. FRefreshProc (FCollection.items[row], FNeedFocus);
  239. end;
  240. {$IFDEF debug}
  241. writeln (FTitle, 'NewSelection End');
  242. {$ENDIF}
  243. end;
  244. procedure TButtonRow.ClickedAdd (Sender : TFPgtkObject; data : pointer);
  245. var i : TCollectionItem;
  246. pm : PGdkPixmap;
  247. m : PGdkBitmap;
  248. begin
  249. {$IFDEF debug}
  250. writeln (FTitle, 'ClickedAdd');
  251. {$ENDIF}
  252. if assigned(FCollection) then
  253. begin
  254. i := FCollection.Add;
  255. i.displayname := sNew;
  256. if assigned (FCalcIconFunc) then
  257. begin
  258. FCalcIconFunc (I, pm, m);
  259. FList.Append (['',I.DisplayName]);
  260. FList.SetPixmap (Flist.count, 0, pm, m);
  261. end
  262. else
  263. FList.Append (i.displayName, '~');
  264. FNeedFocus := True;
  265. FList.SelectRow (FList.Count-1, 0);
  266. end;
  267. {$IFDEF debug}
  268. writeln (FTitle, 'ClickedAdd End');
  269. {$ENDIF}
  270. end;
  271. procedure TButtonRow.ClickedCopy (Sender : TFPgtkObject; data : pointer);
  272. var c, i : TCollectionItem;
  273. pm : PGdkPixmap;
  274. m : PGdkBitmap;
  275. begin
  276. {$IFDEF debug}
  277. writeln (FTitle, 'ClickedCopy');
  278. {$ENDIF}
  279. c := CurrentItem;
  280. if assigned(FCollection) and assigned (c) then
  281. begin
  282. i := FCollection.Add;
  283. i.assign(c);
  284. if assigned (FCalcIconFunc) then
  285. begin
  286. FCalcIconFunc (I, pm, m);
  287. FList.Append (['',I.DisplayName]);
  288. FList.SetPixmap (Flist.count-1, 0, pm, m);
  289. end
  290. else
  291. FList.Append (i.displayName, '~');
  292. FNeedFocus := True;
  293. FList.SelectRow (FList.Count-1,0);
  294. end;
  295. {$IFDEF debug}
  296. writeln (FTitle, 'ClickedCopy End');
  297. {$ENDIF}
  298. end;
  299. procedure TButtonRow.ClickedDelete (Sender : TFPgtkObject; data : pointer);
  300. begin
  301. {$IFDEF debug}
  302. writeln (FTitle, 'ClickedDelete');
  303. {$ENDIF}
  304. if FSelectIndex >= 0 then
  305. begin
  306. FCollection.Items[FSelectIndex].Free;
  307. FList.Remove (FSelectIndex);
  308. FNeedFocus := False;
  309. FList.SelectRow (FSelectIndex, 0);
  310. end;
  311. {$IFDEF debug}
  312. writeln (FTitle, 'ClickedDelete End');
  313. {$ENDIF}
  314. end;
  315. procedure TButtonRow.ClickedUp (Sender : TFPgtkObject; data : pointer);
  316. begin
  317. {$IFDEF debug}
  318. writeln (FTitle, 'ClickedUp');
  319. {$ENDIF}
  320. if FSelectIndex > 0 then
  321. begin
  322. with FCollection.Items[FSelectIndex] do
  323. Index := Index - 1;
  324. with FList do
  325. begin
  326. SwapRows (FSelectIndex, FSelectIndex-1);
  327. FNeedFocus := False;
  328. SelectRow (FSelectIndex-1, 0);
  329. end;
  330. //CheckSensitive (FSelectIndex-1);
  331. end;
  332. {$IFDEF debug}
  333. writeln (FTitle, 'ClickedUp End');
  334. {$ENDIF}
  335. end;
  336. procedure TButtonRow.ClickedDown (Sender : TFPgtkObject; data : pointer);
  337. begin
  338. {$IFDEF debug}
  339. writeln (FTitle, 'ClickedDown');
  340. {$ENDIF}
  341. if (FSelectIndex >= 0) and (FSelectIndex < FCollection.count-1) then
  342. begin
  343. with FCollection.Items[FSelectIndex] do
  344. Index := Index + 1;
  345. with FList do
  346. begin
  347. SwapRows (FSelectIndex, FSelectIndex+1);
  348. FNeedFocus := False;
  349. SelectRow (FSelectIndex+1, 0);
  350. end;
  351. end;
  352. {$IFDEF debug}
  353. writeln (FTitle, 'ClickedDown End');
  354. {$ENDIF}
  355. end;
  356. procedure TButtonRow.ClickedFirst (Sender : TFPgtkObject; data : pointer);
  357. begin
  358. FNeedFocus := False;
  359. with FList do
  360. SelectRow (0, 0);
  361. end;
  362. procedure TButtonRow.ClickedPrevious (Sender : TFPgtkObject; data : pointer);
  363. begin
  364. FNeedFocus := False;
  365. if (FSelectIndex > 0) then
  366. with FList do
  367. SelectRow (FSelectIndex-1, 0);
  368. end;
  369. procedure TButtonRow.ClickedNext (Sender : TFPgtkObject; data : pointer);
  370. begin
  371. FNeedFocus := False;
  372. if (FSelectIndex >= 0) and (FSelectIndex < FCollection.count-1) then
  373. with FList do
  374. SelectRow (FSelectIndex+1, 0);
  375. end;
  376. procedure TButtonRow.ClickedLast (Sender : TFPgtkObject; data : pointer);
  377. begin
  378. FNeedFocus := False;
  379. with FList do
  380. SelectRow (FSelectIndex+1, 0);
  381. end;
  382. procedure TButtonRow.CheckSensitive (index : integer);
  383. var b : boolean;
  384. begin
  385. {$IFDEF debug}
  386. writeln (FTitle, 'CheckSensitive ', index);
  387. {$ENDIF}
  388. b := assigned(FCollection);
  389. FAdd.Sensitive := b;
  390. FMAdd.Sensitive := b;
  391. FMFirst.Sensitive := b;
  392. FMLast.Sensitive := b;
  393. b := assigned(FCollection) and (index >= 0) and (index < FCollection.Count);
  394. FCopy.Sensitive := b;
  395. FMCopy.Sensitive := b;
  396. b := assigned(FCollection) and (index >= 0) and (index < FCollection.count);
  397. FDelete.Sensitive := b;
  398. FMDelete.Sensitive := b;
  399. b := assigned(FCollection) and (index >= 0) and (index < FCollection.count-1);
  400. FDown.Sensitive := b;
  401. FMDown.Sensitive := b;
  402. FMNext.Sensitive := b;
  403. FUp.Sensitive := b;
  404. b := assigned(FCollection) and (index > 0) and (index < FCollection.count);
  405. FUp.Sensitive := b;
  406. FMUp.Sensitive := b;
  407. FMPrev.Sensitive := b;
  408. {$IFDEF debug}
  409. writeln (FTitle, 'CheckSensitive End');
  410. {$ENDIF}
  411. end;
  412. function TButtonRow.CurrentItem : TCollectionItem;
  413. begin
  414. {$IFDEF debug}
  415. writeln (FTitle, 'CurrentItem');
  416. {$ENDIF}
  417. if FSelectIndex >= 0 then
  418. result := FCollection.Items[FSelectIndex]
  419. else
  420. result := nil;
  421. {$IFDEF debug}
  422. writeln (FTitle, 'CurrentItem End');
  423. {$ENDIF}
  424. end;
  425. end.