wviews.pas 74 KB

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