fpmwnd.inc 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. {
  2. This file is part of the Free Pascal Integrated Development Environment
  3. Copyright (c) 1998 by Berczi Gabor
  4. Window menu entries
  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. procedure TIDEApp.TileVertical;
  12. begin
  13. if not assigned(Desktop) then exit;
  14. Desktop^.TileColumnsFirst:=True;
  15. Tile;
  16. Desktop^.TileColumnsFirst:=False;
  17. end;
  18. FUNCTION Tileable (P: PView): Boolean;
  19. BEGIN
  20. Tileable := (P^.Options AND ofTileable <> 0) AND { View is tileable }
  21. (P^.State AND sfVisible <> 0); { View is visible }
  22. END;
  23. { This pretty much copy of window cascade }
  24. { added extra variable `Count` }
  25. { calculate one of `NR.A.Y` or `NR.A.X` in reverse }
  26. procedure TIDEApp.Stepped(aDirection:boolean);
  27. var R: TRect;
  28. VAR CascadeNum, Count: SmallInt; LastView: PView; Min, Max: TPoint;
  29. PROCEDURE DoCount (P: PView);
  30. BEGIN
  31. If Tileable(P) Then Begin
  32. Inc(CascadeNum); LastView := P; { Count tileable }
  33. End;
  34. END;
  35. PROCEDURE DoCascade (P: PView);
  36. VAR PState: Word; NR: TRect;
  37. BEGIN
  38. If Tileable(P) AND (CascadeNum >= 0) Then Begin { View tileable }
  39. NR.Copy(R); { Copy rect area }
  40. if aDirection then
  41. begin
  42. {option 1 active window in lowest position, window titles visible}
  43. Inc(NR.A.X, Count*1-CascadeNum*1-1); { Inc x position }
  44. Inc(NR.A.Y, CascadeNum); { Inc y position }
  45. end else
  46. begin
  47. {option 2 active window in highest position, window titles not visible}
  48. Inc(NR.A.X, CascadeNum*1); { Inc x position }
  49. Inc(NR.A.Y, Count-CascadeNum-1); { Inc y position }
  50. end;
  51. PState := P^.State; { Hold view state }
  52. P^.State := P^.State AND NOT sfVisible; { Temp stop draw }
  53. P^.Locate(NR); { Locate the view }
  54. P^.State := PState; { Now allow draws }
  55. Dec(CascadeNum); { Dec count }
  56. End;
  57. END;
  58. begin
  59. if not assigned(Desktop) then exit;
  60. GetTileRect(R); { Tileable area }
  61. CascadeNum := 0; { Zero step count }
  62. Desktop^.ForEach(TCallbackProcParam(@DoCount)); { Count tileable }
  63. Count:=CascadeNum; { Keep count in Count }
  64. If (CascadeNum>0) Then Begin
  65. LastView^.SizeLimits(Min, Max); { Check size limits }
  66. If (Min.X > R.B.X - R.A.X - CascadeNum) OR
  67. (Min.Y > R.B.Y - R.A.Y - CascadeNum) Then
  68. Desktop^.TileError Else Begin { Check for error }
  69. Dec(CascadeNum); { One less view }
  70. Desktop^.ForEach(TCallbackProcParam(@DoCascade)); { Stepped view }
  71. Desktop^.DrawView; { Redraw now }
  72. End;
  73. End;
  74. end;
  75. procedure TIDEApp.CloseAll;
  76. procedure SendClose(P: PView);
  77. begin
  78. Message(P,evCommand,cmClose,nil);
  79. end;
  80. begin
  81. Desktop^.ForEach(TCallbackProcParam(@SendClose));
  82. end;
  83. procedure TIDEApp.ResizeApplication(x, y : longint);
  84. var
  85. OldR : TRect;
  86. Mode : TVideoMode;
  87. begin
  88. GetBounds(OldR);
  89. { adapt to new size }
  90. if (OldR.B.Y-OldR.A.Y<>y) or
  91. (OldR.B.X-OldR.A.X<>x) then
  92. begin
  93. Mode.color:=ScreenMode.Color;
  94. Mode.col:=x;
  95. Mode.row:=y;
  96. SetScreenVideoMode(Mode);
  97. UpdateRecentFileList; {ensure file menu not go over screen}
  98. Redraw;
  99. end;
  100. end;
  101. type
  102. PWindowListBox = ^TWindowListBox;
  103. TWindowListBox = object(TAdvancedListBox)
  104. constructor Init(var Bounds: TRect; AScrollBar: PScrollBar);
  105. function GetText(Item,MaxLen: Sw_Integer): String; virtual;
  106. end;
  107. PWindowListDialog = ^TWindowListDialog;
  108. TWindowListDialog = object(TCenterDialog)
  109. constructor Init;
  110. procedure HandleEvent(var Event: TEvent); virtual;
  111. destructor Done; virtual;
  112. private
  113. LB: PWindowListBox;
  114. C : PCollection;
  115. BtnShow,BtnHide: PNoUpdateButton;
  116. procedure UpdateList;
  117. procedure UpdateButtons;
  118. end;
  119. constructor TWindowListBox.Init(var Bounds: TRect; AScrollBar: PScrollBar);
  120. begin
  121. inherited Init(Bounds,1,AScrollBar);
  122. end;
  123. function TWindowListBox.GetText(Item,MaxLen: Sw_Integer): String;
  124. var P: PView;
  125. S: string;
  126. savMaxLen: Sw_Integer;
  127. begin
  128. P:=List^.At(Item);
  129. savMaxLen:=MaxLen;
  130. MaxLen:=MaxLen-9; { have to have less to actually fit in long file paths }
  131. case P^.HelpCtx of
  132. hcSourceWindow : S:=PSourceWindow(P)^.GetTitle(MaxLen);
  133. hcHelpWindow : S:=PHelpWindow(P)^.GetTitle(MaxLen);
  134. hcCalcWindow : S:=PCalculator(P)^.GetTitle(MaxLen);
  135. hcBrowserWindow: S:=PBrowserWindow(P)^.GetTitle(MaxLen);
  136. hcCompilerMessagesWindow,
  137. hcMessagesWindow:S:=PFPWindow(P)^.GetTitle(MaxLen);
  138. hcGDBWindow,
  139. hcDisassemblyWindow,
  140. hcWatchesWindow,
  141. hcStackWindow,
  142. hcRegistersWindow,
  143. hcFPURegisters,
  144. hcVectorRegisters,
  145. hcClipboardWindow,
  146. hcASCIITableWindow,
  147. hcUserScreenWindow,
  148. hcBreakpointListWindow :
  149. S:=PWindow(P)^.GetTitle(MaxLen);
  150. else S:='???? - '+PWindow(P)^.GetTitle(MaxLen);
  151. end;
  152. MaxLen:=savMaxLen;
  153. if PWindow(P)^.Number<>0 then
  154. S:=S+'('+IntToStr(PWindow(P)^.Number)+')';
  155. if P^.GetState(sfVisible) then S:=' '+S else
  156. begin
  157. S:='*'+S+' - '+msg_windowlist_hidden;
  158. end;
  159. GetText:=copy(S,1,MaxLen);
  160. end;
  161. constructor TWindowListDialog.Init;
  162. var R,R2: TRect;
  163. SB: PScrollBar;
  164. begin
  165. R.Assign(0,0,Max(60,round(ScreenWidth*5/8)),Max(13,round(ScreenHeight*3/5)));
  166. inherited Init(R, dialog_windowlist);
  167. HelpCtx:=hcWindowList;
  168. New(C, Init(20,10));
  169. GetExtent(R); R.Grow(-2,-2); Inc(R.A.Y); R.B.X:=R.B.X-14;
  170. R2.Copy(R); R2.Move(1,0); R2.A.X:=R2.B.X-1;
  171. New(SB, Init(R2)); Insert(SB);
  172. New(LB, Init(R, SB));
  173. LB^.Default:=true;
  174. LB^.NewList(C);
  175. UpdateList;
  176. if C^.Count>=2 then
  177. if PWindow(C^.At(1))^.GetState(sfVisible) then
  178. LB^.FocusItem(1); { focus the 2nd one }
  179. Insert(LB);
  180. R2.Copy(R); Dec(R2.A.Y); R2.B.Y:=R2.A.Y+1;
  181. Insert(New(PLabel, Init(R2, label_wndlist_windows, LB)));
  182. GetExtent(R); R.Grow(-2,-2); Inc(R.A.Y); R.A.X:=R.B.X-13+1; R.B.Y:=R.A.Y+2;
  183. Insert(New(PButton, Init(R, button_OK, cmOK, bfDefault)));
  184. R.Move(0,2);
  185. Insert(New(PButton, Init(R, button_Delete, cmDeleteItem, bfNormal)));
  186. R.Move(0,2);
  187. New(BtnShow, Init(R, button_Show, cmShowItem, bfNormal));
  188. Insert(BtnShow);
  189. R.Move(0,2);
  190. New(BtnHide, Init(R, button_Hide, cmHideItem, bfNormal));
  191. Insert(BtnHide);
  192. R.Move(0,2);
  193. Insert(New(PButton, Init(R, button_Cancel, cmCancel, bfNormal)));
  194. LB^.Select;
  195. PutCommand(@Self,evBroadcast,cmListFocusChanged,LB);
  196. end;
  197. procedure TWindowListDialog.UpdateList;
  198. var VisState: boolean;
  199. procedure AddIt(P: PView);
  200. begin
  201. if (P<>pointer(Desktop^.Background)) and
  202. (P^.GetState(sfDisabled)=false) and
  203. ((P^.Options and ofSelectable)<>0) and
  204. (P^.GetState(sfVisible)=VisState) then
  205. C^.Insert(P);
  206. end;
  207. begin
  208. C^.DeleteAll;
  209. VisState:=true; Desktop^.ForEach(TCallbackProcParam(@AddIt)); { add visible windows to list }
  210. VisState:=false; Desktop^.ForEach(TCallbackProcParam(@AddIt)); { add hidden windows }
  211. LB^.SetRange(C^.Count);
  212. UpdateButtons;
  213. ReDraw;
  214. end;
  215. procedure TWindowListDialog.UpdateButtons;
  216. var W: PView;
  217. begin
  218. if LB^.Range>0 then
  219. begin
  220. W:=LB^.List^.At(LB^.Focused);
  221. if Assigned(BtnShow) then
  222. BtnShow^.SetState(sfDisabled,W^.GetState(sfVisible));
  223. if Assigned(BtnHide) then
  224. BtnHide^.SetState(sfDisabled,not W^.GetState(sfVisible));
  225. end
  226. else
  227. begin
  228. BtnShow^.SetState(sfDisabled,true);
  229. BtnHide^.SetState(sfDisabled,true);
  230. end;
  231. ReDraw;
  232. end;
  233. procedure TWindowListDialog.HandleEvent(var Event: TEvent);
  234. var W: PWindow;
  235. KeePOwner : PGroup;
  236. begin
  237. case Event.What of
  238. evKeyDown :
  239. case Event.KeyCode of
  240. kbDel :
  241. begin
  242. Message(@Self,evCommand,cmDeleteItem,nil);
  243. ClearEvent(Event);
  244. end;
  245. end;
  246. evBroadcast :
  247. case Event.Command of
  248. cmListFocusChanged :
  249. if Event.InfoPtr=LB then
  250. UpdateButtons;
  251. end;
  252. evCommand :
  253. case Event.Command of
  254. cmDeleteItem :
  255. if C^.Count>0 then
  256. begin
  257. W:=PWindow(C^.At(LB^.Focused));
  258. { we need to remove the window from the list
  259. because otherwise
  260. IDEApp.SourceWindowClosed
  261. is called after the object has been freed
  262. but the ListBox.Redraw will still try to
  263. read the title PM }
  264. KeepOwner:=W^.Owner;
  265. if assigned(KeepOwner) then
  266. KeepOwner^.Delete(W);
  267. UpdateList;
  268. { But reinsert it as Close might only
  269. trigger Hide in some cases }
  270. if assigned(KeepOwner) then
  271. KeepOwner^.Insert(W);
  272. Message(W,evCommand,cmClose,nil);
  273. UpdateList;
  274. ClearEvent(Event);
  275. end;
  276. cmShowItem :
  277. if C^.Count>0 then
  278. begin
  279. PWindow(C^.At(LB^.Focused))^.Show;
  280. UpdateList;
  281. ClearEvent(Event);
  282. end;
  283. cmHideItem :
  284. if C^.Count>0 then
  285. begin
  286. PWindow(C^.At(LB^.Focused))^.Hide;
  287. UpdateList;
  288. ClearEvent(Event);
  289. end;
  290. cmOK :
  291. if C^.Count>0 then
  292. begin
  293. W:=PWindow(C^.At(LB^.Focused));
  294. if W^.GetState(sfVisible)=false then
  295. W^.Show;
  296. W^.MakeFirst;
  297. end;
  298. end;
  299. end;
  300. inherited HandleEvent(Event);
  301. end;
  302. destructor TWindowListDialog.Done;
  303. begin
  304. if C<>nil then begin C^.DeleteAll; Dispose(C, Done); end;
  305. inherited Done;
  306. end;
  307. procedure TIDEApp.WindowList;
  308. var W: PWindowListDialog;
  309. begin
  310. New(W,Init);
  311. ExecView(W);
  312. Dispose(W,Done);
  313. Desktop^.Lock;
  314. { force correct commands to be enabled }
  315. Desktop^.SetState(sfActive,true); { activate everything }
  316. Desktop^.SetState(sfActive,false); { deactivate everything }
  317. if assigned(Desktop^.Current) then
  318. Desktop^.Current^.SetState(sfActive,true); { set active only current }
  319. Desktop^.UnLock;
  320. end;