wviews.pas 77 KB

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