buttonrow.pp 12 KB

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