wviews.pas 76 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849
  1. {
  2. This file is part of the Free Pascal Integrated Development Environment
  3. Copyright (c) 1998 by Berczi Gabor
  4. See the file COPYING.FPC, included in this distribution,
  5. for details about the copyright.
  6. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  9. **********************************************************************}
  10. {$I globdir.inc}
  11. unit WViews;
  12. interface
  13. uses Objects,Drivers,Views,Menus,Dialogs,Outline;
  14. const
  15. evIdle = $8000;
  16. cmCopyWin = 240;
  17. cmPasteWin = 241;
  18. cmSelectAll = 246;
  19. cmUnselect = 247;
  20. cmCommentSel = 250;
  21. cmUnCommentSel = 251;
  22. cmLocalMenu = 54100;
  23. cmUpdate = 54101;
  24. cmListFocusChanged = 54102;
  25. mfUserBtn1 = $00010000;
  26. mfUserBtn2 = $00020000;
  27. mfUserBtn3 = $00040000;
  28. mfUserBtn4 = $00080000;
  29. mfCantCancel = $00100000;
  30. cmUserBtn1 = $fee0;
  31. cmUserBtn2 = $fee1;
  32. cmUserBtn3 = $fee2;
  33. cmUserBtn4 = $fee3;
  34. CPlainCluster = #7#8#9#9#13#9;{normal}{ active }{shortcut}{..}{disabled}{..}
  35. type
  36. longstring = ansistring;
  37. PCenterDialog = ^TCenterDialog;
  38. TCenterDialog = object(TDialog)
  39. constructor Init(var Bounds: TRect; ATitle: TTitleStr);
  40. end;
  41. PAdvancedMenuBox = ^TAdvancedMenuBox;
  42. TAdvancedMenuBox = object(TMenuBox)
  43. function NewSubView(var Bounds: TRect; AMenu: PMenu;
  44. AParentMenu: PMenuView): PMenuView; virtual;
  45. function Execute: Word; virtual;
  46. end;
  47. PAdvancedMenuPopUp = ^TAdvancedMenuPopup;
  48. TAdvancedMenuPopUp = object(TMenuPopup)
  49. function NewSubView(var Bounds: TRect; AMenu: PMenu;
  50. AParentMenu: PMenuView): PMenuView; virtual;
  51. function Execute: Word; virtual;
  52. end;
  53. PAdvancedMenuBar = ^TAdvancedMenuBar;
  54. TAdvancedMenuBar = object(TMenuBar)
  55. constructor Init(var Bounds: TRect; AMenu: PMenu);
  56. function NewSubView(var Bounds: TRect; AMenu: PMenu;
  57. AParentMenu: PMenuView): PMenuView; virtual;
  58. procedure Update; virtual;
  59. function GetMenuItem(cm : word) : PMenuItem;
  60. procedure HandleEvent(var Event: TEvent); virtual;
  61. function Execute: Word; virtual;
  62. end;
  63. PAdvancedStaticText = ^TAdvancedStaticText;
  64. TAdvancedStaticText = object(TStaticText)
  65. procedure SetText(S: string); virtual;
  66. end;
  67. PAdvancedListBox = ^TAdvancedListBox;
  68. TAdvancedListBox = object(TListBox)
  69. Default: boolean;
  70. procedure FocusItem(Item: sw_integer); virtual;
  71. procedure HandleEvent(var Event: TEvent); virtual;
  72. constructor Load(var S: TStream);
  73. procedure Store(var S: TStream);
  74. end;
  75. PNoUpdateButton = ^TNoUpdateButton;
  76. TNoUpdateButton = object(TButton)
  77. procedure HandleEvent(var Event: TEvent); virtual;
  78. end;
  79. TLocalMenuListBox = object(TAdvancedListBox)
  80. procedure HandleEvent(var Event: TEvent); virtual;
  81. procedure LocalMenu(P: TPoint); virtual;
  82. function GetLocalMenu: PMenu; virtual;
  83. function GetCommandTarget: PView; virtual;
  84. private
  85. LastLocalCmd: word;
  86. end;
  87. TLocalMenuOutlineViewer = object(TOutlineViewer)
  88. procedure HandleEvent(var Event: TEvent); virtual;
  89. procedure LocalMenu(P: TPoint); virtual;
  90. function GetLocalMenu: PMenu; virtual;
  91. function GetCommandTarget: PView; virtual;
  92. private
  93. LastLocalCmd: word;
  94. end;
  95. PColorStaticText = ^TColorStaticText;
  96. TColorStaticText = object(TAdvancedStaticText)
  97. Color: word;
  98. DontWrap: boolean;
  99. Delta: TPoint;
  100. constructor Init(var Bounds: TRect; AText: String; AColor: word; AWrap: boolean);
  101. function GetPalette: PPalette; virtual;
  102. procedure Draw; virtual;
  103. constructor Load(var S: TStream);
  104. procedure Store(var S: TStream);
  105. end;
  106. PHSListBox = ^THSListBox;
  107. THSListBox = object(TLocalMenuListBox)
  108. constructor Init(var Bounds: TRect; ANumCols: Word; AHScrollBar, AVScrollBar: PScrollBar);
  109. function SaveToFile(const AFileName: string): boolean; virtual;
  110. function SaveAs: Boolean; virtual;
  111. end;
  112. PDlgWindow = ^TDlgWindow;
  113. TDlgWindow = object(TDialog)
  114. constructor Init(var Bounds: TRect; ATitle: TTitleStr; ANumber: Sw_Integer);
  115. procedure HandleEvent(var Event: TEvent); virtual;
  116. procedure Update; virtual;
  117. end;
  118. PAdvancedStatusLine = ^TAdvancedStatusLine;
  119. TAdvancedStatusLine = object(TStatusLine)
  120. StatusText: PString;
  121. function GetStatusText: string; virtual;
  122. procedure SetStatusText(const S: string); virtual;
  123. procedure ClearStatusText; virtual;
  124. procedure Draw; virtual;
  125. end;
  126. PDropDownListBox = ^TDropDownListBox;
  127. PDDHelperLB = ^TDDHelperLB;
  128. TDDHelperLB = object(TLocalMenuListBox)
  129. constructor Init(ALink: PDropDownListBox; var Bounds: TRect; ANumCols: Word; AScrollBar: PScrollBar);
  130. procedure HandleEvent(var Event: TEvent); virtual;
  131. procedure SetState(AState: Word; Enable: Boolean); virtual;
  132. procedure SelectItem(Item: Sw_Integer); virtual;
  133. function GetText(Item,MaxLen: Sw_Integer): String; virtual;
  134. function GetLocalMenu: PMenu; virtual;
  135. function GetCommandTarget: PView; virtual;
  136. private
  137. Link : PDropDownListBox;
  138. LastTT: longint;
  139. InClose: boolean;
  140. end;
  141. TDropDownListBox = object(TView)
  142. Text: string;
  143. Focused: sw_integer;
  144. List: PCollection;
  145. constructor Init(var Bounds: TRect; ADropLineCount: Sw_integer; AList: PCollection);
  146. procedure HandleEvent(var Event: TEvent); virtual;
  147. function GetText(Item: pointer; MaxLen: sw_integer): string; virtual;
  148. procedure NewList(AList: PCollection); virtual;
  149. procedure CreateListBox(var R: TRect);
  150. procedure DropList(Drop: boolean); virtual;
  151. function GetItemCount: sw_integer; virtual;
  152. procedure FocusItem(Item: sw_integer); virtual;
  153. function LBGetLocalMenu: PMenu; virtual;
  154. function LBGetCommandTarget: PView; virtual;
  155. procedure SetState(AState: Word; Enable: Boolean); virtual;
  156. procedure Draw; virtual;
  157. function GetPalette: PPalette; virtual;
  158. destructor Done; virtual;
  159. private
  160. DropLineCount: Sw_integer;
  161. ListDropped : boolean;
  162. ListBox : PDDHelperLB;
  163. SB : PScrollBar;
  164. end;
  165. PGroupView = ^TGroupView;
  166. TGroupView = object(TLabel)
  167. constructor Init(var Bounds: TRect; AText: String; ALink: PView);
  168. procedure Draw; virtual;
  169. end;
  170. PPlainCheckBoxes = ^TPlainCheckBoxes;
  171. TPlainCheckBoxes = object(TCheckBoxes)
  172. function GetPalette: PPalette; virtual;
  173. end;
  174. PPlainRadioButtons = ^TPlainRadioButtons;
  175. TPlainRadioButtons = object(TRadioButtons)
  176. function GetPalette: PPalette; virtual;
  177. end;
  178. PScrollerRadioButtons = ^TScrollerRadioButtons;
  179. TScrollerRadioButtons = object (TRadioButtons)
  180. VScrollBar : PScrollBar;
  181. Delta : TPoint;
  182. constructor Init (Var Bounds: TRect; AStrings: PSItem; aVScrollBar:PScrollBar);
  183. procedure HandleEvent (Var Event: TEvent); Virtual;
  184. procedure MovedTo (Item: Sw_Integer); Virtual;
  185. procedure ScrollDraw; Virtual;
  186. procedure Draw; Virtual;
  187. procedure DrawScrollMultiBox (Const Icon, Marker: String);
  188. procedure ScrollTo (X,Y: Sw_Integer); Virtual;
  189. procedure CentreSelected;
  190. private
  191. function FindSel (P: TPoint): Sw_Integer;
  192. end;
  193. PPanel = ^TPanel;
  194. TPanel = object(TGroup)
  195. constructor Init(var Bounds: TRect);
  196. end;
  197. PAdvMessageBox = ^TAdvMessageBox;
  198. TAdvMessageBox = object(TDialog)
  199. CanCancel: boolean;
  200. procedure HandleEvent(var Event: TEvent); virtual;
  201. end;
  202. procedure InsertOK(ADialog: PDialog);
  203. procedure InsertButtons(ADialog: PDialog);
  204. procedure Bug(const S: string; Params: pointer);
  205. procedure ErrorBox(const S: string; Params: pointer);
  206. procedure WarningBox(const S: string; Params: pointer);
  207. procedure InformationBox(const S: string; Params: pointer);
  208. function OKCancelBox(const S: string; Params: pointer): word;
  209. function ConfirmBox(const S: string; Params: pointer; CanCancel: boolean): word;
  210. function ChoiceBox(const S: string; Params: pointer; Buttons: array of string; CanCancel: boolean): word;
  211. procedure ShowMessage(Msg: string);
  212. procedure HideMessage;
  213. function SearchMenuItem(Menu: PMenu; Cmd: word): PMenuItem;
  214. procedure SetMenuItemParam(Menu: PMenuItem; Param: string);
  215. function IsSubMenu(P: PMenuItem): boolean;
  216. function IsSeparator(P: PMenuItem): boolean;
  217. function UpdateMenu(M: PMenu): boolean;
  218. function SearchSubMenu(M: PMenu; Index: Sw_integer): PMenuItem;
  219. procedure AppendMenuItem(M: PMenu; I: PMenuItem);
  220. procedure RemoveMenuItem(Menu: PMenu; I: PMenuItem);
  221. function GetMenuItemBefore(Menu:PMenu; BeforeOf: PMenuItem): PMenuItem;
  222. procedure NotImplemented;
  223. function ColorIndex(Color: byte): word;
  224. var FormatParams : array[1..20] of ptrint;
  225. FormatParamCount : integer;
  226. FormatParamStrs : array[1..10] of string;
  227. FormatParamStrCount: integer;
  228. procedure ClearFormatParams;
  229. procedure AddFormatParam(P: pointer);
  230. procedure AddFormatParamInt(L: longint);
  231. procedure AddFormatParamChar(C: AnsiChar);
  232. procedure AddFormatParamStr(const S: string);
  233. function FormatStrF(const Format: string; var Params): string;
  234. function FormatStrStr(const Format, Param: string): string;
  235. function FormatStrStr2(const Format, Param1,Param2: string): string;
  236. function FormatStrStr3(const Format, Param1,Param2,Param3: string): string;
  237. function FormatStrInt(const Format: string; L: PtrInt): string;
  238. const UserButtonName : array[1..4] of string[40] = ('User~1~','User~2~','User~3~','User~4~');
  239. procedure InitAdvMsgBox;
  240. function AdvMessageBox(const Msg: String; Params: Pointer; AOptions: longint): Word;
  241. function AdvMessageBoxRect(var R: TRect; const Msg: String; Params: Pointer; AOptions: longint): Word;
  242. procedure DoneAdvMsgBox;
  243. procedure RegisterWViews;
  244. implementation
  245. uses Mouse,
  246. { Resource,}
  247. {$ifdef WinClipSupported}
  248. WinClip,
  249. FpConst,
  250. {$endif WinClipSupported}
  251. FVConsts,
  252. App,MsgBox,StdDlg,
  253. WConsts,WUtils;
  254. {$ifndef NOOBJREG}
  255. const
  256. RAdvancedListBox: TStreamRec = (
  257. ObjType: 1120;
  258. VmtLink: Ofs(TypeOf(TAdvancedListBox)^);
  259. Load: @TAdvancedListBox.Load;
  260. Store: @TAdvancedListBox.Store
  261. );
  262. RColorStaticText: TStreamRec = (
  263. ObjType: 1121;
  264. VmtLink: Ofs(TypeOf(TColorStaticText)^);
  265. Load: @TColorStaticText.Load;
  266. Store: @TColorStaticText.Store
  267. );
  268. RHSListBox: TStreamRec = (
  269. ObjType: 1122;
  270. VmtLink: Ofs(TypeOf(THSListBox)^);
  271. Load: @THSListBox.Load;
  272. Store: @THSListBox.Store
  273. );
  274. RDlgWindow: TStreamRec = (
  275. ObjType: 1123;
  276. VmtLink: Ofs(TypeOf(TDlgWindow)^);
  277. Load: @TDlgWindow.Load;
  278. Store: @TDlgWindow.Store
  279. );
  280. {$endif}
  281. {$ifdef USERESSTRINGS}
  282. resourcestring
  283. {$else}
  284. const
  285. {$endif}
  286. sConfirm='Confirm';
  287. sError='Error';
  288. sInformation='Information';
  289. sWarning='Warning';
  290. const
  291. MessageDialog : PCenterDialog = nil;
  292. UserButtonCmd : array[Low(UserButtonName)..High(UserButtonName)] of word = (cmUserBtn1,cmUserBtn2,cmUserBtn3,cmUserBtn4);
  293. {$ifdef WinClipSupported}
  294. FromWinClipCmds : TCommandSet = ([cmPasteWin]);
  295. {$endif WinClipSupported}
  296. function ColorIndex(Color: byte): word;
  297. begin
  298. ColorIndex:=(Color and $0f)+(Color and $0f) shl 4;
  299. end;
  300. {*****************************************************************************
  301. TCenterDialog
  302. *****************************************************************************}
  303. constructor TCenterDialog.Init(var Bounds: TRect; ATitle: TTitleStr);
  304. begin
  305. inherited Init(Bounds,ATitle);
  306. Options:=Options or ofCentered;
  307. end;
  308. function TAdvancedMenuBox.NewSubView(var Bounds: TRect; AMenu: PMenu;
  309. AParentMenu: PMenuView): PMenuView;
  310. begin
  311. NewSubView := New(PAdvancedMenuBox, Init(Bounds, AMenu, AParentMenu));
  312. end;
  313. function TAdvancedMenuBox.Execute: word;
  314. type
  315. MenuAction = (DoNothing, DoSelect, DoReturn);
  316. var
  317. AutoSelect: Boolean;
  318. Action: MenuAction;
  319. Ch: AnsiChar;
  320. Res: Word;
  321. ItemShown, P: PMenuItem;
  322. {$ifdef WinClipSupported}
  323. PPW: PMenuItem;
  324. WinClipEmpty: boolean;
  325. {$endif WinClipSupported}
  326. Target: PMenuView;
  327. R: TRect;
  328. E: TEvent;
  329. MouseActive: Boolean;
  330. function IsDisabled(Item: PMenuItem): boolean;
  331. var Found: boolean;
  332. begin
  333. Found:=Item^.Disabled or IsSeparator(Item);
  334. if (Found=false) and (IsSubMenu(Item)=false) then
  335. Found:=CommandEnabled(Item^.Command)=false;
  336. IsDisabled:=Found;
  337. end;
  338. procedure TrackMouse;
  339. var
  340. Mouse: TPoint;
  341. R: TRect;
  342. begin
  343. MakeLocal(E.Where, Mouse);
  344. Current := Menu^.Items;
  345. while Current <> nil do
  346. begin
  347. GetItemRect(Current, R);
  348. if R.Contains(Mouse) then
  349. begin
  350. MouseActive := True;
  351. Break;
  352. end;
  353. Current := Current^.Next;
  354. end;
  355. if (Current<>nil) and IsDisabled(Current) then
  356. begin
  357. Current:=nil;
  358. MouseActive:=false;
  359. end;
  360. end;
  361. procedure TrackKey(FindNext: Boolean);
  362. procedure NextItem;
  363. begin
  364. Current := Current^.Next;
  365. if Current = nil then Current := Menu^.Items;
  366. end;
  367. procedure PrevItem;
  368. var
  369. P: PMenuItem;
  370. begin
  371. P := Current;
  372. if P = Menu^.Items then P := nil;
  373. repeat NextItem until Current^.Next = P;
  374. end;
  375. begin
  376. if Current <> nil then
  377. repeat
  378. if FindNext then NextItem else PrevItem;
  379. until (Current^.Name <> nil) and (IsDisabled(Current)=false);
  380. end;
  381. function MouseInOwner: Boolean;
  382. var
  383. Mouse: TPoint;
  384. R: TRect;
  385. begin
  386. MouseInOwner := False;
  387. if (ParentMenu <> nil) and (ParentMenu^.Size.Y = 1) then
  388. begin
  389. ParentMenu^.MakeLocal(E.Where, Mouse);
  390. ParentMenu^.GetItemRect(ParentMenu^.Current, R);
  391. MouseInOwner := R.Contains(Mouse);
  392. end;
  393. end;
  394. function MouseInMenus: Boolean;
  395. var
  396. P: PMenuView;
  397. begin
  398. P := ParentMenu;
  399. while (P <> nil) and (P^.MouseInView(E.Where)=false) do
  400. P := P^.ParentMenu;
  401. MouseInMenus := P <> nil;
  402. end;
  403. function TopMenu: PMenuView;
  404. var
  405. P: PMenuView;
  406. begin
  407. P := @Self;
  408. while P^.ParentMenu <> nil do P := P^.ParentMenu;
  409. TopMenu := P;
  410. end;
  411. begin
  412. AutoSelect := False; E.What:=evNothing;
  413. Res := 0;
  414. ItemShown := nil;
  415. {$ifdef WinClipSupported}
  416. PPW:=SearchMenuItem(Menu,cmPasteWin);
  417. if Assigned(PPW) then
  418. begin
  419. WinClipEmpty:=GetTextWinClipboardSize=0;
  420. SetCmdState(FromWinClipCmds,Not WinClipEmpty);
  421. PPW^.disabled:=WinClipEmpty;
  422. end;
  423. {$endif WinClipSupported}
  424. Current := Menu^.Default;
  425. MouseActive := False;
  426. if UpdateMenu(Menu) then
  427. begin
  428. if Current<>nil then
  429. if Current^.Disabled then
  430. TrackKey(true);
  431. repeat
  432. Action := DoNothing;
  433. {$ifdef WinClipSupported}
  434. If Assigned(PPW) then
  435. begin
  436. If WinClipEmpty and (GetTextWinClipboardSize>0) then
  437. begin
  438. WinClipEmpty:=false;
  439. SetCmdState(FromWinClipCmds,true);
  440. PPW^.disabled:=WinClipEmpty;
  441. DrawView;
  442. end
  443. else if Not WinClipEmpty and (GetTextWinClipboardSize=0) then
  444. begin
  445. WinClipEmpty:=true;
  446. SetCmdState(FromWinClipCmds,false);
  447. PPW^.disabled:=WinClipEmpty;
  448. DrawView;
  449. end;
  450. end;
  451. {$endif WinClipSupported}
  452. GetEvent(E);
  453. case E.What of
  454. evMouseDown:
  455. if MouseInView(E.Where) or MouseInOwner then
  456. begin
  457. TrackMouse;
  458. if Size.Y = 1 then AutoSelect := True;
  459. end else Action := DoReturn;
  460. evMouseUp:
  461. begin
  462. TrackMouse;
  463. if MouseInOwner then
  464. Current := Menu^.Default
  465. else
  466. if (Current <> nil) and (Current^.Name <> nil) then
  467. Action := DoSelect
  468. else
  469. if MouseActive or MouseInView(E.Where) then Action := DoReturn
  470. else
  471. begin
  472. Current := Menu^.Default;
  473. if Current = nil then Current := Menu^.Items;
  474. Action := DoNothing;
  475. end;
  476. end;
  477. evMouseMove:
  478. if E.Buttons <> 0 then
  479. begin
  480. TrackMouse;
  481. if not (MouseInView(E.Where) or MouseInOwner) and
  482. MouseInMenus then Action := DoReturn;
  483. end;
  484. evKeyDown:
  485. case CtrlToArrow(E.KeyCode) of
  486. kbUp, kbDown:
  487. if Size.Y <> 1 then
  488. TrackKey(CtrlToArrow(E.KeyCode) = kbDown) else
  489. if E.KeyCode = kbDown then AutoSelect := True;
  490. kbLeft, kbRight:
  491. if ParentMenu = nil then
  492. TrackKey(CtrlToArrow(E.KeyCode) = kbRight) else
  493. Action := DoReturn;
  494. kbHome, kbEnd:
  495. if Size.Y <> 1 then
  496. begin
  497. Current := Menu^.Items;
  498. if E.KeyCode = kbEnd then TrackKey(False);
  499. end;
  500. kbEnter:
  501. begin
  502. if Size.Y = 1 then AutoSelect := True;
  503. Action := DoSelect;
  504. end;
  505. kbEsc:
  506. begin
  507. Action := DoReturn;
  508. if (ParentMenu = nil) or (ParentMenu^.Size.Y <> 1) then
  509. ClearEvent(E);
  510. end;
  511. else
  512. Target := @Self;
  513. Ch := GetAltChar(E.KeyCode);
  514. if Ch = #0 then Ch := E.CharCode else Target := TopMenu;
  515. P := Target^.FindItem(Ch);
  516. if P = nil then
  517. begin
  518. P := TopMenu^.HotKey(E.KeyCode);
  519. if (P <> nil) and CommandEnabled(P^.Command) then
  520. begin
  521. Res := P^.Command;
  522. Action := DoReturn;
  523. end
  524. end else
  525. if Target = @Self then
  526. begin
  527. if Size.Y = 1 then AutoSelect := True;
  528. Action := DoSelect;
  529. Current := P;
  530. end else
  531. if (ParentMenu <> Target) or (ParentMenu^.Current <> P) then
  532. Action := DoReturn;
  533. end;
  534. evCommand:
  535. if E.Command = cmMenu then
  536. begin
  537. AutoSelect := False;
  538. if ParentMenu <> nil then Action := DoReturn;
  539. end else Action := DoReturn;
  540. end;
  541. if ItemShown <> Current then
  542. begin
  543. ItemShown := Current;
  544. DrawView;
  545. end;
  546. if (Action = DoSelect) or ((Action = DoNothing) and AutoSelect) then
  547. if Current <> nil then with Current^ do if Name <> nil then
  548. if Command = 0 then
  549. begin
  550. if E.What and (evMouseDown + evMouseMove) <> 0 then PutEvent(E);
  551. GetItemRect(Current, R);
  552. R.A.X := R.A.X + Origin.X;
  553. R.A.Y := R.B.Y + Origin.Y;
  554. R.B := Owner^.Size;
  555. if Size.Y = 1 then Dec(R.A.X);
  556. Target := TopMenu^.NewSubView(R, SubMenu, @Self);
  557. Res := Owner^.ExecView(Target);
  558. Dispose(Target, Done);
  559. end else if Action = DoSelect then Res := Command;
  560. if (Res <> 0) and CommandEnabled(Res) then
  561. begin
  562. Action := DoReturn;
  563. ClearEvent(E);
  564. end
  565. else
  566. Res := 0;
  567. until Action = DoReturn;
  568. end;
  569. if E.What <> evNothing then
  570. if (ParentMenu <> nil) or (E.What = evCommand) then PutEvent(E);
  571. if Current <> nil then
  572. begin
  573. Menu^.Default := Current;
  574. Current := nil;
  575. DrawView;
  576. end;
  577. Execute := Res;
  578. end;
  579. function TAdvancedMenuPopup.NewSubView(var Bounds: TRect; AMenu: PMenu;
  580. AParentMenu: PMenuView): PMenuView;
  581. begin
  582. NewSubView := New(PAdvancedMenuBox, Init(Bounds, AMenu, AParentMenu));
  583. end;
  584. function TAdvancedMenuPopup.Execute: word;
  585. type
  586. MenuAction = (DoNothing, DoSelect, DoReturn);
  587. var
  588. AutoSelect: Boolean;
  589. Action: MenuAction;
  590. Ch: AnsiChar;
  591. Res: Word;
  592. ItemShown, P: PMenuItem;
  593. Target: PMenuView;
  594. R: TRect;
  595. E: TEvent;
  596. MouseActive: Boolean;
  597. function IsDisabled(Item: PMenuItem): boolean;
  598. var Found: boolean;
  599. begin
  600. Found:=Item^.Disabled or IsSeparator(Item);
  601. if (Found=false) and (IsSubMenu(Item)=false) then
  602. Found:=CommandEnabled(Item^.Command)=false;
  603. IsDisabled:=Found;
  604. end;
  605. procedure TrackMouse;
  606. var
  607. Mouse: TPoint;
  608. R: TRect;
  609. begin
  610. MakeLocal(E.Where, Mouse);
  611. Current := Menu^.Items;
  612. while Current <> nil do
  613. begin
  614. GetItemRect(Current, R);
  615. if R.Contains(Mouse) then
  616. begin
  617. MouseActive := True;
  618. Break;
  619. end;
  620. Current := Current^.Next;
  621. end;
  622. if (Current<>nil) and IsDisabled(Current) then
  623. begin
  624. Current:=nil;
  625. MouseActive:=false;
  626. end;
  627. end;
  628. procedure TrackKey(FindNext: Boolean);
  629. procedure NextItem;
  630. begin
  631. Current := Current^.Next;
  632. if Current = nil then Current := Menu^.Items;
  633. end;
  634. procedure PrevItem;
  635. var
  636. P: PMenuItem;
  637. begin
  638. P := Current;
  639. if P = Menu^.Items then P := nil;
  640. repeat NextItem until Current^.Next = P;
  641. end;
  642. begin
  643. if Current <> nil then
  644. repeat
  645. if FindNext then NextItem else PrevItem;
  646. until (Current^.Name <> nil) and (IsDisabled(Current)=false);
  647. end;
  648. function MouseInOwner: Boolean;
  649. var
  650. Mouse: TPoint;
  651. R: TRect;
  652. begin
  653. MouseInOwner := False;
  654. if (ParentMenu <> nil) and (ParentMenu^.Size.Y = 1) then
  655. begin
  656. ParentMenu^.MakeLocal(E.Where, Mouse);
  657. ParentMenu^.GetItemRect(ParentMenu^.Current, R);
  658. MouseInOwner := R.Contains(Mouse);
  659. end;
  660. end;
  661. function MouseInMenus: Boolean;
  662. var
  663. P: PMenuView;
  664. begin
  665. P := ParentMenu;
  666. while (P <> nil) and (P^.MouseInView(E.Where)=false) do
  667. P := P^.ParentMenu;
  668. MouseInMenus := P <> nil;
  669. end;
  670. function TopMenu: PMenuView;
  671. var
  672. P: PMenuView;
  673. begin
  674. P := @Self;
  675. while P^.ParentMenu <> nil do P := P^.ParentMenu;
  676. TopMenu := P;
  677. end;
  678. begin
  679. AutoSelect := False; E.What:=evNothing;
  680. Res := 0;
  681. ItemShown := nil;
  682. Current := Menu^.Default;
  683. MouseActive := False;
  684. if UpdateMenu(Menu) then
  685. begin
  686. if Current<>nil then
  687. if Current^.Disabled then
  688. TrackKey(true);
  689. repeat
  690. Action := DoNothing;
  691. GetEvent(E);
  692. case E.What of
  693. evMouseDown:
  694. if MouseInView(E.Where) or MouseInOwner then
  695. begin
  696. TrackMouse;
  697. if Size.Y = 1 then AutoSelect := True;
  698. end else Action := DoReturn;
  699. evMouseUp:
  700. begin
  701. TrackMouse;
  702. if MouseInOwner then
  703. Current := Menu^.Default
  704. else
  705. if (Current <> nil) and (Current^.Name <> nil) then
  706. Action := DoSelect
  707. else
  708. if MouseActive or MouseInView(E.Where) then Action := DoReturn
  709. else
  710. begin
  711. Current := Menu^.Default;
  712. if Current = nil then Current := Menu^.Items;
  713. Action := DoNothing;
  714. end;
  715. end;
  716. evMouseMove:
  717. if E.Buttons <> 0 then
  718. begin
  719. TrackMouse;
  720. if not (MouseInView(E.Where) or MouseInOwner) and
  721. MouseInMenus then Action := DoReturn;
  722. end;
  723. evKeyDown:
  724. case CtrlToArrow(E.KeyCode) of
  725. kbUp, kbDown:
  726. if Size.Y <> 1 then
  727. TrackKey(CtrlToArrow(E.KeyCode) = kbDown) else
  728. if E.KeyCode = kbDown then AutoSelect := True;
  729. kbLeft, kbRight:
  730. if ParentMenu = nil then
  731. TrackKey(CtrlToArrow(E.KeyCode) = kbRight) else
  732. Action := DoReturn;
  733. kbHome, kbEnd:
  734. if Size.Y <> 1 then
  735. begin
  736. Current := Menu^.Items;
  737. if E.KeyCode = kbEnd then TrackKey(False);
  738. end;
  739. kbEnter:
  740. begin
  741. if Size.Y = 1 then AutoSelect := True;
  742. Action := DoSelect;
  743. end;
  744. kbEsc:
  745. begin
  746. Action := DoReturn;
  747. if (ParentMenu = nil) or (ParentMenu^.Size.Y <> 1) then
  748. ClearEvent(E);
  749. end;
  750. else
  751. Target := @Self;
  752. Ch := GetAltChar(E.KeyCode);
  753. if Ch = #0 then Ch := E.CharCode else Target := TopMenu;
  754. P := Target^.FindItem(Ch);
  755. if P = nil then
  756. begin
  757. P := TopMenu^.HotKey(E.KeyCode);
  758. if (P <> nil) and CommandEnabled(P^.Command) then
  759. begin
  760. Res := P^.Command;
  761. Action := DoReturn;
  762. end
  763. end else
  764. if Target = @Self then
  765. begin
  766. if Size.Y = 1 then AutoSelect := True;
  767. Action := DoSelect;
  768. Current := P;
  769. end else
  770. if (ParentMenu <> Target) or (ParentMenu^.Current <> P) then
  771. Action := DoReturn;
  772. end;
  773. evCommand:
  774. if E.Command = cmMenu then
  775. begin
  776. AutoSelect := False;
  777. if ParentMenu <> nil then Action := DoReturn;
  778. end else Action := DoReturn;
  779. end;
  780. if ItemShown <> Current then
  781. begin
  782. ItemShown := Current;
  783. DrawView;
  784. end;
  785. if (Action = DoSelect) or ((Action = DoNothing) and AutoSelect) then
  786. if Current <> nil then with Current^ do if Name <> nil then
  787. if Command = 0 then
  788. begin
  789. if E.What and (evMouseDown + evMouseMove) <> 0 then PutEvent(E);
  790. GetItemRect(Current, R);
  791. R.A.X := R.A.X + Origin.X;
  792. R.A.Y := R.B.Y + Origin.Y;
  793. R.B := Owner^.Size;
  794. if Size.Y = 1 then Dec(R.A.X);
  795. Target := TopMenu^.NewSubView(R, SubMenu, @Self);
  796. Res := Owner^.ExecView(Target);
  797. Dispose(Target, Done);
  798. end else if Action = DoSelect then Res := Command;
  799. if (Res <> 0) and CommandEnabled(Res) then
  800. begin
  801. Action := DoReturn;
  802. ClearEvent(E);
  803. end
  804. else
  805. Res := 0;
  806. until Action = DoReturn;
  807. end;
  808. if E.What <> evNothing then
  809. if (ParentMenu <> nil) or (E.What = evCommand) then PutEvent(E);
  810. if Current <> nil then
  811. begin
  812. Menu^.Default := Current;
  813. Current := nil;
  814. DrawView;
  815. end;
  816. Execute := Res;
  817. end;
  818. constructor TAdvancedMenuBar.Init(var Bounds: TRect; AMenu: PMenu);
  819. begin
  820. inherited Init(Bounds, AMenu);
  821. EventMask:=EventMask or evBroadcast;
  822. GrowMode:=gfGrowHiX;
  823. end;
  824. function TAdvancedMenuBar.NewSubView(var Bounds: TRect; AMenu: PMenu;
  825. AParentMenu: PMenuView): PMenuView;
  826. begin
  827. NewSubView := New(PAdvancedMenuBox, Init(Bounds, AMenu, AParentMenu));
  828. end;
  829. procedure TAdvancedMenuBar.Update;
  830. begin
  831. UpdateMenu(Menu);
  832. DrawView;
  833. end;
  834. function TAdvancedMenuBar.GetMenuItem(cm : word) : PMenuItem;
  835. type
  836. PItemChain = ^TItemChain;
  837. TItemChain = record
  838. Next : PMenuItem;
  839. Up : PItemChain;
  840. end;
  841. var Cur : PMenuItem;
  842. Up,NUp : PItemChain;
  843. begin
  844. Cur:=Menu^.Items;
  845. Up:=nil;
  846. if cm=0 then
  847. begin
  848. GetMenuItem:=nil;
  849. exit;
  850. end;
  851. while assigned(Cur) and (Cur^.Command<>cm) do
  852. begin
  853. if (Cur^.Command=0) and assigned(Cur^.SubMenu) and
  854. assigned(Cur^.Name) and
  855. assigned(Cur^.SubMenu^.Items) then
  856. {subMenu}
  857. begin
  858. If assigned(Cur^.Next) then
  859. begin
  860. New(Nup);
  861. Nup^.Up:=Up;
  862. Nup^.next:=Cur^.Next;
  863. Up:=Nup;
  864. end;
  865. Cur:=Cur^.SubMenu^.Items;
  866. end
  867. else
  868. { normal item }
  869. begin
  870. if assigned(Cur^.Next) then
  871. Cur:=Cur^.Next
  872. else if assigned(Up) then
  873. begin
  874. Cur:=Up^.next;
  875. NUp:=Up;
  876. Up:=Up^.Up;
  877. Dispose(NUp);
  878. end
  879. else
  880. Cur:=Nil;
  881. end;
  882. end;
  883. GetMenuItem:=Cur;
  884. While assigned(Up) do
  885. begin
  886. NUp:=Up;
  887. Up:=Up^.up;
  888. Dispose(NUp);
  889. end;
  890. end;
  891. procedure TAdvancedMenuBar.HandleEvent(var Event: TEvent);
  892. begin
  893. case Event.What of
  894. evBroadcast :
  895. case Event.Command of
  896. cmCommandSetChanged : Update;
  897. cmUpdate : Update;
  898. end;
  899. end;
  900. inherited HandleEvent(Event);
  901. end;
  902. function TAdvancedMenuBar.Execute: word;
  903. type
  904. MenuAction = (DoNothing, DoSelect, DoReturn);
  905. var
  906. AutoSelect: Boolean;
  907. Action: MenuAction;
  908. Ch: AnsiChar;
  909. Res: Word;
  910. ItemShown, P: PMenuItem;
  911. Target: PMenuView;
  912. R: TRect;
  913. E: TEvent;
  914. MouseActive: Boolean;
  915. function IsDisabled(Item: PMenuItem): boolean;
  916. var Dis : boolean;
  917. begin
  918. Dis:=Item^.Disabled or IsSeparator(Item);
  919. if (Dis=false) and (IsSubMenu(Item)=false) then
  920. Dis:=CommandEnabled(Item^.Command)=false;
  921. IsDisabled:=Dis;
  922. end;
  923. procedure TrackMouse;
  924. var
  925. Mouse: TPoint;
  926. R: TRect;
  927. begin
  928. MakeLocal(E.Where, Mouse);
  929. Current := Menu^.Items;
  930. while Current <> nil do
  931. begin
  932. GetItemRect(Current, R);
  933. if R.Contains(Mouse) then
  934. begin
  935. MouseActive := True;
  936. Break;
  937. end;
  938. Current := Current^.Next;
  939. end;
  940. if (Current<>nil) and IsDisabled(Current) then
  941. Current:=nil;
  942. end;
  943. procedure TrackKey(FindNext: Boolean);
  944. procedure NextItem;
  945. begin
  946. Current := Current^.Next;
  947. if Current = nil then Current := Menu^.Items;
  948. end;
  949. procedure PrevItem;
  950. var
  951. P: PMenuItem;
  952. begin
  953. P := Current;
  954. if P = Menu^.Items then P := nil;
  955. repeat NextItem until Current^.Next = P;
  956. end;
  957. begin
  958. if Current <> nil then
  959. repeat
  960. if FindNext then NextItem else PrevItem;
  961. until (Current^.Name <> nil) and (IsDisabled(Current)=false);
  962. end;
  963. function MouseInOwner: Boolean;
  964. var
  965. Mouse: TPoint;
  966. R: TRect;
  967. begin
  968. MouseInOwner := False;
  969. if (ParentMenu <> nil) and (ParentMenu^.Size.Y = 1) then
  970. begin
  971. ParentMenu^.MakeLocal(E.Where, Mouse);
  972. ParentMenu^.GetItemRect(ParentMenu^.Current, R);
  973. MouseInOwner := R.Contains(Mouse);
  974. end;
  975. end;
  976. function MouseInMenus: Boolean;
  977. var
  978. P: PMenuView;
  979. begin
  980. P := ParentMenu;
  981. while (P <> nil) and not P^.MouseInView(E.Where) do P := P^.ParentMenu;
  982. MouseInMenus := P <> nil;
  983. end;
  984. function TopMenu: PMenuView;
  985. var
  986. P: PMenuView;
  987. begin
  988. P := @Self;
  989. while P^.ParentMenu <> nil do P := P^.ParentMenu;
  990. TopMenu := P;
  991. end;
  992. begin
  993. AutoSelect := False; E.What:=evNothing;
  994. Res := 0;
  995. ItemShown := nil;
  996. Current := Menu^.Default;
  997. MouseActive := False;
  998. if UpdateMenu(Menu) then
  999. begin
  1000. if Current<>nil then
  1001. if Current^.Disabled then
  1002. TrackKey(true);
  1003. repeat
  1004. Action := DoNothing;
  1005. GetEvent(E);
  1006. case E.What of
  1007. evMouseDown:
  1008. if MouseInView(E.Where) or MouseInOwner then
  1009. begin
  1010. TrackMouse;
  1011. if Size.Y = 1 then AutoSelect := True;
  1012. end else Action := DoReturn;
  1013. evMouseUp:
  1014. begin
  1015. TrackMouse;
  1016. if MouseInOwner then
  1017. Current := Menu^.Default
  1018. else
  1019. if (Current <> nil) and (Current^.Name <> nil) then
  1020. Action := DoSelect
  1021. else
  1022. if MouseActive or MouseInView(E.Where) then Action := DoReturn
  1023. else
  1024. begin
  1025. Current := Menu^.Default;
  1026. if Current = nil then Current := Menu^.Items;
  1027. Action := DoNothing;
  1028. end;
  1029. end;
  1030. evMouseMove:
  1031. if E.Buttons <> 0 then
  1032. begin
  1033. TrackMouse;
  1034. if not (MouseInView(E.Where) or MouseInOwner) and
  1035. MouseInMenus then Action := DoReturn;
  1036. end;
  1037. evKeyDown:
  1038. case CtrlToArrow(E.KeyCode) of
  1039. kbUp, kbDown:
  1040. if Size.Y <> 1 then
  1041. TrackKey(CtrlToArrow(E.KeyCode) = kbDown) else
  1042. if E.KeyCode = kbDown then AutoSelect := True;
  1043. kbLeft, kbRight:
  1044. if ParentMenu = nil then
  1045. TrackKey(CtrlToArrow(E.KeyCode) = kbRight) else
  1046. Action := DoReturn;
  1047. kbHome, kbEnd:
  1048. if Size.Y <> 1 then
  1049. begin
  1050. Current := Menu^.Items;
  1051. if E.KeyCode = kbEnd then TrackKey(False);
  1052. end;
  1053. kbEnter:
  1054. begin
  1055. if Size.Y = 1 then AutoSelect := True;
  1056. Action := DoSelect;
  1057. end;
  1058. kbEsc:
  1059. begin
  1060. Action := DoReturn;
  1061. if (ParentMenu = nil) or (ParentMenu^.Size.Y <> 1) then
  1062. ClearEvent(E);
  1063. end;
  1064. else
  1065. Target := @Self;
  1066. Ch := GetAltChar(E.KeyCode);
  1067. if Ch = #0 then Ch := E.CharCode else Target := TopMenu;
  1068. P := Target^.FindItem(Ch);
  1069. if P = nil then
  1070. begin
  1071. P := TopMenu^.HotKey(E.KeyCode);
  1072. if (P <> nil) and CommandEnabled(P^.Command) then
  1073. begin
  1074. Res := P^.Command;
  1075. Action := DoReturn;
  1076. end
  1077. end else
  1078. if Target = @Self then
  1079. begin
  1080. if Size.Y = 1 then AutoSelect := True;
  1081. Action := DoSelect;
  1082. Current := P;
  1083. end else
  1084. if (ParentMenu <> Target) or (ParentMenu^.Current <> P) then
  1085. Action := DoReturn;
  1086. end;
  1087. evCommand:
  1088. if E.Command = cmMenu then
  1089. begin
  1090. AutoSelect := False;
  1091. if ParentMenu <> nil then Action := DoReturn;
  1092. end else Action := DoReturn;
  1093. end;
  1094. if ItemShown <> Current then
  1095. begin
  1096. ItemShown := Current;
  1097. DrawView;
  1098. end;
  1099. if (Action = DoSelect) or ((Action = DoNothing) and AutoSelect) then
  1100. if Current <> nil then with Current^ do if Name <> nil then
  1101. if Command = 0 then
  1102. begin
  1103. if E.What and (evMouseDown + evMouseMove) <> 0 then PutEvent(E);
  1104. GetItemRect(Current, R);
  1105. R.A.X := R.A.X + Origin.X;
  1106. R.A.Y := R.B.Y + Origin.Y;
  1107. R.B := Owner^.Size;
  1108. if Size.Y = 1 then Dec(R.A.X);
  1109. Target := TopMenu^.NewSubView(R, SubMenu, @Self);
  1110. Res := Owner^.ExecView(Target);
  1111. Dispose(Target, Done);
  1112. end else if Action = DoSelect then Res := Command;
  1113. if (Res <> 0) and CommandEnabled(Res) then
  1114. begin
  1115. Action := DoReturn;
  1116. ClearEvent(E);
  1117. end
  1118. else
  1119. Res := 0;
  1120. until Action = DoReturn;
  1121. end;
  1122. if E.What <> evNothing then
  1123. if (ParentMenu <> nil) or (E.What = evCommand) then PutEvent(E);
  1124. if Current <> nil then
  1125. begin
  1126. Menu^.Default := Current;
  1127. Current := nil;
  1128. DrawView;
  1129. end;
  1130. Execute := Res;
  1131. end;
  1132. procedure TAdvancedStaticText.SetText(S: string);
  1133. begin
  1134. if Text<>nil then DisposeStr(Text);
  1135. Text:=NewStr(S);
  1136. DrawView;
  1137. end;
  1138. procedure TAdvancedListBox.FocusItem(Item: sw_integer);
  1139. var OFocused: sw_integer;
  1140. begin
  1141. OFocused:=Focused;
  1142. inherited FocusItem(Item);
  1143. if Focused<>OFocused then
  1144. Message(Owner,evBroadcast,cmListFocusChanged,@Self);
  1145. end;
  1146. procedure TAdvancedListBox.HandleEvent(var Event: TEvent);
  1147. var eEvent : TEvent;
  1148. begin
  1149. case Event.What of
  1150. evMouseDown :
  1151. if MouseInView(Event.Where) {and (Event.Double)} then
  1152. begin
  1153. eEvent:=Event; {save for later use after inherited call}
  1154. inherited HandleEvent(Event);
  1155. if eEvent.Double then
  1156. if Range>Focused then
  1157. SelectItem(Focused);
  1158. end;
  1159. evBroadcast :
  1160. case Event.Command of
  1161. cmListItemSelected :
  1162. Message(Owner,evBroadcast,cmDefault,nil);
  1163. end;
  1164. end;
  1165. inherited HandleEvent(Event);
  1166. end;
  1167. constructor TColorStaticText.Init(var Bounds: TRect; AText: String; AColor: word; AWrap: boolean);
  1168. begin
  1169. inherited Init(Bounds,AText);
  1170. DontWrap:=not AWrap;
  1171. Color:=AColor;
  1172. end;
  1173. function TColorStaticText.GetPalette: PPalette;
  1174. begin
  1175. GetPalette:=nil;
  1176. end;
  1177. procedure TColorStaticText.Draw;
  1178. procedure MoveColorTxt(var b;const curs:string;c:word);
  1179. var
  1180. p : ^word;
  1181. i : sw_integer;
  1182. col : byte;
  1183. tilde : boolean;
  1184. begin
  1185. tilde:=false;
  1186. col:=lo(c);
  1187. p:=@b;
  1188. i:=0;
  1189. while (i<length(Curs)) do
  1190. begin
  1191. Inc(i);
  1192. case CurS[i] of
  1193. #1 :
  1194. begin
  1195. Inc(i);
  1196. Col:=ord(curS[i]);
  1197. end;
  1198. #2 :
  1199. begin
  1200. if tilde then
  1201. col:=hi(Color)
  1202. else
  1203. col:=lo(Color)
  1204. end;
  1205. '~' :
  1206. begin
  1207. tilde:=not tilde;
  1208. if tilde then
  1209. col:=hi(Color)
  1210. else
  1211. col:=lo(Color)
  1212. end;
  1213. else
  1214. begin
  1215. p^:=(col shl 8) or ord(curs[i]);
  1216. inc(p);
  1217. end;
  1218. end;
  1219. end;
  1220. end;
  1221. var
  1222. C: word;
  1223. Center: Boolean;
  1224. I, J, L, P, Y: Sw_Integer;
  1225. B: TDrawBuffer;
  1226. S: String;
  1227. T: string;
  1228. CurS: string;
  1229. TildeCount,Po: Sw_integer;
  1230. TempS: string;
  1231. begin
  1232. if Size.X=0 then Exit;
  1233. C:=Color;
  1234. if (C and $0f)=((C and $f0) shr 4) then
  1235. C:=GetColor(C and $0f);
  1236. if DontWrap=false then
  1237. begin
  1238. GetText(S);
  1239. L := Length(S);
  1240. P := 1;
  1241. Y := 0;
  1242. Center := False;
  1243. while Y < Size.Y do
  1244. begin
  1245. MoveChar(B, ' ', Lo(C), Size.X);
  1246. if P <= L then
  1247. begin
  1248. if S[P] = #3 then
  1249. begin
  1250. Center := True;
  1251. Inc(P);
  1252. end;
  1253. I := P;
  1254. repeat
  1255. J := P;
  1256. while (P <= L) and (S[P] = ' ') do Inc(P);
  1257. while (P <= L) and (S[P] <> ' ') and (S[P] <> #13) do Inc(P);
  1258. until (P > L) or (P >= I + Size.X) or (S[P] = #13);
  1259. TildeCount:=0; TempS:=copy(S,I,P-I);
  1260. repeat
  1261. Po:=Pos('~',TempS);
  1262. if Po>0 then begin Inc(TildeCount); Delete(TempS,1,Po); end;
  1263. until Po=0;
  1264. if P > I + Size.X + TildeCount then
  1265. if J > I then P := J else P := I + Size.X;
  1266. T:=copy(S,I,P-I);
  1267. if Center then J := (Size.X - {P + I}CStrLen(T)) div 2 else J := 0;
  1268. MoveColorTxt(B[J],T,C);
  1269. while (P <= L) and (S[P] = ' ') do Inc(P);
  1270. if (P <= L) and (S[P] = #13) then
  1271. begin
  1272. Center := False;
  1273. Inc(P);
  1274. if (P <= L) and (S[P] = #10) then Inc(P);
  1275. end;
  1276. end;
  1277. WriteLine(0, Y, Size.X, 1, B);
  1278. Inc(Y);
  1279. end;
  1280. end { Wrap=false } else
  1281. begin
  1282. GetText(S);
  1283. I:=1;
  1284. for Y:=0 to Size.Y-1 do
  1285. begin
  1286. MoveChar(B, ' ', Lo(C), Size.X);
  1287. CurS:='';
  1288. if S<>'' then
  1289. begin
  1290. P:=Pos(#13,S);
  1291. if P=0 then P:=length(S)+1;
  1292. CurS:=copy(S,1,P-1);
  1293. CurS:=copy(CurS,Delta.X+1,High(CurS));
  1294. CurS:=copy(CurS,1,MaxViewWidth);
  1295. Delete(S,1,P);
  1296. end;
  1297. if CurS<>'' then
  1298. MoveColorTxt(B,CurS,C);
  1299. WriteLine(0,Y,Size.X,1,B);
  1300. end;
  1301. end;
  1302. end;
  1303. constructor TColorStaticText.Load(var S: TStream);
  1304. begin
  1305. inherited Load(S);
  1306. S.Read(Color,SizeOf(Color));
  1307. S.Read(DontWrap,SizeOf(DontWrap));
  1308. S.Read(Delta,SizeOf(Delta));
  1309. end;
  1310. procedure TColorStaticText.Store(var S: TStream);
  1311. begin
  1312. inherited Store(S);
  1313. S.Write(Color,SizeOf(Color));
  1314. S.Write(DontWrap,SizeOf(DontWrap));
  1315. S.Write(Delta,SizeOf(Delta));
  1316. end;
  1317. constructor THSListBox.Init(var Bounds: TRect; ANumCols: Word; AHScrollBar, AVScrollBar: PScrollBar);
  1318. begin
  1319. inherited Init(Bounds,ANumCols,AVScrollBar);
  1320. HScrollBar:=AHScrollBar;
  1321. if assigned(VScrollBar) then
  1322. VScrollBar^.SetStep(Bounds.B.Y-Bounds.A.Y-2,1);
  1323. if assigned(HScrollBar) then
  1324. HScrollBar^.SetStep(Bounds.B.X-Bounds.A.X-2,1);
  1325. end;
  1326. function THSListBox.SaveToFile(const AFileName: string): boolean;
  1327. var OK: boolean;
  1328. S: PBufStream;
  1329. i, count : sw_integer;
  1330. st : string;
  1331. begin
  1332. New(S, Init(AFileName,stCreate,4096));
  1333. OK:=Assigned(S) and (S^.Status=stOK);
  1334. if OK then
  1335. begin
  1336. if assigned(List) then
  1337. Count:=List^.Count
  1338. else
  1339. Count:=0;
  1340. for i:=0 to Count-1 do
  1341. begin
  1342. st:=GetText(i,High(st));
  1343. S^.Write(St[1],length(St));
  1344. if i<Count then
  1345. S^.Write(EOL[1],length(EOL));
  1346. OK:=(S^.Status=stOK);
  1347. if not OK then
  1348. break;
  1349. end;
  1350. end;
  1351. if Assigned(S) then Dispose(S, Done);
  1352. SaveToFile:=OK;
  1353. end;
  1354. function THSListBox.SaveAs: Boolean;
  1355. var
  1356. DefExt,Title,Filename : string;
  1357. Re : word;
  1358. begin
  1359. SaveAs := False;
  1360. Filename:='listbox.txt';
  1361. DefExt:='*.txt';
  1362. Title:='Save list box content';
  1363. Re:=Application^.ExecuteDialog(New(PFileDialog, Init(DefExt,
  1364. Title, label_name, fdOkButton, FileId)), @FileName);
  1365. if Re <> cmCancel then
  1366. SaveAs := SaveToFile(FileName);
  1367. end;
  1368. constructor TDlgWindow.Init(var Bounds: TRect; ATitle: TTitleStr; ANumber: Sw_Integer);
  1369. begin
  1370. inherited Init(Bounds,ATitle);
  1371. Number:=ANumber;
  1372. Flags:=Flags or (wfMove + wfGrow + wfClose + wfZoom);
  1373. end;
  1374. procedure TDlgWindow.Update;
  1375. begin
  1376. DrawView;
  1377. end;
  1378. procedure TDlgWindow.HandleEvent(var Event: TEvent);
  1379. begin
  1380. case Event.What of
  1381. evBroadcast :
  1382. case Event.Command of
  1383. cmUpdate : Update;
  1384. end;
  1385. end;
  1386. inherited HandleEvent(Event);
  1387. end;
  1388. procedure TLocalMenuListBox.LocalMenu(P: TPoint);
  1389. var M: PMenu;
  1390. MV: PAdvancedMenuPopUp;
  1391. R: TRect;
  1392. Re: word;
  1393. begin
  1394. M:=GetLocalMenu;
  1395. if M=nil then Exit;
  1396. if LastLocalCmd<>0 then
  1397. M^.Default:=SearchMenuItem(M,LastLocalCmd);
  1398. Desktop^.GetExtent(R);
  1399. MakeGlobal(P,R.A); {Desktop^.MakeLocal(R.A,R.A);}
  1400. New(MV, Init(R, M));
  1401. Re:=Application^.ExecView(MV);
  1402. if M^.Default=nil then LastLocalCmd:=0
  1403. else LastLocalCmd:=M^.Default^.Command;
  1404. Dispose(MV, Done);
  1405. if Re<>0 then
  1406. Message(GetCommandTarget,evCommand,Re,@Self);
  1407. end;
  1408. function TLocalMenuListBox.GetLocalMenu: PMenu;
  1409. begin
  1410. GetLocalMenu:=nil;
  1411. { Abstract;}
  1412. end;
  1413. function TLocalMenuListBox.GetCommandTarget: PView;
  1414. begin
  1415. GetCommandTarget:=@Self;
  1416. end;
  1417. procedure TLocalMenuListBox.HandleEvent(var Event: TEvent);
  1418. var DontClear: boolean;
  1419. P: TPoint;
  1420. begin
  1421. case Event.What of
  1422. evMouseDown :
  1423. if MouseInView(Event.Where) then
  1424. begin
  1425. if (Event.Buttons=mbRightButton) then
  1426. begin
  1427. MakeLocal(Event.Where,P); Inc(P.X); Inc(P.Y);
  1428. LocalMenu(P);
  1429. ClearEvent(Event);
  1430. end;
  1431. end;
  1432. evKeyDown :
  1433. begin
  1434. DontClear:=false;
  1435. case Event.KeyCode of
  1436. kbAltF10 : Message(@Self,evCommand,cmLocalMenu,@Self);
  1437. else DontClear:=true;
  1438. end;
  1439. if DontClear=false then ClearEvent(Event);
  1440. end;
  1441. evCommand :
  1442. begin
  1443. DontClear:=false;
  1444. case Event.Command of
  1445. cmLocalMenu :
  1446. begin
  1447. P:=Cursor; Inc(P.X); Inc(P.Y);
  1448. LocalMenu(P);
  1449. end;
  1450. else DontClear:=true;
  1451. end;
  1452. if not DontClear then ClearEvent(Event);
  1453. end;
  1454. end;
  1455. inherited HandleEvent(Event);
  1456. end;
  1457. procedure TLocalMenuOutlineViewer.LocalMenu(P: TPoint);
  1458. var M: PMenu;
  1459. MV: PAdvancedMenuPopUp;
  1460. R: TRect;
  1461. Re: word;
  1462. begin
  1463. M:=GetLocalMenu;
  1464. if M=nil then Exit;
  1465. if LastLocalCmd<>0 then
  1466. M^.Default:=SearchMenuItem(M,LastLocalCmd);
  1467. Desktop^.GetExtent(R);
  1468. MakeGlobal(P,R.A); {Desktop^.MakeLocal(R.A,R.A);}
  1469. New(MV, Init(R, M));
  1470. Re:=Application^.ExecView(MV);
  1471. if M^.Default=nil then LastLocalCmd:=0
  1472. else LastLocalCmd:=M^.Default^.Command;
  1473. Dispose(MV, Done);
  1474. if Re<>0 then
  1475. Message(GetCommandTarget,evCommand,Re,@Self);
  1476. end;
  1477. function TLocalMenuOutlineViewer.GetLocalMenu: PMenu;
  1478. begin
  1479. GetLocalMenu:=nil;
  1480. { Abstract;}
  1481. end;
  1482. function TLocalMenuOutlineViewer.GetCommandTarget: PView;
  1483. begin
  1484. GetCommandTarget:=@Self;
  1485. end;
  1486. procedure TLocalMenuOutlineViewer.HandleEvent(var Event: TEvent);
  1487. var DontClear: boolean;
  1488. P: TPoint;
  1489. begin
  1490. case Event.What of
  1491. evMouseDown :
  1492. if MouseInView(Event.Where) then
  1493. begin
  1494. if (Event.Buttons=mbRightButton) then
  1495. begin
  1496. MakeLocal(Event.Where,P); Inc(P.X); Inc(P.Y);
  1497. LocalMenu(P);
  1498. ClearEvent(Event);
  1499. end;
  1500. end;
  1501. evKeyDown :
  1502. begin
  1503. DontClear:=false;
  1504. case Event.KeyCode of
  1505. kbAltF10 : Message(@Self,evCommand,cmLocalMenu,@Self);
  1506. else DontClear:=true;
  1507. end;
  1508. if DontClear=false then ClearEvent(Event);
  1509. end;
  1510. evCommand :
  1511. begin
  1512. DontClear:=false;
  1513. case Event.Command of
  1514. cmLocalMenu :
  1515. begin
  1516. P:=Cursor; Inc(P.X); Inc(P.Y);
  1517. LocalMenu(P);
  1518. end;
  1519. else DontClear:=true;
  1520. end;
  1521. if not DontClear then ClearEvent(Event);
  1522. end;
  1523. end;
  1524. inherited HandleEvent(Event);
  1525. end;
  1526. function TAdvancedStatusLine.GetStatusText: string;
  1527. var S: string;
  1528. begin
  1529. if StatusText=nil then S:='' else S:=StatusText^;
  1530. GetStatusText:=S;
  1531. end;
  1532. procedure TAdvancedStatusLine.SetStatusText(const S: string);
  1533. begin
  1534. if StatusText<>nil then DisposeStr(StatusText);
  1535. StatusText:=NewStr(S);
  1536. DrawView;
  1537. end;
  1538. procedure TAdvancedStatusLine.ClearStatusText;
  1539. begin
  1540. SetStatusText('');
  1541. end;
  1542. procedure TAdvancedStatusLine.Draw;
  1543. var B: TDrawBuffer;
  1544. C: word;
  1545. S: string;
  1546. begin
  1547. S:=GetStatusText;
  1548. if S='' then inherited Draw else
  1549. begin
  1550. C:=GetColor(1);
  1551. MoveChar(B,' ',C,Size.X);
  1552. MoveStr(B[1],S,C);
  1553. WriteLine(0,0,Size.X,Size.Y,B);
  1554. end;
  1555. end;
  1556. procedure Bug(const S: string; Params: pointer);
  1557. begin
  1558. ErrorBox(FormatStrStr(msg_bugcheckfailed,S),Params);
  1559. end;
  1560. procedure ErrorBox(const S: string; Params: pointer);
  1561. begin
  1562. AdvMessageBox(S,Params,mfError+mfInsertInApp+mfOKButton);
  1563. end;
  1564. procedure WarningBox(const S: string; Params: pointer);
  1565. begin
  1566. AdvMessageBox(S,Params,mfWarning+mfInsertInApp+mfOKButton);
  1567. end;
  1568. procedure InformationBox(const S: string; Params: pointer);
  1569. begin
  1570. AdvMessageBox(S,Params,mfInformation+mfInsertInApp+mfOKButton);
  1571. end;
  1572. function OKCancelBox(const S: string; Params: pointer): word;
  1573. begin
  1574. OKCancelBox:=AdvMessageBox(S,Params,mfInformation+mfInsertInApp+mfOKButton+mfCancelButton);
  1575. end;
  1576. function b2i(B: boolean): longint;
  1577. begin
  1578. if b then b2i:=1 else b2i:=0;
  1579. end;
  1580. function ConfirmBox(const S: string; Params: pointer; CanCancel: boolean): word;
  1581. begin
  1582. ConfirmBox:=AdvMessageBox(S,Params,mfConfirmation+mfInsertInApp+mfYesButton+mfNoButton+
  1583. b2i(CanCancel)*mfCancelButton+b2i(not CanCancel)*mfCantCancel);
  1584. end;
  1585. function ChoiceBox(const S: string; Params: pointer; Buttons: array of string; CanCancel: boolean): word;
  1586. var BtnMask,M: longint;
  1587. I,BtnCount: integer;
  1588. begin
  1589. BtnCount:=Min(High(Buttons)-Low(Buttons)+1,High(UserButtonName)-Low(UserButtonName)+1);
  1590. BtnMask:=0; M:=mfUserBtn1;
  1591. for I:=Low(Buttons) to Low(Buttons)+BtnCount-1 do
  1592. begin
  1593. UserButtonName[Low(UserButtonName)+I-Low(Buttons)]:=Buttons[I];
  1594. BtnMask:=BtnMask or M; M:=M shl 1;
  1595. end;
  1596. ChoiceBox:=AdvMessageBox(S,Params,mfConfirmation+BtnMask+
  1597. b2i(CanCancel)*mfCancelButton+b2i(not CanCancel)*mfCantCancel);
  1598. end;
  1599. function IsSeparator(P: PMenuItem): boolean;
  1600. begin
  1601. IsSeparator:=(P<>nil) and (P^.Name=nil) and (P^.HelpCtx=hcNoContext);
  1602. end;
  1603. function IsSubMenu(P: PMenuItem): boolean;
  1604. begin
  1605. IsSubMenu:=(P<>nil) and (P^.Name<>nil) and (P^.Command=0) and (P^.SubMenu<>nil);
  1606. end;
  1607. function SearchMenuItem(Menu: PMenu; Cmd: word): PMenuItem;
  1608. var P,I: PMenuItem;
  1609. begin
  1610. I:=nil;
  1611. if Menu=nil then P:=nil else P:=Menu^.Items;
  1612. while (P<>nil) and (I=nil) do
  1613. begin
  1614. if IsSubMenu(P) then
  1615. I:=SearchMenuItem(P^.SubMenu,Cmd);
  1616. if I=nil then
  1617. if P^.Command=Cmd then I:=P else
  1618. P:=P^.Next;
  1619. end;
  1620. SearchMenuItem:=I;
  1621. end;
  1622. procedure SetMenuItemParam(Menu: PMenuItem; Param: string);
  1623. begin
  1624. if Menu=nil then Exit;
  1625. if Menu^.Param<>nil then DisposeStr(Menu^.Param);
  1626. Menu^.Param:=NewStr(Param);
  1627. end;
  1628. function UpdateMenu(M: PMenu): boolean;
  1629. var P: PMenuItem;
  1630. IsEnabled: boolean;
  1631. begin
  1632. if M=nil then begin UpdateMenu:=false; Exit; end;
  1633. P:=M^.Items; IsEnabled:=false;
  1634. while (P<>nil) do
  1635. begin
  1636. if IsSubMenu(P) then
  1637. begin
  1638. P^.Disabled:=not UpdateMenu(P^.SubMenu);
  1639. if not P^.Disabled then
  1640. IsEnabled:=true;
  1641. end
  1642. else
  1643. begin
  1644. if not IsSeparator(P) and
  1645. Application^.CommandEnabled(P^.Command) then
  1646. begin
  1647. p^.disabled:=false;
  1648. IsEnabled:=true;
  1649. end;
  1650. end;
  1651. P:=P^.Next;
  1652. end;
  1653. UpdateMenu:=IsEnabled;
  1654. end;
  1655. function SearchSubMenu(M: PMenu; Index: Sw_integer): PMenuItem;
  1656. var P,C: PMenuItem;
  1657. Count: Sw_integer;
  1658. begin
  1659. P:=nil; Count:=-1;
  1660. if M<>nil then C:=M^.Items else C:=nil;
  1661. while (C<>nil) and (P=nil) do
  1662. begin
  1663. if IsSubMenu(C) then
  1664. begin
  1665. Inc(Count);
  1666. if Count=Index then P:=C;
  1667. end;
  1668. C:=C^.Next;
  1669. end;
  1670. SearchSubMenu:=P;
  1671. end;
  1672. procedure AppendMenuItem(M: PMenu; I: PMenuItem);
  1673. var P: PMenuItem;
  1674. begin
  1675. if (M=nil) or (I=nil) then Exit;
  1676. I^.Next:=nil;
  1677. if M^.Items=nil then M^.Items:=I else
  1678. begin
  1679. P:=M^.Items;
  1680. while (P^.Next<>nil) do P:=P^.Next;
  1681. P^.Next:=I;
  1682. end;
  1683. end;
  1684. procedure DisposeMenuItem(P: PMenuItem);
  1685. begin
  1686. if P<>nil then
  1687. begin
  1688. if IsSubMenu(P) then DisposeMenu(P^.SubMenu) else
  1689. if IsSeparator(P)=false then
  1690. if P^.Param<>nil then DisposeStr(P^.Param);
  1691. if P^.Name<>nil then DisposeStr(P^.Name);
  1692. Dispose(P);
  1693. end;
  1694. end;
  1695. procedure RemoveMenuItem(Menu: PMenu; I: PMenuItem);
  1696. var P,PrevP: PMenuItem;
  1697. begin
  1698. if (Menu=nil) or (I=nil) then Exit;
  1699. P:=Menu^.Items; PrevP:=nil;
  1700. while (P<>nil) do
  1701. begin
  1702. if P=I then
  1703. begin
  1704. if Menu^.Items<>I then PrevP^.Next:=P^.Next
  1705. else Menu^.Items:=P^.Next;
  1706. DisposeMenuItem(P);
  1707. Break;
  1708. end;
  1709. PrevP:=P; P:=P^.Next;
  1710. end;
  1711. end;
  1712. function GetMenuItemBefore(Menu: PMenu; BeforeOf: PMenuItem): PMenuItem;
  1713. var P,C: PMenuItem;
  1714. begin
  1715. P:=nil;
  1716. if Menu<>nil then C:=Menu^.Items else C:=nil;
  1717. while (C<>nil) do
  1718. begin
  1719. if C^.Next=BeforeOf then begin P:=C; Break; end;
  1720. C:=C^.Next;
  1721. end;
  1722. GetMenuItemBefore:=P;
  1723. end;
  1724. procedure NotImplemented;
  1725. begin
  1726. InformationBox(msg_functionnotimplemented,nil);
  1727. end;
  1728. procedure InsertButtons(ADialog: PDialog);
  1729. var R : TRect;
  1730. W,H : Sw_integer;
  1731. X : Sw_integer;
  1732. X1,X2: Sw_integer;
  1733. begin
  1734. with ADialog^ do
  1735. begin
  1736. GetExtent(R);
  1737. W:=R.B.X-R.A.X; H:=(R.B.Y-R.A.Y);
  1738. R.Assign(0,0,W,H+3); ChangeBounds(R);
  1739. X:=W div 2; X1:=X div 2+1; X2:=X+X1-1;
  1740. R.Assign(X1-3,H,X1+7,H+2);
  1741. Insert(New(PButton, Init(R, btn_OK, cmOK, bfDefault)));
  1742. R.Assign(X2-7,H,X2+3,H+2);
  1743. Insert(New(PButton, Init(R, btn_Cancel, cmCancel, bfNormal)));
  1744. SelectNext(true);
  1745. end;
  1746. end;
  1747. procedure InsertOK(ADialog: PDialog);
  1748. var BW: Sw_integer;
  1749. R: TRect;
  1750. begin
  1751. with ADialog^ do
  1752. begin
  1753. GetBounds(R); R.Grow(0,1); Inc(R.B.Y);
  1754. ChangeBounds(R);
  1755. BW:=10;
  1756. R.A.Y:=R.B.Y-2; R.B.Y:=R.A.Y+2;
  1757. R.A.X:=R.A.X+(R.B.X-R.A.X-BW) div 2; R.B.X:=R.A.X+BW;
  1758. Insert(New(PButton, Init(R, btn_OK, cmOK, bfDefault)));
  1759. SelectNext(true);
  1760. end;
  1761. end;
  1762. procedure ShowMessage(Msg: string);
  1763. var R: TRect;
  1764. Width: Sw_integer;
  1765. begin
  1766. Width:=length(Msg)+4*2;
  1767. if Width<(Desktop^.Size.X div 2) then Width:=(Desktop^.Size.X div 2);
  1768. R.Assign(0,0,Width,5);
  1769. New(MessageDialog, Init(R, ''));
  1770. with MessageDialog^ do
  1771. begin
  1772. Flags:=0;
  1773. GetExtent(R); R.Grow(-4,-2);
  1774. if copy(Msg,1,1)<>^C then Msg:=^C+Msg;
  1775. Insert(New(PStaticText, Init(R, Msg)));
  1776. end;
  1777. Application^.Insert(MessageDialog);
  1778. end;
  1779. procedure HideMessage;
  1780. begin
  1781. if MessageDialog<>nil then
  1782. begin
  1783. Application^.Delete(MessageDialog);
  1784. Dispose(MessageDialog, Done);
  1785. MessageDialog:=nil;
  1786. end;
  1787. end;
  1788. constructor TDDHelperLB.Init(ALink: PDropDownListBox; var Bounds: TRect; ANumCols: Word; AScrollBar: PScrollBar);
  1789. begin
  1790. inherited Init(Bounds,ANumCols,AScrollBar);
  1791. EventMask:=EventMask or (evMouseMove+evIdle);
  1792. { Options:=Options or ofPreProcess;}
  1793. Link:=ALink;
  1794. end;
  1795. procedure TDDHelperLB.SetState(AState: Word; Enable: Boolean);
  1796. {var OState: longint;}
  1797. begin
  1798. { OState:=State;}
  1799. inherited SetState(AState,Enable);
  1800. { if (((State xor OState) and sfFocused)<>0) and (GetState(sfFocused)=false) then
  1801. Link^.DropList(false);}
  1802. end;
  1803. function TDDHelperLB.GetText(Item,MaxLen: Sw_Integer): String;
  1804. var P: pointer;
  1805. S: string;
  1806. begin
  1807. P:=List^.At(Item);
  1808. if Link=nil then S:='' else
  1809. S:=Link^.GetText(P,MaxLen);
  1810. GetText:=S;
  1811. end;
  1812. function TDDHelperLB.GetLocalMenu: PMenu;
  1813. begin
  1814. GetLocalMenu:=Link^.LBGetLocalMenu;
  1815. end;
  1816. function TDDHelperLB.GetCommandTarget: PView;
  1817. begin
  1818. GetCommandTarget:=Link^.LBGetCommandTarget;
  1819. end;
  1820. procedure TDDHelperLB.HandleEvent(var Event: TEvent);
  1821. const
  1822. MouseAutosToSkip = 4;
  1823. var
  1824. Mouse : TPoint;
  1825. OldItem, NewItem : Sw_Integer;
  1826. ColWidth : sw_integer;
  1827. Count : Sw_Word;
  1828. GoSelectItem: sw_integer;
  1829. MouseWhere: TPoint;
  1830. begin
  1831. GoSelectItem:=-1;
  1832. TView.HandleEvent(Event);
  1833. case Event.What of
  1834. evMouseDown :
  1835. if MouseInView(Event.Where)=false then
  1836. GoSelectItem:=-2
  1837. else
  1838. begin
  1839. ColWidth := Size.X div NumCols + 1;
  1840. OldItem := Focused;
  1841. MakeLocal(Event.Where, Mouse);
  1842. if MouseInView(Event.Where) then
  1843. NewItem := Mouse.Y + (Size.Y * (Mouse.X div ColWidth)) + TopItem
  1844. else
  1845. NewItem := OldItem;
  1846. Count := 0;
  1847. repeat
  1848. if NewItem <> OldItem then
  1849. begin
  1850. FocusItemNum(NewItem);
  1851. DrawView;
  1852. end;
  1853. OldItem := NewItem;
  1854. MakeLocal(Event.Where, Mouse);
  1855. if MouseInView(Event.Where) then
  1856. NewItem := Mouse.Y + (Size.Y * (Mouse.X div ColWidth)) + TopItem
  1857. else
  1858. begin
  1859. if NumCols = 1 then
  1860. begin
  1861. if Event.What = evMouseAuto then Inc(Count);
  1862. if Count = MouseAutosToSkip then
  1863. begin
  1864. Count := 0;
  1865. if Mouse.Y < 0 then NewItem := Focused-1
  1866. else if Mouse.Y >= Size.Y then NewItem := Focused+1;
  1867. end;
  1868. end
  1869. else
  1870. begin
  1871. if Event.What = evMouseAuto then Inc(Count);
  1872. if Count = MouseAutosToSkip then
  1873. begin
  1874. Count := 0;
  1875. if Mouse.X < 0 then NewItem := Focused-Size.Y
  1876. else if Mouse.X >= Size.X then NewItem := Focused+Size.Y
  1877. else if Mouse.Y < 0 then
  1878. NewItem := Focused - Focused mod Size.Y
  1879. else if Mouse.Y > Size.Y then
  1880. NewItem := Focused - Focused mod Size.Y + Size.Y - 1;
  1881. end
  1882. end;
  1883. end;
  1884. until not MouseEvent(Event, evMouseMove + evMouseAuto);
  1885. FocusItemNum(NewItem);
  1886. DrawView;
  1887. if Event.Double and (Range > Focused) then SelectItem(Focused);
  1888. ClearEvent(Event);
  1889. GoSelectItem:=Focused;
  1890. end;
  1891. evMouseMove,evMouseAuto:
  1892. if GetState(sfFocused) then
  1893. if MouseInView(Event.Where) then
  1894. begin
  1895. MakeLocal(Event.Where,Mouse);
  1896. FocusItemNum(TopItem+Mouse.Y);
  1897. ClearEvent(Event);
  1898. end;
  1899. evKeyDown :
  1900. begin
  1901. if (Event.KeyCode=kbEsc) then
  1902. begin
  1903. GoSelectItem:=-2;
  1904. ClearEvent(Event);
  1905. end else
  1906. if ((Event.KeyCode=kbEnter) or (Event.CharCode = ' ')) and
  1907. (Focused < Range) then
  1908. begin
  1909. GoSelectItem:=Focused;
  1910. NewItem := Focused;
  1911. end
  1912. else
  1913. case CtrlToArrow(Event.KeyCode) of
  1914. kbUp : NewItem := Focused - 1;
  1915. kbDown : NewItem := Focused + 1;
  1916. kbRight: if NumCols > 1 then NewItem := Focused + Size.Y else Exit;
  1917. kbLeft : if NumCols > 1 then NewItem := Focused - Size.Y else Exit;
  1918. kbPgDn : NewItem := Focused + Size.Y * NumCols;
  1919. kbPgUp : NewItem := Focused - Size.Y * NumCols;
  1920. kbHome : NewItem := TopItem;
  1921. kbEnd : NewItem := TopItem + (Size.Y * NumCols) - 1;
  1922. kbCtrlPgDn: NewItem := Range - 1;
  1923. kbCtrlPgUp: NewItem := 0;
  1924. else
  1925. Exit;
  1926. end;
  1927. FocusItemNum(NewItem);
  1928. DrawView;
  1929. ClearEvent(Event);
  1930. end;
  1931. evBroadcast :
  1932. case Event.Command of
  1933. cmReceivedFocus :
  1934. if (Event.InfoPtr<>@Self) and (InClose=false) then
  1935. begin
  1936. GoSelectItem:=-2;
  1937. end;
  1938. else
  1939. if Options and ofSelectable <> 0 then
  1940. if (Event.Command = cmScrollBarClicked) and
  1941. ((Event.InfoPtr = HScrollBar) or (Event.InfoPtr = VScrollBar)) then
  1942. Select
  1943. else
  1944. if (Event.Command = cmScrollBarChanged) then
  1945. begin
  1946. if (VScrollBar = Event.InfoPtr) then
  1947. begin
  1948. FocusItemNum(VScrollBar^.Value);
  1949. DrawView;
  1950. end
  1951. else
  1952. if (HScrollBar = Event.InfoPtr) then
  1953. DrawView;
  1954. end;
  1955. end;
  1956. evIdle :
  1957. begin
  1958. MouseWhere.X:=MouseWhereX shr 3; MouseWhere.Y:=MouseWhereY shr 3;
  1959. if MouseInView(MouseWhere)=false then
  1960. if abs(GetDosTicks-LastTT)>=1 then
  1961. begin
  1962. LastTT:=GetDosTicks;
  1963. MakeLocal(MouseWhere,Mouse);
  1964. if ((Mouse.Y<-1) or (Mouse.Y>=Size.Y)) and
  1965. ((0<=Mouse.X) and (Mouse.X<Size.X)) then
  1966. if Range>0 then
  1967. if Mouse.Y<0 then
  1968. FocusItemNum(Focused-(0-Mouse.Y))
  1969. else
  1970. FocusItemNum(Focused+(Mouse.Y-(Size.Y-1)));
  1971. end;
  1972. end;
  1973. end;
  1974. if (Range>0) and (GoSelectItem<>-1) then
  1975. begin
  1976. InClose:=true;
  1977. if GoSelectItem=-2 then
  1978. Link^.DropList(false)
  1979. else
  1980. SelectItem(GoSelectItem);
  1981. end;
  1982. end;
  1983. procedure TDDHelperLB.SelectItem(Item: Sw_Integer);
  1984. begin
  1985. inherited SelectItem(Item);
  1986. Link^.FocusItem(Focused);
  1987. Link^.DropList(false);
  1988. end;
  1989. constructor TDropDownListBox.Init(var Bounds: TRect; ADropLineCount: Sw_integer; AList: PCollection);
  1990. begin
  1991. inherited Init(Bounds);
  1992. Options:=Options or (ofSelectable);
  1993. EventMask:=EventMask or (evBroadcast);
  1994. DropLineCount:=ADropLineCount;
  1995. NewList(AList);
  1996. end;
  1997. procedure TDropDownListBox.HandleEvent(var Event: TEvent);
  1998. var DontClear: boolean;
  1999. Count: sw_integer;
  2000. begin
  2001. case Event.What of
  2002. evKeyDown :
  2003. if GetState(sfFocused) then
  2004. begin
  2005. DontClear:=false;
  2006. Count:=GetItemCount;
  2007. if Count>0 then
  2008. case Event.KeyCode of
  2009. kbUp :
  2010. if Focused>0 then
  2011. FocusItem(Focused-1);
  2012. kbDown :
  2013. if Focused<Count-1 then
  2014. FocusItem(Focused+1);
  2015. kbHome :
  2016. FocusItem(0);
  2017. kbEnd :
  2018. FocusItem(Count-1);
  2019. kbEnter,
  2020. kbPgDn :
  2021. DropList(true);
  2022. else DontClear:=true;
  2023. end;
  2024. if DontClear=false then ClearEvent(Event);
  2025. end;
  2026. evBroadcast :
  2027. case Event.Command of
  2028. cmReleasedFocus :
  2029. if (ListBox<>nil) and (Event.InfoPtr=ListBox) then
  2030. DropList(false);
  2031. cmListItemSelected :
  2032. if (ListBox<>nil) and (Event.InfoPtr=ListBox) then
  2033. begin
  2034. FocusItem(ListBox^.Focused);
  2035. Text:=GetText(List^.At(Focused),High(Text));
  2036. DrawView;
  2037. DropList(false);
  2038. end;
  2039. end;
  2040. evMouseDown :
  2041. if MouseInView(Event.Where) then
  2042. begin
  2043. DropList(not ListDropped);
  2044. ClearEvent(Event);
  2045. end;
  2046. end;
  2047. inherited HandleEvent(Event);
  2048. end;
  2049. function TDropDownListBox.GetText(Item: pointer; MaxLen: Sw_integer): string;
  2050. var S: string;
  2051. begin
  2052. S:=GetStr(Item);
  2053. GetText:=copy(S,1,MaxLen);
  2054. end;
  2055. procedure TDropDownListBox.NewList(AList: PCollection);
  2056. begin
  2057. if List<>nil then Dispose(List, Done); List:=nil;
  2058. List:=AList; FocusItem(0);
  2059. end;
  2060. procedure TDropDownListBox.CreateListBox(var R: TRect);
  2061. var R2: TRect;
  2062. begin
  2063. R2.Copy(R); R2.A.X:=R2.B.X-1;
  2064. New(SB, Init(R2));
  2065. Dec(R.B.X);
  2066. New(ListBox, Init(@Self,R,1,SB));
  2067. end;
  2068. procedure TDropDownListBox.DropList(Drop: boolean);
  2069. var R: TRect;
  2070. LB: PListBox;
  2071. begin
  2072. if (ListDropped=Drop) then Exit;
  2073. if Drop then
  2074. begin
  2075. R.Assign(Origin.X+1,Origin.Y+Size.Y,Origin.X+Size.X,Origin.Y+Size.Y+DropLineCount);
  2076. if Owner<>nil then Owner^.Lock;
  2077. CreateListBox(R);
  2078. if SB<>nil then
  2079. Owner^.Insert(SB);
  2080. if ListBox<>nil then
  2081. begin
  2082. ListBox^.NewList(List);
  2083. ListBox^.FocusItem(Focused);
  2084. Owner^.Insert(ListBox);
  2085. end;
  2086. if Owner<>nil then Owner^.UnLock;
  2087. end
  2088. else
  2089. begin
  2090. if Owner<>nil then Owner^.Lock;
  2091. if ListBox<>nil then
  2092. begin
  2093. { ListBox^.List:=nil;}
  2094. LB:=ListBox; ListBox:=nil; { this prevents GPFs while deleting }
  2095. Dispose(LB, Done);
  2096. end;
  2097. if SB<>nil then
  2098. begin
  2099. Dispose(SB, Done);
  2100. SB:=nil;
  2101. end;
  2102. Select;
  2103. if Owner<>nil then Owner^.UnLock;
  2104. end;
  2105. ListDropped:=Drop;
  2106. DrawView;
  2107. end;
  2108. function TDropDownListBox.GetItemCount: sw_integer;
  2109. var Count: sw_integer;
  2110. begin
  2111. if assigned(List)=false then Count:=0 else
  2112. Count:=List^.Count;
  2113. GetItemCount:=Count;
  2114. end;
  2115. procedure TDropDownListBox.FocusItem(Item: sw_integer);
  2116. var P: pointer;
  2117. begin
  2118. Focused:=Item;
  2119. if assigned(ListBox) and (Item>=0) then
  2120. ListBox^.FocusItem(Item);
  2121. if (GetItemCount>0) and (Focused>=0) then
  2122. begin
  2123. P:=List^.At(Focused);
  2124. Text:=GetText(P,Size.X-4);
  2125. end;
  2126. DrawView;
  2127. end;
  2128. function TDropDownListBox.LBGetLocalMenu: PMenu;
  2129. begin
  2130. LBGetLocalMenu:=nil;
  2131. end;
  2132. function TDropDownListBox.LBGetCommandTarget: PView;
  2133. begin
  2134. LBGetCommandTarget:=@Self;
  2135. end;
  2136. procedure TDropDownListBox.SetState(AState: Word; Enable: Boolean);
  2137. begin
  2138. inherited SetState(AState,Enable);
  2139. if (AState and (sfSelected + sfActive + sfFocused)) <> 0 then DrawView;
  2140. end;
  2141. procedure TDropDownListBox.Draw;
  2142. var B: TDrawBuffer;
  2143. C,TextC: word;
  2144. LC: AnsiChar;
  2145. begin
  2146. if GetState(sfFocused)=false then
  2147. begin
  2148. C:=GetColor(2);
  2149. TextC:=GetColor(2);
  2150. end
  2151. else
  2152. begin
  2153. C:=GetColor(3);
  2154. TextC:=GetColor(3);
  2155. end;
  2156. MoveChar(B,' ',C,Size.X);
  2157. MoveStr(B[1],copy(Text,1,Size.X-2),TextC);
  2158. if ListDropped then LC:='^' else LC:='v';
  2159. MoveChar(B[Size.X-2],LC,C,1);
  2160. WriteLine(0,0,Size.X,Size.Y,B);
  2161. end;
  2162. function TDropDownListBox.GetPalette: PPalette;
  2163. const P: string[length(CListViewer)] = CListViewer;
  2164. begin
  2165. GetPalette:=@P;
  2166. end;
  2167. destructor TDropDownListBox.Done;
  2168. begin
  2169. if ListDropped then DropList(false);
  2170. inherited Done;
  2171. end;
  2172. constructor TGroupView.Init(var Bounds: TRect; AText: String; ALink: PView);
  2173. begin
  2174. inherited Init(Bounds,AText,ALink);
  2175. end;
  2176. procedure TGroupView.Draw;
  2177. var B: TDrawBuffer;
  2178. FrameC,LabelC: word;
  2179. begin
  2180. FrameC:=GetColor(1);
  2181. if Light then
  2182. LabelC:=GetColor(2)+GetColor(4) shl 8
  2183. else
  2184. LabelC:=GetColor(1)+GetColor(3) shl 8;
  2185. { First Line }
  2186. MoveChar(B[0],''#$DA'',FrameC,1);
  2187. MoveChar(B[1],''#$C4'',FrameC,Size.X-2);
  2188. MoveChar(B[Size.X-1],''#$BF'',FrameC,1);
  2189. if Text<>nil then
  2190. begin
  2191. MoveCStr(B[1],' '+Text^+' ',LabelC);
  2192. end;
  2193. WriteLine(0,0,Size.X,1,B);
  2194. { Mid Lines }
  2195. MoveChar(B[0],''#$B3'',FrameC,1);
  2196. MoveChar(B[1],' ',FrameC,Size.X-2);
  2197. MoveChar(B[Size.X-1],''#$B3'',FrameC,1);
  2198. WriteLine(0,1,Size.X,Size.Y-2,B);
  2199. { Last Line }
  2200. MoveChar(B[0],''#$C0'',FrameC,1);
  2201. MoveChar(B[1],''#$C4'',FrameC,Size.X-2);
  2202. MoveChar(B[Size.X-1],''#$D9'',FrameC,1);
  2203. WriteLine(0,Size.Y-1,Size.X,1,B);
  2204. end;
  2205. function TPlainCheckBoxes.GetPalette: PPalette;
  2206. const P: string[length(CPlainCluster)] = CPlainCluster;
  2207. begin
  2208. GetPalette:=@P;
  2209. end;
  2210. function TPlainRadioButtons.GetPalette: PPalette;
  2211. const P: string[length(CPlainCluster)] = CPlainCluster;
  2212. begin
  2213. GetPalette:=@P;
  2214. end;
  2215. constructor TScrollerRadioButtons.Init (Var Bounds: TRect; AStrings: PSItem; aVScrollBar:PScrollBar);
  2216. var Y : sw_word;
  2217. begin
  2218. inherited init (Bounds, AStrings);
  2219. VScrollBar:=aVScrollBar;
  2220. EventMask := evMouseWheel + evMouseDown + evKeyDown + evCommand + evBroadcast;
  2221. Y:=Strings.count;
  2222. if (VScrollBar<> nil) and (Y>=size.Y) and (Size.Y>0) then
  2223. VScrollBar^.SetParams(0, 0,Y-Size.Y, Size.Y-1, VScrollBar^.ArStep); { Set vert scrollbar }
  2224. end;
  2225. procedure TScrollerRadioButtons.HandleEvent (Var Event: TEvent);
  2226. VAR I: Sw_Integer; Mouse: TPoint;
  2227. LinesScroll : sw_integer;
  2228. begin
  2229. TView.HandleEvent(Event); { Call TView, skip TCluster }
  2230. { Set focus to this view }
  2231. If ((Options AND ofSelectable) <> 0) Then
  2232. begin
  2233. If (Event.What = evMouseWheel) Then Begin { Mouse wheel event }
  2234. if (Event.Wheel=mwDown) then { Mouse scroll down }
  2235. begin
  2236. LinesScroll:=1;
  2237. if Event.Double then LinesScroll:=LinesScroll+4;
  2238. ScrollTo(Delta.X, Delta.Y + LinesScroll);
  2239. ClearEvent(Event); { Event was handled }
  2240. end else
  2241. if (Event.Wheel=mwUp) then { Mouse scroll up }
  2242. begin
  2243. LinesScroll:=-1;
  2244. if Event.Double then LinesScroll:=LinesScroll-4;
  2245. ScrollTo(Delta.X, Delta.Y + LinesScroll);
  2246. ClearEvent(Event); { Event was handled }
  2247. end;
  2248. end else
  2249. if (Event.What = evMouseDown) Then Begin { Mouse down event }
  2250. if (VScrollBar<>nil) then begin { mouse click if we have scrollbar}
  2251. MakeLocal(Event.Where, Mouse); { Make point local }
  2252. I := FindSel(Mouse); { Find selected item }
  2253. If (I <> -1) Then { Check in view }
  2254. If ButtonState(I) Then Sel := I; { If enabled select }
  2255. DrawView; { Now draw changes }
  2256. Repeat
  2257. MakeLocal(Event.Where, Mouse); { Make point local }
  2258. Until NOT MouseEvent(Event, evMouseMove); { Wait for mouse up }
  2259. MakeLocal(Event.Where, Mouse); { Make point local }
  2260. If (FindSel(Mouse) = Sel) AND ButtonState(Sel) { If valid/selected }
  2261. Then Begin
  2262. Press(Sel); { Call pressed }
  2263. DrawView; { Now draw changes }
  2264. End;
  2265. ClearEvent(Event); { Event was handled }
  2266. end;
  2267. end;
  2268. end;
  2269. Inherited HandleEvent(Event); { Call ancestor }
  2270. If (Event.What = evBroadcast) AND
  2271. (Event.Command = cmScrollBarChanged) AND { Scroll bar change }
  2272. ({(Event.InfoPtr = HScrollBar) OR} { Our scrollbar? }
  2273. (Event.InfoPtr = VScrollBar)) Then
  2274. begin
  2275. ScrollDraw;
  2276. ClearEvent(Event);
  2277. end;
  2278. end;
  2279. procedure TScrollerRadioButtons.ScrollTo (X,Y: Sw_Integer);
  2280. begin
  2281. if X>Size.X then X:=Size.X-1;
  2282. if X<0 then X:=0;
  2283. if (Y>(Strings.Count-Size.Y)) then Y:=(Strings.Count-Size.Y);
  2284. if Y<0 then Y:=0;
  2285. if Delta.Y<>Y then
  2286. begin
  2287. Delta.Y:=Y;
  2288. if (VScrollBar<>nil) then if VScrollBar^.Value<>Delta.Y then VScrollBar^.SetValue(Delta.Y);
  2289. DrawView;
  2290. end;
  2291. end;
  2292. function TScrollerRadioButtons.FindSel (P: TPoint): Sw_Integer;
  2293. var I, S, Vh: Sw_Integer; R: TRect;
  2294. begin
  2295. GetExtent(R); { Get view extents }
  2296. If R.Contains(P) Then Begin { Point in view }
  2297. Vh := Size.Y; { View height }
  2298. I := 0; { Preset zero value }
  2299. {While (P.X >= Column(I+Vh)) Do Inc(I, Vh);} { Inc view size }
  2300. S := I + P.Y+ Delta.Y; { Line to select }
  2301. If ((S >= 0) AND (S < Strings.Count)) { Valid selection }
  2302. Then FindSel := S Else FindSel := -1; { Return selected item }
  2303. End Else FindSel := -1; { Point outside view }
  2304. end;
  2305. procedure TScrollerRadioButtons.MovedTo (Item: Sw_Integer);
  2306. begin
  2307. if (Item<Delta.Y) then begin Delta.Y:=Item; end;
  2308. if (Item>=(Size.Y+Delta.Y)) then begin Delta.Y:=Item-Size.Y+1; end;
  2309. if (VScrollBar<>nil) then if VScrollBar^.Value<>Delta.Y then VScrollBar^.SetValue(Delta.Y);
  2310. inherited MovedTo(Item);
  2311. end;
  2312. procedure TScrollerRadioButtons.ScrollDraw;
  2313. begin
  2314. if (VScrollBar<> nil) then Delta.Y:=VScrollBar^.Value;
  2315. Drawview;
  2316. end;
  2317. procedure TScrollerRadioButtons.CentreSelected;
  2318. var Y : Sw_Integer;
  2319. begin
  2320. if (VScrollBar<> nil) then
  2321. begin
  2322. Y:=Sel-(Size.Y div 2);
  2323. if Y<0 then Y:=0;
  2324. if (Size.Y+Y) >= Strings.Count then Y:=Strings.Count-Size.Y;
  2325. if Y<0 then Y:=0;
  2326. if Delta.Y<>Y then
  2327. begin
  2328. Delta.Y:=Y;
  2329. VScrollBar^.SetValue(Y);
  2330. DrawView;
  2331. end;
  2332. end;
  2333. end;
  2334. procedure TScrollerRadioButtons.Draw;
  2335. begin
  2336. if VScrollBar=nil then begin inherited draw; exit; end;
  2337. if Size.Y >= Strings.Count then begin inherited draw; exit; end;
  2338. DrawScrollMultiBox(' ( ) ',' *');
  2339. end;
  2340. procedure TScrollerRadioButtons.DrawScrollMultiBox (Const Icon, Marker: String);
  2341. VAR I, J, Cur, Col: Sw_Integer;
  2342. CNorm, CSel, CDis, Color: Word; B: TDrawBuffer;
  2343. begin
  2344. CNorm := GetColor($0301); { Normal colour }
  2345. CSel := GetColor($0402); { Selected colour }
  2346. CDis := GetColor($0505); { Disabled colour }
  2347. For I := 0 To Size.Y-1 Do Begin { For each line }
  2348. MoveChar(B, ' ', Byte(CNorm), Size.X); { Fill buffer }
  2349. {For J := 0 To (Strings.Count - 1) DIV Size.Y + 1
  2350. Do}
  2351. J:=0;
  2352. Begin
  2353. Cur := {J*Size.Y} Delta.Y + I; { Current line }
  2354. If (Cur < Strings.Count) Then Begin
  2355. Col := {Column(Cur)}1; { Calc column }
  2356. If (Col + CStrLen(PString(Strings.At(Cur))^)+
  2357. 5 < Sizeof(TDrawBuffer) DIV SizeOf(Word))
  2358. AND (Col < Size.X) Then Begin { Text fits in column }
  2359. If NOT ButtonState(Cur) Then
  2360. Color := CDis Else If (Cur = Sel) AND { Disabled colour }
  2361. (State and sfFocused <> 0) Then
  2362. Color := CSel Else { Selected colour }
  2363. Color := CNorm; { Normal colour }
  2364. MoveChar(B[Col], ' ', Byte(Color),
  2365. Size.X-Col); { Set this colour }
  2366. MoveStr(B[Col], Icon, Byte(Color)); { Transfer icon string }
  2367. WordRec(B[Col+2]).Lo := Byte(Marker[
  2368. MultiMark(Cur) + 1]); { Transfer marker }
  2369. MoveCStr(B[Col+5], PString(Strings.At(
  2370. Cur))^, Color); { Transfer item string }
  2371. If ShowMarkers AND (State AND sfFocused <> 0)
  2372. AND (Cur = Sel) Then Begin { Current is selected }
  2373. WordRec(B[Col]).Lo := Byte(SpecialChars[0]);
  2374. WordRec(B[{Column(Cur+Size.Y)}1-1]).Lo
  2375. := Byte(SpecialChars[1]); { Set special character }
  2376. End;
  2377. End;
  2378. End;
  2379. End;
  2380. WriteBuf(0, I, Size.X, 1, B); { Write buffer }
  2381. End;
  2382. SetCursor({Column(Sel)}1+2,{Row(Sel)}Sel-Delta.Y);
  2383. end;
  2384. constructor TAdvancedListBox.Load(var S: TStream);
  2385. begin
  2386. inherited Load(S);
  2387. S.Read(Default,SizeOf(Default));
  2388. end;
  2389. procedure TAdvancedListBox.Store(var S: TStream);
  2390. begin
  2391. inherited Store(S);
  2392. S.Write(Default,SizeOf(Default));
  2393. end;
  2394. procedure TNoUpdateButton.HandleEvent(var Event: TEvent);
  2395. begin
  2396. if (Event.What<>evBroadcast) or (Event.Command<>cmCommandSetChanged) then
  2397. inherited HandleEvent(Event);
  2398. end;
  2399. constructor TPanel.Init(var Bounds: TRect);
  2400. begin
  2401. inherited Init(Bounds);
  2402. Options:=Options or (ofSelectable+ofTopSelect);
  2403. GrowMode:=gfGrowHiX+gfGrowHiY;
  2404. end;
  2405. procedure TAdvMessageBox.HandleEvent(var Event: TEvent);
  2406. var I: integer;
  2407. begin
  2408. if (not CanCancel) and (Event.What=evCommand) and (Event.Command=cmCancel) then
  2409. ClearEvent(Event);
  2410. inherited HandleEvent(Event);
  2411. case Event.What of
  2412. evCommand:
  2413. begin
  2414. for I:=Low(UserButtonCmd) to High(UserButtonCmd) do
  2415. if Event.Command=UserButtonCmd[I] then
  2416. if State and sfModal <> 0 then
  2417. begin
  2418. EndModal(Event.Command);
  2419. ClearEvent(Event);
  2420. end;
  2421. end;
  2422. end;
  2423. end;
  2424. procedure ClearFormatParams;
  2425. begin
  2426. FormatParamCount:=0; FillChar(FormatParams,sizeof(FormatParams),0);
  2427. FormatParamStrCount:=0;
  2428. end;
  2429. procedure AddFormatParam(P: pointer);
  2430. begin
  2431. Inc(FormatParamCount);
  2432. FormatParams[FormatParamCount]:=ptrint(P);
  2433. end;
  2434. procedure AddFormatParamInt(L: longint);
  2435. begin
  2436. Inc(FormatParamCount);
  2437. FormatParams[FormatParamCount]:=L;
  2438. end;
  2439. procedure AddFormatParamChar(C: AnsiChar);
  2440. begin
  2441. AddFormatParamInt(ord(C));
  2442. end;
  2443. procedure AddFormatParamStr(const S: string);
  2444. begin
  2445. Inc(FormatParamStrCount);
  2446. FormatParamStrs[FormatParamStrCount]:=S;
  2447. AddFormatParam(@FormatParamStrs[FormatParamStrCount]);
  2448. end;
  2449. function FormatStrF(const Format: string; var Params): string;
  2450. var S: string;
  2451. begin
  2452. S:='';
  2453. FormatStr(S,Format,Params);
  2454. FormatStrF:=S;
  2455. end;
  2456. function FormatStrStr(const Format, Param: string): string;
  2457. var S: string;
  2458. P: pointer;
  2459. begin
  2460. P:=@Param;
  2461. FormatStr(S,Format,P);
  2462. FormatStrStr:=S;
  2463. end;
  2464. function FormatStrStr2(const Format, Param1,Param2: string): string;
  2465. var S: string;
  2466. P: array[1..2] of pointer;
  2467. begin
  2468. P[1]:=@Param1; P[2]:=@Param2;
  2469. FormatStr(S,Format,P);
  2470. FormatStrStr2:=S;
  2471. end;
  2472. function FormatStrStr3(const Format, Param1,Param2,Param3: string): string;
  2473. var S: string;
  2474. P: array[1..3] of pointer;
  2475. begin
  2476. P[1]:=@Param1;
  2477. P[2]:=@Param2;
  2478. P[3]:=@Param3;
  2479. FormatStr(S,Format,P);
  2480. FormatStrStr3:=S;
  2481. end;
  2482. function FormatStrInt(const Format: string; L: PtrInt): string;
  2483. var S: string;
  2484. begin
  2485. FormatStr(S,Format,L);
  2486. FormatStrInt:=S;
  2487. end;
  2488. const
  2489. Cmds: array[0..3] of word =
  2490. (cmYes, cmNo, cmOK, cmCancel);
  2491. var
  2492. ButtonName: array[0..3] of string;
  2493. Titles: array[0..3] of string;
  2494. function AdvMessageBox(const Msg: String; Params: Pointer; AOptions: longint): Word;
  2495. var
  2496. R: TRect;
  2497. begin
  2498. R.Assign(0, 0, 0, 0);
  2499. AdvMessageBox := AdvMessageBoxRect(R, Msg, Params, AOptions);
  2500. end;
  2501. procedure GetStaticTextDimensions(const S: string; ViewWidth: integer; var MaxCols, Rows: integer);
  2502. var
  2503. Center: Boolean;
  2504. I, J, L, P, Y: Sw_Integer;
  2505. CurLine: string;
  2506. begin
  2507. MaxCols:=0;
  2508. L := Length(S);
  2509. P := 1;
  2510. Y := 0;
  2511. Center := False;
  2512. while (Y < 32767) and (P<=length(S)) do
  2513. begin
  2514. CurLine:='';
  2515. if P <= L then
  2516. begin
  2517. if S[P] = #3 then
  2518. begin
  2519. Center := True;
  2520. Inc(P);
  2521. end;
  2522. I := P;
  2523. repeat
  2524. J := P;
  2525. while (P <= L) and (S[P] = ' ') do Inc(P);
  2526. while (P <= L) and (S[P] <> ' ') and (S[P] <> #13) do Inc(P);
  2527. until (P > L) or (P >= I + ViewWidth) or (S[P] = #13);
  2528. if P > I + ViewWidth then
  2529. if J > I then P := J else P := I + ViewWidth;
  2530. if Center then J := (ViewWidth - P + I) div 2 else J := 0;
  2531. CurLine:=CurLine+copy(S,I,P-I);
  2532. { MoveBuf(B[J], S[I], Color, P - I);}
  2533. while (P <= L) and (S[P] = ' ') do Inc(P);
  2534. if (P <= L) and (S[P] = #13) then
  2535. begin
  2536. Center := False;
  2537. Inc(P);
  2538. if (P <= L) and (S[P] = #10) then Inc(P);
  2539. end;
  2540. end;
  2541. if length(CurLine)>MaxCols then
  2542. MaxCols:=length(CurLine);
  2543. { WriteLine(0, Y, Size.X, 1, B);}
  2544. Inc(Y);
  2545. end;
  2546. Rows:=Y;
  2547. end;
  2548. function AdvMessageBoxRect(var R: TRect; const Msg: String; Params: Pointer; AOptions: longint): Word;
  2549. var
  2550. I, X, ButtonCount: Sw_Integer;
  2551. Dialog: PAdvMessageBox;
  2552. Control: PView;
  2553. ButtonList: array[0..4] of PView;
  2554. S,BtnName: String;
  2555. Cols,Rows: integer;
  2556. begin
  2557. FormatStr(S, Msg, Params^);
  2558. if R.Empty then
  2559. begin
  2560. GetStaticTextDimensions(S,40,Cols,Rows);
  2561. if Cols<32 then Cols:=32; if Rows=0 then Rows:=1;
  2562. R.Assign(0,0,3+Cols+3,Rows+6);
  2563. if (AOptions and mfInsertInApp)= 0 then
  2564. R.Move((Desktop^.Size.X-(R.B.X-R.A.X)) div 2,(Desktop^.Size.Y-(R.B.Y-R.A.Y)) div 2)
  2565. else
  2566. R.Move((Application^.Size.X-(R.B.X-R.A.X)) div 2,(Application^.Size.Y-(R.B.Y-R.A.Y)) div 2);
  2567. end;
  2568. New(Dialog,Init(R, Titles[AOptions and $3]));
  2569. with Dialog^ do
  2570. begin
  2571. CanCancel:=(Options and mfCantCancel)=0;
  2572. R.Assign(3,2, Size.X-2,Size.Y-3);
  2573. Control := New(PStaticText, Init(R, S));
  2574. Insert(Control);
  2575. X := -2;
  2576. ButtonCount := 0;
  2577. for I := 0 to 3 do
  2578. if AOptions and ($10000 shl I) <> 0 then
  2579. begin
  2580. BtnName:=UserButtonName[I+1];
  2581. R.Assign(0, 0, Max(10,length(BtnName)+2), 2);
  2582. Control := New(PButton, Init(R, BtnName, UserButtonCmd[I+1], bfNormal));
  2583. Inc(X, Control^.Size.X + 2);
  2584. ButtonList[ButtonCount] := Control;
  2585. Inc(ButtonCount);
  2586. end;
  2587. for I := 0 to 3 do
  2588. if AOptions and ($0100 shl I) <> 0 then
  2589. begin
  2590. R.Assign(0, 0, 10, 2);
  2591. Control := New(PButton, Init(R, ButtonName[I], Cmds[i], bfNormal));
  2592. Inc(X, Control^.Size.X + 2);
  2593. ButtonList[ButtonCount] := Control;
  2594. Inc(ButtonCount);
  2595. end;
  2596. X := (Size.X - X) div 2;
  2597. for I := 0 to ButtonCount - 1 do
  2598. begin
  2599. Control := ButtonList[I];
  2600. Insert(Control);
  2601. Control^.MoveTo(X, Size.Y - 3);
  2602. Inc(X, Control^.Size.X + 2);
  2603. end;
  2604. SelectNext(False);
  2605. end;
  2606. if AOptions and mfInsertInApp = 0 then
  2607. AdvMessageBoxRect := DeskTop^.ExecView(Dialog)
  2608. else
  2609. AdvMessageBoxRect := Application^.ExecView(Dialog);
  2610. Dispose(Dialog, Done);
  2611. end;
  2612. procedure InitAdvMsgBox;
  2613. begin
  2614. ButtonName[0] := slYes;
  2615. ButtonName[1] := slNo;
  2616. ButtonName[2] := slOk;
  2617. ButtonName[3] := slCancel;
  2618. Titles[0] := sWarning;
  2619. Titles[1] := sError;
  2620. Titles[2] := sInformation;
  2621. Titles[3] := sConfirm;
  2622. end;
  2623. procedure DoneAdvMsgBox;
  2624. begin
  2625. end;
  2626. procedure RegisterWViews;
  2627. begin
  2628. {$ifndef NOOBJREG}
  2629. RegisterType(RAdvancedListBox);
  2630. RegisterType(RColorStaticText);
  2631. RegisterType(RHSListBox);
  2632. RegisterType(RDlgWindow);
  2633. {$endif}
  2634. end;
  2635. END.