1 // SPDX-License-Identifier: GPL-3.0-only
2 unit UMenu;
3
4 {$mode objfpc}{$H+}
5
6 interface
7
8 uses
9 Classes, SysUtils, ActnList, Forms, Menus, UTool, LCLType, ExtCtrls, UConfig,
10 Controls, LazPaintType;
11
12 type
13
14 { TMainFormMenu }
15
16 TMainFormMenu = class
17 private
18 FActionList: TActionList;
19 FDarkTheme: boolean;
20 FMainMenus: array of TMenuItem;
21 FToolsShortcuts: array[TPaintToolType] of TUTF8Char;
22 FToolbars: array of record
23 tb: TPanel;
24 fixed: boolean;
25 end;
26 FToolbarsHeight : integer;
27 FToolbarBackground: TPanel;
28 FImageList: TImageList;
29 procedure IconSizeItemClick(Sender: TObject);
30 procedure IconSizeMenuClick(Sender: TObject);
31 procedure Script_Click(Sender: TObject);
32 procedure SetDarkTheme(AValue: boolean);
33 protected
34 FInstance: TLazPaintCustomInstance;
35 FInstalledScripts: TStringList;
36 FTargetDPI: integer;
37 procedure AddMenus(AMenu: TMenuItem; AActionList: TActionList; AActionsCommaText: string; AIndex: integer = -1); overload;
38 procedure AddMenus(AMenuName: string; AActionsCommaText: string); overload;
39 procedure AddInstalledScripts(AMenu: TMenuItem; AIndex: integer = -1);
40 procedure ApplyShortcuts;
41 procedure ActionShortcut(AName: string; AShortcut: TUTF8Char);
42 procedure ApplyTheme;
GetIndividualToolbarHeightnull43 function GetIndividualToolbarHeight: integer;
44 public
45 constructor Create(AInstance: TLazPaintCustomInstance; AActionList: TActionList);
46 destructor Destroy; override;
47 procedure PredefinedMainMenus(const AMainMenus: array of TMenuItem);
48 procedure Toolbars(const AToolbars: array of TPanel; AToolbarBackground: TPanel);
49 procedure ScaleToolbars(ATargetDPI: integer);
50 procedure CycleTool(var ATool: TPaintToolType; var AShortCut: TUTF8Char);
51 procedure Apply;
52 procedure ArrangeToolbars(ClientWidth: integer);
53 procedure RepaintToolbar;
54 property ToolbarsHeight: integer read FToolbarsHeight;
55 property ImageList: TImageList read FImageList write FImageList;
56 property DarkTheme: boolean read FDarkTheme write SetDarkTheme;
57 end;
58
59 implementation
60
61 uses UResourceStrings, BGRAUTF8, LCScaleDPI, ComCtrls, Graphics,
62 StdCtrls, BGRAText, math, udarktheme,
63 ugraph, BGRABitmapTypes, LCVectorialFillControl,
64 UPython, UTranslation;
65
66 { TMainFormMenu }
67
68 procedure TMainFormMenu.IconSizeMenuClick(Sender: TObject);
69 var
70 menu: TMenuItem;
71 i, iconSize: Integer;
72 begin
73 menu := Sender as TMenuItem;
74 iconSize := FInstance.Config.DefaultIconSize(0);
75 for i := 0 to menu.Count-1 do
76 menu.Items[i].Checked := (menu.Items[i].Tag = iconSize);
77 end;
78
79 procedure TMainFormMenu.Script_Click(Sender: TObject);
80 var
81 item: TMenuItem;
82 scriptIndex: integer;
83 begin
84 if Assigned(FInstalledScripts) then
85 begin
86 item := Sender as TMenuItem;
87 scriptIndex := item.Tag;
88 FInstance.RunScript(FInstalledScripts[scriptIndex], item.Caption);
89 end;
90 end;
91
92 procedure TMainFormMenu.SetDarkTheme(AValue: boolean);
93 begin
94 if FDarkTheme=AValue then Exit;
95 FDarkTheme:=AValue;
96 ApplyTheme;
97 end;
98
99 procedure TMainFormMenu.IconSizeItemClick(Sender: TObject);
100 var
101 item: TMenuItem;
102 begin
103 item:= Sender as TMenuItem;
104 FInstance.ChangeIconSize(item.Tag);
105 end;
106
107 procedure TMainFormMenu.AddMenus(AMenu: TMenuItem; AActionList: TActionList;
108 AActionsCommaText: string; AIndex: integer);
109 var actions: TStringList;
110 foundAction: TBasicAction;
111 item: TMenuItem;
112 i,j: NativeInt;
113
114 procedure AddSubItem(ACaption: string; AOnClick: TNotifyEvent; ATag: integer);
115 var
116 subItem: TMenuItem;
117 begin
118 subItem := TMenuItem.Create(item);
119 subItem.Caption := ACaption;
120 subItem.Tag := ATag;
121 subItem.OnClick := AOnClick;
122 item.Add(subItem);
123 end;
124
125 procedure AddSubItem(AAction: TBasicAction; ATag: integer = 0);
126 var
127 subItem: TMenuItem;
128 begin
129 subItem := TMenuItem.Create(item);
130 subItem.Action := AAction;
131 subItem.Tag := ATag;
132 item.Add(subItem);
133 end;
134
135 begin
136 actions := TStringList.Create;
137 actions.CommaText := AActionsCommaText;
138 for i := 0 to actions.Count-1 do
139 if (actions[i]='*') and (AIndex = -1) then
140 AIndex := 0;
141 for i := 0 to actions.Count-1 do
142 begin
143 if actions[i]='*' then
144 begin
145 AIndex := -1;
146 Continue;
147 end;
148 if actions[i]='InstalledScripts' then
149 begin
150 AddInstalledScripts(AMenu, AIndex);
151 continue;
152 end;
153 item := TMenuItem.Create(nil);
154 if trim(actions[i]) = '-' then
155 item.Caption := cLineCaption
156 else
157 begin
158 foundAction := AActionList.ActionByName(actions[i]);
159 if foundAction <> nil then
160 item.Action := foundAction
161 else
162 begin
163 for j := 0 to AMenu.Count-1 do
164 if UTF8CompareText(AMenu.Items[j].Name,actions[i])=0 then
165 begin
166 FreeAndNil(item);
167 AMenu.Items[j].Visible := true;
168 if (AIndex <> -1) and (AIndex < j) then
169 begin
170 item := AMenu.Items[j];
171 AMenu.Remove(item);
172 AMenu.Insert(AIndex,item);
173 item := nil;
174 inc(AIndex);
175 end else
176 if AIndex = -1 then
177 begin
178 item := AMenu.Items[j];
179 AMenu.Remove(item);
180 AMenu.Add(item);
181 item := nil;
182 end;
183 break;
184 end;
185 if Assigned(item) and (actions[i] = 'MenuIconSize') then
186 begin
187 item.Caption := rsIconSize;
188 item.OnClick:=@IconSizeMenuClick;
189 AddSubItem('16px', @IconSizeItemClick, 16);
190 AddSubItem('20px', @IconSizeItemClick, 20);
191 AddSubItem('24px', @IconSizeItemClick, 24);
192 AddSubItem('32px', @IconSizeItemClick, 32);
193 AddSubItem('40px', @IconSizeItemClick, 40);
194 AddSubItem('48px', @IconSizeItemClick, 48);
195 AddSubItem(rsAutodetect, @IconSizeItemClick, 0);
196 AMenu.Add(item);
197 item := nil;
198 end else
199 if Assigned(item) and (actions[i] = 'EditShapeAlign') then
200 begin
201 item.Caption := rsAlignShape;
202 AddSubItem(AActionList.ActionByName('EditShapeAlignLeft'));
203 AddSubItem(AActionList.ActionByName('EditShapeCenterHorizontally'));
204 AddSubItem(AActionList.ActionByName('EditShapeAlignRight'));
205 AddSubItem('-',nil,0);
206 AddSubItem(AActionList.ActionByName('EditShapeAlignTop'));
207 AddSubItem(AActionList.ActionByName('EditShapeCenterVertically'));
208 AddSubItem(AActionList.ActionByName('EditShapeAlignBottom'));
209 AMenu.Add(item);
210 item := nil;
211 end;
212 if Assigned(item) then item.Caption := trim(actions[i])+'?';
213 end;
214 end;
215 if Assigned(item) then
216 begin
217 if AIndex = -1 then
218 AMenu.Add(item)
219 else
220 begin
221 AMenu.Insert(AIndex,item);
222 inc(AIndex);
223 end;
224 end;
225 end;
226 actions.Free;
227 end;
228
229 procedure TMainFormMenu.AddMenus(AMenuName: string; AActionsCommaText: string);
230 var i: NativeInt;
231 begin
232 for i := 0 to MenuDefinitionKeys.count-1 do
233 if UTF8CompareText(MenuDefinitionKeys[i],AMenuName)=0 then
234 begin
235 AActionsCommaText:= MenuDefinitionValues[i];
236 if AActionsCommaText = '' then exit;
237 break;
238 end;
239 for i := 0 to high(FMainMenus) do
240 if FMainMenus[i].Name = AMenuName then
241 begin
242 AddMenus(FMainMenus[i], FActionList, AActionsCommaText);
243 FMainMenus[i].Visible := true;
244 end;
245 end;
246
247 procedure TMainFormMenu.AddInstalledScripts(AMenu: TMenuItem; AIndex: integer);
248
249 procedure AddScriptRec(AMenu: TMenuItem; var AIndex: integer; AItem: TMenuItem);
250 var
251 posSub, j, subIndex: integer;
252 sectionName: String;
253 sectionItem: TMenuItem;
254 begin
255 posSub := pos('>', AItem.Caption);
256 if posSub > 0 then
257 begin
258 sectionName := copy(AItem.Caption, 1, posSub-1);
259 AItem.Caption := copy(AItem.Caption, posSub+1, length(AItem.Caption) - posSub);
260 subIndex := -1;
261 for j := 0 to AMenu.Count-1 do
262 if AMenu.Items[j].Caption = sectionName then
263 begin
264 AddScriptRec(AMenu.Items[j], subIndex, AItem);
265 exit;
266 end;
267 sectionItem := TMenuItem.Create(AMenu);
268 sectionItem.Caption := sectionName;
269 if AIndex = -1 then
270 AMenu.Add(sectionItem)
271 else
272 begin
273 AMenu.Insert(AIndex, sectionItem);
274 inc(AIndex);
275 end;
276 AddScriptRec(sectionItem, subIndex, AItem);
277 exit;
278 end;
279
280 if AIndex = -1 then
281 AMenu.Add(AItem)
282 else
283 begin
284 AMenu.Insert(AIndex, AItem);
285 inc(AIndex);
286 end;
287 end;
288
289 var
290 path, fullname, title: String;
291 searchRec: TSearchRec;
292 t: textFile;
293 item: TMenuItem;
294 items: TStringList;
295 i: Integer;
296
297 begin
298 if FInstalledScripts = nil then FInstalledScripts := TStringList.Create;
299 path := TPythonScript.DefaultScriptDirectory;
300 if FindFirstUTF8(path+PathDelim+'*.py', faAnyFile, searchRec)=0 then
301 begin
302 items := TStringList.Create;
303 items.Sorted := true;
304 try
305 repeat
306 fullname := path+PathDelim+searchRec.Name;
307 if FileExistsUTF8(fullname) then
308 begin
309 title := GetScriptTitle(fullname);
310 if title <> '' then
311 begin
312 item := TMenuItem.Create(AMenu);
313 item.Caption := title;
314 item.Tag := FInstalledScripts.Add(fullname);
315 item.OnClick:=@Script_Click;
316 items.AddObject(title, item);
317 end;
318 end;
319 until FindNextUTF8(searchRec)<>0;
320 finally
321 FindCloseUTF8(searchRec);
322 for i := 0 to items.Count-1 do
323 AddScriptRec(AMenu, AIndex, TMenuItem(items.Objects[i]));
324 items.Free;
325 end;
326 end;
327 end;
328
329 procedure TMainFormMenu.ActionShortcut(AName: string; AShortcut: TUTF8Char);
330 var foundAction: TBasicAction;
331 ShortcutStr: string;
332 begin
333 foundAction := FActionList.ActionByName(AName);
334 if foundAction <> nil then
335 begin
336 ShortcutStr := AShortcut;
337 if (length(AName) >= 5) and (copy(AName,1,4) = 'Tool') and
338 (AName[5] = upcase(AName[5])) then
339 FToolsShortcuts[StrToPaintToolType(copy(AName,5,length(AName)-4))] := AShortcut;
340 AppendShortcut(foundAction as TAction, ShortcutStr);
341 end;
342 end;
343
344 procedure TMainFormMenu.ApplyTheme;
345 var
346 i, j: Integer;
347 begin
348 for i := 0 to high(FToolbars) do
349 begin
350 with FToolbars[i].tb do
351 begin
352 DarkThemeInstance.Apply(FToolbars[i].tb, DarkTheme);
353 for j := 0 to ControlCount-1 do
354 if Controls[j] is TLabel then
355 begin
356 if (Controls[j].Name = 'Label_CurrentZoom') then
357 begin
358 Controls[j].Color := DarkThemeInstance.GetColorEditableFace(FDarkTheme);
359 Controls[j].Font.Color := DarkThemeInstance.GetColorEditableText(FDarkTheme);
360 end;
361 end;
362 end;
363 end;
364 if Assigned(FToolbarBackground) then
365 FToolbarBackground.Color := DarkThemeInstance.GetColorButtonFace(FDarkTheme);
366 end;
367
TMainFormMenu.GetIndividualToolbarHeightnull368 function TMainFormMenu.GetIndividualToolbarHeight: integer;
369 begin
370 result := DoScaleY(24,OriginalDPI,FTargetDPI);
371 end;
372
373 constructor TMainFormMenu.Create(AInstance: TLazPaintCustomInstance; AActionList: TActionList);
374 begin
375 FInstance := AInstance;
376 FActionList := AActionList;
377 FToolbarsHeight := 0;
378 FTargetDPI := OriginalDPI;
379 end;
380
381 destructor TMainFormMenu.Destroy;
382 begin
383 FInstalledScripts.Free;
384 inherited Destroy;
385 end;
386
387 procedure TMainFormMenu.PredefinedMainMenus(const AMainMenus: array of TMenuItem);
388 var i: NativeInt;
389 begin
390 setlength(FMainMenus, length(AMainMenus));
391 for i := 0 to high(AMainMenus) do
392 FMainMenus[i] := AMainMenus[i];
393 end;
394
395 procedure TMainFormMenu.Toolbars(const AToolbars: array of TPanel; AToolbarBackground: TPanel);
396 var i,j: NativeInt;
397 begin
398 setlength(FToolbars, length(AToolbars));
399 for i := 0 to high(FToolbars) do
400 begin
401 FToolbars[i].tb := AToolbars[i];
402 FToolbars[i].tb.Cursor := crArrow;
403 with FToolbars[i].tb do
404 for j := 0 to ControlCount-1 do
405 begin
406 Controls[j].Cursor := crArrow;
407 if Controls[j] is TLabel then
408 begin
409 if (Controls[j].Name = 'Label_Coordinates') or
410 (Controls[j].Name = 'Label_CurrentZoom') or
411 (Controls[j].Name = 'Label_CurrentDiff') then
412 Controls[j].Font.Height := -DoScaleY(12, OriginalDPI, FTargetDPI);
413 end;
414 end;
415 end;
416 FToolbarBackground := AToolbarBackground;
417 end;
418
419 procedure TMainFormMenu.ScaleToolbars(ATargetDPI: integer);
420 var
421 i: Integer;
422 begin
423 FTargetDPI := ATargetDPI;
424 for i := 0 to high(FToolbars) do
425 ScaleControl(FToolbars[i].tb, OriginalDPI, ATargetDPI, ATargetDPI, true);
426 end;
427
428 procedure TMainFormMenu.CycleTool(var ATool: TPaintToolType;
429 var AShortCut: TUTF8Char);
430 var
431 curTool: TPaintToolType;
432 begin
433 AShortCut := UTF8UpperCase(AShortCut);
434 curTool := ATool;
435 repeat
436 if curTool = high(TPaintToolType) then
437 curTool := low(TPaintToolType)
438 else
439 curTool := succ(curTool);
440
441 if (FToolsShortcuts[curTool] = AShortCut) and not
442 ((curTool = ptHotSpot) and not FInstance.Image.IsCursor) then
443 begin
444 ATool := curTool;
445 AShortCut:= '';
446 exit;
447 end;
448 until curTool = ATool;
449 end;
450
451 procedure TMainFormMenu.Apply;
452 const ImageBrowser = 'FileUseImageBrowser,';
453 var i,j,tbHeight,tbHeightOrig: NativeInt;
454 begin
455 for i := 0 to FActionList.ActionCount-1 do
456 with FActionList.Actions[i] as TAction do
457 if (Caption = '') and (Hint <> '') then Caption := Hint;
458
459 AddMenus('MenuFile', 'FileNew,FileOpen,LayerFromFile,FileChooseEntry,FileReload,MenuRecentFiles,-,FileSave,FileSaveAsInSameFolder,FileSaveAs,FileExport,-,FileImport3D,-,FilePrint,-,'+ImageBrowser+'FileRememberSaveFormat,ForgetDialogAnswers,MenuLanguage,*');
460 AddMenus('MenuEdit', 'EditUndo,EditRedo,-,EditCut,EditCopy,EditPaste,EditPasteAsNew,EditPasteAsNewLayer,EditDeleteSelection,-,EditMoveUp,EditMoveToFront,EditMoveDown,EditMoveToBack,EditShapeAlign,EditShapeToCurve');
461 AddMenus('MenuSelect', 'EditSelection,FileLoadSelection,FileSaveSelectionAs,-,EditSelectAll,EditInvertSelection,EditSelectionFit,EditDeselect,-,ToolSelectRect,ToolSelectEllipse,ToolSelectPoly,ToolSelectSpline,-,ToolMoveSelection,ToolRotateSelection,SelectionHorizontalFlip,SelectionVerticalFlip,-,ToolSelectPen,ToolMagicWand');
462 AddMenus('MenuView', 'ViewGrid,ViewZoomOriginal,ViewZoomIn,ViewZoomOut,ViewZoomFit,-,ViewToolBox,ViewColors,ViewPalette,ViewLayerStack,ViewImageList,ViewStatusBar,-,*,-,ViewDarkTheme,ViewWorkspaceColor,MenuIconSize');
463 AddMenus('MenuImage', 'ImageCrop,ImageCropLayer,ImageFlatten,MenuRemoveTransparency,-,ImageNegative,ImageLinearNegative,ImageSwapRedBlue,-,ImageChangeCanvasSize,ImageRepeat,-,ImageResample,ImageSmartZoom3,-,ImageRotateCW,ImageRotateCCW,ImageRotate180,ImageHorizontalFlip,ImageVerticalFlip');
464 AddMenus('MenuRemoveTransparency', 'ImageClearAlpha,ImageFillBackground');
465 AddMenus('MenuFilter', 'MenuRadialBlur,FilterBlurMotion,FilterBlurCustom,FilterPixelate,-,FilterSharpen,FilterSmooth,FilterNoise,FilterMedian,FilterClearType,FilterClearTypeInverse,FilterFunction,-,FilterContour,FilterEmboss,FilterPhong,-,FilterSphere,FilterTwirl,FilterWaveDisplacement,FilterCylinder');
466 AddMenus('MenuRadialBlur', 'FilterBlurBox,FilterBlurFast,FilterBlurRadial,FilterBlurCorona,FilterBlurDisk');
467 AddMenus('MenuColors', 'ColorCurves,ColorPosterize,ColorColorize,ColorShiftColors,FilterComplementaryColor,ColorIntensity,-,ColorLightness,FilterNegative,FilterLinearNegative,FilterNormalize,FilterGrayscale');
468 AddMenus('MenuTool', 'ToolHand,ToolHotSpot,ToolColorPicker,-,ToolPen,ToolBrush,ToolEraser,ToolFloodFill,ToolClone,-,ToolEditShape,ToolRect,ToolEllipse,ToolPolyline,ToolOpenedCurve,ToolPolygon,ToolSpline,ToolGradient,ToolPhong,ToolText,-,ToolDeformation,ToolTextureMapping');
469 AddMenus('MenuRender', 'RenderPerlinNoise,RenderCyclicPerlinNoise,-,RenderWater,RenderCustomWater,RenderSnowPrint,RenderWood,RenderWoodVertical,RenderMetalFloor,RenderPlastik,RenderStone,RenderRoundStone,RenderMarble,RenderCamouflage,-,RenderClouds,FilterRain');
470 AddMenus('MenuScript', 'FileRunScript,-,InstalledScripts');
471 AddMenus('MenuHelp', 'HelpIndex,-,HelpAbout');
472 for i := 0 to high(FMainMenus) do
473 if FMainMenus[i].Count = 0 then FMainMenus[i].visible := false;
474
475 ApplyShortcuts;
476
477 if Assigned(FImageList) then
478 FActionList.Images := FImageList;
479
480 tbHeightOrig := GetIndividualToolbarHeight;
481 tbHeight := tbHeightOrig;
482 for i := 0 to high(FToolbars) do
483 with FToolbars[i].tb do
484 begin
485 Top := 0;
486 Left := -Width;
487 Color := clBtnFace;
488 for j := 0 to ControlCount-1 do
489 begin
490 if Controls[j] is TToolBar then
491 begin
492 if assigned(FImageList) then TToolbar(Controls[j]).Images := FImageList;
493 TToolbar(Controls[j]).ButtonWidth := TToolbar(Controls[j]).Images.Width+ScaleX(6, 96);
494 TToolbar(Controls[j]).ButtonHeight := TToolbar(Controls[j]).Images.Height+ScaleY(5, 96);
495 end else
496 if Controls[j] is TLCVectorialFillControl then
497 begin
498 if assigned(FImageList) then
499 TLCVectorialFillControl(Controls[j]).ToolIconSize:= FImageList.Height;
500 end;
501 end;
502 end;
503 for i := 0 to high(FToolbars) do
504 with FToolbars[i].tb do
505 begin
506 Height := tbHeight;
507 for j := 0 to ControlCount-1 do
508 Controls[j].Top := Controls[j].Top + (tbHeight-tbHeightOrig) div 2;
509 end;
510
511 ApplyTheme;
512 end;
513
514 procedure TMainFormMenu.ArrangeToolbars(ClientWidth: integer);
515 var i,j,k,curx,cury,maxh, w, minNextX, delta,
516 tbNormalHeight: integer;
517 tb: TPanel;
518 vfc: TLCVectorialFillControl;
519 begin
520 tbNormalHeight := GetIndividualToolbarHeight;
521 curx := 0;
522 cury := 0;
523 maxh := 0;
524 for i := 0 to high(FToolbars) do
525 begin
526 tb := FToolbars[i].tb;
527
528 if not FToolbars[i].fixed then
529 begin
530 for j := 0 to tb.ControlCount-1 do
531 begin
532 tb.Controls[j].Top := DoScaleY(1, OriginalDPI, FTargetDPI);
533 if tb.Controls[j] is TLCVectorialFillControl then
534 begin
535 vfc := TLCVectorialFillControl(tb.Controls[j]);
536 if tb.Height < vfc.PreferredSize.cy then
537 vfc.Height := min(vfc.ToolIconSize + vfc.VerticalPadding,
538 tb.Height - tb.Controls[j].Top - 1)
539 else
540 vfc.Height := vfc.PreferredSize.cy;
541 end else
542 if tb.Controls[j] is TLabel then
543 tb.Controls[j].Height := tbNormalHeight - DoScaleY(3, OriginalDPI, FTargetDPI)
544 else
545 tb.Controls[j].Height := tbNormalHeight - DoScaleY(2, OriginalDPI, FTargetDPI);
546 if tb.Controls[j] is TToolBar then
547 begin
548 minNextX := MaxLongInt;
549 for k := 0 to tb.ControlCount-1 do
550 if tb.Controls[k].Left > tb.Controls[j].Left then
551 minNextX := min(minNextX, tb.Controls[k].Left);
552 delta := tb.Controls[j].Left+tb.Controls[j].Width+2-minNextX;
553 for k := 0 to tb.ControlCount-1 do
554 if tb.Controls[k].Left > tb.Controls[j].Left then
555 tb.Controls[k].Left := tb.Controls[k].Left+delta;
556 end;
557 end;
558 end;
559
560 w := DoScaleX(4, OriginalDPI);
561 for j := 0 to tb.ControlCount-1 do
562 if tb.Controls[j].Visible then
563 w := max(w, tb.Controls[j].Left + tb.Controls[j].Width);
564 w += DoScaleX(4, OriginalDPI);
565 tb.Width := w;
566
567 if tb.Visible then
568 begin
569 if curx+tb.Width > ClientWidth then
570 begin
571 curx := 0;
572 cury += maxh;
573 maxh := 0;
574 end;
575 tb.Left := curx;
576 tb.Top := cury;
577 inc(curx, tb.Width);
578 if tb.Height > maxh then maxh := tb.Height;
579 maxh := min(maxh, tbNormalHeight);
580 end else
581 begin
582 //hide fix for Gtk
583 tb.Top := -tb.Height;
584 end;
585 end;
586 if curx <> 0 then FToolbarsHeight := cury+maxh else FToolbarsHeight := cury;
587 if FToolbarsHeight = 0 then
588 begin
589 FToolbarBackground.Visible := false;
590 end else
591 begin
592 FToolbarBackground.Top := 0;
593 FToolbarBackground.Left := 0;
594 FToolbarBackground.width := ClientWidth;
595 FToolbarBackground.Height := FToolbarsHeight;
596 FToolbarBackground.Anchors:= [akLeft,akTop,akRight];
597 FToolbarBackground.Visible := true;
598 end;
599 end;
600
601 procedure TMainFormMenu.RepaintToolbar;
602 var i: NativeInt;
603 begin
604 FToolbarBackground.Invalidate;
605 for i := 0 to high(FToolbars) do FToolbars[i].tb.Invalidate;
606 FToolbarBackground.Update;
607 for i := 0 to high(FToolbars) do FToolbars[i].tb.Update;
608 end;
609
610 procedure TMainFormMenu.ApplyShortcuts;
611 begin
612 ActionShortcut('ToolHand','H');
613 ActionShortcut('ToolHotSpot','H');
614 ActionShortcut('ToolPen','P');
615 ActionShortcut('ToolBrush','B');
616 ActionShortcut('ToolColorPicker','C');
617 ActionShortcut('ToolEraser','E');
618 ActionShortcut('ToolEditShape','J');
619 ActionShortcut('ToolRect','U');
620 ActionShortcut('ToolEllipse','U');
621 ActionShortcut('ToolPolyline','L');
622 ActionShortcut('ToolOpenedCurve','N');
623 ActionShortcut('ToolPolygon','D');
624 ActionShortcut('ToolSpline','D');
625 ActionShortcut('ToolFloodfill','G');
626 ActionShortcut('ToolGradient','G');
627 ActionShortcut('ToolPhong','G');
628 ActionShortcut('ToolText','T');
629 ActionShortcut('ToolSelectRect','M');
630 ActionShortcut('ToolSelectEllipse','M');
631 ActionShortcut('ToolSelectPoly','A');
632 ActionShortcut('ToolSelectSpline','A');
633 ActionShortcut('ToolMoveSelection','V');
634 ActionShortcut('ToolRotateSelection','V');
635 ActionShortcut('ToolSelectPen','O');
636 ActionShortcut('ToolMagicWand','W');
637 ActionShortcut('ViewZoomIn','+');
638 ActionShortcut('ViewZoomOut','-');
639 end;
640
641 end.
642
643