wviews.pas 76 KB

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