1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461 |
- //
- // The multimedia graphics platform GLScene https://github.com/glscene
- //
- unit GLS.Memo;
- (* Memo for GLScene *)
- interface
- {$I GLScene.inc}
- uses
- WinApi.Windows,
- WinApi.Messages,
- System.SysUtils,
- System.Classes,
- System.UITypes,
- VCL.Graphics,
- VCL.Controls,
- VCL.Forms,
- VCL.Dialogs,
- VCL.ClipBrd,
- VCL.StdCtrls,
- VCL.ExtCtrls;
- type
- TBorderType = (btRaised, btLowered, btFlatRaised, btFlatLowered);
- TCommand = Integer;
- TCellSize = record
- W, H: integer;
- end;
- TCellPos = record
- X, Y: integer;
- end;
- TFullPos = record
- LineNo, Pos: integer;
- end;
- TLineProp = class
- FObject: TObject;
- FStyleNo: integer;
- FInComment: Boolean;
- FInBrackets: integer;
- FValidAttrs: Boolean;
- FCharAttrs: string;
- end;
- TCharStyle = class(TPersistent)
- private
- FTextColor, FBkColor: TColor;
- FStyle: TFontStyles;
- published
- property TextColor: TColor read FTextColor write FTextColor;
- property BkColor: TColor read FBkColor write FBkColor;
- property Style: TFontStyles read FStyle write FStyle;
- end;
- TStyleList = class(TList)
- private
- procedure CheckRange(Index: integer);
- function GetTextColor(Index: Integer): TColor;
- procedure SetTextColor(Index: Integer; Value: TColor);
- function GetBkColor(Index: Integer): TColor;
- procedure SetBkColor(Index: Integer; Value: TColor);
- function GetStyle(Index: Integer): TFontStyles;
- procedure SetStyle(Index: Integer; Value: TFontStyles);
- protected
-
- property TextColor[Index: Integer]: TColor read GetTextColor write
- SetTextColor;
- property BkColor[Index: Integer]: TColor read GetBkColor write SetBkColor;
- property Style[Index: Integer]: TFontStyles read GetStyle write SetStyle;
- public
-
- destructor Destroy; override;
- procedure Clear; override;
- procedure Delete(Index: Integer);
- function Add(ATextColor, ABkCOlor: TColor; AStyle: TFontStyles): Integer;
- procedure Change(Index: integer; ATextColor, ABkColor: TColor; AStyle:
- TFontStyles);
- end;
- TGLAbstractMemoObject = class(TObject)
- public
- function MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer):
- Boolean; virtual; abstract;
- function MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer):
- Boolean; virtual; abstract;
- function MouseMove(Shift: TShiftState; X, Y: Integer):
- Boolean; virtual; abstract;
- end;
- TGLSMemoScrollBar = class;
- TGLSMemoAbstractScrollableObject = class(TCustomControl)
- protected
- procedure DoScroll(Sender: TGLSMemoScrollBar; ByValue: integer);
- virtual; abstract;
- procedure DoScrollPage(Sender: TGLSMemoScrollBar; ByValue: integer);
- virtual; abstract;
- end;
- TGLSCustomMemo = class;
- TsbState =
- (
- sbsWait,
- sbsBack,
- sbsForward,
- sbsPageBack,
- sbsPageForward,
- sbsDragging
- );
- TGLSMemoScrollBar = class(TGLAbstractMemoObject)
- private
- FKind: TScrollBarKind;
- FParent: TGLSMemoAbstractScrollableObject;
- FLeft, FTop, FWidth, FHeight: integer;
- FTotal, FMaxPosition, FPosition: integer;
- FButtonLength: integer;
- FState: TsbState;
- FXOffset, FYOffset: integer;
- procedure SetParams(Index: integer; Value: integer);
- procedure SetState(Value: TsbState);
- function GetRect: TRect;
- function GetThumbRect: TRect;
- function GetBackRect: TRect;
- function GetMiddleRect: TRect;
- function GetForwardRect: TRect;
- function GetPgBackRect: TRect;
- function GetPgForwardRect: TRect;
- public
- constructor Create(AParent: TGLSMemoAbstractScrollableObject;
- AKind: TScrollBarKind);
- procedure PaintTo(ACanvas: TCanvas);
- function MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer):
- Boolean; override;
- function MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer):
- Boolean; override;
- function MouseMove(Shift: TShiftState; X, Y: Integer):
- Boolean; override;
- function MoveThumbTo(X, Y: Integer): integer;
- property Parent: TGLSMemoAbstractScrollableObject read FParent;
- property Kind: TScrollBarKind read FKind write FKind;
- property State: TsbState read FState write SetState;
- property Left: integer index 0 read FLeft write SetParams;
- property Top: integer index 1 read FTop write SetParams;
- property Width: integer index 2 read FWidth write SetParams;
- property Height: integer index 3 read FHeight write SetParams;
- property Total: integer index 4 read FTotal write SetParams;
- property MaxPosition: integer index 5 read FMaxPosition write SetParams;
- property Position: integer index 6 read FPosition write SetParams;
- property FullRect: TRect read GetRect;
- property ThumbRect: TRect read GetThumbRect;
- property BackRect: TRect read GetBackRect;
- property MiddleRect: TRect read GetMiddleRect;
- property ForwardRect: TRect read GetForwardRect;
- property PageForwardRect: TRect read GetPgForwardRect;
- property PageBackRect: TRect read GetPgBackRect;
- end;
- TGLSMemoStrings = class(TStringList)
- private
- FMemo: TGLSCustomMemo;
- FLockCount: integer;
- FDeleting: Boolean;
- procedure CheckRange(Index: integer);
- function GetLineProp(Index: integer): TLineProp;
- procedure SetLineStyle(Index: integer; Value: integer);
- function GetLineStyle(Index: integer): integer;
- function GetInComment(Index: Integer): Boolean;
- procedure SetInComment(Index: Integer; Value: Boolean);
- function GetInBrackets(Index: Integer): integer;
- procedure SetInBrackets(Index: Integer; Value: integer);
- function GetValidAttrs(Index: Integer): Boolean;
- procedure SetValidAttrs(Index: Integer; Value: Boolean);
- function GetCharAttrs(Index: Integer): string;
- procedure SetCharAttrs(Index: Integer; const Value: string);
- protected
- function GetObject(Index: Integer): TObject; override;
- procedure PutObject(Index: Integer; AObject: TObject); override;
- procedure SetUpdateState(Updating: Boolean); override;
- function CreateProp(Index: integer): TLineProp;
- property LineProp[Index: integer]: TLineProp read GetLineProp; //PALOFF
- property Style[Index: integer]: integer read GetLineStyle write
- SetLineStyle;
- property InComment[Index: integer]: Boolean read GetInComment write
- SetInComment;
- property InBrackets[Index: integer]: integer read GetInBrackets write
- SetInBrackets;
- property ValidAttrs[Index: integer]: Boolean read GetValidAttrs write
- SetValidAttrs;
- property CharAttrs[Index: integer]: string read GetCharAttrs write
- SetCharAttrs;
- public
- destructor Destroy; override;
- procedure Clear; override;
- function DoAdd(const S: string): Integer;
- function Add(const S: string): Integer; override;
- function AddObject(const S: string; AObject: TObject): Integer; override;
- procedure Assign(Source: TPersistent); override;
- procedure Insert(Index: Integer; const S: string); override;
- procedure DoInsert(Index: Integer; const S: string);
- procedure InsertObject(Index: Integer; const S: string; AObject: TObject);
- override;
- procedure Delete(Index: Integer); override;
- procedure LoadFromFile(const FileName: string); override;
- end;
- TGLSMemoGutter = class(TObject)
- private
- FMemo: TGLSCustomMemo;
- FLeft, FTop, FWidth, FHeight: integer;
- FColor: TColor;
- procedure SetParams(Index: integer; Value: integer);
- function GetRect: TRect;
- protected
- procedure PaintTo(ACanvas: TCanvas);
- procedure Invalidate;
- public
- property Left: integer index 0 read FLeft write SetParams;
- property Top: integer index 1 read FTop write SetParams;
- property Width: integer index 2 read FWidth write SetParams;
- property Height: integer index 3 read FHeight write SetParams;
- property FullRect: TRect read GetRect;
- end;
- TGLSMemoUndo = class
- private
- FMemo: TGLSCustomMemo;
- FUndoCurX0, FUndoCurY0: integer;
- FUndoCurX, FUndoCurY: integer;
- FUndoText: string;
- public
- constructor Create(ACurX0, ACurY0, ACurX, ACurY: integer; const AText: string);
- function Append(NewUndo: TGLSMemoUndo): Boolean; virtual;
- procedure Undo;
- procedure Redo;
- procedure PerformUndo; virtual; abstract;
- procedure PerformRedo; virtual; abstract;
- property UndoCurX0: integer read FUndoCurX0 write FUndoCurX0;
- property UndoCurY0: integer read FUndoCurY0 write FUndoCurY0;
- property UndoCurX: integer read FUndoCurX write FUndoCurX;
- property UndoCurY: integer read FUndoCurY write FUndoCurY;
- end;
- TGLSMemoInsCharUndo = class(TGLSMemoUndo)
- public
- function Append(NewUndo: TGLSMemoUndo): Boolean; override;
- procedure PerformUndo; override;
- procedure PerformRedo; override;
- end;
- TGLSMemoDelCharUndo = class(TGLSMemoUndo)
- private
- FIsBackspace: Boolean;
- public
- function Append(NewUndo: TGLSMemoUndo): Boolean; override;
- procedure PerformUndo; override;
- procedure PerformRedo; override;
- property IsBackspace: Boolean read FIsBackspace write FIsBackspace;
- end;
- TGLSMEmoDelLineUndo = class(TGLSMemoUndo)
- private
- FIndex: integer;
- public
- constructor Create(AIndex, ACurX0, ACurY0, ACurX, ACurY: integer; const AText:
- string);
- procedure PerformUndo; override;
- procedure PerformRedo; override;
- end;
- TGLSMemoSelUndo = class(TGLSMemoUndo)
- private
- FUndoSelStartX, FUndoSelStartY,
- FUndoSelEndX, FUndoSelEndY: integer;
- public
- property UndoSelStartX: integer read FUndoSelStartX write FUndoSelStartX;
- property UndoSelStartY: integer read FUndoSelStartY write FUndoSelStartY;
- property UndoSelEndX: integer read FUndoSelEndX write FUndoSelEndX;
- property UndoSelEndY: integer read FUndoSelEndY write FUndoSelEndY;
- end;
- TGLSMemoDeleteBufUndo = class(TGLSMemoSelUndo)
- public
- procedure PerformUndo; override;
- procedure PerformRedo; override;
- end;
- TGLSMemoPasteUndo = class(TGLSMemoUndo)
- public
- procedure PerformUndo; override;
- procedure PerformRedo; override;
- end;
- TGLSMemoUndoList = class(TList)
- private
- FPos: integer;
- FMemo: TGLSCustomMemo;
- FIsPerforming: Boolean;
- FLimit: integer;
- protected
- function Get(Index: Integer): TGLSMemoUndo;
- procedure SetLimit(Value: integer);
- public
- constructor Create;
- destructor Destroy; override;
- function Add(Item: Pointer): Integer;
- procedure Clear; override;
- procedure Delete(Index: Integer);
- procedure Undo;
- procedure Redo;
- property Items[Index: Integer]: TGLSMemoUndo read Get; default;
- property IsPerforming: Boolean read FIsPerforming write FIsPerforming;
- property Memo: TGLSCustomMemo read FMemo write FMemo;
- property Pos: integer read FPos write FPos;
- property Limit: integer read FLimit write SetLimit;
- end;
- //--------------------------------------------------------------
- TGutterClickEvent = procedure(Sender: TObject; LineNo: integer) of object;
- TGutterDrawEvent = procedure(Sender: TObject; ACanvas: TCanvas;
- LineNo: integer; rct: TRect) of object;
- TGetLineAttrsEvent = procedure(Sender: TObject; LineNo: integer;
- var Attrs: string) of object;
- TUndoChangeEvent = procedure(Sender: TObject;
- CanUndo, CanRedo: Boolean) of object;
- TScrollMode = (smAuto, smStrict);
- TGLSCustomMemo = class(TGLSMemoAbstractScrollableObject)
- private
- FAutoIndent: Boolean;
- FMargin: integer;
- FHiddenCaret, FCaretVisible: Boolean;
- FCellSize: TCellSize;
- FCurX, FCurY: integer;
- FLeftCol, FTopLine: integer;
- FTabSize: integer;
- FFont: TFont;
- FBkColor: TColor;
- FSelColor: TColor;
- FSelBkColor: TColor;
- FReadOnly: Boolean;
- FDelErase: Boolean;
- FLines: TStrings;
- FSelStartX, FSelStartY,
- FSelEndX, FSelEndY,
- FPrevSelX, FPrevSelY: integer;
- FScrollBars: System.UITypes.TScrollStyle;
- FScrollBarWidth: integer;
- FGutter: TGLSMemoGutter;
- FGutterWidth: integer;
- sbVert, sbHorz: TGLSMemoScrollBar;
- FStyles: TStyleList;
- FLineBitmap: TBitmap;
- FSelCharPos: TFullPos;
- FSelCharStyle: integer;
- FLeftButtonDown: Boolean;
- FScrollMode: TScrollMode;
- FUndoList: TGLSMemoUndoList;
- FFirstUndoList: TGLSMemoUndoList;
- FUndoLimit: integer;
- FLastMouseUpX,
- FLastMouseUpY: integer;
- FAfterDoubleClick: Boolean;
- // events
- FOnMoveCursor: TNotifyEvent;
- FOnChange: TNotifyEvent;
- FOnAttrChange: TNotifyEvent;
- FOnStatusChange: TNotifyEvent;
- FOnSelectionChange: TNotifyEvent;
- FOnGutterDraw: TGutterDrawEvent;
- FOnGutterClick: TGutterClickEvent;
- FOnGetLineAttrs: TGetLineAttrsEvent;
- FOnUndoChange: TUndoChangeEvent;
- FHideCursor: Boolean;
- procedure SetHiddenCaret(Value: Boolean);
- procedure SetScrollBars(Value: System.UITypes.TScrollStyle);
- procedure SetGutterWidth(Value: integer);
- procedure SetGutterColor(Value: TColor);
- function GetGutterColor: TColor;
- procedure SetCurX(Value: integer);
- procedure SetCurY(Value: integer);
- procedure SetFont(Value: TFont);
- procedure SetColor(Index: integer; Value: TColor);
- function GetSelStart: TPoint;
- function GetSelEnd: TPoint;
- procedure SetLines(ALines: TStrings);
- procedure SetLineStyle(Index: integer; Value: integer);
- function GetLineStyle(Index: integer): integer;
- function GetInComment(Index: integer): Boolean;
- procedure SetInComment(Index: integer; Value: Boolean);
- function GetInBrackets(Index: Integer): integer;
- procedure SetInBrackets(Index: Integer; Value: integer);
- function GetValidAttrs(Index: integer): Boolean;
- procedure SetValidAttrs(Index: integer; Value: Boolean);
- function GetCharAttrs(Index: integer): string;
- procedure SetCharAttrs(Index: integer; const Value: string);
- procedure ExpandSelection;
- function GetSelText: string;
- procedure SetSelText(const AValue: string);
- function GetSelLength: integer;
- procedure MovePage(dP: integer; Shift: TShiftState);
- procedure ShowCaret(State: Boolean);
- procedure MakeVisible;
- function GetVisible(Index: integer): integer;
- function MaxLength: integer;
- procedure WMSize(var Msg: TWMSize); message WM_SIZE;
- procedure WMGetDlgCode(var Msg: TWMGetDlgCode); message WM_GETDLGCODE;
- procedure WMEraseBkgnd(var Msg: TWmEraseBkgnd); message WM_ERASEBKGND;
- procedure WMSetCursor(var Msg: TWMSetCursor); message WM_SETCURSOR;
- procedure WMSetFocus(var Msg: TWMSetFocus); message WM_SETFOCUS;
- procedure WMKillFocus(var Msg: TWMSetFocus); message WM_KILLFOCUS;
- procedure WMMouseWheel(var Message: TMessage); message WM_MOUSEWHEEL;
- procedure MoveCursor(dX, dY: integer; Shift: TShiftState);
- procedure ResizeEditor;
- procedure ResizeScrollBars;
- procedure ResizeGutter;
- procedure DoCommand(cmd: TCommand; const AShift: TShiftState);
- procedure DrawLine(LineNo: integer);
- function IsLineVisible(LineNo: integer): Boolean;
- procedure FreshLineBitmap;
- procedure SetUndoLimit(Value: integer);
- protected
- procedure WndProc(var Message: TMessage); override;
- function EditorRect: TRect;
- function LineRangeRect(FromLine, ToLine: integer): TRect;
- function ColRangeRect(FromCol, ToCol: integer): TRect;
- procedure InvalidateLineRange(FromLine, ToLine: integer);
- function AddString(const S: string): integer;
- procedure InsertString(Index: integer; S: string);
- procedure GoHome(Shift: TShiftState);
- procedure GoEnd(Shift: TShiftState);
- procedure InsertChar(C: Char);
- procedure DeleteChar(OldX, OldY: integer);
- procedure DeleteLine(Index, OldX, OldY, NewX, NewY: integer; FixUndo: Boolean);
- procedure BackSpace;
- procedure BackSpaceWord;
- function IndentCurrLine: string;
- procedure NewLine;
- procedure CreateParams(var Params: TCreateParams); override;
- procedure Paint; override;
- procedure DrawMargin;
- procedure DrawGutter;
- procedure DrawScrollBars;
- procedure KeyDown(var Key: Word; Shift: TShiftState); override;
- procedure KeyPress(var Key: Char); override;
- procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
- procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
- procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
- procedure DblClick; override;
- procedure DoScroll(Sender: TGLSMemoScrollBar; ByValue: integer); override;
- procedure DoScrollPage(Sender: TGLSMemoScrollBar; ByValue: integer); override;
- property VisiblePosCount: integer index 0 read GetVisible;
- property VisibleLineCount: integer index 1 read GetVisible;
- property LastVisiblePos: integer index 2 read GetVisible;
- property LastVisibleLine: integer index 3 read GetVisible;
- procedure DeleteSelection(bRepaint: Boolean);
- procedure Changed(FromLine, ToLine: integer); virtual;
- procedure AttrChanged(LineNo: integer); virtual;
- procedure SelectionChanged; virtual;
- procedure StatusChanged; virtual;
- procedure ClearUndoList;
- procedure UndoChange;
- property AutoIndent: Boolean read FAutoIndent write FAutoIndent;
- property GutterWidth: integer read FGutterWidth write SetGutterWidth;
- property GutterColor: TColor read GetGutterColor write SetGutterColor;
- property ScrollBars: System.UITypes.TScrollStyle read FScrollBars write SetScrollBars default ssBoth;
- property Font: TFont read FFont write SetFont;
- property ReadOnly: Boolean read FReadOnly write FReadOnly;
- property Lines: TStrings read FLines write SetLines;
- property BkColor: TColor index 0 read FBkColor write SetColor;
- property SelColor: TColor index 1 read FSelColor write SetColor;
- property SelBkColor: TColor index 2 read FSelBkColor write SetColor;
- property HiddenCaret: Boolean read FHiddenCaret write SetHiddenCaret;
- property TabSize: integer read FTabSize write FTabSize;
- property ScrollMode: TScrollMode read FScrollMode write FScrollMode default smAuto;
- property UndoLimit: integer read FUndoLimit write SetUndoLimit;
- property HideCursor: Boolean read FHideCursor write FHideCursor;
- property InComment[Index: integer]: Boolean read GetInComment write SetInComment;
- property InBrackets[Index: integer]: integer read GetInBrackets write SetInBrackets;
- property ValidAttrs[Index: integer]: Boolean read GetValidAttrs write SetValidAttrs;
- property CharAttrs[Index: integer]: string read GetCharAttrs write SetCharAttrs;
- {events}
- property OnGutterClick: TGutterClickEvent read FOnGutterClick write FOnGutterClick;
- property OnGutterDraw: TGutterDrawEvent read FOnGutterDraw write FOnGutterDraw;
- property OnChange: TNotifyEvent read FOnChange write FOnChange;
- property OnMoveCursor: TNotifyEvent read FOnMoveCursor write FOnMoveCursor;
- property OnAttrChange: TNotifyEvent read FOnAttrChange write FOnAttrChange;
- property OnSelectionChange: TNotifyEvent read FOnSelectionChange write FOnSelectionChange;
- property OnStatusChange: TNotifyEvent read FOnStatusChange write FOnStatusChange;
- property OnGetLineAttrs: TGetLineAttrsEvent read FOnGetLineAttrs write FOnGetLineAttrs;
- property OnUndoChange: TUndoChangeEvent read FOnUndoChange write FOnUndoChange;
- public
- constructor Create(AOwner: TComponent); override;
- destructor Destroy; override;
- procedure CopyToClipBoard;
- procedure PasteFromClipBoard;
- procedure CutToClipBoard;
- procedure SelectLines(StartLine, EndLine: Integer);
- procedure SelectAll;
- property SelStart: TPoint read GetSelStart;
- property SelEnd: TPoint read GetSelEnd;
- property Selection: string read GetSelText write SetSelText;
- property SelLength: integer read GetSelLength;
- procedure ClearSelection;
- procedure Clear;
- procedure SetCursor(ACurX, ACurY: Integer);
- function SelectLine(LineNo, StyleNo: Integer): integer;
- procedure SelectChar(LineNo, Pos, StyleNo: Integer);
- function CellFromPos(X, Y: integer): TCellPos;
- function CharFromPos(X, Y: integer): TFullPos;
- function CellRect(ACol, ARow: integer): TRect;
- function LineRect(ARow: integer): TRect;
- function ColRect(ACol: integer): TRect;
- function CharStyleNo(LineNo, Pos: integer): integer;
- procedure InsertTemplate(AText: string);
- procedure UnSelectChar;
- procedure Undo;
- procedure Redo;
- function CanUndo: Boolean;
- function CanRedo: Boolean;
- function FindText(Text: string; Options: TFindOptions; Select: Boolean): Boolean;
- property CurX: integer read FCurX write SetCurX;
- property CurY: integer read FCurY write SetCurY;
- property DelErase: Boolean read FDelErase write FDelErase;
- property LineStyle[Index: integer]: integer read GetLineStyle write
- SetLineStyle;
- property Styles: TStyleList read FStyles;
- property UndoList: TGLSMemoUndoList read FUndoList write FUndoList;
- end;
- TGLSMemo = class(TGLSCustomMemo)
- published
- {TControl }
- property PopupMenu;
- {TCustomControl }
- property Align;
- property Enabled;
- property ShowHint;
- property TabOrder;
- property TabStop;
- property Visible;
- property ReadOnly;
- {TGLSCustomMemo }
- property AutoIndent;
- property GutterColor;
- property GutterWidth;
- property ScrollBars;
- property Font;
- property BkColor;
- property Selection;
- property SelColor;
- property SelBkColor;
- property Lines;
- property HiddenCaret;
- property TabSize;
- property ScrollMode;
- property UndoLimit;
- property DelErase;
- {Inherited events }
- property OnClick;
- property OnDblClick;
- property OnDragDrop;
- property OnDragOver;
- property OnEndDrag;
- property OnMouseDown;
- property OnMouseMove;
- property OnMouseUp;
- property OnStartDrag;
- property OnEnter;
- property OnExit;
- property OnKeyDown;
- property OnKeyPress;
- property OnKeyUp;
- {Events }
- property OnGutterDraw;
- property OnGutterClick;
- property OnChange;
- property OnMoveCursor;
- property OnAttrChange;
- property OnSelectionChange;
- property OnStatusChange;
- property OnGetLineAttrs;
- property OnUndoChange;
- end;
- TGLSMemoStringList = class(TStringList)
- private
- procedure ReadStrings(Reader: TReader);
- procedure WriteStrings(Writer: TWriter);
- protected
- procedure DefineProperties(Filer: TFiler); override;
- end;
- TDelimiters = TSysCharSet;
- TTokenType =
- (
- ttWord,
- ttBracket,
- ttSpecial,
- ttDelimiter,
- ttSpace,
- ttEOL,
- ttInteger,
- ttFloat,
- ttComment,
- ttOther,
- ttWrongNumber);
- //--------------------------------------------------------------
- // SYNTAX MEMO - declaration
- //--------------------------------------------------------------
- TGLSSynHiMemo = class(TGLSCustomMemo)
- private
- FIsPainting: Boolean;
- FInComment: Boolean;
- FWordList: TGLSMemoStringList;
- FSpecialList: TGLSMemoStringList;
- FBracketList: TGLSMemoStringList;
- FDelimiters: TDelimiters;
- FInBrackets: integer;
- FLineComment: string;
- FMultiCommentLeft: string;
- FMultiCommentRight: string;
- FDelimiterStyle: TCharStyle;
- FCommentStyle: TCharStyle;
- FNumberStyle: TCharStyle;
- FDelimiterStyleNo,
- FCommentStyleNo,
- FNumberStyleNo: integer;
- FCaseSensitive: Boolean;
- function GetToken(const S: string; var From: integer;
- out TokenType: TTokenType; out StyleNo: integer): string;
- procedure SetWordList(Value: TGLSMemoStringList);
- procedure SetSpecialList(Value: TGLSMemoStringList);
- procedure SetBracketList(Value: TGLSMemoStringList);
- procedure FindLineAttrs(Sender: TObject; LineNo: integer; var Attrs:
- string);
- procedure SetStyle(Index: integer; Value: TCharStyle);
- procedure SetCaseSensitive(Value: Boolean);
- protected
- procedure Paint; override;
- public
- constructor Create(AOwner: TComponent); override;
- destructor Destroy; override;
- procedure AddWord(StyleNo: integer; const ArrS: array of string);
- procedure AddSpecial(StyleNo: integer; const ArrS: array of string);
- procedure AddBrackets(StyleNo: integer; const ArrS: array of string);
- property Delimiters: TDelimiters read FDelimiters write FDelimiters;
- published
- {TControl}
- property PopupMenu;
- {TCustomControl}
- property Align;
- property Enabled;
- property ShowHint;
- property TabOrder;
- property TabStop;
- property Visible;
- property ReadOnly;
- {TGLSCustomMemo}
- property AutoIndent;
- property GutterColor;
- property GutterWidth;
- property ScrollBars;
- property Font;
- property BkColor;
- property SelColor;
- property SelBkColor;
- property Lines;
- property HiddenCaret;
- property TabSize;
- property ScrollMode;
- property UndoLimit;
- property DelErase;
- {Inherited events }
- property OnClick;
- property OnDblClick;
- property OnDragDrop;
- property OnDragOver;
- property OnEndDrag;
- property OnMouseDown;
- property OnMouseMove;
- property OnMouseUp;
- property OnStartDrag;
- property OnEnter;
- property OnExit;
- property OnKeyDown;
- property OnKeyPress;
- property OnKeyUp;
- {Events }
- property OnGutterClick;
- property OnGutterDraw;
- property OnChange;
- property OnMoveCursor;
- property OnSelectionChange;
- property OnStatusChange;
- property OnUndoChange;
- {TGLSSyntaxMemo }
- property LineComment: string read FLineComment write FLineComment;
- property MultiCommentLeft: string read FMultiCommentLeft write FMultiCommentLeft;
- property MultiCommentRight: string read FMultiCommentRight write FMultiCommentRight;
- property WordList: TGLSMemoStringList read FWordList write SetWordList;
- property SpecialList: TGLSMemoStringList read FSpecialList write SetSpecialList;
- property BracketList: TGLSMemoStringList read FBracketList write SetBracketList;
- property DelimiterStyle: TCharStyle index 0 read FDelimiterStyle write SetStyle;
- property CommentStyle: TCharStyle index 1 read FCommentStyle write SetStyle;
- property NumberStyle: TCharStyle index 2 read FNumberStyle write SetStyle;
- property CaseSensitive: Boolean read FCaseSensitive write SetCaseSensitive;
- end;
- procedure Border(Canvas: TCanvas; const rct: TRect; BorderType: TBorderType);
- //==========================================================
- implementation
- //==========================================================
- const
- cmDelete = VK_DELETE;
- cmBackSpace = VK_BACK;
- cmWordBackSpace = 127; // Ctrl-BackSpace
- cmNewLine = VK_RETURN;
- cmHome = VK_HOME;
- cmEnd = VK_END;
- cmPageUp = VK_PRIOR;
- cmPageDown = VK_NEXT;
- cmInsert = VK_INSERT;
- cmDelLine = 25; // Ctrl-Y
- cmCopy = 3; // Ctrl-C
- cmCut = 24; // Ctrl-X
- cmPaste = 22; // Ctrl-V
- resourcestring
- SObjectsNotSupported = 'Linked object not supported';
- var
- bmScrollBarFill: TBitmap;
- bmScrollBarUp: TBitmap;
- bmScrollBarDown: TBitmap;
- bmScrollBarLeft: TBitmap;
- bmScrollBarRight: TBitmap;
- fIntelliWheelSupport: Boolean; // True if IntelliMouse + wheel enabled
- fIntelliMessage: UINT; // message sent from mouse on wheel roll
- fIntelliScrollLines: Integer; // number of lines to scroll per wheel roll
- // ---------------------Helper functions
- function PointInRect(const P: TPoint; const rct: TRect): Boolean; inline;
- begin
- with rct do
- Result := (Left <= P.X) and (Top <= P.Y) and
- (Right >= P.X) and (Bottom >= P.Y);
- end;
- procedure Swap(var I1, I2: integer); inline;
- var
- temp: integer;
- begin
- temp := I1;
- I1 := I2;
- I2 := temp;
- end;
- procedure OrderPos(var StartX, StartY, EndX, EndY: integer); inline;
- begin
- if (EndY < StartY) or
- ((EndY = StartY) and (EndX < StartX)) then
- begin
- Swap(StartX, EndX);
- Swap(StartY, EndY);
- end;
- end;
- function TotalRect(const rct1, rct2: TRect): TRect; inline;
- begin
- Result := rct1;
- with Result do
- begin
- if rct2.Left < Left then
- Left := rct2.Left;
- if rct2.Top < Top then
- Top := rct2.Top;
- if rct2.Right > Right then
- Right := rct2.Right;
- if rct2.Bottom > Bottom then
- Bottom := rct2.Bottom;
- end;
- end;
- // ---------------------TGLSCustomMemo functions
- procedure TGLSCustomMemo.WndProc(var Message: TMessage);
- function GetShiftState: Integer;
- begin
- Result := 0;
- if GetAsyncKeyState(vk_Shift) < 0 then
- Result := Result or mk_Shift;
- if GetAsyncKeyState(vk_Control) < 0 then
- Result := Result or mk_Control;
- if GetAsyncKeyState(vk_LButton) < 0 then
- Result := Result or mk_LButton;
- if GetAsyncKeyState(vk_RButton) < 0 then
- Result := Result or mk_RButton;
- if GetAsyncKeyState(vk_MButton) < 0 then
- Result := Result or mk_MButton;
- end;
- //---------------------------------------------------
- begin
- if (Message.Msg = fIntelliMessage) and (fIntelliMessage <> wm_MouseWheel) then
- begin
- PostMessage(Handle, wm_MouseWheel, MakeLong(GetShiftState, Message.wParam),
- Message.lParam);
- end
- else
- inherited;
- end;
- //------------------------------------------------
- // INTELLIMOUSE INIT
- //------------------------------------------------
- procedure IntelliMouseInit;
- var
- hWndMouse: hWnd;
- mQueryScrollLines: UINT;
- //--------------------------------------------
- function NativeMouseWheelSupport: Boolean;
- var
- ver: TOSVersionInfo;
- begin
- Result := False;
- ver.dwOSVersionInfoSize := sizeof(ver);
- // For Windows 98, assume dwMajorVersion = 5 (It's 4 for W95)
- // For NT, we need 4.0 or better.
- if GetVersionEx(ver) then
- case ver.dwPlatformID of
- ver_Platform_Win32_Windows: Result := ver.dwMajorVersion >= 5;
- ver_Platform_Win32_NT: Result := ver.dwMajorVersion >= 4;
- end;
- { Quick and dirty temporary hack for Windows 98 beta 3 }
- if (not Result) and (ver.szCSDVersion = ' Beta 3') then
- Result := True;
- end;
- //--------------------------------------------
- begin
- if NativeMouseWheelSupport then
- begin
- fIntelliWheelSupport := Boolean(GetSystemMetrics(sm_MouseWheelPresent));
- SystemParametersInfo(spi_GetWheelScrollLines, 0, @fIntelliScrollLines, 0);
- fIntelliMessage := wm_MouseWheel;
- end
- else
- begin
- { Look for hidden mouse window }
- hWndMouse := FindWindow('MouseZ', 'Magellan MSWHEEL');
- if hWndMouse <> 0 then
- begin
- { We're in business - get the scroll line info }
- fIntelliWheelSupport := True;
- mQueryScrollLines := RegisterWindowMessage('MSH_SCROLL_LINES_MSG');
- fIntelliScrollLines := SendMessage(hWndMouse, mQueryScrollLines, 0, 0);
- { Finally, get the custom mouse message as well }
- fIntelliMessage := RegisterWindowMessage('MSWHEEL_ROLLMSG');
- end;
- end;
- if (fIntelliScrollLines < 0) or (fIntelliScrollLines > 100) then
- fIntelliScrollLines := 3;
- end;
- //------------------------------------------------
- // WM MOUSE WHEEL
- //------------------------------------------------
- procedure TGLSCustomMemo.WMMouseWheel(var Message: TMessage);
- {$J+}
- {$IFOPT R+} {$DEFINE StoreRangeCheck} {$ENDIF} {$R-}
- const
- Delta: SmallInt = 0;
- begin
- Delta := Delta + SmallInt(HiWord(Message.wParam));
- while Abs(Delta) >= 120 do
- begin
- if Delta < 0 then
- begin
- DoScroll(sbVert, fIntelliScrollLines);
- Delta := Delta + 120;
- end
- else
- begin
- DoScroll(sbVert, -fIntelliScrollLines);
- Delta := Delta - 120;
- end;
- end;
- end;
- {$J-}
- {$IFDEF StoreRangeCheck} {$R+} {$UNDEF StoreRangeCheck} {$ENDIF}
- //--------------------------------------------------------------
- // SET CURSOR
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.SetCursor(ACurX, ACurY: Integer);
- begin
- ClearSelection;
- CurX := 0;
- CurY := ACurY;
- CurX := ACurX;
- end;
- //--------------------------------------------------------------
- // SELECT LINE, CHAR
- //--------------------------------------------------------------
- function TGLSCustomMemo.SelectLine(LineNo, StyleNo: Integer): integer;
- var
- rct: TRect;
- begin
- Result := LineStyle[LineNo];
- LineStyle[LineNo] := StyleNo;
- rct := LineRect(LineNo);
- InvalidateRect(Handle, @rct, True);
- end;
- procedure TGLSCustomMemo.SelectLines(StartLine, EndLine: Integer);
- var
- rct: TRect;
- begin
- FSelStartX := 0;
- FSelStartY := StartLine;
- FSelEndX := Length(Lines[EndLine]);
- FSelEndY := EndLine;
- rct := LineRangeRect(FSelStartY, FSelEndY);
- SelectionChanged;
- InvalidateRect(Handle, @rct, true);
- end;
- procedure TGLSCustomMemo.SelectChar(LineNo, Pos, StyleNo: Integer);
- var
- rct: TRect;
- begin
- UnselectChar;
- FSelCharPos.LineNo := LineNo;
- FSelCharPos.Pos := Pos;
- FSelCharStyle := StyleNo;
- rct := LineRect(LineNo);
- InvalidateRect(Handle, @rct, True);
- end;
- procedure TGLSCustomMemo.UnSelectChar;
- var
- rct: TRect;
- begin
- with FSelCharPos do
- begin
- if LineNo < 0 then
- Exit;
- rct := LineRect(LineNo);
- LineNo := -1;
- Pos := -1;
- end;
- FSelCharStyle := -1;
- InvalidateRect(Handle, @rct, True);
- end;
- //--------------------------------------------------------------
- // CLEAR
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.Clear;
- begin
- CurY := 0;
- CurX := 0;
- FLeftCol := 0;
- FTopLine := 0;
- Lines.Clear;
- TGLSMemoStrings(Lines).DoAdd('');
- ClearUndoList;
- Invalidate;
- end;
- //--------------------------------------------------------------
- // SELECT ALL
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.SelectAll;
- begin
- FSelStartY := 0;
- FSelStartX := 0;
- FSelEndY := Lines.Count - 1;
- FSelEndX := Length(Lines[Lines.Count - 1]);
- Invalidate;
- end;
- //-----------------------------------------------------------
- // SET CLIPBOARD CODE PAGE
- //-----------------------------------------------------------
- procedure SetClipboardCodePage(const CodePage: longint);
- var
- Data: THandle;
- DataPtr: Pointer;
- begin
- // Define new code page for clipboard
- Data := GlobalAlloc(GMEM_MOVEABLE + GMEM_DDESHARE, 4);
- try
- DataPtr := GlobalLock(Data);
- try
- Move(CodePage, DataPtr^, 4);
- SetClipboardData(CF_LOCALE, Data);
- finally
- GlobalUnlock(Data);
- end;
- except
- GlobalFree(Data);
- end;
- end;
- //--------------------------------------------------------------
- // COPY TO CLIPBOARD
- //--------------------------------------------------------------
- procedure CopyStringToClipboard(const Value: string);
- const
- RusLocale = (SUBLANG_DEFAULT shl $A) or LANG_RUSSIAN;
- begin
- Clipboard.Open;
- SetClipboardCodePage(RusLocale);
- try
- Clipboard.AsText := Value;
- finally
- SetClipboardCodePage(RusLocale);
- Clipboard.Close;
- end;
- end;
- procedure TGLSCustomMemo.CopyToClipBoard;
- begin
- CopyStringToClipboard(GetSelText);
- end;
- //--------------------------------------------------------------
- // PASTE FROM CLIPBOARD
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.PasteFromClipBoard;
- var
- H, len: integer;
- Buff: string;
- begin
- H := ClipBoard.GetAsHandle(CF_TEXT);
- len := GlobalSize(H);
- if len = 0 then
- Exit;
- SetLength(Buff, len);
- SetLength(Buff, ClipBoard.GetTextBuf(PChar(Buff), len));
- AdjustLineBreaks(Buff);
- SetSelText(Buff);
- end;
- //--------------------------------------------------------------
- // DELETE SELECTION
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.DeleteSelection(bRepaint: Boolean);
- var
- xSelStartX, xSelStartY, xSelEndX, xSelEndY: integer;
- i, len: integer;
- OldX, OldY: integer;
- S1, S2, S, AddSpaces: string;
- Undo: TGLSMemoDeleteBufUndo;
- begin
- if (FSelStartY = FSelEndY) and (FSelStartX = FSelEndX) then
- Exit;
- OldX := CurX;
- OldY := CurY;
- xSelStartX := FSelStartX;
- xSelStartY := FSelStartY;
- xSelEndX := FSelEndX;
- xSelEndY := FSelEndY;
- OrderPos(xSelStartX, xSelStartY, xSelEndX, xSelEndY);
- if xSelStartY = xSelEndY then
- begin
- S1 := Copy(Lines[xSelStartY], xSelStartX + 1, xSelEndX - xSelStartX);
- S2 := '';
- AddSpaces := '';
- end
- else
- begin
- len := Length(Lines[xSelStartY]);
- S1 := Copy(Lines[xSelStartY], xSelStartX + 1, len);
- AddSpaces := StringOfChar(' ', xSelStartX - len);
- S2 := Copy(Lines[xSelEndY], 1, xSelEndX);
- end;
- Lines[xSelStartY] := Copy(Lines[xSelStartY], 1, xSelStartX) + AddSpaces +
- Copy(Lines[xSelEndY], xSelEndX + 1, Length(Lines[xSelEndY]));
- S := S1;
- for i := xSelStartY + 1 to xSelEndY do
- begin
- S := S + #13#10;
- if i <> xSelEndY then
- S := S + Lines[xSelStartY + 1];
- DeleteLine(xSelStartY + 1, -1, -1, -1, -1, False);
- end;
- S := S + S2;
- CurY := xSelStartY;
- CurX := xSelStartX;
- ClearSelection;
- Changed(xSelStartY, -1);
- SelectionChanged;
- if bRepaint then
- Invalidate;
- Undo := TGLSMemoDeleteBufUndo.Create(OldX, OldY, CurX, CurY, S);
- Undo.UndoSelStartX := xSelStartX;
- Undo.UndoSelStartY := xSelStartY;
- Undo.UndoSelEndX := xSelEndX;
- Undo.UndoSelEndY := xSelEndY;
- if Assigned(FUndoList) then
- FUndoList.Add(Undo);
- end;
- //--------------------------------------------------------------
- // CUT TO CLIPBOARD
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.CutToClipBoard;
- begin
- ClipBoard.SetTextBuf(PChar(GetSelText));
- DeleteSelection(True);
- end;
- //--------------------------------------------------------------
- // GET SEL TEXT
- //--------------------------------------------------------------
- function TGLSCustomMemo.GetSelText: string;
- var
- i: integer;
- xSelStartX, xSelStartY, xSelEndX, xSelEndY: integer;
- begin
- Result := '';
- if (FSelStartY = FSelEndY) and (FSelStartX = FSelEndX) then
- Exit;
- xSelStartX := FSelStartX;
- xSelStartY := FSelStartY;
- xSelEndX := FSelEndX;
- xSelEndY := FSelEndY;
- OrderPos(xSelStartX, xSelStartY, xSelEndX, xSelEndY);
- if xSelStartY = xSelEndY then
- Result := Copy(Lines[xSelStartY], xSelStartX + 1, xSelEndX - xSelStartX)
- else
- begin
- Result := Copy(Lines[xSelStartY], xSelStartX + 1,
- Length(Lines[xSelStartY]));
- for i := xSelStartY + 1 to xSelEndY - 1 do
- Result := Result + #13#10 + Lines[i];
- Result := Result + #13#10 + Copy(Lines[xSelEndY], 1, xSelEndX);
- end;
- end;
- //--------------------------------------------------------------
- // GET SEL START
- //--------------------------------------------------------------
- function TGLSCustomMemo.GetSelStart: TPoint;
- var
- xSelStartX, xSelStartY, xSelEndX, xSelEndY: integer;
- begin
- xSelStartX := FSelStartX;
- xSelStartY := FSelStartY;
- xSelEndX := FSelEndX;
- xSelEndY := FSelEndY;
- OrderPos(xSelStartX, xSelStartY, xSelEndX, xSelEndY);
- Result := Point(xSelStartX, xSelStartY);
- end;
- //--------------------------------------------------------------
- // GET SEL END
- //--------------------------------------------------------------
- function TGLSCustomMemo.GetSelEnd: TPoint;
- var
- xSelStartX, xSelStartY, xSelEndX, xSelEndY: integer;
- begin
- xSelStartX := FSelStartX;
- xSelStartY := FSelStartY;
- xSelEndX := FSelEndX;
- xSelEndY := FSelEndY;
- OrderPos(xSelStartX, xSelStartY, xSelEndX, xSelEndY);
- Result := Point(xSelEndX, xSelEndY);
- end;
- //--------------------------------------------------------------
- // SET SEL TEXT
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.SetSelText(const AValue: string);
- var
- i, k: integer;
- xSelStartX, xSelStartY, xSelEndX, xSelEndY: integer;
- Buff, S: string;
- OldX, OldY: integer;
- begin
- Buff := AValue;
- xSelStartX := FSelStartX;
- xSelStartY := FSelStartY;
- xSelEndX := FSelEndX;
- xSelEndY := FSelEndY;
- OrderPos(xSelStartX, xSelStartY, xSelEndX, xSelEndY);
- DeleteSelection(False);
- OldX := CurX;
- OldY := CurY;
- i := Pos(#13#10, Buff);
- S := Lines[xSelStartY];
- if i = 0 then
- begin
- Lines[xSelStartY] := Copy(S, 1, xSelStartX) + Buff
- + Copy(S, xSelStartX + 1, Length(S));
- CurX := xSelStartX;
- if Buff <> '' then
- CurX := CurX + Length(Buff);
- end
- else
- begin
- k := xSelStartY;
- Lines[k] := Copy(S, 1, xSelStartX) + Copy(Buff, 1, i - 1);
- TGLSMemoStrings(Lines).DoInsert(k + 1, Copy(S, xSelStartX + 1, Length(S)));
- while True do
- begin
- Buff := Copy(Buff, i + 2, Length(Buff));
- i := Pos(#13#10, Buff);
- k := k + 1;
- if i = 0 then
- break;
- TGLSMemoStrings(Lines).DoInsert(k, Copy(Buff, 1, i - 1));
- end;
- Lines[k] := Buff + Lines[k];
- CurY := k;
- CurX := Length(Buff);
- end;
- ClearSelection;
- Changed(xSelStartY, -1);
- if Assigned(FUndoList) then
- FUndoList.Add(TGLSMemoPasteUndo.Create(OldX, OldY, CurX, CurY, AValue));
- Invalidate;
- end;
- //--------------------------------------------------------------
- // GET SEL LENGTH
- //--------------------------------------------------------------
- function TGLSCustomMemo.GetSelLength: integer;
- begin
- Result := Length(GetSelText);
- end;
- //--------------------------------------------------------------
- // CHANGED
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.Changed(FromLine, ToLine: integer);
- var
- i: integer;
- begin
- if ToLine < FromLine then
- ToLine := Lines.Count - 1;
- for i := FromLine to ToLine do
- ValidAttrs[i] := False;
- InvalidateLineRange(FromLine, ToLine);
- if Assigned(FOnChange) then
- FOnChange(Self);
- end;
- //--------------------------------------------------------------
- // ATTR CHANGED
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.AttrChanged(LineNo: integer);
- begin
- ValidAttrs[LineNo] := False;
- InvalidateLineRange(LineNo, LineNo);
- if Assigned(FOnAttrChange) then
- FOnAttrChange(Self);
- end;
- //--------------------------------------------------------------
- // SELECTION CHANGED
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.SelectionChanged;
- begin
- if Assigned(FOnSelectionChange) then
- FOnSelectionChange(Self);
- end;
- //--------------------------------------------------------------
- // STATUS CHANGED
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.StatusChanged;
- begin
- if Assigned(FOnStatusChange) then
- FOnStatusChange(Self);
- end;
- //--------------------------------------------------------------
- // CLEAR SELECTION
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.ClearSelection;
- var
- rct: TRect;
- Changed: Boolean;
- begin
- Changed := not ((FSelStartX = FSelEndX) and (FSelStartY = FSelEndY));
- rct := LineRangeRect(FSelStartY, FSelEndY);
- FSelStartX := CurX;
- FSelStartY := CurY;
- FSelEndX := CurX;
- FSelEndY := CurY;
- FPrevSelX := CurX;
- FPrevSelY := CurY;
- if Changed then
- begin
- SelectionChanged;
- InvalidateRect(Handle, @rct, true);
- end;
- if Assigned(FOnMoveCursor) then
- FOnMoveCursor(Self);
- end;
- //--------------------------------------------------------------
- // EXPAND SELECTION
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.ExpandSelection;
- var
- rct: TRect;
- begin
- rct := LineRangeRect(FPrevSelY, CurY);
- FSelEndX := CurX;
- FSelEndY := CurY;
- FPrevSelX := CurX;
- FPrevSelY := CurY;
- SelectionChanged;
- InvalidateRect(Handle, @rct, true);
- if Assigned(FOnMoveCursor) then
- FOnMoveCursor(Self);
- end;
- //--------------------------------------------------------------
- // MAX LENGTH
- //--------------------------------------------------------------
- function TGLSCustomMemo.MaxLength: integer;
- var
- i, len: integer;
- begin
- Result := 0;
- for i := 0 to Lines.Count - 1 do
- begin
- len := Length(Lines[i]);
- if len > Result then
- Result := len;
- end;
- end;
- //--------------------------------------------------------------
- // DO SCROLL
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.DoScroll(Sender: TGLSMemoScrollBar; ByValue: integer);
- var
- eRect, scrRect, sbRect: TRect;
- Old: integer;
- begin
- eRect := EditorRect;
- case Sender.Kind of
- sbVertical:
- begin
- Old := FTopLine;
- FTopLine := FTopLine + ByValue;
- if FTopLine > Sender.MaxPosition then
- FTopLine := Sender.MaxPosition;
- if FTopLine < 0 then
- FTopLine := 0;
- if Old <> FTopLine then
- begin
- ShowCaret(False);
- if CurY < FTopLine then
- CurY := FTopLine;
- if CurY > LastVisibleLine then
- CurY := LastVisibleLine;
- ScrollDC(Canvas.Handle, 0, (Old - FTopLine) * FCellSize.H,
- eRect, eRect, 0, @scrRect);
- InvalidateRect(Handle, @scrRect, True);
- sbRect := Sender.FullRect;
- InvalidateRect(Handle, @sbRect, True);
- FGutter.Invalidate;
- ShowCaret(True);
- end;
- end;
- sbHorizontal:
- begin
- Old := FLeftCol;
- FLeftCol := FLeftCol + ByValue;
- if FLeftCol > Sender.MaxPosition then
- FLeftCol := Sender.MaxPosition;
- if FLeftCol < 0 then
- FLeftCol := 0;
- if Old <> FLeftCol then
- begin
- ShowCaret(False);
- if CurX < FLeftCol then
- CurX := FLeftCol;
- if CurX > LastVisiblePos then
- CurX := LastVisiblePos;
- ScrollDC(Canvas.Handle, (Old - FLeftCol) * FCellSize.W, 0,
- eRect, eRect, 0, @scrRect);
- InvalidateRect(Handle, @scrRect, True);
- sbRect := Sender.FullRect;
- InvalidateRect(Handle, @sbRect, True);
- ShowCaret(True);
- end;
- end;
- end;
- end;
- //--------------------------------------------------------------
- // DO SCROLL PAGE
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.DoScrollPage(Sender: TGLSMemoScrollBar; ByValue:
- integer);
- begin
- case Sender.Kind of
- sbVertical: DoScroll(Sender, ByValue * VisibleLineCount);
- sbHorizontal: DoScroll(Sender, ByValue * VisiblePosCount);
- end;
- end;
- //--------------------------------------------------------------
- // SET LINES
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.SetLines(ALines: TStrings);
- begin
- if ALines <> nil then
- begin
- FLines.Assign(ALines);
- Changed(0, -1);
- SelectionChanged;
- Invalidate;
- end;
- end;
- //--------------------------------------------------------------
- // SET/GET LINE STYLE
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.SetLineStyle(Index: integer; Value: integer);
- begin
- TGLSMemoStrings(FLines).Style[Index] := Value;
- if IsLineVisible(Index) then
- AttrChanged(Index);
- end;
- function TGLSCustomMemo.GetLineStyle(Index: integer): integer;
- begin
- Result := TGLSMemoStrings(FLines).Style[Index];
- end;
- //--------------------------------------------------------------
- // GET/SET IN COMMENT
- //--------------------------------------------------------------
- function TGLSCustomMemo.GetInComment(Index: integer): Boolean;
- begin
- Result := TGLSMemoStrings(FLines).InComment[Index];
- end;
- procedure TGLSCustomMemo.SetInComment(Index: integer; Value: Boolean);
- begin
- TGLSMemoStrings(FLines).InComment[Index] := Value;
- end;
- //--------------------------------------------------------------
- // GET/SET IN BRACKETS
- //--------------------------------------------------------------
- function TGLSCustomMemo.GetInBrackets(Index: integer): integer;
- begin
- Result := TGLSMemoStrings(FLines).InBrackets[Index];
- end;
- procedure TGLSCustomMemo.SetInBrackets(Index: integer; Value: integer);
- begin
- TGLSMemoStrings(FLines).InBrackets[Index] := Value;
- end;
- //--------------------------------------------------------------
- // GET/SET VALID ATTRS
- //--------------------------------------------------------------
- function TGLSCustomMemo.GetValidAttrs(Index: integer): Boolean;
- begin
- Result := TGLSMemoStrings(FLines).ValidAttrs[Index];
- end;
- procedure TGLSCustomMemo.SetValidAttrs(Index: integer; Value: Boolean);
- begin
- TGLSMemoStrings(FLines).ValidAttrs[Index] := Value;
- end;
- //--------------------------------------------------------------
- // GET/SET CHAR ATTRS
- //--------------------------------------------------------------
- function TGLSCustomMemo.GetCharAttrs(Index: integer): string;
- begin
- Result := TGLSMemoStrings(FLines).CharAttrs[Index];
- end;
- procedure TGLSCustomMemo.SetCharAttrs(Index: integer; const Value: string);
- begin
- TGLSMemoStrings(FLines).CharAttrs[Index] := Value;
- if IsLineVisible(Index) then
- AttrChanged(Index);
- end;
- //--------------------------------------------------------------
- // SET CUR X
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.SetCurX(Value: integer);
- var
- len: integer;
- WasVisible: Boolean;
- begin
- if Value < 0 then
- if CurY = 0 then
- Value := 0
- else
- begin
- CurY := CurY - 1;
- Value := Length(Lines[CurY]);
- end;
- if (CurY >= 0) and (CurY < Lines.Count) then
- begin
- len := Length(Lines[CurY]);
- if Value > len then
- begin
- Lines[CurY] := Lines[CurY] + StringOfChar(' ', Value - len);
- // Value := len;
- ValidAttrs[CurY] := False;
- InvalidateLineRange(CurY, CurY);
- end;
- end;
- FCurX := Value;
- WasVisible := FCaretVisible;
- if WasVisible then
- ShowCaret(False);
- MakeVisible;
- ResizeScrollBars;
- StatusChanged;
- if WasVisible then
- ShowCaret(True);
- end;
- //--------------------------------------------------------------
- // SET CUR Y
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.SetCurY(Value: integer);
- var
- Old: integer;
- WasVisible: Boolean;
- begin
- WasVisible := FCaretVisible;
- if WasVisible then
- ShowCaret(False);
- Old := CurY;
- if Value < 0 then
- Value := 0;
- if Value >= Lines.Count then
- Value := Lines.Count - 1;
- FCurY := Value;
- if (CurY <> Old) and (Old >= 0) and (Old < Lines.Count) then
- Lines[Old] := TrimRight(Lines[Old]);
- CurX := CurX;
- MakeVisible;
- ResizeScrollBars;
- StatusChanged;
- if WasVisible then
- ShowCaret(True);
- end;
- //--------------------------------------------------------------
- // MOVE CURSOR
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.MoveCursor(dX, dY: integer; Shift: TShiftState);
- var
- Selecting: Boolean;
- //------------------------------------------------------------
- function IsDelimiter(c: char): Boolean;
- begin
- Result := Pos(c, ' .,;:/?!@#$%^&*(){}[]<>-+=|\') > 0;
- end;
- //------------------------------------------------------------
- function IsStopChar(c, cThis: char): Boolean;
- begin
- Result := IsDelimiter(c) <> IsDelimiter(cThis);
- end;
- //------------------------------------------------------------
- procedure MoveWordLeft;
- var
- S: string;
- begin
- CurX := CurX - 1;
- S := TrimRight(Lines[CurY]);
- while CurX > 0 do
- begin
- if IsStopChar(S[CurX], S[CurX + 1]) then
- break;
- CurX := CurX - 1;
- end;
- if (CurX < 0) then
- if CurY > 0 then
- begin
- CurY := CurY - 1;
- CurX := Length(Lines[CurY]);
- end;
- end;
- //------------------------------------------------------------
- procedure MoveWordRight;
- var
- Len: integer;
- S: string;
- begin
- S := TrimRight(Lines[CurY]);
- Len := Length(S);
- CurX := CurX + 1;
- while CurX < Len do
- begin
- if IsStopChar(S[CurX + 1], S[CurX]) then
- break;
- CurX := CurX + 1;
- end;
- if CurX > Len then
- if CurY < Lines.Count - 1 then
- begin
- CurY := CurY + 1;
- CurX := 0;
- end;
- end;
- //------------------------------------------------------------
- begin
- Selecting := (ssShift in Shift) and (CurX = FPrevSelX)
- and (CurY = FPrevSelY);
- if ssCtrl in Shift then
- begin
- if dX > 0 then
- MoveWordRight;
- if dX < 0 then
- MoveWordLeft;
- end
- else
- begin
- CurY := CurY + dY;
- CurX := CurX + dX;
- end;
- if Selecting then
- ExpandSelection
- else
- ClearSelection;
- end;
- //--------------------------------------------------------------
- // MOVE PAGE
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.MovePage(dP: integer; Shift: TShiftState);
- var
- eRect: TRect;
- LinesPerPage: integer;
- Selecting: Boolean;
- begin
- if FCellSize.H = 0 then
- Exit;
- Selecting := (ssShift in Shift) and (CurX = FPrevSelX)
- and (CurY = FPrevSelY);
- eRect := EditorRect;
- LinesPerPage := (eRect.Bottom - eRect.Top) div FCellSize.H - 1;
- CurY := CurY + dP * LinesPerPage;
- if ssCtrl in Shift then
- if dP > 0 then
- begin
- CurY := Lines.Count - 1;
- CurX := Length(Lines[Lines.Count - 1]);
- end
- else
- begin
- CurY := 0;
- CurX := 0;
- end;
- if Selecting then
- ExpandSelection
- else
- ClearSelection;
- end;
- //--------------------------------------------------------------
- // GO HOME
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.GoHome(Shift: TShiftState);
- var
- Selecting: Boolean;
- begin
- Selecting := (ssShift in Shift) and (CurX = FPrevSelX)
- and (CurY = FPrevSelY);
- CurX := 0;
- FLeftCol := 0;
- if Selecting then
- ExpandSelection
- else
- ClearSelection;
- end;
- //--------------------------------------------------------------
- // GO END
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.GoEnd(Shift: TShiftState);
- var
- Selecting: Boolean;
- S, S1: string;
- begin
- Selecting := (ssShift in Shift) and (CurX = FPrevSelX)
- and (CurY = FPrevSelY);
- S := Lines[CurY];
- if not Selecting then
- S := TrimRight(S);
- S1 := TrimRight(Copy(S, CurX + 1, Length(S)));
- S := Copy(S, 1, CurX);
- Lines[CurY] := S + S1;
- CurX := Length(Lines[CurY]);
- if Selecting then
- ExpandSelection
- else
- ClearSelection;
- end;
- //--------------------------------------------------------------
- // INSERT CHAR
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.InsertChar(C: Char);
- var
- S, S1: string;
- NewPlace: integer;
- rct: TRect;
- CurX0, CurY0: integer;
- begin
- CurX0 := CurX;
- CurY0 := CurY;
- S := Lines[CurY];
- NewPlace := CurX + 1;
- if C = #9 then
- begin
- while (NewPlace mod TabSize) <> 0 do
- Inc(NewPlace);
- S1 := StringOfChar(' ', NewPlace - CurX);
- end
- else
- S1 := C;
- Insert(S1, S, CurX + 1);
- Lines[CurY] := S;
- CurX := NewPlace;
- ClearSelection;
- rct := LineRect(CurY);
- Changed(CurY, CurY);
- if Assigned(FUndoList) then
- FUndoList.Add(TGLSMemoInsCharUndo.Create(CurX0, CurY0, CurX, CurY, S1));
- InvalidateRect(Handle, @rct, True);
- end;
- //--------------------------------------------------------------
- // INSERT TEMPLATE
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.InsertTemplate(AText: string);
- var
- i, NewCurX, NewCurY: integer;
- Indent: string;
- FoundCursor: Boolean;
- begin
- Indent := IndentCurrLine;
- DeleteSelection(False);
- ClearSelection;
- NewCurX := CurX;
- NewCurY := CurY;
- FoundCursor := False;
- i := 1;
- while i <= Length(AText) do
- begin
- if AText[i] = #13 then
- begin
- if (i = Length(AText)) or (AText[i + 1] <> #10) then
- Insert(#10 + Indent, AText, i + 1);
- if not FoundCursor then
- begin
- Inc(NewCurY);
- NewCurX := Length(Indent);
- end;
- Inc(i, 1 + Length(Indent));
- end
- else if AText[i] = #7 then
- begin
- FoundCursor := True;
- Delete(AText, i, 1);
- Dec(i);
- end
- else if Ord(AText[i]) < Ord(' ') then
- begin
- Delete(AText, i, 1);
- Dec(i);
- end
- else if not FoundCursor then
- Inc(NewCurX);
- Inc(i);
- end;
- SetSelText(AText);
- SetCursor(NewCurX, NewCurY);
- ClearSelection;
- try
- SetFocus;
- except
- end;
- end;
- //--------------------------------------------------------------
- // DELETE CHAR
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.DeleteChar(OldX, OldY: integer);
- var
- S, S1: string;
- rct: TRect;
- C: char;
- Undo: TGLSMemoDelCharUndo;
- IsBackspace: Boolean;
- begin
- if FReadOnly then
- Exit;
- if OldX < 0 then
- begin
- OldX := CurX;
- OldY := CurY;
- IsBackspace := False;
- end
- else
- IsBackspace := True;
- ClearSelection;
- S := Lines[CurY];
- S1 := Copy(S, CurX + 1, Length(S));
- if not IsBackspace then
- S1 := TrimRight(S1);
- S := Copy(S, 1, CurX);
- Lines[CurY] := S + S1;
- if CurX < Length(Lines[CurY]) then
- begin
- S := Lines[CurY];
- C := S[CurX + 1];
- Delete(S, CurX + 1, 1);
- Lines[CurY] := S;
- Changed(CurY, CurY);
- rct := LineRect(CurY);
- Undo := TGLSMemoDelCharUndo.Create(OldX, OldY, CurX, CurY, C);
- Undo.IsBackSpace := IsBackSpace;
- if Assigned(FUndoList) then
- FUndoList.Add(Undo);
- end
- else if CurY < Lines.Count - 1 then
- begin
- S := Lines[CurY] + Lines[CurY + 1];
- Lines[CurY] := S;
- DeleteLine(CurY + 1, OldX, OldY, CurX, CurY, False);
- Changed(CurY, -1);
- rct := EditorRect;
- Undo := TGLSMemoDelCharUndo.Create(OldX, OldY, CurX, CurY, #13);
- Undo.IsBackSpace := IsBackSpace;
- if Assigned(FUndoList) then
- FUndoList.Add(Undo);
- end;
- ClearSelection;
- InvalidateRect(Handle, @rct, True);
- end;
- //--------------------------------------------------------------
- // DELETE LINE
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.DeleteLine(Index, OldX, OldY, NewX, NewY: integer;
- FixUndo: Boolean);
- var
- rct: TRect;
- s: string;
- begin
- if Index < 0 then
- Index := CurY;
- if OldX < 0 then
- begin
- OldX := CurX;
- OldY := CurY;
- end;
- s := Lines[Index];
- TGLSMemoStrings(Lines).FDeleting := True;
- if Lines.Count = 1 then
- TGLSMemoStrings(Lines)[0] := ''
- else
- Lines.Delete(Index);
- TGLSMemoStrings(Lines).FDeleting := False;
- ClearSelection;
- if Index >= Lines.Count then
- Changed(Index - 1, -1)
- else
- Changed(Index, -1);
- rct := EditorRect;
- InvalidateRect(Handle, @rct, True);
- if NewX < 0 then
- begin
- if Length(Lines[0]) < CurX then
- CurX := Length(Lines[0]);
- if Index >= Lines.Count then
- CurY := Index - 1
- else
- CurY := Index;
- NewX := CurX;
- NewY := CurY;
- end
- else
- begin
- CurX := NewX;
- CurY := NewY;
- end;
- if Assigned(FUndoList) and FixUndo then
- FUndoList.Add(TGLSMEmoDelLineUndo.Create(Index, OldX, OldY, NewX, NewY, s));
- end;
- //--------------------------------------------------------------
- // BACK SPACE
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.BackSpace;
- var
- OldX, OldY: integer;
- begin
- OldX := CurX;
- OldY := CurY;
- MoveCursor(-1, 0, []);
- if (OldX = CurX) and (OldY = CurY) then
- Exit;
- DeleteChar(OldX, OldY);
- end;
- //--------------------------------------------------------------
- // BACK SPACE WORD
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.BackSpaceWord;
- begin
- ClearSelection;
- MoveCursor(-1, 0, [ssShift, ssCtrl]);
- DeleteSelection(True);
- end;
- //--------------------------------------------------------------
- // INDENT CURR LINE
- //--------------------------------------------------------------
- function TGLSCustomMemo.IndentCurrLine: string;
- var
- Len, Count: integer;
- CurS: string;
- begin
- Result := '';
- if not AutoIndent then
- Exit;
- CurS := Lines[CurY];
- Len := Length(CurS);
- Count := 0;
- while (Count < CurX) and (Count < Len) do
- begin
- if CurS[Count + 1] <> ' ' then
- break;
- Inc(Count);
- end;
- Result := StringOfChar(' ', Count);
- end;
- //--------------------------------------------------------------
- // NEW LINE
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.NewLine;
- var
- S, sIndent: string;
- OldX, OldY: integer;
- begin
- OldX := CurX;
- OldY := CurY;
- S := Lines[CurY];
- sIndent := IndentCurrLine;
- Lines[CurY] := Copy(S, 1, CurX);
- S := TrimRight(Copy(S, CurX + 1, Length(S)));
- if AutoIndent then
- while (Length(S) > 0) and (S[1] = ' ') do
- Delete(S, 1, 1);
- TGLSMemoStrings(Lines).DoInsert(CurY + 1, sIndent + S);
- GoHome([]);
- MoveCursor(0, 1, []);
- CurX := Length(sIndent);
- ClearSelection;
- if Assigned(FUndoList) then
- FUndoList.Add(TGLSMemoInsCharUndo.Create(OldX, OldY, CurX, CurY, #13 +
- sIndent));
- Invalidate;
- Changed(CurY - 1, -1);
- end;
- //--------------------------------------------------------------
- // ADD STRING
- //--------------------------------------------------------------
- function TGLSCustomMemo.AddString(const S: string): integer;
- begin
- if Lines.Count = 0 then
- TGLSMemoStrings(Lines).DoAdd('');
- MovePage(1, [ssCtrl]); // end of text
- if not ((Lines.Count = 1) and (Lines[0] = '')) then
- begin
- TGLSMemoStrings(Lines).DoAdd('');
- CurX := 0;
- CurY := Lines.Count;
- ClearSelection;
- // S := #13#10 + S;
- end;
- SetSelText(S);
- Result := Lines.Count - 1;
- end;
- //--------------------------------------------------------------
- // INSERT STRING
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.InsertString(Index: integer; S: string);
- begin
- CurY := Index;
- CurX := 0;
- ClearSelection;
- if not ((Lines.Count = 1) and (Lines[0] = '')) then
- S := S + #13#10;
- SetSelText(S);
- end;
- //--------------------------------------------------------------
- // DO COMMAND
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.DoCommand(cmd: TCommand; const AShift: TShiftState);
- begin
- case cmd of
- cmDelete: if not FReadOnly then
- begin
- if ssShift in AShift then
- CutToClipboard
- else if FDelErase and
- (not ((FSelStartX = FSelEndX) and (FSelStartY = FSelEndY))) then
- DeleteSelection(True)
- else
- DeleteChar(-1, -1);
- end;
- cmBackSpace: BackSpace;
- cmWordBackSpace: BackSpaceWord;
- cmNewLine: NewLine;
- cmDelLine: DeleteLine(-1, -1, -1, -1, -1, True);
- cmCopy: CopyToClipboard;
- cmCut: CutToClipboard;
- cmPaste: PasteFromClipboard;
- cmHome: GoHome(AShift);
- cmEnd: GoEnd(AShift);
- cmPageDown: MovePage(1, AShift);
- cmPageUp: MovePage(-1, AShift);
- cmInsert:
- begin
- if ssShift in AShift then
- PasteFromClipboard;
- if ssCtrl in AShift then
- CopyToClipboard;
- end;
- end;
- end;
- //--------------------------------------------------------------
- // KEY DOWN
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.KeyDown(var Key: Word; Shift: TShiftState);
- begin
- ShowCaret(False);
- inherited;
- case Key of
- VK_LEFT: MoveCursor(-1, 0, Shift);
- VK_RIGHT: MoveCursor(1, 0, Shift);
- VK_UP: MoveCursor(0, -1, Shift);
- VK_DOWN: MoveCursor(0, 1, Shift);
- VK_HOME, VK_END,
- VK_DELETE: DoCommand(Key, Shift);
- VK_PRIOR, VK_NEXT:
- DoCommand(Key, Shift);
- VK_INSERT: DoCommand(Key, Shift);
- end;
- ShowCaret(True);
- end;
- //--------------------------------------------------------------
- // KEY PRESS
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.KeyPress(var Key: Char);
- begin
- if FReadOnly then
- Exit;
- ShowCaret(False);
- inherited;
- if (ord(Key) in [9, 32..255]) and (ord(Key) <> 127) then
- begin
- if FDelErase and (not ((FSelStartX = FSelEndX) and (FSelStartY = FSelEndY)))
- then
- DeleteSelection(True);
- InsertChar(Key);
- end
- else
- DoCommand(Ord(Key), []);
- ShowCaret(True);
- end;
- //--------------------------------------------------------------
- // MOUSE DOWN
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.MouseDown(Button: TMouseButton; Shift: TShiftState;
- X, Y: Integer);
- var
- newPos: TCellPos;
- charPos: TFullPos;
- Selecting: Boolean;
- begin
- inherited;
- if not Focused then
- begin
- SetFocus;
- // Exit;
- end;
- if FAfterDoubleClick then
- begin
- FAfterDoubleClick := False;
- Exit;
- end;
- if Button <>mbLeft then
- Exit;
- if sbVert.MouseDown(Button, Shift, X, Y) then
- Exit;
- if sbHorz.MouseDown(Button, Shift, X, Y) then
- Exit;
- if PointInRect(Point(X, Y), EditorRect) then
- begin
- ShowCaret(False);
- newPos := CellFromPos(X, Y);
- CurY := newPos.Y + FTopLine;
- CurX := newPos.X + FLeftCol;
- if Assigned(FOnMoveCursor) then
- FOnMoveCursor(Self);
- Selecting := ssShift in Shift;
- if Button = mbLeft then
- begin
- if Selecting then
- ExpandSelection
- else
- ClearSelection;
- FLeftButtonDown := True;
- end
- else
- ShowCaret(True);
- end;
- if Assigned(FOnGutterClick) then
- if PointInRect(Point(X, Y), FGutter.FullRect) then
- begin
- charPos := CharFromPos(X, Y);
- if charPos.LineNo < Lines.Count then
- FOnGutterClick(Self, charPos.LineNo);
- end;
- end;
- //--------------------------------------------------------------
- // MOUSE MOVE
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.MouseMove(Shift: TShiftState; X, Y: Integer);
- var
- newPos: TCellPos;
- begin
- inherited;
- if sbVert.MouseMove(Shift, X, Y) then
- Exit;
- if sbHorz.MouseMove(Shift, X, Y) then
- Exit;
- if PointInRect(Point(X, Y), EditorRect) then
- begin
- if (ssLeft in Shift) and FLeftButtonDown then
- begin
- newPos := CellFromPos(X, Y);
- CurY := newPos.Y + FTopLine;
- CurX := newPos.X + FLeftCol;
- ExpandSelection;
- end;
- end
- end;
- //--------------------------------------------------------------
- // MOUSE UP
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y:
- Integer);
- begin
- inherited;
- if sbVert.MouseUp(Button, Shift, X, Y) then
- Exit;
- if sbHorz.MouseUp(Button, Shift, X, Y) then
- Exit;
- if Button = mbLeft then
- ShowCaret(True);
- FLeftButtonDown := False;
- FLastMouseUpX := X;
- FLastMouseUpY := Y;
- end;
- //--------------------------------------------------------------
- // DBL CLICK
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.DblClick;
- var
- clickPos: TCellPos;
- clickX, clickY: integer;
- //------------------------------------------------------------
- // SELECT WORD
- //------------------------------------------------------------
- procedure SelectWord;
- const
- stopChars: TSysCharSet = [' ', ';', '.', ',', ':', '?', '!', '''', '"',
- '<', '>', '/', '*', '+', '-', '=', '(', ')',
- '[', ']', '{', '}', '@', '#', '$', '%', '^',
- '&', '|', '\'];
- var
- s: string;
- i: integer;
- rct: TRect;
- begin
- CurX := clickX;
- CurY := clickY;
- if (CurX = clickX) and (CurY = clickY) then
- begin
- s := Lines[clickY];
- if s[clickX + 1] = ' ' then
- Exit;
- i := clickX;
- while (i >= 0) and not CharInSet(s[i + 1], stopChars) do
- Dec(i);
- FSelStartY := clickY;
- FSelStartX := i + 1;
- i := clickX;
- while (i < Length(s)) and not CharInSet(s[i + 1], stopChars) do
- Inc(i);
- FSelEndY := clickY;
- FSelEndX := i;
- if FSelEndX <> FSelStartX then
- begin
- FAfterDoubleClick := True;
- rct := LineRangeRect(CurY, CurY);
- SelectionChanged;
- InvalidateRect(Handle, @rct, true);
- end;
- end;
- end;
- //------------------------------------------------------------
- begin
- if PointInRect(Point(FLastMouseUpX, FLastMouseUpY), EditorRect) then
- begin
- clickPos := CellFromPos(FLastMouseUpX, FLastMouseUpY);
- clickX := clickPos.X + FLeftCol;
- clickY := clickPos.Y + FTopLine;
- SelectWord;
- end;
- inherited;
- end;
- //--------------------------------------------------------------
- // WM_GETDLGCODE
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.WMGetDlgCode(var Msg: TWMGetDlgCode);
- begin
- Msg.Result := DLGC_WANTARROWS or DLGC_WANTTAB;
- end;
- //--------------------------------------------------------------
- // WM_ERASEBKGND
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.WMEraseBkgnd(var Msg: TWmEraseBkgnd);
- begin
- Msg.Result := 1;
- end;
- //--------------------------------------------------------------
- // WM_SIZE
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.WMSize(var Msg: TWMSize);
- begin
- if not (csLoading in ComponentState) then
- try
- ResizeEditor;
- except
- end;
- end;
- //--------------------------------------------------------------
- // WM_SETCURSOR
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.WMSetCursor(var Msg: TWMSetCursor);
- var
- P: TPoint;
- begin
- Msg.Result := 1;
- GetCursorPos(P);
- P := ScreenToClient(P);
- if PointInRect(P, EditorRect) then
- Winapi.Windows.SetCursor(Screen.Cursors[crIBeam])
- else
- Winapi.Windows.SetCursor(Screen.Cursors[crArrow]);
- end;
- //--------------------------------------------------------------
- // WM_SETFOCUS
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.WMSetFocus(var Msg: TWMSetFocus);
- begin
- if FCellSize.H = 0 then
- SetFont(FFont);
- CreateCaret(Handle, HBITMAP(0), 2, FCellSize.H - 2);
- ShowCaret(true);
- end;
- //--------------------------------------------------------------
- // WM_KILLFOCUS
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.WMKillFocus(var Msg: TWMSetFocus);
- begin
- DestroyCaret;
- FCaretVisible := False;
- inherited;
- end;
- //--------------------------------------------------------------
- // SHOW CARET
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.ShowCaret(State: Boolean);
- var
- rct: TRect;
- begin
- FCaretVisible := False;
- if not State then
- HideCaret(Handle)
- else if Focused and not HiddenCaret then
- begin
- rct := CellRect(CurX - FLeftCol, CurY - FTopLine);
- SetCaretPos(rct.Left, rct.Top + 1);
- Winapi.Windows.ShowCaret(Handle);
- FCaretVisible := True;
- end;
- end;
- //--------------------------------------------------------------
- // CELL RECT
- //--------------------------------------------------------------
- function TGLSCustomMemo.CellRect(ACol, ARow: integer): TRect;
- var
- rct: TRect;
- begin
- rct := EditorRect;
- with FCellSize do
- Result := Rect(rct.Left + W * ACol, rct.Top + H * ARow,
- rct.Left + W * (ACol + 1), rct.Top + H * (ARow + 1));
- end;
- //--------------------------------------------------------------
- // LINE RECT
- //--------------------------------------------------------------
- function TGLSCustomMemo.LineRect(ARow: integer): TRect;
- var
- rct: TRect;
- begin
- rct := EditorRect;
- ARow := ARow - FTopLine;
- with FCellSize do
- Result := Rect(rct.Left, rct.Top + H * ARow, rct.Right, rct.Top + H * (ARow
- + 1));
- end;
- //--------------------------------------------------------------
- // COL RECT
- //--------------------------------------------------------------
- function TGLSCustomMemo.ColRect(ACol: integer): TRect;
- var
- rct: TRect;
- begin
- rct := EditorRect;
- ACol := ACol - FLeftCol;
- with FCellSize do
- Result := Rect(rct.Left + W * ACol, rct.Top, rct.Left + W * (ACol + 1),
- rct.Bottom);
- end;
- //--------------------------------------------------------------
- // LINE RANGE RECT
- //--------------------------------------------------------------
- function TGLSCustomMemo.LineRangeRect(FromLine, ToLine: integer): TRect;
- var
- rct1, rct2: TRect;
- begin
- rct1 := LineRect(FromLine);
- rct2 := LineRect(ToLine);
- Result := TotalRect(rct1, rct2);
- end;
- //--------------------------------------------------------------
- // INVALIDATE LINE RANGE
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.InvalidateLineRange(FromLine, ToLine: integer);
- var
- rct: TRect;
- begin
- if ToLine < FromLine then
- ToLine := Lines.Count - 1;
- rct := LineRangeRect(FromLine, ToLine);
- if GutterWidth > 2 then
- rct.Left := FGutter.Left;
- InvalidateRect(Handle, @rct, True);
- end;
- //--------------------------------------------------------------
- // COL RANGE RECT
- //--------------------------------------------------------------
- function TGLSCustomMemo.ColRangeRect(FromCol, ToCol: integer): TRect;
- var
- rct1, rct2: TRect;
- begin
- rct1 := ColRect(FromCol);
- rct2 := ColRect(ToCol);
- Result := TotalRect(rct1, rct2);
- end;
- //--------------------------------------------------------------
- // CELL and CHAR FROM POS
- //--------------------------------------------------------------
- function TGLSCustomMemo.CellFromPos(X, Y: integer): TCellPos;
- var
- rct: TRect;
- begin
- rct := EditorRect;
- if (FCellSize.H = 0) and Assigned(FFont) then
- SetFont(FFont);
- if (FCellSize.W <> 0) and (FCellSize.H <> 0) then
- begin
- Result.X := (X - rct.Left) div FCellSize.W;
- Result.Y := (Y - rct.Top) div FCellSize.H;
- end
- else
- begin
- Result.X := 0;
- Result.Y := 0;
- end;
- end;
- function TGLSCustomMemo.CharFromPos(X, Y: integer): TFullPos;
- var
- rct: TRect;
- begin
- rct := EditorRect;
- if (FCellSize.H = 0) and Assigned(FFont) then
- SetFont(FFont);
- if (FCellSize.W <> 0) and (FCellSize.H <> 0) then
- begin
- Result.Pos := (X - rct.Left) div FCellSize.W + FLeftCol;
- Result.LineNo := (Y - rct.Top) div FCellSize.H + FTopLine;
- end
- else
- begin
- Result.Pos := 1;
- Result.LineNo := 1;
- end;
- end;
- //--------------------------------------------------------------
- // SET COLOR
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.SetColor(Index: integer; Value: TColor);
- var
- eRect: TRect;
- Changed: Boolean;
- begin
- Changed := False;
- case Index of
- 0: if FBkColor <> Value then
- begin
- FBkColor := Value;
- FStyles.BkColor[0] := Value;
- Changed := True;
- end;
- 1: if FSelColor <> Value then
- begin
- FSelColor := Value;
- Changed := True;
- end;
- 2: if FSelBkColor <> Value then
- begin
- FSelBkColor := Value;
- Changed := True;
- end;
- end;
- if Changed then
- begin
- eRect := EditorRect;
- InvalidateRect(Handle, @eRect, True);
- end;
- end;
- //--------------------------------------------------------------
- // SET FONT
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.SetFont(Value: TFont);
- var
- wW, wi: integer;
- OldFontName: string;
- eRect: TRect;
- begin
- OldFontName := Canvas.Font.Name;
- Canvas.Font.Name := Value.Name;
- wW := Canvas.TextWidth('W');
- wi := Canvas.TextWidth('i');
- Canvas.Font.Name := OldFontName;
- if wW <> wi then
- raise EAbort.Create('Monospace font required');
- FFont.Assign(Value);
- Canvas.Font.Assign(Value);
- FCellSize.W := Canvas.TextWidth('W');
- FCellSize.H := Canvas.TextHeight('W') + 1;
- if FCaretVisible then
- begin
- ShowCaret(False);
- DestroyCaret;
- CreateCaret(Handle, HBITMAP(0), 2, FCellSize.H - 2);
- ShowCaret(true);
- end;
- FStyles.TextColor[0] := FFont.Color;
- FStyles.Style[0] := FFont.Style;
- eRect := EditorRect;
- InvalidateRect(Handle, @eRect, True);
- end;
- //--------------------------------------------------------------
- // SET GUTTER WIDTH
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.SetGutterWidth(Value: integer);
- begin
- FGutterWidth := Value;
- FGutter.FWidth := Value;
- if not (csLoading in ComponentState) then
- ResizeEditor;
- end;
- //--------------------------------------------------------------
- // SET GUTTER COLOR
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.SetGutterColor(Value: TColor);
- begin
- if FGutter.FColor <> Value then
- begin
- FGutter.FColor := Value;
- FGutter.Invalidate;
- end;
- end;
- //--------------------------------------------------------------
- // GET GUTTER COLOR
- //--------------------------------------------------------------
- function TGLSCustomMemo.GetGutterColor: TColor;
- begin
- Result := FGutter.FColor;
- end;
- //--------------------------------------------------------------
- // CHAR STYLE NO
- //--------------------------------------------------------------
- function TGLSCustomMemo.CharStyleNo(LineNo, Pos: integer): integer;
- var
- ChStyle: string;
- begin
- Result := 0;
- if (LineNo < 0) or (LineNo >= Lines.Count) then
- Exit;
- ChStyle := CharAttrs[LineNo];
- if (Pos <= 0) or (Pos > Length(ChStyle)) then
- Exit;
- Result := integer(ChStyle[Pos]);
- end;
- //--------------------------------------------------------------
- // DRAW LINE
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.DrawLine(LineNo: integer);
- var
- eRect, rct0, rct1, rct, lineRct: TRect;
- LineSelStart, LineSelEnd, LineStyleNo, pos: integer;
- S, S1, S2, S3, ChStyle: string;
- //--------- FIND LINE SELECTION -------------
- procedure FindLineSelection;
- var
- len: integer;
- xSelStartX, xSelStartY, xSelEndX, xSelEndY: integer;
- begin
- xSelStartX := FSelStartX;
- xSelStartY := FSelStartY;
- xSelEndX := FSelEndX;
- xSelEndY := FSelEndY;
- OrderPos(xSelStartX, xSelStartY, xSelEndX, xSelEndY);
- len := Length(Lines[LineNo]);
- LineSelStart := 0;
- LineSelEnd := 0;
- if xSelStartY = Lineno then
- begin
- LineSelStart := xSelStartX - FLeftCol;
- LineSelEnd := len - FLeftCol;
- end
- else if (xSelStartY < LineNo) and (LineNo < xSelEndY) then
- begin
- LineSelStart := 0;
- LineSelEnd := len - FLeftCol;
- end;
- if xSelEndY = LineNo then
- LineSelEnd := xSelEndX - FLeftCol;
- if LineSelEnd < LineSelStart then
- Swap(LineSelEnd, LineSelStart);
- if LineSelStart < 0 then
- LineSelStart := 0;
- S := Copy(Lines[LineNo], FLeftCol + 1, len);
- S1 := Copy(S, 1, LineSelStart);
- S2 := Copy(S, LineSelStart + 1, LineSelEnd - LineSelStart);
- S3 := Copy(S, LineSelEnd + 1, len);
- end;
- //------------- DRAW PART ---------------------
- procedure DrawPart(const Part: string; PartStyle, StartPos: integer;
- var rct: TRect; IsSelection: Boolean);
- var
- len, w: integer;
- rctInternal: TRect;
- begin
- len := Length(Part);
- if len > 0 then
- with FLineBitmap.Canvas do
- begin
- w := FCellSize.W * len;
- Font.Style := FStyles.Style[PartStyle];
- if IsSelection then
- begin
- Font.Color := SelColor;
- Brush.Color := SelBkColor;
- end
- else
- begin
- if LineStyleNo = 0 then
- begin
- Font.Color := FStyles.TextColor[PartStyle];
- Brush.Color := FStyles.BkColor[PartStyle];
- end
- else
- begin
- if (LineNo = FSelCharPos.LineNo) and
- (StartPos = FSelCharPos.Pos + 1) and (Length(Part) = 1) then
- begin
- Font.Color := FStyles.TextColor[PartStyle];
- Brush.Color := FStyles.BkColor[PartStyle];
- end
- else
- begin
- Font.Color := FStyles.TextColor[LineStyleNo];
- Brush.Color := FStyles.BkColor[LineStyleNo];
- Font.Style := FStyles.Style[LineStyleNo];
- end;
- end;
- end;
- rct.Right := rct.Left + w;
- rctInternal := rct;
- rctInternal.Left := rctInternal.Left - eRect.Left;
- rctInternal.Right := rctInternal.Right - eRect.Left;
- rctInternal.Top := rctInternal.Top - rct.Top;
- rctInternal.Bottom := rctInternal.Bottom - rct.Top;
- FillRect(rctInternal);
- DrawText(Handle, PChar(Part), len, rctInternal, DT_LEFT
- or DT_SINGLELINE or DT_NOPREFIX);
- rct0.Left := rct.Left + w;
- rct := rct0;
- end;
- end;
- //------------- DRAW SEGMENTS ---------------------
- procedure DrawSegments(S: string; WorkPos: integer;
- var rct: TRect; IsSelection: Boolean);
- var
- i, len, ThisStyle: integer;
- begin
- while True do
- begin
- Len := Length(S);
- if Len = 0 then
- Exit;
- ThisStyle := Ord(ChStyle[WorkPos]);
- i := 1;
- while (i <= Len) and
- (ThisStyle = Ord(ChStyle[WorkPos + i - 1])) do
- Inc(i);
- DrawPart(Copy(S, 1, i - 1), ThisStyle, WorkPos, rct, IsSelection);
- Inc(WorkPos, i - 1);
- s := Copy(s, i, Len);
- end;
- end;
- //---------------------------------------------
- begin
- eRect := EditorRect;
- rct := CellRect(0, LineNo - FTopLine);
- rct0 := Rect(eRect.Left, rct.Top, eRect.Right, rct.Bottom);
- lineRct := rct0;
- if LineNo < Lines.Count then
- begin
- rct := rct0;
- S := Lines[LineNo];
- LineStyleNo := LineStyle[LineNo];
- ChStyle := CharAttrs[LineNo];
- FindLineSelection;
- if not Assigned(FOnGetLineAttrs) then
- ChStyle := StringOfChar(#0, Length(Lines[LineNo]));
- if Length(S) > 0 then
- if (FSelCharStyle >= 0) and (LineNo = FSelCharPos.LineNo) then
- ChStyle[FSelCharPos.Pos + 1] := Char(FSelCharStyle);
- pos := FLeftCol + 1; // 1
- DrawSegments(S1, pos, rct, False);
- Inc(pos, Length(S1));
- DrawSegments(S2, pos, rct, True);
- Inc(pos, Length(S2));
- DrawSegments(S3, pos, rct, False);
- // else begin
- // DrawPart(S1,StyleNo,rct,False);
- // DrawPart(S2,StyleNo,rct,True);
- // DrawPart(S3,StyleNo,rct,False);
- // end;
- rct1 := rct;
- rct1.Left := rct1.Left - eRect.Left;
- rct1.Right := rct1.Right - eRect.Left;
- rct1.Top := rct1.Top - rct.Top;
- rct1.Bottom := rct1.Bottom - rct.Top;
- with FLineBitmap.Canvas do
- begin
- Brush.Color := FStyles.BkColor[LineStyleNo];
- FillRect(rct1);
- end;
- with LineRct do
- BitBlt(Canvas.Handle, Left, Top, Right - Left, Bottom - Top,
- FLineBitmap.Canvas.Handle, 0, 0, SRCCOPY);
- end
- else
- with Canvas do
- begin
- Brush.Color := BkColor;
- FillRect(rct0);
- end;
- end;
- //--------------------------------------------------------------
- // SET HIDDEN CARET
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.SetHiddenCaret(Value: Boolean);
- begin
- if Value <> FHiddenCaret then
- begin
- FHiddenCaret := Value;
- if Focused then
- if FHiddenCaret = FCaretVisible then
- ShowCaret(not FHiddenCaret);
- end;
- end;
- //--------------------------------------------------------------
- // BORDER
- //--------------------------------------------------------------
- procedure Border(Canvas: TCanvas; const rct: TRect; BorderType: TBorderType);
- const
- Colors: array[TBorderType] of array[1..4] of TColor
- = (($D0D0D0, clWhite, clGray, clBlack),
- (clGray, clBlack, $D0D0D0, clWhite),
- (clWhite, clWhite, clWhite, clGray),
- (clGray, clWhite, clWhite, clGray));
- begin
- with Canvas do
- begin
- Pen.Color := Colors[BorderType][1];
- MoveTo(rct.Left, rct.Bottom - 1);
- LineTo(rct.Left, rct.Top);
- LineTo(rct.Right, rct.Top);
- if BorderType in [btRaised, btLowered] then
- begin
- Pen.Color := Colors[BorderType][2];
- MoveTo(rct.Left + 1, rct.Bottom);
- LineTo(rct.Left + 1, rct.Top + 1);
- LineTo(rct.Right, rct.Top + 1);
- Pen.Color := Colors[BorderType][3];
- MoveTo(rct.Left + 1, rct.Bottom - 2);
- LineTo(rct.Right - 2, rct.Bottom - 2);
- LineTo(rct.Right - 2, rct.Top + 1);
- end;
- Pen.Color := Colors[BorderType][4];
- MoveTo(rct.Left, rct.Bottom - 1);
- LineTo(rct.Right - 1, rct.Bottom - 1);
- LineTo(rct.Right - 1, rct.Top);
- end;
- end;
- //--------------------------------------------------------------
- // EDITOR RECT
- //--------------------------------------------------------------
- function TGLSCustomMemo.EditorRect: TRect;
- var
- l, t, r, b: integer;
- begin
- l := 2;
- r := Width - 2;
- t := 2;
- b := Height - 2;
- if GutterWidth > 2 then
- l := l + GutterWidth;
- if FScrollBars in [ssBoth, ssVertical] then
- r := r - FScrollBarWidth;
- if FScrollBars in [ssBoth, ssHorizontal] then
- b := b - FScrollBarWidth;
- Result := Rect(l + FMargin, t, r, b);
- end;
- //--------------------------------------------------------------
- // DRAW MARGIN
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.DrawMargin;
- var
- eRect: TRect;
- i: integer;
- begin
- eRect := EditorRect;
- with Canvas do
- begin
- Pen.Color := clWhite;
- for i := 1 to FMargin do
- begin
- MoveTo(eRect.Left - i, eRect.Top);
- LineTo(eRect.Left - i, eRect.Bottom + 1);
- end;
- end;
- end;
- //--------------------------------------------------------------
- // DRAW GUTTER
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.DrawGutter;
- begin
- if GutterWidth < 2 then
- Exit;
- ResizeGutter;
- FGutter.PaintTo(Canvas);
- end;
- //--------------------------------------------------------------
- // DRAW SCROLLBARS
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.DrawScrollBars;
- begin
- ResizeScrollBars;
- if FScrollBars in [ssBoth, ssVertical] then
- sbVert.PaintTo(Canvas);
- if FScrollBars in [ssBoth, ssHorizontal] then
- sbHorz.PaintTo(Canvas);
- if FScrollBars = ssBoth then
- with Canvas do
- begin
- Brush.Color := clSilver;
- FillRect(Rect(sbVert.Left, sbHorz.Top + 1,
- sbVert.Left + sbVert.Width, sbHorz.Top + sbHorz.Height));
- end;
- end;
- //--------------------------------------------------------------
- // FRESH LINE BITMAP
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.FreshLineBitmap;
- var
- eRect: TRect;
- begin
- eRect := EditorRect;
- with FLineBitmap do
- begin
- Width := eRect.Right - eRect.Left;
- Height := FCellSize.H;
- FLineBitmap.Canvas.Font.Assign(Self.Canvas.Font);
- end;
- end;
- //--------------------------------------------------------------
- // PAINT
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.Paint;
- var
- pTop, pBottom: TFullPos;
- rct, eRect: TRect;
- i: integer;
- clipRgn: HRGN;
- Attrs: string;
- begin
- if TGLSMemoStrings(Lines).FLockCount > 0 then
- Exit;
- with Canvas do
- begin
- if FCellSize.H = 0 then
- SetFont(FFont);
- FreshLineBitmap;
- Border(Canvas, Rect(0, 0, Width, Height), btLowered);
- DrawMargin;
- DrawGutter;
- DrawScrollBars;
- eRect := EditorRect;
- clipRgn := CreateRectRgn(eRect.Left, eRect.Top, eRect.Right, eRect.Bottom);
- ExtSelectClipRgn(Canvas.Handle, clipRgn, RGN_AND);
- DeleteObject(clipRgn);
- rct := Canvas.ClipRect;
- pTop := CharFromPos(rct.Left, rct.Top);
- pBottom := CharFromPos(rct.Left, rct.Bottom);
- if Assigned(FOnGetLineAttrs) then
- for i := 0 to Lines.Count - 1 do
- if not ValidAttrs[i] then
- begin
- FOnGetLineAttrs(Self, i, Attrs);
- CharAttrs[i] := Attrs;
- ValidAttrs[i] := True;
- end;
- for i := pTop.LineNo to pBottom.LineNo do
- DrawLine(i);
- end;
- end;
- //--------------------------------------------------------------
- // GET VISIBLE
- //--------------------------------------------------------------
- function TGLSCustomMemo.GetVisible(Index: integer): integer;
- var
- Coord: TFullPos;
- Cell: TCellPos;
- eRect: TRect;
- begin
- eRect := EditorRect;
- Coord := CharFromPos(eRect.Right - 1, eRect.Bottom - 1);
- Cell := CellFromPos(eRect.Right - 1, eRect.Bottom - 1);
- case Index of
- 0: Result := Cell.X;
- 1: Result := Cell.Y;
- 2: Result := Coord.Pos - 1;
- 3: Result := Coord.LineNo - 1;
- else
- Result := 0;
- end;
- end;
- //--------------------------------------------------------------
- // IS LINE VISIBLE
- //--------------------------------------------------------------
- function TGLSCustomMemo.IsLineVisible(LineNo: integer): Boolean;
- begin
- if FCellSize.H = 0 then
- SetFont(FFont);
- Result := (FTopLine <= LineNo) and (LineNo <= LastVisibleLine + 1);
- end;
- //--------------------------------------------------------------
- // MAKE VISIBLE
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.MakeVisible;
- var
- Modified: Boolean;
- begin
- Modified := False;
- if CurX < FLeftCol then
- begin
- FLeftCol := CurX - 2;
- if FLeftCol < 0 then
- FLeftCol := 0;
- Modified := True;
- end;
- if CurX > LastVisiblePos then
- begin
- if (FScrollBars in [ssBoth, ssHorizontal]) or
- (ScrollMode = smAuto) then
- begin
- FLeftCol := FLeftCol + CurX - LastVisiblePos + 2;
- end
- else
- CurX := LastVisiblePos;
- Modified := True;
- end;
- if CurY < FTopLine then
- begin
- FTopLine := CurY;
- if FTopLine < 0 then
- FTopLine := 0;
- Modified := True;
- end;
- if CurY > LastVisibleLine then
- begin
- if (FScrollBars in [ssBoth, ssVertical]) or
- (ScrollMode = smAuto) then
- begin
- FTopLine := FTopLine + CurY - LastVisibleLine;
- end
- else
- CurY := LastVisibleLine;
- Modified := True;
- end;
- if Modified then
- Invalidate;
- end;
- //--------------------------------------------------------------
- // RESIZE EDITOR
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.ResizeEditor;
- begin
- ResizeScrollBars;
- ResizeGutter;
- MakeVisible;
- Invalidate;
- end;
- //--------------------------------------------------------------
- // FIND TEXT
- //--------------------------------------------------------------
- function TGLSCustomMemo.FindText(Text: string; Options: TFindOptions; Select:
- Boolean): Boolean;
- var
- i, p: integer;
- s1, s0, s: string;
- //-----------------------------------------------------------
- function LastPos(const Substr, s: string): integer;
- var
- i, j, lenSub: integer;
- begin
- Result := 0;
- lenSub := Length(Substr);
- i := Length(s) - lenSub + 1;
- while i > 0 do
- begin
- if s[i] = Substr[1] then
- begin
- Result := i;
- for j := i + 1 to i + lenSub - 1 do
- if s[j] <> Substr[j - i + 1] then
- begin
- Result := 0;
- break;
- end;
- end;
- if Result <> 0 then
- break;
- Dec(i);
- end;
- end;
- //-----------------------------------------------------------
- begin
- Result := False;
- if not (frMatchCase in Options) then
- Text := AnsiLowerCase(Text);
- if SelLength > 0 then
- ClearSelection;
- s := Lines[CurY];
- s0 := Copy(s, 1, CurX);
- s1 := Copy(s, CurX + 1, Length(s));
- i := CurY;
- while True do
- begin
- if not (frMatchCase in Options) then
- begin
- s0 := AnsiLowerCase(s0);
- s1 := AnsiLowerCase(s1);
- end;
- if frDown in Options then
- p := Pos(Text, s1)
- else
- p := LastPos(Text, s0);
- if p > 0 then
- begin
- Result := True;
- CurY := i;
- if frDown in Options then
- CurX := Length(s0) + p - 1
- else
- CurX := p - 1;
- if Select then
- begin
- if not (frDown in Options) then
- CurX := CurX + Length(Text);
- ClearSelection;
- if frDown in Options then
- CurX := CurX + Length(Text)
- else
- CurX := CurX - Length(Text);
- ExpandSelection;
- end;
- break;
- end;
- if frDown in Options then
- Inc(i)
- else
- Dec(i);
- if (i < 0) or (i > Lines.Count - 1) then
- break;
- if frDown in Options then
- begin
- s0 := '';
- s1 := Lines[i];
- end
- else
- begin
- s0 := Lines[i];
- s1 := '';
- end;
- end;
- end;
- //--------------------------------------------------------------
- // RESIZE SCROLLBARS
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.ResizeScrollBars;
- var
- eRect, sbRect: TRect;
- MaxLen, OldMax, NewTop, Margin: integer;
- begin
- eRect := EditorRect;
- if FScrollBars in [ssBoth, ssVertical] then
- begin
- with sbVert do
- begin
- Width := 16;
- Height := eRect.Bottom - eRect.Top + 1;
- Left := eRect.Right;
- Top := eRect.Top;
- OldMax := MaxPosition;
- MaxPosition := (Lines.Count - 1) - (LastVisibleLine - FTopLine);
- NewTop := FTopLine;
- if (FTopLine > 0) and (LastVisibleLine > Lines.Count - 1) then
- begin
- Dec(NewTop, LastVisibleLine - (Lines.Count - 1));
- if NewTop < 0 then
- NewTop := 0;
- MaxPosition := NewTop;
- end;
- if MaxPosition < 0 then
- MaxPosition := 0;
- Position := NewTop;
- Total := Lines.Count;
- if OldMax <> MaxPosition then
- begin
- if NewTop <> FTopLine then
- begin
- DoScroll(sbVert, NewTop - FTopLine);
- FGutter.Invalidate;
- end;
- sbRect := sbVert.FullRect;
- InvalidateRect(Handle, @sbRect, True);
- end;
- end;
- end;
- if FScrollBars in [ssBoth, ssHorizontal] then
- begin
- MaxLen := MaxLength;
- with sbHorz do
- begin
- Width := Self.Width - 4;
- if FScrollBars = ssBoth then
- Width := Width - sbVert.Width;
- Height := 16;
- Left := 2;
- Top := eRect.Bottom;
- OldMax := MaxPosition;
- Margin := LastVisiblePos - MaxLen;
- if Margin < 2 then
- Margin := 2;
- MaxPosition := MaxLen - (LastVisiblePos - FLeftCol) + Margin;
- if MaxPosition < 0 then
- MaxPosition := 0;
- Position := FLeftCol;
- Total := MaxLen;
- if OldMax <> MaxPosition then
- begin
- if MaxPosition = 0 then
- begin
- FLeftCol := 0;
- InvalidateRect(Handle, @eRect, True);
- ;
- FGutter.Invalidate;
- end;
- sbRect := sbHorz.FullRect;
- InvalidateRect(Handle, @sbRect, True);
- end;
- end;
- end;
- end;
- //--------------------------------------------------------------
- // RESIZE GUTTER
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.ResizeGutter;
- var
- eRect: TRect;
- begin
- eRect := EditorRect;
- with FGutter do
- begin
- Height := eRect.Bottom - eRect.Top;
- end;
- end;
- //--------------------------------------------------------------
- // CREATE PARAMS
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.CreateParams(var Params: TCreateParams);
- begin
- inherited;
- end;
- //--------------------------------------------------------------
- // UNDO, REDO
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.Undo;
- begin
- FUndoList.Undo;
- end;
- procedure TGLSCustomMemo.Redo;
- begin
- FUndoList.Redo;
- end;
- //--------------------------------------------------------------
- // SET UNDO LIMIT
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.SetUndoLimit(Value: integer);
- begin
- if (FUndoLimit <> Value) then
- begin
- if Value <= 0 then
- Value := 1;
- if Value > 100 then
- Value := 100;
- FUndoLimit := Value;
- FUndoList.Limit := Value;
- end;
- end;
- //--------------------------------------------------------------
- // UNDO (REDO) CHANGE
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.UndoChange;
- begin
- if Assigned(FOnUndoChange) then
- FOnUndoChange(Self, FUndoList.Pos < FUndoList.Count,
- FUndoList.Pos > 0);
- end;
- //--------------------------------------------------------------
- // CAN UNDO
- //--------------------------------------------------------------
- function TGLSCustomMemo.CanUndo: boolean;
- begin
- Result := FUndoList.FPos < FUndoList.Count;
- end;
- //--------------------------------------------------------------
- // CAN REDO
- //--------------------------------------------------------------
- function TGLSCustomMemo.CanRedo: Boolean;
- begin
- Result := FUndoList.FPos > 0;
- end;
- //--------------------------------------------------------------
- // CLEAR UNDO LIST
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.ClearUndoList;
- begin
- if Assigned(FUndoList) then
- FUndoList.Clear;
- end;
- //--------------------------------------------------------------
- // SET SCROLL BARS
- //--------------------------------------------------------------
- procedure TGLSCustomMemo.SetScrollBars(Value: System.UITypes.TScrollStyle);
- begin
- if FScrollBars <> Value then
- begin
- FScrollBars := Value;
- if not (csLoading in ComponentState) then
- ResizeEditor;
- end;
- end;
- //--------------------------------------------------------------
- // CREATE
- //--------------------------------------------------------------
- constructor TGLSCustomMemo.Create(AOwner: TComponent);
- begin
- inherited;
- ControlStyle := [csCaptureMouse, csClickEvents,
- csDoubleClicks, csReplicatable];
- Width := 100;
- Height := 40;
- TabStop := True;
- Cursor := crIBeam;
- FFont := TFont.Create;
- FFont.Name := 'Courier New';
- FFont.Size := 10;
- Canvas.Font.Assign(FFont);
- FHiddenCaret := False;
- FCaretVisible := False;
- FCurX := 0;
- FCurY := 0;
- FLeftCol := 0;
- FTopLine := 0;
- FTabSize := 4;
- FMargin := 2;
- FAutoIndent := True;
- FLines := TGLSMemoStrings.Create;
- TGLSMemoStrings(FLines).FMemo := Self;
- FScrollBars := ssBoth;
- FScrollBarWidth := 16;
- sbVert := TGLSMemoScrollBar.Create(Self, sbVertical);
- sbVert.Width := FScrollBarWidth;
- sbHorz := TGLSMemoScrollBar.Create(Self, sbHorizontal);
- sbHorz.Height := FScrollBarWidth;
- FGutter := TGLSMemoGutter.Create;
- with FGutter do
- begin
- FLeft := 2;
- FTop := 2;
- FWidth := 0;
- FHeight := 0;
- FColor := clBtnFace;
- FMemo := Self;
- end;
- FSelStartX := 0;
- FSelStartY := 0;
- FSelEndX := 0;
- FSelEndY := 0;
- FBkColor := clWhite;
- FSelColor := clWhite;
- FSelBkColor := clNavy;
- FStyles := TStyleList.Create;
- FStyles.Add(clBlack, clWhite, []);
- FSelCharPos.LineNo := -1;
- FSelCharPos.Pos := -1;
- FSelCharStyle := -1;
- FLineBitmap := TBitmap.Create;
- FLeftButtonDown := False;
- FScrollMode := smAuto;
- FUndoList := TGLSMemoUndoList.Create;
- FFirstUndoList := FUndoList;
- FUndoList.Memo := Self;
- FUndoLimit := 100;
- TGLSMemoStrings(FLines).DoAdd('');
- FAfterDoubleClick := False;
- end;
- //--------------------------------------------------------------
- // DESTROY
- //--------------------------------------------------------------
- destructor TGLSCustomMemo.Destroy;
- begin
- FFont.Free;
- FLines.Free;
- FGutter.Free;
- sbVert.Free;
- sbHorz.Free;
- FStyles.Free;
- FLineBitmap.Free;
- FFirstUndoList.Free;
- inherited;
- end;
-
- // ---------------------TGLSMemoScrollBar functions
- procedure TGLSMemoScrollBar.SetParams(Index: integer; Value: integer);
- begin
- case Index of
- 0: if Left <> Value then
- FLeft := Value;
- 1: if Top <> Value then
- FTop := Value;
- 2: if Width <> Value then
- FWidth := Value;
- 3: if Height <> Value then
- FHeight := Value;
- 4: if Total <> Value then
- FTotal := Value;
- 5: if MaxPosition <> Value then
- FMaxPosition := Value;
- 6: if Position <> Value then
- FPosition := Value;
- end;
- end;
- //-------------------- CREATE ------------------------------
- constructor TGLSMemoScrollBar.Create(AParent: TGLSMemoAbstractScrollableObject;
- AKind: TScrollBarKind);
- begin
- FParent := AParent;
- FButtonLength := 16;
- FKind := AKind;
- FState := sbsWait;
- end;
- //-------------------- RECT -----------------------
- function TGLSMemoScrollBar.GetRect: TRect;
- begin
- Result := Rect(Left, Top, Left + Width, Top + Height);
- end;
- //-------------------- GET THUMB RECT -----------------------
- function TGLSMemoScrollBar.GetThumbRect: TRect;
- var
- TotalLen, FreeLen, ThumbLen, ThumbOffset, ThumbCoord: integer;
- K: double;
- begin
- if MaxPosition <= 0 then
- begin
- Result := Rect(0, 0, 0, 0);
- Exit;
- end;
- if Kind = sbVertical then
- TotalLen := Height
- else
- TotalLen := Width;
- FreeLen := TotalLen - 2 * FButtonLength;
- K := (Total - MaxPosition) / MaxPosition;
- if K > 0 then
- begin
- ThumbLen := round(FreeLen * K / (1 + K));
- if ThumbLen < 8 then
- ThumbLen := 8;
- end
- else
- ThumbLen := 8;
- if ThumbLen >= FreeLen then
- Result := Rect(0, 0, 0, 0)
- else
- begin
- ThumbOffset := round((FreeLen - ThumbLen) * Position / MaxPosition);
- ThumbCoord := FButtonLength + ThumbOffset;
- if Kind = sbVertical then
- Result := Rect(Left + 1, Top + ThumbCoord, Left + Width, Top + ThumbCoord
- + ThumbLen)
- else
- Result := Rect(Left + ThumbCoord, Top + 1, Left + ThumbCoord + ThumbLen,
- Top + Height);
- end;
- end;
- //-------------------- GET Back RECT -----------------------
- function TGLSMemoScrollBar.GetBackRect: TRect;
- begin
- if Kind = sbVertical then
- Result := Rect(Left + 1, Top, Left + Width, Top + FButtonLength)
- else
- Result := Rect(Left, Top + 1, Left + FButtonLength, Top + Height);
- end;
- //-------------------- GET MIDDLE RECT -----------------------
- function TGLSMemoScrollBar.GetMiddleRect: TRect;
- var
- bRect, fRect: TRect;
- begin
- bRect := BackRect;
- fRect := ForwardRect;
- if Kind = sbVertical then
- Result := Rect(Left + 1, bRect.Bottom, Left + Width, fRect.Top)
- else
- Result := Rect(bRect.Right, Top + 1, fRect.Left, Top + Height);
- end;
- //-------------------- GET Forward RECT -----------------------
- function TGLSMemoScrollBar.GetForwardRect: TRect;
- begin
- if Kind = sbVertical then
- Result := Rect(Left + 1, Top + Height - FButtonLength, Left + Width, Top +
- Height)
- else
- Result := Rect(Left + Width - FButtonLength, Top + 1, Left + Width, Top +
- Height);
- end;
- //-------------------- GET PAGE BACK RECT -----------------------
- function TGLSMemoScrollBar.GetPgBackRect: TRect;
- var
- thRect: TRect;
- begin
- thRect := GetThumbRect;
- if thRect.Bottom = 0 then
- begin
- Result := Rect(0, 0, 0, 0);
- Exit;
- end;
- if Kind = sbVertical then
- Result := Rect(Left + 1, Top + FButtonLength, Left + Width, thRect.Top - 1)
- else
- Result := Rect(Left + FButtonLength, Top + 1, thRect.Left - 1, Top +
- Height);
- end;
- //-------------------- GET PG FORWARD RECT -----------------------
- function TGLSMemoScrollBar.GetPgForwardRect: TRect;
- var
- thRect: TRect;
- begin
- thRect := GetThumbRect;
- if thRect.Bottom = 0 then
- begin
- Result := Rect(0, 0, 0, 0);
- Exit;
- end;
- if Kind = sbVertical then
- Result := Rect(Left + 1, thRect.Bottom, Left + Width, Top + Height -
- FButtonLength)
- else
- Result := Rect(thRect.Right, Top + 1, Left + Width - FButtonLength, Top +
- Height);
- end;
- //-------------------- PAINT TO -----------------------
- procedure TGLSMemoScrollBar.PaintTo(ACanvas: TCanvas);
- var
- sRect, mRect, gRect, thRect: TRect;
- iconX, iconY, shift: integer;
- begin
- with ACanvas do
- begin
- if Kind = sbVertical then
- begin
- Pen.Color := clSilver;
- MoveTo(Left, Top);
- LineTo(Left, Top + Height);
- sRect := BackRect;
- Brush.Color := clSilver;
- FillRect(sRect);
- if State = sbsBack then
- begin
- shift := 1;
- Pen.Color := clGray;
- with sRect do
- Rectangle(Left, Top, Right, Bottom);
- end
- else
- begin
- shift := 0;
- Border(ACanvas, sRect, btFlatRaised);
- end;
- iconX := sRect.Left + (Width - 1 - 7) div 2;
- iconY := sRect.Top + (FButtonLength - 8) div 2;
- Draw(iconX + shift, iconY + shift, bmScrollBarUp);
- gRect := ForwardRect;
- Brush.Color := clSilver;
- FillRect(gRect);
- if State = sbsForward then
- begin
- shift := 1;
- Pen.Color := clGray;
- with gRect do
- Rectangle(Left, Top, Right, Bottom);
- end
- else
- begin
- shift := 0;
- Border(ACanvas, gRect, btFlatRaised);
- end;
- iconX := gRect.Left + (Width - 1 - 7) div 2;
- iconY := gRect.Top + (FButtonLength - 8) div 2;
- Draw(iconX + shift, iconY + shift, bmScrollBarDown);
- mRect := Rect(sRect.Left, sRect.Bottom, gRect.Right, gRect.Top);
- end
- else
- begin
- Pen.Color := clSilver;
- MoveTo(Left, Top);
- LineTo(Left + Width, Top);
- sRect := BackRect;
- Brush.Color := clSilver;
- FillRect(sRect);
- if State = sbsBack then
- begin
- shift := 1;
- Pen.Color := clGray;
- with sRect do
- Rectangle(Left, Top, Right, Bottom);
- end
- else
- begin
- shift := 0;
- Border(ACanvas, sRect, btFlatRaised);
- end;
- iconX := sRect.Left + shift + (FButtonLength - 8) div 2;
- iconY := sRect.Top + shift + (Height - 1 - 7) div 2;
- Draw(iconX + shift, iconY + shift, bmScrollBarLeft);
- gRect := ForwardRect;
- Brush.Color := clSilver;
- FillRect(gRect);
- if State = sbsForward then
- begin
- shift := 1;
- Pen.Color := clGray;
- with gRect do
- Rectangle(Left, Top, Right, Bottom);
- end
- else
- begin
- shift := 0;
- Border(ACanvas, gRect, btFlatRaised);
- end;
- iconX := gRect.Left + (FButtonLength - 8) div 2;
- iconY := gRect.Top + (Height - 1 - 7) div 2;
- Draw(iconX + shift, iconY + shift, bmScrollBarRight);
- mRect := Rect(sRect.Right, sRect.Top, gRect.Left, gRect.Bottom);
- end;
- Brush.Bitmap := bmScrollBarFill;
- FillRect(mRect);
- Brush.Bitmap := nil;
- if State = sbsPageBack then
- begin
- Brush.Color := clGray;
- FillRect(PageBackRect);
- end;
- if State = sbsPageForward then
- begin
- Brush.Color := clGray;
- FillRect(PageForwardRect);
- end;
- thRect := ThumbRect;
- Brush.Color := clSilver;
- FillRect(thRect);
- Border(ACanvas, thRect, btFlatRaised);
- end;
- end;
- //-------------------- SET STATE ----------
- procedure TGLSMemoScrollBar.SetState(Value: TsbState);
- begin
- if FState <> Value then
- begin
- FState := Value;
- end;
- end;
- //-------------------- MOUSE DOWN ------------
- function TGLSMemoScrollBar.MouseDown(Button: TMouseButton; Shift: TShiftState;
- X,
- Y: Integer):
- Boolean;
- var
- sRect, gRect, thRect, pbRect, pfRect: TRect;
- begin
- Result := False;
- if (Width = 0) or (Height = 0) then
- Exit;
- sRect := BackRect;
- gRect := ForwardRect;
- pbRect := PageBackRect;
- pfRect := PageForwardRect;
- thRect := ThumbRect;
- if PointInRect(Point(X, Y), sRect) then
- begin
- State := sbsBack;
- InvalidateRect(Parent.Handle, @sRect, True);
- Result := True;
- Exit;
- end;
- if PointInRect(Point(X, Y), gRect) then
- begin
- State := sbsForward;
- InvalidateRect(Parent.Handle, @gRect, True);
- Result := True;
- Exit;
- end;
- if PointInRect(Point(X, Y), pbRect) then
- begin
- State := sbsPageBack;
- InvalidateRect(Parent.Handle, @pbRect, True);
- Result := True;
- Exit;
- end;
- if PointInRect(Point(X, Y), pfRect) then
- begin
- State := sbsPageForward;
- InvalidateRect(Parent.Handle, @pfRect, True);
- Result := True;
- Exit;
- end;
- if PointInRect(Point(X, Y), thRect) then
- begin
- State := sbsDragging;
- FXOffset := X - thRect.Left;
- FYOffset := Y - thRect.Top;
- Result := True;
- Exit;
- end;
- end;
- //-------------------- MOUSE UP ----------
- function TGLSMemoScrollBar.MouseUp(Button: TMouseButton; Shift: TShiftState; X,
- Y:
- Integer):
- Boolean;
- var
- sRect, gRect, thRect, pbRect, pfRect: TRect;
- begin
- Result := False;
- if (Width = 0) or (Height = 0) then
- Exit;
- sRect := BackRect;
- gRect := ForwardRect;
- pbRect := PageBackRect;
- pfRect := PageForwardRect;
- thRect := ThumbRect;
- case State of
- sbsBack:
- begin
- State := sbsWait;
- InvalidateRect(Parent.Handle, @sRect, True);
- FParent.DoScroll(Self, -1);
- Result := True;
- Exit;
- end;
- sbsForward:
- begin
- State := sbsWait;
- InvalidateRect(Parent.Handle, @gRect, True);
- FParent.DoScroll(Self, 1);
- Result := True;
- Exit;
- end;
- sbsPageBack:
- begin
- State := sbsWait;
- InvalidateRect(Parent.Handle, @pbRect, True);
- FParent.DoScrollPage(Self, -1);
- Result := True;
- Exit;
- end;
- sbsPageForward:
- begin
- State := sbsWait;
- InvalidateRect(Parent.Handle, @pfRect, True);
- FParent.DoScrollPage(Self, 1);
- Result := True;
- Exit;
- end;
- sbsDragging:
- begin
- State := sbsWait;
- Result := True;
- Exit;
- end;
- end;
- end;
- //-------------------- MOUSE MOVE -----------
- function TGLSMemoScrollBar.MouseMove(Shift: TShiftState; X, Y: Integer):
- Boolean;
- var
- sRect, gRect, thRect, pbRect, pfRect: TRect;
- begin
- Result := False;
- if (Width = 0) or (Height = 0) then
- Exit;
- sRect := BackRect;
- gRect := ForwardRect;
- pbRect := PageBackRect;
- pfRect := PageForwardRect;
- thRect := ThumbRect;
- case State of
- sbsBack:
- if not PointInRect(Point(X, Y), sRect) then
- begin
- State := sbsWait;
- InvalidateRect(Parent.Handle, @sRect, True);
- Result := True;
- Exit;
- end;
- sbsForward:
- if not PointInRect(Point(X, Y), gRect) then
- begin
- State := sbsWait;
- InvalidateRect(Parent.Handle, @gRect, True);
- Result := True;
- Exit;
- end;
- sbsPageBack:
- if not PointInRect(Point(X, Y), pbRect) then
- begin
- State := sbsWait;
- InvalidateRect(Parent.Handle, @pbRect, True);
- Result := True;
- Exit;
- end;
- sbsPageForward:
- if not PointInRect(Point(X, Y), pfRect) then
- begin
- State := sbsWait;
- InvalidateRect(Parent.Handle, @pfRect, True);
- Result := True;
- Exit;
- end;
- sbsDragging:
- begin
- MoveThumbTo(X, Y);
- Result := True;
- Exit;
- end;
- end;
- end;
- //-------------------- MOVE THUMB TO ------------
- function TGLSMemoScrollBar.MoveThumbTo(X, Y: Integer): integer;
- var
- thRect, mRect: TRect;
- FreeLen, ThumbLen, NewPosition, NewOffset: integer;
- begin
- thRect := ThumbRect;
- mRect := MiddleRect;
- NewOffset := 0;
- FreeLen := 0;
- ThumbLen := 0;
- case Kind of
- sbVertical:
- begin
- FreeLen := mRect.Bottom - mRect.Top;
- ThumbLen := thRect.Bottom - thRect.Top;
- NewOffset := Y - FYOffset - (Top + FButtonLength);
- end;
- sbHorizontal:
- begin
- FreeLen := mRect.Right - mRect.Left;
- ThumbLen := thRect.Right - thRect.Left;
- NewOffset := X - FXOffset - (Left + FButtonLength);
- end
- end;
- NewPosition := round(NewOffset * MaxPosition / (FreeLen - ThumbLen));
- Result := NewPosition - Position;
- if NewPosition <> Position then
- begin
- Parent.DoScroll(Self, NewPosition - Position);
- end;
- end;
- //--------------------------------------------------------------
- // GUTTER
- //--------------------------------------------------------------
- //-------------------- SET PARAMS -----------------------
- procedure TGLSMemoGutter.SetParams(Index: integer; Value: integer);
- begin
- case Index of
- 0: FLeft := Value;
- 1: FTop := Value;
- 2: FWidth := Value;
- 3: FHeight := Value;
- end;
- end;
- //-------------------- PAINT TO -----------------------
- procedure TGLSMemoGutter.PaintTo(ACanvas: TCanvas);
- var
- LineNo, T, H: integer;
- begin
- with ACanvas do
- begin
- Pen.Color := clGray;
- MoveTo(Left + Width - 1, Top);
- LineTo(Left + Width - 1, Top + Height);
- Pen.Color := clWhite;
- MoveTo(Left + Width - 2, Top);
- LineTo(Left + Width - 2, Top + Height);
- Brush.Color := Self.FColor;
- FillRect(Rect(Left, Top, Left + Width - 2, Top + Height));
- if Assigned(FMemo.OnGutterDraw) then
- begin
- T := Top;
- H := FMemo.FCellSize.H;
- LineNo := FMemo.FTopLine;
- while T < Top + Height do
- begin
- FMemo.OnGutterDraw(FMemo, ACanvas, LineNo,
- Rect(Left, T, Left + Width - 2, T + H));
- T := T + H;
- Inc(LineNo);
- if LineNo >= FMemo.Lines.Count then
- break;
- end;
- end;
- end;
- end;
- //-------------------- INVALIDATE -----------------------
- procedure TGLSMemoGutter.Invalidate;
- var
- gRect: TRect;
- begin
- gRect := Rect(Left, Top, Left + Width, Top + Height);
- InvalidateRect(FMemo.Handle, @gRect, True);
- end;
- //-------------------- GET RECT -----------------------
- function TGLSMemoGutter.GetRect: TRect;
- begin
- Result := Rect(Left, Top, Left + Width, Top + Height);
- end;
-
- // ---------------------TStyleList
- procedure TStyleList.CheckRange(Index: integer);
- begin
- if (Index < 0) or (Index >= Count) then
- raise EListError.Create('Incorrect list item index ' + IntToStr(Index));
- end;
- //-------------------- DESTROY ---------------------------
- destructor TStyleList.Destroy;
- begin
- Clear;
- inherited;
- end;
- //-------------------- CHANGE ---------------------------
- procedure TStyleList.Change(Index: integer; ATextColor, ABkCOlor: TColor;
- AStyle: TFontStyles);
- var
- P: TCharStyle;
- begin
- CheckRange(Index);
- P := TCharStyle(Items[Index]);
- P.TextColor := ATextColor;
- P.BkColor := ABkColor;
- P.Style := AStyle;
- end;
- //-------------------- ADD ---------------------------
- function TStyleList.Add(ATextColor, ABkColor: TColor; AStyle: TFontStyles):
- Integer;
- var
- P: TCharStyle;
- begin
- P := TCharStyle.Create;
- with P do
- begin
- TextColor := ATextColor;
- BkColor := ABkColor;
- Style := AStyle;
- end;
- Result := inherited Add(P);
- end;
- //-------------------- CLEAR ---------------------------
- procedure TStyleList.Clear;
- begin
- while Count > 0 do
- Delete(0);
- end;
- //-------------------- DELETE ---------------------------
- procedure TStyleList.Delete(Index: Integer);
- var
- P: TCharStyle;
- begin
- CheckRange(Index);
- P := TCharStyle(Items[Index]);
- P.Free;
- inherited;
- end;
- //-------------------- GET/SET TEXT COLOR ---------------------------
- function TStyleList.GetTextColor(Index: Integer): TColor;
- begin
- CheckRange(Index);
- Result := TCharStyle(Items[Index]).TextColor;
- end;
- procedure TStyleList.SetTextColor(Index: Integer; Value: TColor);
- begin
- CheckRange(Index);
- TCharStyle(Items[Index]).TextColor := Value;
- end;
- //-------------------- GET/SET BK COLOR ---------------------------
- function TStyleList.GetBkColor(Index: Integer): TColor;
- begin
- CheckRange(Index);
- Result := TCharStyle(Items[Index]).BkColor;
- end;
- procedure TStyleList.SetBkColor(Index: Integer; Value: TColor);
- begin
- CheckRange(Index);
- TCharStyle(Items[Index]).BkColor := Value;
- end;
- //-------------------- GET/SET STYLE ---------------------------
- function TStyleList.GetStyle(Index: Integer): TFontStyles;
- begin
- CheckRange(Index);
- Result := TCharStyle(Items[Index]).Style;
- end;
- procedure TStyleList.SetStyle(Index: Integer; Value: TFontStyles);
- begin
- CheckRange(Index);
- TCharStyle(Items[Index]).Style := Value;
- end;
-
- // ---------------------TGLSMemoStrings
- destructor TGLSMemoStrings.Destroy;
- var
- P: TObject;
- begin
- while Count > 0 do
- begin
- P := inherited GetObject(0);
- P.Free;
- inherited Delete(0);
- end;
- inherited;
- end;
- //-------------------- CLEAR ----------------------
- procedure TGLSMemoStrings.Clear;
- begin
- while Count > 0 do
- begin
- Delete(0);
- if (Count = 1) and (Strings[0] = '') then
- break;
- end;
- end;
- //-------------------- ASSIGN ----------------------
- procedure TGLSMemoStrings.Assign(Source: TPersistent);
- var
- P: TObject;
- begin
- if Source is TStrings then
- begin
- BeginUpdate;
- try
- while Count > 0 do
- begin
- P := inherited GetObject(0);
- P.Free;
- inherited Delete(0);
- end;
- // inherited Clear;
- AddStrings(TStrings(Source));
- finally
- EndUpdate;
- end;
- Exit;
- end;
- inherited Assign(Source);
- end;
- //-------------------- ADD ----------------------
- function TGLSMemoStrings.DoAdd(const S: string): Integer;
- begin
- Result := inherited AddObject(S, nil);
- end;
- //-------------------- ADD ----------------------
- function TGLSMemoStrings.Add(const S: string): Integer;
- begin
- if Assigned(FMemo.Parent) then
- Result := FMemo.AddString(S)
- else
- Result := DoAdd(S);
- end;
- //-------------------- OBJECT ----------------------
- function TGLSMemoStrings.AddObject(const S: string; AObject: TObject): Integer;
- begin
- if AObject <> nil then
- raise EInvalidOp.Create(SObjectsNotSupported);
- Result := DoAdd(S);
- end;
- //-------------------- INSERT ----------------------
- procedure TGLSMemoStrings.InsertObject(Index: Integer;
- const S: string; AObject: TObject);
- begin
- if AObject <> nil then
- raise EInvalidOp.Create(SObjectsNotSupported);
- DoInsert(Index, S);
- end;
- //-------------------- DO INSERT ----------------------
- procedure TGLSMemoStrings.DoInsert(Index: Integer; const S: string);
- begin
- InsertItem(Index, S, nil);
- end;
- //-------------------- INSERT ----------------------
- procedure TGLSMemoStrings.Insert(Index: Integer; const S: string);
- begin
- if Assigned(FMemo) then
- FMemo.InsertString(Index, S)
- else
- DoInsert(Index, S);
- end;
- //-------------------- DELETE ----------------------
- procedure TGLSMemoStrings.Delete(Index: Integer);
- var
- P: TObject;
- begin
- if (Index < 0) or (Index > Count - 1) then
- Exit;
- if FDeleting or (not Assigned(FMemo)) then
- begin
- P := inherited GetObject(Index);
- P.Free;
- inherited;
- end
- else
- begin
- FMemo.DeleteLine(Index, -1, -1, -1, -1, True);
- end;
- end;
- //-------------------- LOAD FROM FILE ----------------------
- procedure TGLSMemoStrings.LoadFromFile(const FileName: string);
- begin
- with FMemo do
- begin
- ClearSelection;
- ClearUndoList;
- CurX := 0;
- CurY := 0;
- end;
- Clear;
- inherited;
- FMemo.Invalidate;
- end;
- //-------------------- SET UPDATE STATE ----------------------
- procedure TGLSMemoStrings.SetUpdateState(Updating: Boolean);
- begin
- if Updating then
- Inc(FLockCount)
- else if FLockCount > 0 then
- Dec(FLockCount);
- end;
- //-------------------- CHECK RANGE ---------------------------
- procedure TGLSMemoStrings.CheckRange(Index: integer);
- begin
- if (Index < 0) or (Index >= Count) then
- raise EListError('Incorrect index of list item ' + IntToStr(Index));
- end;
- //-------------------- GET OBJECT ---------------------------
- function TGLSMemoStrings.GetObject(Index: Integer): TObject;
- begin
- CheckRange(Index);
- Result := inherited GetObject(Index);
- if Assigned(Result) and (Result is TLineProp) then
- Result := TLineProp(Result).FObject;
- end;
- //-------------------- PUT OBJECT ---------------------------
- procedure TGLSMemoStrings.PutObject(Index: Integer; AObject: TObject);
- var
- P: TObject;
- begin
- CheckRange(Index);
- P := Objects[Index];
- if Assigned(P) and (P is TLineProp) then
- TLineProp(P).FObject := AObject
- else
- inherited PutObject(Index, AObject);
- end;
- //-------------------- GET LINE PROP ---------------------------
- function TGLSMemoStrings.GetLineProp(Index: integer): TLineProp;
- var
- P: TObject;
- begin
- CheckRange(Index);
- Result := nil;
- P := inherited GetObject(Index);
- if Assigned(P) and (P is TLineProp) then
- Result := TLineProp(P);
- end;
- //-------------------- CREATE PROP --------------------------
- function TGLSMemoStrings.CreateProp(Index: integer): TLineProp;
- begin
- Result := TLineProp.Create;
- with Result do
- begin
- FStyleNo := 0;
- FInComment := False;
- FInBrackets := -1;
- FValidAttrs := False;
- FCharAttrs := '';
- FObject := Objects[Index];
- end;
- inherited PutObject(Index, Result);
- end;
- //-------------------- GET LINE STYLE --------------------------
- function TGLSMemoStrings.GetLineStyle(Index: integer): integer;
- var
- P: TLineProp;
- begin
- P := LineProp[Index];
- if P = nil then
- Result := 0
- else
- Result := P.FStyleNo;
- end;
- //-------------------- SET LINE STYLE --------------------------
- procedure TGLSMemoStrings.SetLineStyle(Index: integer; Value: integer);
- var
- P: TLineProp;
- begin
- P := LineProp[Index];
- if P = nil then
- P := CreateProp(Index);
- P.FStyleNo := Value;
- end;
- //-------------------- GET/SET IN COMMENT ---------------------------
- function TGLSMemoStrings.GetInComment(Index: Integer): Boolean;
- var
- P: TLineProp;
- begin
- P := LineProp[Index];
- if P = nil then
- Result := False
- else
- Result := P.FInComment;
- end;
- procedure TGLSMemoStrings.SetInComment(Index: Integer; Value: Boolean);
- var
- P: TLineProp;
- begin
- P := LineProp[Index];
- if P = nil then
- P := CreateProp(Index);
- P.FInComment := Value;
- end;
- //-------------------- GET/SET IN BRACKETS ---------------------------
- function TGLSMemoStrings.GetInBrackets(Index: Integer): integer;
- var
- P: TLineProp;
- begin
- P := LineProp[Index];
- if P = nil then
- Result := -1
- else
- Result := P.FInBrackets;
- end;
- procedure TGLSMemoStrings.SetInBrackets(Index: Integer; Value: integer);
- var
- P: TLineProp;
- begin
- P := LineProp[Index];
- if P = nil then
- P := CreateProp(Index);
- P.FInBrackets := Value;
- end;
- //-------------------- GET/SET VALID ATTRS ---------------------------
- function TGLSMemoStrings.GetValidAttrs(Index: Integer): Boolean;
- var
- P: TLineProp;
- begin
- P := LineProp[Index];
- if P = nil then
- Result := False
- else
- Result := P.FValidAttrs;
- end;
- procedure TGLSMemoStrings.SetValidAttrs(Index: Integer; Value: Boolean);
- var
- P: TLineProp;
- begin
- P := LineProp[Index];
- if P = nil then
- P := CreateProp(Index);
- P.FValidAttrs := Value;
- end;
- //-------------------- GET/SET CHAR ATTRS ---------------------------
- function TGLSMemoStrings.GetCharAttrs(Index: Integer): string;
- var
- P: TLineProp;
- begin
- P := LineProp[Index];
- if P = nil then
- Result := ''
- else
- Result := P.FCharAttrs;
- end;
- procedure TGLSMemoStrings.SetCharAttrs(Index: Integer; const Value: string);
- var
- P: TLineProp;
- begin
- P := LineProp[Index];
- if P = nil then
- P := CreateProp(Index);
- P.FCharAttrs := Value;
- end;
-
- // ---------------------TGLSMemoUndo
- constructor TGLSMemoUndo.Create(ACurX0, ACurY0, ACurX, ACurY: integer; const AText:
- string);
- begin
- inherited Create;
- FUndoCurX0 := ACurX0;
- FUndoCurY0 := ACurY0;
- FUndoCurX := ACurX;
- FUndoCurY := ACurY;
- FUndoText := AText;
- end;
- procedure TGLSMemoUndo.Undo;
- begin
- if Assigned(FMemo) then
- with FMemo do
- begin
- CurY := FUndoCurY;
- CurX := FUndoCurX;
- PerformUndo;
- CurY := FUndoCurY0;
- CurX := FUndoCurX0;
- end;
- end;
- procedure TGLSMemoUndo.Redo;
- begin
- if Assigned(FMemo) then
- with FMemo do
- begin
- CurY := FUndoCurY0;
- CurX := FUndoCurX0;
- PerformRedo;
- CurY := FUndoCurY;
- CurX := FUndoCurX;
- end;
- end;
- function TGLSMemoUndo.Append(NewUndo: TGLSMemoUndo): Boolean;
- begin
- Result := False;
- end;
- //---------------- TINSERT CHAR UNDO --------------------------
- procedure TGLSMemoInsCharUndo.PerformUndo;
- var
- i: integer;
- CurrLine: string;
- begin
- for i := Length(FUndoText) downto 1 do
- begin
- CurrLine := FMemo.Lines[FMemo.CurY];
- if ((FUndoText[i] = #13) and (FMemo.CurX = 0)) or
- (FUndoText[i] = CurrLine[FMemo.CurX]) then
- FMemo.BackSpace;
- end;
- end;
- procedure TGLSMemoInsCharUndo.PerformRedo;
- var
- i: integer;
- begin
- with FMemo do
- for i := 1 to Length(FUndoText) do
- if FUndoText[i] = #13 then
- NewLine
- else
- InsertChar(FUndoText[i]);
- end;
- function TGLSMemoInsCharUndo.Append(NewUndo: TGLSMemoUndo): Boolean;
- begin
- Result := False;
- if not ((NewUndo is TGLSMemoInsCharUndo) and
- (NewUndo.UndoCurX0 = FUndoCurX) and
- (NewUndo.UndoCurY0 = FUndoCurY)) then
- Exit;
- FUndoText := FUndoText + NewUndo.FUndoText;
- FUndoCurX := NewUndo.UndoCurX;
- FUndoCurY := NewUndo.UndoCurY;
- Result := True;
- end;
- //---------------- TDELETE CHAR UNDO --------------------------
- procedure TGLSMemoDelCharUndo.PerformUndo;
- var
- i: integer;
- begin
- with FMemo do
- for i := 1 to Length(FUndoText) do
- begin
- if not FIsBackspace then
- begin
- CurY := FUndoCurY0;
- CurX := FUndoCurX0;
- end;
- if FUndoText[i] = #13 then
- NewLine
- else
- InsertChar(FUndoText[i]);
- end;
- end;
- procedure TGLSMemoDelCharUndo.PerformRedo;
- var
- i: integer;
- begin
- with FMemo do
- for i := 1 to Length(FUndoText) do
- if FIsBackspace then
- BackSpace
- else
- DeleteChar(-1, -1);
- end;
- function TGLSMemoDelCharUndo.Append(NewUndo: TGLSMemoUndo): Boolean;
- begin
- Result := False;
- if not ((NewUndo is TGLSMemoDelCharUndo) and
- (NewUndo.UndoCurX0 = FUndoCurX) and
- (NewUndo.UndoCurY0 = FUndoCurY)) then
- Exit;
- if TGLSMemoDelCharUndo(NewUndo).FIsBackspace <> FIsBackspace then
- Exit;
- FUndoText := NewUndo.FUndoText + FUndoText;
- FUndoCurX := NewUndo.UndoCurX;
- FUndoCurY := NewUndo.UndoCurY;
- Result := True;
- end;
- //---------------- TDELETE BUF, LINE UNDO --------------------------
- constructor TGLSMemoDelLineUndo.Create(AIndex, ACurX0, ACurY0, ACurX, ACurY:
- integer; const AText: string);
- begin
- inherited Create(ACurX0, ACurY0, ACurX, ACurY, AText);
- FIndex := AIndex;
- end;
- procedure TGLSMemoDelLineUndo.PerformUndo;
- var
- SaveCurX: integer;
- begin
- with FMemo do
- begin
- SaveCurX := CurX;
- CurX := 0;
- ClearSelection;
- SetSelText(PChar(FUndoText + #13#10));
- CurX := SaveCurX;
- end;
- end;
- procedure TGLSMemoDelLineUndo.PerformRedo;
- begin
- FMemo.DeleteLine(FIndex, FUndoCurX0, FUndoCurY0, FUndoCurX, FUndoCurY, True);
- end;
- procedure TGLSMemoDeleteBufUndo.PerformUndo;
- begin
- with FMemo do
- begin
- ClearSelection;
- SetSelText(PChar(FUndoText));
- end;
- end;
- procedure TGLSMemoDeleteBufUndo.PerformRedo;
- begin
- with FMemo do
- begin
- FSelStartX := FUndoSelStartX;
- FSelStartY := FUndoSelStartY;
- FSelEndX := FUndoSelEndX;
- FSelEndY := FUndoSelEndY;
- DeleteSelection(True);
- end;
- end;
- //---------------- TPASTE UNDO --------------------------
- procedure TGLSMemoPasteUndo.PerformUndo;
- begin
- with FMemo do
- begin
- FSelStartX := FUndoCurX0;
- FSelStartY := FUndoCurY0;
- FSelEndX := FUndoCurX;
- FSelEndY := FUndoCurY;
- DeleteSelection(True);
- end;
- end;
- procedure TGLSMemoPasteUndo.PerformRedo;
- begin
- with FMemo do
- begin
- ClearSelection;
- SetSelText(PChar(FUndoText));
- end;
- end;
- //---------------- TUNDO LIST --------------------------
- constructor TGLSMemoUndoList.Create;
- begin
- inherited;
- FPos := 0;
- FIsPerforming := False;
- FLimit := 100;
- end;
- destructor TGLSMemoUndoList.Destroy;
- begin
- Clear;
- inherited;
- end;
- function TGLSMemoUndoList.Get(Index: Integer): TGLSMemoUndo;
- begin
- Result := TGLSMemoUndo(inherited Get(Index));
- end;
- function TGLSMemoUndoList.Add(Item: Pointer): Integer;
- begin
- Result := -1;
- if FIsPerforming then
- begin
- TGLSMemoUndo(Item).Free;
- Exit;
- end;
- if (Count > 0) and
- Items[0].Append(TGLSMemoUndo(Item)) then
- begin
- TGLSMemoUndo(Item).Free;
- Exit;
- end;
- TGLSMemoUndo(Item).FMemo := Self.FMemo;
- if FPos > 0 then
- while FPos > 0 do
- begin
- Delete(0);
- Dec(FPos);
- end;
- Insert(0, Item);
- if Count > FLimit then
- Delete(Count - 1);
- Memo.UndoChange;
- Result := 0;
- end;
- procedure TGLSMemoUndoList.Clear;
- begin
- while Count > 0 do
- Delete(0);
- FPos := 0;
- with Memo do
- if not (csDestroying in ComponentState) then
- UndoChange;
- end;
- procedure TGLSMemoUndoList.Delete(Index: Integer);
- begin
- TGLSMemoUndo(Items[Index]).Free;
- inherited;
- end;
- procedure TGLSMemoUndoList.Undo;
- var
- OldAutoIndent: Boolean;
- begin
- if FPos < Count then
- begin
- OldAutoIndent := Memo.AutoIndent;
- Memo.AutoIndent := False;
- FIsPerforming := True;
- Items[FPos].Undo;
- Inc(FPos);
- FIsPerforming := False;
- Memo.AutoIndent := OldAutoIndent;
- Memo.UndoChange;
- end;
- end;
- procedure TGLSMemoUndoList.Redo;
- var
- OldAutoIndent: Boolean;
- begin
- if FPos > 0 then
- begin
- OldAutoIndent := Memo.AutoIndent;
- Memo.AutoIndent := False;
- FIsPerforming := True;
- Dec(FPos);
- Items[FPos].Redo;
- FIsPerforming := False;
- Memo.AutoIndent := OldAutoIndent;
- Memo.UndoChange;
- end;
- end;
- procedure TGLSMemoUndoList.SetLimit(Value: integer);
- begin
- if FLimit <> Value then
- begin
- if Value <= 0 then
- Value := 10;
- if Value > 0 then
- Value := 100;
- FLimit := Value;
- Clear;
- end;
- end;
- procedure TGLSSynHiMemo.Paint;
- begin
- FIsPainting := True;
- try
- DelimiterStyle := FDelimiterStyle;
- CommentStyle := FCommentStyle;
- NumberStyle := FNumberStyle;
- inherited;
- finally
- FIsPainting := False;
- end;
- end;
-
- // ---------------------TGLSSynHiMemo
- procedure TGLSSynHiMemo.SetStyle(Index: integer; Value: TCharStyle);
- var
- No: integer;
- eRect: TRect;
- begin
- No := -1;
- case Index of
- 0: No := FDelimiterStyleNo;
- 1: No := FCommentStyleNo;
- 2: No := FNumberStyleNo;
- end;
- with Value do
- Styles.Change(No, TextColor, BkColor, Style);
- if not FIsPainting then
- begin
- eRect := EditorRect;
- InvalidateRect(Handle, @eRect, True);
- end;
- end;
- //--------------------------------------------------------------
- // SYNTAX MEMO - SET WORD LIST
- //--------------------------------------------------------------
- procedure TGLSSynHiMemo.SetWordList(Value: TGLSMemoStringList);
- begin
- FWordList.Assign(Value);
- end;
- procedure TGLSSynHiMemo.SetSpecialList(Value: TGLSMemoStringList);
- begin
- FSpecialList.Assign(Value);
- end;
- procedure TGLSSynHiMemo.SetBracketList(Value: TGLSMemoStringList);
- begin
- FBracketList.Assign(Value);
- end;
- //--------------------------------------------------------------
- // SYNTAX MEMO - SET CASE SENSITIVE
- //--------------------------------------------------------------
- procedure TGLSSynHiMemo.SetCaseSensitive(Value: Boolean);
- var
- LineNo: integer;
- begin
- if Value <> FCaseSensitive then
- begin
- FCaseSensitive := Value;
- for LineNo := 0 to Lines.Count - 1 do
- ValidAttrs[LineNo] := False;
- Invalidate;
- end;
- end;
- //--------------------------------------------------------------
- // SYNTAX MEMO - GET TOKEN
- //--------------------------------------------------------------
- function TGLSSynHiMemo.GetToken(const S: string; var From: integer;
- out TokenType: TTokenType; out StyleNo: integer): string;
- var
- i, toStart, toEnd, Len, LenSpec: integer;
- Done: Boolean;
- Brackets: string;
- IntPart: integer;
- WasPoint: Boolean;
- //-------------------------------------------------------------
- function StartsFrom(const S: string; Pos: integer; const S0: string): Boolean;
- begin
- Result := (StrLComp(PChar(S) + Pos - 1, PChar(S0), Length(S0)) = 0);
- end;
- //-------------------------------------------------------------
- function Equal(const s1, s2: string): Boolean;
- begin
- if FCaseSensitive then
- Result := s1 = s2
- else
- Result := AnsiLowerCase(s1) = AnsiLowerCase(s2);
- end;
- begin
- toStart := From;
- toEnd := From;
- TokenType := ttOther;
- StyleNo := 0;
- Len := Length(S);
- // End of line
- if From > Len then
- begin
- From := -1;
- Result := '';
- TokenType := ttEOL;
- StyleNo := 0;
- Exit;
- end;
- // Begin of multiline comment
- if (MultiCommentLeft <> '') and (MultiCommentRight <> '') and
- StartsFrom(S, From, MultiCommentLeft) then
- begin
- Result := MultiCommentLeft;
- FInComment := True;
- TokenType := ttComment;
- StyleNo := FCommentStyleNo;
- Inc(From, Length(MultiCommentLeft));
- Exit;
- end;
- // Inside multiline comment
- if FInComment then
- begin
- toEnd := toStart;
- while (toEnd <= Len) and (not StartsFrom(S, toEnd, MultiCommentRight)) do
- Inc(toEnd);
- if toEnd > Len then
- begin
- Result := Copy(S, From, toEnd - From);
- From := toEnd;
- end
- else
- begin
- FInComment := False;
- toEnd := toEnd + Length(MultiCommentRight);
- Result := Copy(S, From, toEnd - From);
- From := toEnd;
- end;
- TokenType := ttComment;
- StyleNo := FCommentStyleNo;
- Exit;
- end;
- // Inside brikets
- if FInBrackets >= 0 then
- begin
- Brackets := FBracketList[FInBrackets];
- toEnd := toStart + 1;
- while (toEnd <= Len) and (S[toEnd] <> Brackets[2]) do
- Inc(toEnd);
- StyleNo := integer(FBracketList.Objects[FInBrackets]);
- if toEnd <= Len then
- begin
- FInBrackets := -1;
- From := toEnd + 1;
- end
- else
- From := toEnd;
- Result := Copy(S, toStart, toEnd - toStart + 1);
- TokenType := ttBracket;
- Exit;
- end;
- // Spaces
- while (toStart <= Len) and (S[toStart] = ' ') do
- Inc(toStart);
- if toStart > From then
- begin
- Result := Copy(S, From, toStart - From);
- From := toStart;
- TokenType := ttSpace;
- StyleNo := 0;
- Exit;
- end;
- // Comment
- if (FLineComment <> '') and StartsFrom(S, From, FLineComment) then
- begin
- Result := Copy(S, From, Len);
- From := Len + 1;
- TokenType := ttComment;
- StyleNo := FCommentStyleNo;
- Exit;
- end;
- // Special keyword
- Done := False;
- for i := 0 to FSpecialList.Count - 1 do
- begin
- LenSpec := Length(FSpecialList[i]);
- if StrLComp(PChar(S) + toStart - 1,
- PChar(FSpecialList[i]), LenSpec) = 0 then
- begin
- toEnd := toStart + LenSpec - 1;
- StyleNo := integer(FSpecialList.Objects[i]);
- TokenType := ttSpecial;
- From := toEnd + 1;
- Done := True;
- break;
- end;
- end;
- // Brickets
- if not Done then
- begin
- for i := 0 to FBracketList.Count - 1 do
- begin
- Brackets := FBracketList[i];
- if S[toStart] = Brackets[1] then
- begin
- FInBrackets := i;
- toEnd := toStart + 1;
- while (toEnd <= Len) and (S[toEnd] <> Brackets[2]) do
- Inc(toEnd);
- if toEnd <= Len then
- FInBrackets := -1
- else
- Dec(toEnd);
- StyleNo := integer(FBracketList.Objects[i]);
- TokenType := ttBracket;
- Done := True;
- break;
- end;
- end;
- end;
- // Delimeters
- if not Done and CharInSet(S[toStart], Delimiters) then
- begin
- toEnd := toStart;
- StyleNo := FDelimiterStyleNo;
- TokenType := ttDelimiter;
- Done := True;
- end;
- // --- Integer or float type
- if not Done and CharInSet(S[toStart], ['0'..'9', '.']) then
- begin
- IntPart := 0;
- WasPoint := False;
- toEnd := toStart;
- Done := True;
- TokenType := ttInteger;
- StyleNo := FNumberStyleNo;
- while (toEnd <= Len) and CharInSet(S[toEnd], ['0'..'9', '.']) do
- begin
- if S[toEnd] = '.' then
- begin
- if not WasPoint then
- begin
- WasPoint := True;
- TokenType := ttFloat;
- end
- else
- begin
- TokenType := ttWrongNumber;
- Color := clRed;
- end;
- end
- else if not WasPoint then
- try
- IntPart := IntPart * 10 + Ord(S[toEnd]) - Ord('0');
- except
- IntPart := MaxInt;
- end;
- Inc(toEnd);
- end;
- Dec(toEnd);
- end;
- // Select word
- if not Done then
- begin
- toEnd := toStart;
- while (toEnd <= Len) and not CharInSet(S[toEnd], Delimiters) do
- Inc(toEnd);
- Dec(toEnd);
- end;
- // Find in dictionary
- Result := Copy(S, toStart, toEnd - toStart + 1);
- for i := 0 to FWordList.Count - 1 do
- if Equal(Result, FWordList[i]) then
- begin
- StyleNo := integer(FWordList.Objects[i]);
- TokenType := ttWord;
- break;
- end;
- From := toEnd + 1;
- end;
- //--------------------------------------------------------------
- // SYNTAX MEMO - FIND LINE ATTRS
- //--------------------------------------------------------------
- procedure TGLSSynHiMemo.FindLineAttrs(Sender: TObject; LineNo: integer;
- var Attrs: string);
- var
- i, From, TokenLen: integer;
- S, Token: string;
- TokenType: TTokenType;
- StyleNo, OldInBrackets: integer;
- OldInComment: Boolean;
- begin
- S := Lines[LineNo];
- SetLength(Attrs, Length(S));
- FInComment := InComment[LineNo];
- FInBrackets := InBrackets[LineNo];
- From := 1;
- while True do
- begin
- Token := GetToken(S, From, TokenType, StyleNo);
- if TokenType = ttEOL then
- break;
- TokenLen := Length(Token);
- for i := From - TokenLen to From - 1 do
- Attrs[i] := Char(StyleNo);
- end;
- if LineNo < Lines.Count - 1 then
- begin
- OldInComment := InComment[LineNo + 1];
- OldInBrackets := InBrackets[LineNo + 1];
- if OldInComment <> FInComment then
- begin
- InComment[LineNo + 1] := FInComment;
- ValidAttrs[LineNo + 1] := False;
- end;
- if OldInBrackets <> FInBrackets then
- begin
- InBrackets[LineNo + 1] := FInBrackets;
- ValidAttrs[LineNo + 1] := False;
- end;
- end;
- end;
- //--------------------------------------------------------------
- // SYNTAX MEMO - ADD WORD
- //--------------------------------------------------------------
- procedure TGLSSynHiMemo.AddWord(StyleNo: integer; const ArrS: array of string);
- var
- i: integer;
- begin
- for i := Low(ArrS) to high(ArrS) do
- FWordList.AddObject(ArrS[i], TObject(StyleNo));
- end;
- //--------------------------------------------------------------
- // SYNTAX MEMO - ADD SPECIAL
- //--------------------------------------------------------------
- procedure TGLSSynHiMemo.AddSpecial(StyleNo: integer; const ArrS: array of string);
- var
- i: integer;
- begin
- for i := Low(ArrS) to high(ArrS) do
- FSpecialList.AddObject(ArrS[i], TObject(StyleNo));
- end;
- //--------------------------------------------------------------
- // SYNTAX MEMO - ADD BRACKETS
- //--------------------------------------------------------------
- procedure TGLSSynHiMemo.AddBrackets(StyleNo: integer; const ArrS: array of string);
- var
- i: integer;
- begin
- for i := Low(ArrS) to high(ArrS) do
- FBracketList.AddObject(ArrS[i], TObject(StyleNo));
- end;
- //--------------------------------------------------------------
- // SYNTAX MEMO - CREATE
- //--------------------------------------------------------------
- constructor TGLSSynHiMemo.Create(AOwner: TComponent);
- begin
- inherited;
- FInBrackets := -1;
- FIsPainting := False;
- FInComment := False;
- FWordList := TGLSMemoStringList.Create;
- FSpecialList := TGLSMemoStringList.Create;
- FBracketList := TGLSMemoStringList.Create;
- FDelimiterStyle := TCharStyle.Create;
- with FDelimiterStyle do
- begin
- TextColor := clBlue;
- BkColor := clWhite;
- Style := [];
- end;
- FCommentStyle := TCharStyle.Create;
- with FCommentStyle do
- begin
- TextColor := clYellow;
- BkColor := clSkyBlue;
- Style := [fsItalic];
- end;
- FNumberStyle := TCharStyle.Create;
- with FNumberStyle do
- begin
- TextColor := clNavy;
- BkColor := clWhite;
- Style := [fsBold];
- end;
- FDelimiterStyleNo := Styles.Add(clBlue, clWhite, []);
- FCommentStyleNo := Styles.Add(clSilver, clWhite, [fsItalic]);
- FNumberStyleNo := Styles.Add(clNavy, clWhite, [fsBold]);
- OnGetLineAttrs := FindLineAttrs;
- Delimiters := [' ', ',', ';', ':', '.', '(', ')', '{', '}', '[', ']',
- '=', '+', '-', '*', '/', '^', '%', '<', '>',
- '"', '''', #13, #10];
- end;
- //--------------------------------------------------------------
- // SYNTAX MEMO - DESTROY
- //--------------------------------------------------------------
- destructor TGLSSynHiMemo.Destroy;
- begin
- FWordList.Free;
- FSpecialList.Free;
- FBracketList.Free;
- FDelimiterStyle.Free;
- FCommentStyle.Free;
- FNumberStyle.Free;
- inherited;
- end;
- // ---------------------TGLSMemoStringList
- procedure TGLSMemoStringList.ReadStrings(Reader: TReader);
- var
- i: Integer;
- begin
- try
- Reader.ReadListBegin;
- Clear;
- while not Reader.EndOfList do
- begin
- i := Add(Reader.ReadString);
- Objects[i] := TObject(Reader.ReadInteger);
- end;
- Reader.ReadListEnd;
- finally
- end;
- end;
- //--------------------------------------------------------------
- // STRING LIST - WRITE STRINGS
- //--------------------------------------------------------------
- procedure TGLSMemoStringList.WriteStrings(Writer: TWriter);
- var
- i: Integer;
- begin
- with Writer do
- begin
- WriteListBegin;
- for i := 0 to Count - 1 do
- begin
- WriteString(Strings[i]);
- WriteInteger(Integer(Objects[i]));
- end;
- WriteListEnd;
- end;
- end;
- //--------------------------------------------------------------
- // STRING LIST - DEFINE PROPERTIES
- //--------------------------------------------------------------
- procedure TGLSMemoStringList.DefineProperties(Filer: TFiler);
- begin
- Filer.DefineProperty('Strings', ReadStrings, WriteStrings, Count > 0);
- end;
-
- // ---------------------ScrollBar bitmaps
- procedure CreateScrollBarBitmaps;
- var
- i, j: integer;
- begin
- bmScrollBarFill := TBitmap.Create;
- with bmScrollBarFill, Canvas do
- begin
- Width := 8;
- Height := 8;
- Transparent := False;
- for i := 0 to 7 do
- for j := 0 to 7 do
- if Odd(i + j) then
- Pixels[i, j] := clSilver;
- end;
- bmScrollBarUp := TBitmap.Create;
- with bmScrollBarUp, Canvas do
- begin
- Width := 7;
- Height := 8;
- Brush.Color := clSilver;
- FillRect(Rect(0, 0, Width, Height));
- Pixels[3, 2] := clBlack;
- MoveTo(2, 3);
- LineTo(5, 3);
- MoveTo(1, 4);
- LineTo(6, 4);
- MoveTo(0, 5);
- LineTo(7, 5);
- end;
- bmScrollBarDown := TBitmap.Create;
- with bmScrollBarDown, Canvas do
- begin
- Width := 7;
- Height := 8;
- Brush.Color := clSilver;
- FillRect(Rect(0, 0, Width, Height));
- MoveTo(0, 2);
- LineTo(7, 2);
- MoveTo(1, 3);
- LineTo(6, 3);
- MoveTo(2, 4);
- LineTo(5, 4);
- Pixels[3, 5] := clBlack;
- end;
- bmScrollBarLeft := TBitmap.Create;
- with bmScrollBarLeft, Canvas do
- begin
- Width := 8;
- Height := 7;
- Brush.Color := clSilver;
- FillRect(Rect(0, 0, Width, Height));
- Pixels[2, 3] := clBlack;
- MoveTo(3, 2);
- LineTo(3, 5);
- MoveTo(4, 1);
- LineTo(4, 6);
- MoveTo(5, 0);
- LineTo(5, 7);
- end;
- bmScrollBarRight := TBitmap.Create;
- with bmScrollBarRight, Canvas do
- begin
- Width := 8;
- Height := 7;
- Brush.Color := clSilver;
- FillRect(Rect(0, 0, Width, Height));
- MoveTo(2, 0);
- LineTo(2, 7);
- MoveTo(3, 1);
- LineTo(3, 6);
- MoveTo(4, 2);
- LineTo(4, 5);
- Pixels[5, 3] := clBlack;
- end;
- end;
- //------------------ FREE SCROLL BAR BITMAPs -------------------
- procedure FreeScrollBarBitmaps;
- begin
- bmScrollBarFill.Free;
- bmScrollBarUp.Free;
- bmScrollBarDown.Free;
- bmScrollBarLeft.Free;
- bmScrollBarRight.Free;
- end;
- //----------------------------------
- initialization
- //----------------------------------
- RegisterClasses([TGLSSynHiMemo]);
- CreateScrollBarBitmaps;
- IntelliMouseInit;
- //----------------------------------
- finalization
- //----------------------------------
- FreeScrollBarBitmaps;
- end.
|