1 {
2 *****************************************************************************
3 This file is part of the EducationLaz package
4
5 See the file COPYING.modifiedLGPL.txt, included in this distribution,
6 for details about the license.
7 *****************************************************************************
8
9 Author: Mattias Gaertner, Michael Kuhardt
10
11 Abstract:
12 Frame to setup the component palette.
13 }
14 unit EduCompPalette;
15
16 {$mode objfpc}{$H+}
17
18 interface
19
20 uses
21 Classes, SysUtils, Laz_AVL_Tree,
22 // LCL
23 LCLProc, LCLType, LResources, Forms, Controls, Graphics, Dialogs, ComCtrls,
24 ExtCtrls, StdCtrls,
25 // LazUtils
26 LazConfigStorage, AvgLvlTree,
27 // IdeIntf
28 FormEditingIntf, IDEOptionsIntf, IDEOptEditorIntf, ComponentReg, IDEImagesIntf,
29 // Education
30 EduOptions;
31
32 type
33 { TEduComponentPaletteOptions }
34
35 TEduComponentPaletteOptions = class(TEduOptionsNode)
36 private
37 fVisible: TStringToStringTree;
GetComponentVisiblenull38 function GetComponentVisible(ComponentName: string): boolean;
39 procedure SetComponentVisible(ComponentName: string; const AValue: boolean);
40 procedure VoteForVisible(AComponent: TRegisteredComponent; var Vote: integer);
41 public
42 constructor Create; override;
43 destructor Destroy; override;
Loadnull44 function Load(Config: TConfigStorage): TModalResult; override;
Savenull45 function Save(Config: TConfigStorage): TModalResult; override;
46 procedure Apply(Enable: boolean); override;
47 property ComponentVisible[ComponentName: string]: boolean read GetComponentVisible write SetComponentVisible;
48 end;
49
50 { TEduCompPaletteFrame }
51
52 TEduCompPaletteFrame = class(TAbstractIDEOptionsEditor)
53 ShowExtendedButton: TButton;
54 ShowMinimalButton: TButton;
55 ComponentsGroupBox: TGroupBox;
56 ComponentsTreeView: TTreeView;
57 HideAllButton: TButton;
58 LeftPanel: TPanel;
59 ShowAllButton: TButton;
60 procedure ComponentsTreeViewMouseDown(Sender: TObject;
61 Button: TMouseButton; {%H-}Shift: TShiftState; X, Y: Integer);
62 procedure FrameClick(Sender: TObject);
63 procedure HideAllButtonClick(Sender: TObject);
64 procedure ShowAllButtonClick(Sender: TObject);
65 procedure ShowExtendedButtonClick(Sender: TObject);
66 procedure ShowMinimalButtonClick(Sender: TObject);
67 private
68 HideImgID: LongInt;
69 ShowImgID: LongInt;
70 fCompNameToImgIndex: TStringToPointerTree; // Component.ClassName to index+1 in TreeViews.Images
71 procedure FillComponentTreeView;
72 procedure SaveFillComponentTreeView;
73 procedure ShowHideAll(aShow: boolean);
74 procedure ShowSelected(extended: boolean);
75 public
76 destructor Destroy; override;
GetTitlenull77 function GetTitle: String; override;
78 procedure ReadSettings(AOptions: TAbstractIDEOptions); override;
79 procedure Setup({%H-}ADialog: TAbstractOptionsEditorDialog); override;
SupportedOptionsClassnull80 class function SupportedOptionsClass: TAbstractIDEOptionsClass; override;
81 procedure WriteSettings(AOptions: TAbstractIDEOptions); override;
82 end;
83
84 var
85 EduComponentPaletteOptions: TEduComponentPaletteOptions = nil;
86
87 procedure Register;
88
89 implementation
90
91 procedure Register;
92 begin
93 EduComponentPaletteOptions:=TEduComponentPaletteOptions.Create;
94 EducationOptions.Root.Add(EduComponentPaletteOptions);
95 EduOptionCompPaletteID:=RegisterIDEOptionsEditor(EduOptionID,
96 TEduCompPaletteFrame,EduOptionCompPaletteID)^.Index;
97 end;
98
99 { TEduCompPaletteFrame }
100
101 procedure TEduCompPaletteFrame.ComponentsTreeViewMouseDown(Sender: TObject;
102 Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
103 var
104 Node: TTreeNode;
105 Hit: THitTests;
106 begin
107 if Button<>mbLeft then exit;
108 Node:=ComponentsTreeView.GetNodeAt(X,Y);
109 if (Node=nil) then exit;
110 if Node.Parent=nil then exit;
111 Hit:=ComponentsTreeView.GetHitTestInfoAt(X,Y);
112 if [htOnIcon,htOnStateIcon]*Hit<>[] then begin
113 if Node.StateIndex=ShowImgID then
114 Node.StateIndex:=HideImgID
115 else
116 Node.StateIndex:=ShowImgID;
117 end;
118 end;
119
120 procedure TEduCompPaletteFrame.FrameClick(Sender: TObject);
121 begin
122
123 end;
124
125 procedure TEduCompPaletteFrame.HideAllButtonClick(Sender: TObject);
126 begin
127 ShowHideAll(false);
128 end;
129
130 procedure TEduCompPaletteFrame.ShowAllButtonClick(Sender: TObject);
131 begin
132 ShowHideAll(true);
133 end;
134
135 procedure TEduCompPaletteFrame.ShowExtendedButtonClick(Sender: TObject);
136 begin
137 ShowHideAll(false);
138 ShowSelected(true);
139 end;
140
141 procedure TEduCompPaletteFrame.ShowMinimalButtonClick(Sender: TObject);
142 begin
143 ShowHideAll(false);
144 ShowSelected(false);
145 end;
146
147 procedure TEduCompPaletteFrame.FillComponentTreeView;
148
GetIconCopynull149 function GetIconCopy(ResName: string): TCustomBitMap;
150 var
151 ResHandle: TLResource;
152 begin
153 Result := nil;
154 // prevent raising exception and speedup a bit search/load
155 ResHandle := LazarusResources.Find(ResName);
156 if ResHandle <> nil then
157 Result := CreateBitmapFromLazarusResource(ResHandle)
158 else
159 if FindResource(HInstance, PChar(ResName), PChar(RT_BITMAP)) <> 0 then
160 begin
161 Result := TBitmap.Create;
162 Result.LoadFromResourceName(HInstance, ResName);
163 Result.Transparent := True;
164 end
165 else
166 if FindResource(HInstance, PChar(ResName), PChar(RT_RCDATA)) <> 0 then
167 Result := CreateBitmapFromResourceName(HInstance, ResName);
168 end;
169
GetCompImgIndexnull170 function GetCompImgIndex(ResName: string): integer;
171 var
172 Img: TCustomBitmap;
173 begin
174 if fCompNameToImgIndex=nil then
175 fCompNameToImgIndex:=TStringToPointerTree.Create(false);
176 if fCompNameToImgIndex.Contains(ResName) then begin
177 Result:=PtrUInt(fCompNameToImgIndex[ResName])-1;
178 end else begin
179 // load
180 Img:=GetIconCopy(ResName);
181 if Img=nil then
182 Img:=GetIconCopy('unregisteredcomponent');
183 if Img<>nil then begin
184 Result:=ComponentsTreeView.Images.Add(Img,nil);
185 Img.Free;
186 end else begin
187 Result:=-1;
188 end;
189 fCompNameToImgIndex[ResName]:=Pointer(PtrUInt(Result+1));
190 end;
191 end;
192
193 var
194 i: Integer;
195 Page: TBaseComponentPage;
196 PageNode: TTreeNode;
197 CompNode: TTreeNode;
198 CompName: String;
199 Comp: TRegisteredComponent;
200 begin
201 ComponentsTreeView.BeginUpdate;
202 ComponentsTreeView.Items.Clear;
203 if ComponentsTreeView.Images=nil then begin
204 ComponentsTreeView.Images:=TImageList.Create(Self);
205 ComponentsTreeView.Images.Width:=ComponentPaletteImageWidth;
206 ComponentsTreeView.Images.Height:=ComponentPaletteImageHeight;
207 ComponentsTreeView.StateImages:=IDEImages.Images_16;
208 end else
209 ComponentsTreeView.Images.Clear;
210 ShowImgID:=IDEImages.LoadImage('menu_run');
211 HideImgID:=IDEImages.LoadImage('menu_stop');
212 for i:=0 to IDEComponentPalette.Comps.Count-1 do begin
213 Comp:=IDEComponentPalette.Comps[i];
214 Page:=Comp.RealPage;
215 if (Page=nil) or (Page.PageName='') then continue;
216 PageNode:=ComponentsTreeView.Items.FindTopLvlNode(Page.PageName);
217 if PageNode=nil then
218 PageNode:=ComponentsTreeView.Items.Add(nil,Page.PageName);
219 CompName:=Comp.ComponentClass.ClassName;
220 CompNode:=ComponentsTreeView.Items.AddChild(PageNode,CompName);
221 CompNode.ImageIndex:=GetCompImgIndex(CompName);
222 CompNode.SelectedIndex:=CompNode.ImageIndex;
223 if EduComponentPaletteOptions.ComponentVisible[CompName] then
224 CompNode.StateIndex:=ShowImgID
225 else
226 CompNode.StateIndex:=HideImgID;
227 PageNode.Expanded:=true;
228 end;
229 ComponentsTreeView.EndUpdate;
230 end;
231
232 procedure TEduCompPaletteFrame.SaveFillComponentTreeView;
233 var
234 Node: TTreeNode;
235 CompName: String;
236 begin
237 Node:=ComponentsTreeView.Items.GetFirstNode;
238 while Node<>nil do begin
239 if Node.Parent<>nil then begin
240 CompName:=Node.Text;
241 EduComponentPaletteOptions.ComponentVisible[CompName]:=
242 Node.StateIndex=ShowImgID;
243 end else begin
244
245 end;
246 Node:=Node.GetNext;
247 end;
248 end;
249
250 procedure TEduCompPaletteFrame.ShowHideAll(aShow: boolean);
251 var
252 Node: TTreeNode;
253 CompName: String;
254 begin
255 ComponentsTreeView.BeginUpdate;
256 Node:=ComponentsTreeView.Items.GetFirstNode;
257 while Node<>nil do begin
258 if Node.Parent<>nil then begin
259 CompName:=Node.Text;
260
261 EduComponentPaletteOptions.ComponentVisible[CompName]:=aShow;
262 if aShow then
263 Node.StateIndex:=ShowImgID
264 else
265 Node.StateIndex:=HideImgID;
266 end
267
268 else begin
269
270 end;
271
272 Node:=Node.GetNext;
273 end;
274 ComponentsTreeView.EndUpdate;
275 end;
276
277 procedure TEduCompPaletteFrame.ShowSelected(extended: boolean);
278 var
279 Node: TTreeNode;
280 CompName: String;
281 MinimalComponents: array[0..12] of String;
282 ExtendedComponents: array[0..25] of String;
283 i,k: integer;
284 begin
285
286 MinimalComponents[0] := 'TEdit';
287 MinimalComponents[1] := 'TButton';
288 MinimalComponents[2] := 'TCheckBox';
289 MinimalComponents[3] := 'TLabel';
290 MinimalComponents[4] := 'TListBox';
291 MinimalComponents[5] := 'TComboBox';
292 MinimalComponents[6] := 'TRadioGroup';
293 MinimalComponents[7] := 'TRadioButton';
294 MinimalComponents[8] := 'TPanel';
295 MinimalComponents[9] := 'TMainMenu';
296 MinimalComponents[10] := 'TMemo';
297 MinimalComponents[11] := 'TGroupBox';
298 MinimalComponents[12] := 'TImage';
299
300 ExtendedComponents[0] := 'TBitBtn';
301 ExtendedComponents[1] := 'TScrollBar';
302 ExtendedComponents[2] := 'TPopupMenu';
303 ExtendedComponents[3] := 'TCheckGroup';
304 ExtendedComponents[4] := 'TActionList';
305 ExtendedComponents[5] := 'TStringGrid';
306 ExtendedComponents[6] := 'TSpeedButton';
307 ExtendedComponents[7] := 'TTimer';
308 ExtendedComponents[8] := 'TIdleTimer';
309 ExtendedComponents[9] := 'TPageControl';
310 ExtendedComponents[10] := 'TStaticText';
311 ExtendedComponents[11] := 'TDBGrid';
312 ExtendedComponents[12] := 'TOpenDialog';
313 ExtendedComponents[13] := 'TSaveDialog';
314 ExtendedComponents[14] := 'TSelectDirectoryDialog';
315 ExtendedComponents[15] := 'TDataSource';
316 ExtendedComponents[16] := 'TDBNavigator';
317 ExtendedComponents[17] := 'TDBText';
318 ExtendedComponents[18] := 'TDBEdit';
319 ExtendedComponents[19] := 'TDBMemo';
320 ExtendedComponents[20] := 'TDBImage';
321 ExtendedComponents[21] := 'TDBListBox';
322 ExtendedComponents[22] := 'TDBLookupListBox';
323 ExtendedComponents[23] := 'TDBComboBox';
324 ExtendedComponents[24] := 'TDBLookupComboBox';
325 ExtendedComponents[25] := 'TDBCheckBox';
326
327 ComponentsTreeView.BeginUpdate;
328 Node:=ComponentsTreeView.Items.GetFirstNode;
329 while Node<>nil do begin
330 if Node.Parent<>nil then begin
331 CompName:=Node.Text;
332 for i := 0 to 12 do begin
333 if (CompareText (CompName , MinimalComponents[i] )=0) then begin
334 EduComponentPaletteOptions.ComponentVisible[CompName]:=true;
335 Node.StateIndex:=ShowImgID;
336 end;
337 end;
338
339 if extended then begin
340 for k := 0 to 25 do begin
341 if (CompareText (CompName , ExtendedComponents[k] )=0) then begin
342 EduComponentPaletteOptions.ComponentVisible[CompName]:=true;
343 Node.StateIndex:=ShowImgID;
344 end;
345 end;
346 end;
347
348 end;
349
350 Node:=Node.GetNext;
351 end;
352 ComponentsTreeView.EndUpdate;
353 end;
354
355 destructor TEduCompPaletteFrame.Destroy;
356 begin
357 FreeAndNil(fCompNameToImgIndex);
358 inherited Destroy;
359 end;
360
TEduCompPaletteFrame.GetTitlenull361 function TEduCompPaletteFrame.GetTitle: String;
362 begin
363 Result:=ersEduCompPaletteTitle;
364 end;
365
366 procedure TEduCompPaletteFrame.ReadSettings(AOptions: TAbstractIDEOptions);
367 begin
368 if AOptions=EducationOptions then begin
369 FillComponentTreeView;
370 end;
371 end;
372
373 procedure TEduCompPaletteFrame.Setup(ADialog: TAbstractOptionsEditorDialog);
374 begin
375 ShowAllButton.Caption:=ersShowAll;
376 HideAllButton.Caption:=ersHideAll;
377 ShowMinimalButton.Caption:=ersShowMinimal;
378 ShowExtendedButton.Caption:=ersShowExtended;
379 ComponentsGroupBox.Caption:=ersVisibleComponents;
380 end;
381
TEduCompPaletteFrame.SupportedOptionsClassnull382 class function TEduCompPaletteFrame.SupportedOptionsClass: TAbstractIDEOptionsClass;
383 begin
384 Result:=EducationIDEOptionsClass;
385 end;
386
387 procedure TEduCompPaletteFrame.WriteSettings(AOptions: TAbstractIDEOptions);
388 begin
389 if AOptions=EducationOptions then begin
390 SaveFillComponentTreeView;
391 end;
392 end;
393
394 { TEduComponentPaletteOptions }
395
GetComponentVisiblenull396 function TEduComponentPaletteOptions.GetComponentVisible(ComponentName: string): boolean;
397 begin
398 Result:=fVisible[ComponentName]='1';
399 end;
400
401 procedure TEduComponentPaletteOptions.SetComponentVisible(
402 ComponentName: string; const AValue: boolean);
403 begin
404 if AValue then
405 fVisible[ComponentName]:='1'
406 else
407 fVisible.Remove(ComponentName);
408 end;
409
410 procedure TEduComponentPaletteOptions.VoteForVisible(
411 AComponent: TRegisteredComponent; var Vote: integer);
412 begin
413 if not ComponentVisible[AComponent.ComponentClass.ClassName] then dec(Vote,100);
414 end;
415
416 constructor TEduComponentPaletteOptions.Create;
417 begin
418 inherited Create;
419 Name:='ComponentPalette';
420 fVisible:=TStringToStringTree.Create(false);
421 IDEComponentPalette.AddHandlerUpdateVisible(@VoteForVisible);
422 end;
423
424 destructor TEduComponentPaletteOptions.Destroy;
425 begin
426 if IDEComponentPalette<>nil then
427 IDEComponentPalette.RemoveHandlerUpdateVisible(@VoteForVisible);
428 FreeAndNil(fVisible);
429 inherited Destroy;
430 end;
431
TEduComponentPaletteOptions.Loadnull432 function TEduComponentPaletteOptions.Load(Config: TConfigStorage): TModalResult;
433 var
434 Cnt: LongInt;
435 i: Integer;
436 ComponentName: String;
437 begin
438 fVisible.Clear;
439 Cnt:=Config.GetValue('Visible/Count',0);
440 for i:=1 to Cnt do begin
441 ComponentName:=Config.GetValue('Visible/Item'+IntToStr(i),'');
442 if ComponentName='' then continue;
443 fVisible[ComponentName]:='1';
444 end;
445 Result:=inherited Load(Config);
446 end;
447
TEduComponentPaletteOptions.Savenull448 function TEduComponentPaletteOptions.Save(Config: TConfigStorage): TModalResult;
449 var
450 Node: TAvlTreeNode;
451 Item: PStringToStringItem;
452 Cnt: Integer;
453 begin
454 Cnt:=0;
455 Node:=fVisible.Tree.FindLowest;
456 while Node<>nil do begin
457 inc(Cnt);
458 Item:=PStringToStringItem(Node.Data);
459 Config.SetDeleteValue('Visible/Item'+IntToStr(Cnt),Item^.Name,'');
460 Node:=fVisible.Tree.FindSuccessor(Node);
461 end;
462 Config.SetDeleteValue('Visible/Count',Cnt,0);
463 Result:=inherited Save(Config);
464 end;
465
466 procedure TEduComponentPaletteOptions.Apply(Enable: boolean);
467 begin
468 inherited Apply(Enable);
469 if IDEComponentPalette<>nil then
470 IDEComponentPalette.Update(False);
471 end;
472
473 {$R *.lfm}
474
475 end.
476