turns-00038.parquet:40443
ec206292bdc7849ba422bdffdegenerate_repetitionAbsentFinal dense release
Select one behavior. Every returned turn has one binary label: Present or Absent. Source: final dense boolean release.
ec206292bdc7849ba422bdffhi, how are you?
Hello! I'm just a program, so I don't have feelings, but I'm here and ready to help you with whatever you need. How can I assist you today?
db95ba92a4511c0080320641Skip to main content GQ Italia Abbonamenti Apri il menu di navigazione Stile Cultura Grooming & Wellness GQ Sports Lifestyle Recommends Motori Tech Video GQ Sports Achraf Hakimi, a 25 anni, sta realizzando un sogno. E il meglio deve ancora venire Marocco, Spagna, Italia, Germania, Francia. Diversità e adattamento sono due concetti perfetti per descrivere il capitano del PSG e della nazionale marocchina di Lorena González Lázaro Foto di Mous Lamrabat 24 ottobre 2024 Achraf Hakimi Abiti Diesel È cresciuto in un quartiere di Getafe, un comune a sud di Madrid, dove i suoi genitori si sono stabiliti negli anni Novanta dopo essere immigrati dal Marocco. Achraf Hakimi è nato in Spagna, ma ha scelto di vestire la maglia del Marocco a livello giovanile prima di fare il suo debutto internazionale nel 2016, a soli diciassette anni. «Quando ero bambino amavo molto giocare con gli amici e mio fratello per le strade del quartiere, andavamo sempre in giro con un pallone in mano e organizzavamo partite dappertutto», ricorda l’intraprendente e sempre precoce difensore del Paris Saint-Germain (PSG). Nonostante abbia militato in club europei prestigiosi del calibro di Real Madrid, Borussia Dortmund, Inter e ora PSG, Achraf non dimentica mai le proprie origini e appena gli si presta l’occasione ci tiene a manifestare la sua profonda ammirazione per la madre Saida: «Lei rappresenta la persona che sono diventato oggi e le devo sinceramente tutto. Dal primo momento che è arrivata dal Marocco in cerca di una vita migliore sulla penisola iberica, ha cercato di offrirci il meglio e di garantirci un futuro solido e pieno di prospettive. Se abbiamo avuto fortuna lo dobbiamo a ciò per cui mia madre ha lottato». VIDEO Artie 5ive racconta quali sono gli oggetti di cui non può fare a meno Un sogno diventato realtà. Nell’ultima Coppa del Mondo, l’edizione giocata in Qatar nel 2022, la seconda della sua carriera, Achraf è stato il miglior giocatore del Marocco, una delle nazionali rivelazione del torneo che si è tolta la soddisfazione di battere la Spagna e il Portogallo prima di arrendersi in semifinale contro la Francia. Dopo ogni vittoria, compresa l’eliminazione della Spagna agli ottavi di finale, Achraf non ha mancato di fare una dedica speciale a sua madre. Una delle immagini più commoventi della competizione è stata quella del marocchino che dopo avere segnato il rigore decisivo nella serie dei calci di rigore contro le Furie rosse spagnole, si è precipitato verso le tribune alla ricerca di Saida per condividere con lei tutta l’emozione di questo momento storico e abbracciarla fino alle lacrime. Achraf Hakimi, 25 anni, centrocampista del Paris Saint-Germain e del Marocco. Abiti Diesel Saida e Hassan Hakimi, il padre di Achraf, sono emigrati dal Marocco alla Spagna pieni di speranze con la volontà di costruire una famiglia. Hassan ha lavorato come venditore ambulante nei mercati locali, mentre Saida ha fatto la donna delle pulizie. Nel 1998 è arrivato il loro primo figlio, Achraf, che fin da piccolo ha mostrato un talento naturale per il calcio. Successivamente, la famiglia si è allargata con l’arrivo di Nabil e Ouidad, l’unica femmina dei tre fratelli. Hassan accompagnava Achraf agli allenamenti ogni pomeriggio, attraversando mezza Madrid per portarlo alla Ciudad Deportiva del Real Madrid, dove Achraf ha iniziato a rincorrerre la palla all’età di otto anni. «Tutti si sono sacrificati per me, compresi i miei fratelli, per permettermi di continuare a giocare a calcio. Mia madre, comunque, ha voluto assicurarsi che non trascurassi gli studi», ha dichiarato Achraf. Ora, è lui a lottare per il futuro degli Hakimi. Nato il 4 novembre 1998, Achraf non dà importanza al numero degli anni anche se gli converrebbe, visto che ne ha appena venticinque. Per lui, crescere significa vivere esperienze significative. «Alla mia età, sono perfettamente consapevole di essere molto più maturo rispetto alla media. Questo perché ho anticipato una serie di tappe fondamentali e ho iniziato da molto giovane», riflette. «Avere due figli mi ha dato una marcia speciale, permettendomi di riflettere sulle cose con maggiore rapidità e profondità. Questa maturità mi permette di trasmettere saggezza ai miei compagni di squadra e di supportare i giovani con efficacia». Non per niente Achraf è un punto di riferimento nell’attuale formazione del PSG, dove è arrivato nel 2021, una squadra piena di stelle che gli ha permesso di condividere lo spogliatoio con Messi, Neymar, Di María, Mbappé, Verratti e Sergio Ramos. Marocco, Spagna, Germania, Italia, Francia… La diversità e la capacità di adattamento sono due concetti perfetti per descrivere il carattere di Achraf: «Fin da piccolo, a casa, vivevo una cultura diversa rispetto al resto della Spagna. A 18 anni mi sono trasferito in un altro Paese, dove si parlava un linguaggio del tutto differente, e ogni due anni, al massimo, cambiavo città e lingua. Posso dire che cerco sempre di apprendere rapidamente per adattarmi nel modo più efficace possibile», afferma, e non a caso. Articoli più letti Stile Swatch (ri)celebra l'arte di Keith Haring con tre orologi imperdibili di Paola Montanaro Cultura Berlinguer – La grande ambizione non è un biopic, ma il Bignami di una pagina di storia italiana di Martina Barone Cultura In Joker: Folie à Deux, che senso ha il colpo di scena di Due Facce? di Jack King Abiti e calzature Diesel Da ogni luogo ha portato con sé un pezzetto che l’ha forgiato dentro e fuori dal campo: «A Madrid mi sono divertito un sacco perché ero giovanissimo ed era il mio sogno. Non potevo sapere cosa sarebbe accaduto il giorno dopo. Sapevo solo di dover assorbire il più possibile da un gruppo di campioni che per me erano dei riferimenti. Soprattutto, ho imparato che cos’è il calcio professionistico», racconta con un’invidiabile capacità di sintesi. «La Germania ha rappresentato per me la costanza, la regolarità nel gioco e nel minutaggio, facendomi sentire importante all’interno di una squadra. L’Inter ha significato consolidarmi nell’élite portando il mio nome al massimo livello possibile, arrivando ad essere inoltre campioni d’Italia. Parigi è stata, beh, magnifica! Mi trovo in uno dei momenti migliori della mia carriera, e nella capitale francese sto continuando a consolidare l’esperienza vissuta sulla sponda nerazzurra di Milano». Achraf ricorda sempre con vivo entusiasmo il suo esordio da professionista al Real Madrid, dove ha dovuto confrontarsi con Dani Carvajal, simbolo e capitano della squadra. Ha dimostrato di sapersi sacrificare in difesa senza dimenticare di correre, quando possibile, con audacia in attacco. Ha segnato alcuni gol, vinto la Supercoppa di Spagna, ma non è riuscito a raggiungere la continuità necessaria, così è passato in prestito al Borussia Dortmund. La Germania è stata la sua consacrazione, il periodo in cui ha saputo potenziare la sua dote più ammirata dai veri intenditori di calcio: la versatilità. Hakimi può giocare in diverse posizioni ed è la gioia di ogni allenatore alla ricerca di nuove soluzioni tattiche. Da allora, il Real Madrid non lo ha mai perso di vista, ed è per questo che solo pochi mesi fa si è nuovamente interessato a lui per rafforzare la difesa della fascia destra. Articoli più letti Stile Swatch (ri)celebra l'arte di Keith Haring con tre orologi imperdibili di Paola Montanaro Cultura Berlinguer – La grande ambizione non è un biopic, ma il Bignami di una pagina di storia italiana di Martina Barone Cultura In Joker: Folie à Deux, che senso ha il colpo di scena di Due Facce? di Jack King Abiti Diesel Ora nella città delle luci, la Ville Lumière, la sua esistenza scorre tranquilla nonostante la frenesia di una professione dove è fondamentale il rispetto di un programma fitto di impegni a orari precisi: «Mi sveglio tra le 8.00 e le 8.15, esco dal letto, mi vengono a prendere e andiamo all’allenamento. Arriviamo presso il centro sportivo verso le 9.15, faccio colazione, lavoro con i fisioterapisti, vado in palestra, finché non arriva l’allenatore per il consueto meeting e alle 11.00 in punto iniziamo l’allenamento. Quando finisco, continuo in palestra con esercizi specifici, torno dal preparatore atletico e alle 14.00 sono a tavola», illustra Achraf Hakimi con la stessa meticolosa precisione dei suoi interventi difensivi in area di rigore. «I pomeriggi li passo in modo decisamente più tranquillo, me ne sto a casa a giocare con la Playstation, vengono a trovarmi degli amici e poi mi piace uscire a cena. Adoro provare piatti che non conosco e scoprire nuovi ristoranti». Oltre a queste abitudini, confessa di dedicarsi con attenzione alla cura di sé anche da un punto di vista estetico, soprattutto della pelle: «Sono un po’ fissato al riguardo, seguo una precisa routine di trattamenti e massaggi per il viso, senza escludere il resto del corpo grazie alla preziosa assistenza del mio fisioterapista. Uso maschere, creme e quant’altro...», ammette con orgoglio. «Credo sia una cosa normale, bisogna prendersi cura di sé. Ho iniziato presto, ma non ero così costante. Forse perché ho sempre avuto una pelle sana con poca acne. Diciamo che, da tre o quattro anni, ho iniziato a usare delle ottime creme e a seguire una cura con la giusta costanza». Abiti e accessori Diesel Abiti e accessori Diesel Abiti e accessori Diesel Abiti e accessori Diesel Nel calcio contemporaneo, un universo quasi unico in cui ogni tre giorni si può passare dal successo al fallimento, mantenere un equilibrio emotivo stabile non è certo un’impresa da tutti. Perfino Achraf ha avuto, a volte, bisogno di un aiuto psicologico nel corso della carriera, ma è convinto di una cosa: «Sono lo psicologo di me stesso. Riconosco di essere un uomo estremamente autonomo, ma non rifiuto l’aiuto delle persone a cui sono legato: mia madre, il mio migliore amico, mio fratello, i miei agenti... Sono loro ad aiutarmi a riflettere e a curarmi quando ne ho davvero bisogno», precisa. «Passo molto tempo in solitudine, leggo e mi piace stare nel mio mondo per ragionare su ciò che voglio e sulla direzione da prendere. Ho bisogno del mio spazio per farlo. Anche se ho abbandonato la terapia tre anni fa, ci tengo a dire che mi è stata di grandissimo aiuto. In realtà non l’ho usata per migliorarmi come calciatore, ma a livello personale. Ti aiuta sempre: andare in analisi non significa essere pazzi, secondo il pregiudizio di alcuni, ma ti permette di vedere la vita da altre prospettive. Forse ci tornerò». "Sono lo psicologo di me stesso, ma non rifiuto l’aiuto delle persone a cui sono legato: mia madre, il mio migliore amico, mio fratello" Achraf ha imparato a difendere il suo spazio, sia in campo che fuori: «Le persone che mi conoscono da quando avevo sei anni, appena si accorgono che potrei prendere una strada sbagliata, sanno riportarmi subito in riga, mi rimproverano. All’inizio, magari, cerco di non ascoltarle e mi giro dall’altra parte perché le loro parole al momento mi danno fastidio, ma poi, quando sono da solo, rifletto e capisco. Non do peso a chi non mi conosce», confida. Articoli più letti Stile Swatch (ri)celebra l'arte di Keith Haring con tre orologi imperdibili di Paola Montanaro Cultura Berlinguer – La grande ambizione non è un biopic, ma il Bignami di una pagina di storia italiana di Martina Barone Cultura In Joker: Folie à Deux, che senso ha il colpo di scena di Due Facce? di Jack King Tuttavia, non è sempre stato così. L’esposizione mediatica a cui è sottoposto un calciatore, l’opinione dei social network (Achraf è seguito attualmente da più di 20 milioni di follower su Instagram), i media e la stessa società possono giocare brutti scherzi, soprattutto a un giovane che debutta nel Real Madrid appena maggiorenne: «Quando ho iniziato non mi ero ancora fatto un’idea precisa di cosa dovevo prepararmi ad affrontare. Non sapevo esattamente cosa fossero le critiche, gli elogi, la stampa... Ero più colpito dalle parole negative. Con il tempo, però, ho imparato a credere in me stesso. Sono arrivato a comprendere come le medesime persone che oggi mi criticano, domani potrebbero lodarmi portandomi al settimo cielo. Anche chi mi getta addosso veleno non può farmi del male. Ora non mi colpiscono più nemmeno gli elogi», conclude con la serenità di un veterano. In ogni caso, la gioventù e la spensieratezza di Achraf si riflettono nel suo stile: «Sono sempre stato attratto dalla moda, amo vestirmi bene perché mi fa sentire sicuro di me stesso. Appena mi si è presentata l’occasione, ho cercato il modo di essere all’ultimo grido, ma senza perdere la testa. Ho cambiato spesso il mio stile e ora ho un’altra visione del vestire». In materia di abbigliamento gli piace cambiare e sa essere audace. «Oggi ritengo giusto indossare una camicia e domani qualcosa di totalmente diverso. Insomma, mi butto. Sono timido, ma non ho vergogna a provare qualcosa di nuovo. Lo stesso mi succede con le lingue, e nella moda mi diverto a sperimentare. Se non ti piace, non guardare», afferma sorridendo. Indossa una grande felpa con cappuccio che all’occorrenza gli può tornare utile per mascherare la timidezza che comunque ha in presenza di un giornalista. Magari si tratta di una forma di diffidenza da mettere gradualmente da parte per rilassarsi durante la chiacchierata. «Il mio stile rappresenta chi sono veramente. Quando mi vedono voglio sentir dire che sono Achraf Hakimi. Non mi vesto per compiacere qualcuno e le mie scelte sono spontanee, vengono in modo naturale da dentro di me». Si mette comodo e continua a parlare. «Non ho mai sfilato, ma mai dire mai. Sono riservato, sì, ma sono anche consapevole della mia esposizione professionale e so lasciarmi andare». Abiti, calzature e accessori Diesel Articoli più letti Stile Swatch (ri)celebra l'arte di Keith Haring con tre orologi imperdibili di Paola Montanaro Cultura Berlinguer – La grande ambizione non è un biopic, ma il Bignami di una pagina di storia italiana di Martina Barone Cultura In Joker: Folie à Deux, che senso ha il colpo di scena di Due Facce? di Jack King Nella vita privata, in mezzo alla sua gente, non si fa problemi e si trova a perfetto agio: «Di solito, sono una persona tranquilla e riservata, ma con le persone che mi circondano divento particolarmente affettuoso, un ragazzo sorridente, sempre felice. Bisogna godersi la vita. I miei figli rappresentano tutto, sono il mio sangue, la mia famiglia. Anche loro mi rispettano e devo dare l’esempio attraverso le mie azioni, perché mi guardano con ammirazione e tanta attenzione. Voglio dare loro una buona educazione come quella che mia madre ha riservato a me. Sono in una posizione delicata perché il loro padre è molto conosciuto, perciò cerco di rendere tutto naturale e di non pensarci troppo. Sotto molti aspetti sono fortunati, ma non devono dimenticare la necessità di lavorare per ottenere dei risultati». Ancora una volta ricorda quanto sua madre gli ha insegnato riferendosi ai figli, frutto della relazione con l’attrice spagnola Hiba Abouk. Secondo lui sono pazzi per il calcio, perfino il più piccolo, Naím di due anni, che imita il fratello maggiore, Amín di quattro anni. Achraf Hakimi è molto attento a proteggere la propria privacy e quella dei suoi figli, preparandoli anche a eventuali situazioni di esclusione che potrebbero affrontare a causa delle loro origini. Un’esperienza che lui stesso ha vissuto. «Non è stato qualcosa di eclatante, ma ho percepito numerosi atteggiamenti spiacevoli dovuti al mio aspetto, nonostante io sia spagnolo. Ho affrontato discriminazioni, ma le ho superate con la consapevolezza di avere gli stessi diritti di chiunque altro; l’origine non cambia una persona», racconta facendosi serio come mai era avvenuto durante il nostro incontro. Abiti, calzature e accessori Diesel Articoli più letti Stile Swatch (ri)celebra l'arte di Keith Haring con tre orologi imperdibili di Paola Montanaro Cultura Berlinguer – La grande ambizione non è un biopic, ma il Bignami di una pagina di storia italiana di Martina Barone Cultura In Joker: Folie à Deux, che senso ha il colpo di scena di Due Facce? di Jack King Hakimi riflette su come la discriminazione sia diventata più evidente nella nostra attuale società. «Non sono stato insultato direttamente, ma se ti siedi accanto a qualcuno e questo si alza, a volte non c’è bisogno di parole per capire certe cose. Ti fanno dei brutti gesti e poi, quando scoprono chi sei, si avvicinano. A quel punto, dico loro di no allontanandole, perché sono una persona prima che un calciatore», dice con fermezza. Questa consapevolezza lo ha portato a essere ancora più determinato nel proteggere i propri cari e a insegnare loro a non lasciarsi abbattere dalle discriminazioni. Desidera con determinazione che i suoi figli crescano sapendo che devono essere orgogliosi delle loro radici e nessuno ha il diritto di farli sentire inferiori per questo. Abiti Diesel, cappello vintage Uno degli insegnamenti principali di Achraf Hakimi è l’orgoglio per le proprie origini arabe: «Molte persone mi seguono e io cerco di rappresentare la mia cultura, il mio Paese, in modo trasparente. Possiamo avere visioni differenti ma non ho la minima pretesa che la pensino diversamente. Lo faccio senza obblighi, mi viene naturale», afferma il calciatore che non manca di sottolineare come ci siano molti pregiudizi sulla cultura araba, ricordando l’esperienza della Coppa del Mondo in Qatar. Articoli più letti Stile Swatch (ri)celebra l'arte di Keith Haring con tre orologi imperdibili di Paola Montanaro Cultura Berlinguer – La grande ambizione non è un biopic, ma il Bignami di una pagina di storia italiana di Martina Barone Cultura In Joker: Folie à Deux, che senso ha il colpo di scena di Due Facce? di Jack King «All’inizio, molti si lamentavano di come sarebbe stata organizzata. Temevano che alcune cose non sarebbero state permesse e ci sarebbe stato il caos. Invece, il risultato è stato straordinario: non ci sarà mai più una Coppa del Mondo come quella. Non solo per l’organizzazione impeccabile, ma anche per il modo in cui i tifosi si sono divertiti. Gli inglesi erano insieme ai marocchini, ed era un messaggio chiaro: dobbiamo aiutarci a vicenda», racconta. Abiti e calzature Diesel, coperta vintage Per il difensore del PSG, il calcio rappresenta l’unione tra culture diverse. «Veniamo da Paesi diversi, ma dobbiamo unirci per il bene generale», afferma con estrema convinzione. Questo spirito di unità e collaborazione è ciò che cerca di trasmettere, dentro e fuori dal campo, dimostrando che le differenze culturali possono essere una forza, non un ostacolo. L’immagine e il messaggio espresso da Hakimi è che il calcio si presta per la sua universalità a essere uno strumento di estrema importanza sociale e culturale: un ponte ideale tra le culture, le religioni e le lingue del mondo. «La cultura del mio Paese d’origine, per esempio, è ricca di tesori che molti nemmeno conoscono, ma quando li scoprono ne rimangono affascinati. Abbiamo una cucina eccellente, persone amichevoli, di grande umanità e disposte a collaborare», afferma. «Ogni giorno scopro qualcosa di nuovo che mi sorprende e mi incuriosisce sempre di più». Il pilastro della Nazionale del Marocco, i Leoni dell’Atlante, riflette anche sui pregiudizi che spesso accompagnano la sua professione. «Quando dici di essere un calciatore, la gente ti vede in modo diverso. Ogni persona è unica, ma spesso veniamo giudicati prima ancora di essere conosciuti», si rammarica il giocatore. Articoli più letti Stile Swatch (ri)celebra l'arte di Keith Haring con tre orologi imperdibili di Paola Montanaro Cultura Berlinguer – La grande ambizione non è un biopic, ma il Bignami di una pagina di storia italiana di Martina Barone Cultura In Joker: Folie à Deux, che senso ha il colpo di scena di Due Facce? di Jack King “Ho subito discriminazioni, ma le ho superate perché so di avere gli stessi diritti degli altri. L’origine non cambia una persona” Il calcio è stato per lui l’occasione per stringere grandi amicizie: «Con il portiere della Nazionale marocchina, Munir Mohand Mohamedi, ho da anni un rapporto davvero speciale. È tra le persone per me più fidate a cui posso confidare tutto ed è bello aprirsi completamente. Lo stesso vale per Luca Zidane, il figlio dell’immenso Zinédine, mio compagno di gioco da quando ero bambino nelle giovanili del Madrid. Poi, naturalmente, non posso non citare Kylian Mbappé, fino alla scorsa stagione con me nel PSG. A Parigi abbiamo stretto un legame molto forte e so di poter contare su di lui che sa come funziona questo mondo». I due condividono anche la passione per la moda e spesso, come Hakimi stesso ci tiene a raccontare, si scambiano consigli di stile. Sono grandi amici e, quando possono, viaggiano insieme. L’anno scorso, ad esempio, hanno visitato New York dove non si sono lasciati sfuggire l’occasione di assistere a una partita dell’NBA, ospitati da Kevin Durant. La chiacchierata con Achraf prosegue, tra passato e presente, senza soluzione di continuità. «Ho una fondazione, la Fondazione Achraf Hakimi, creata allo scopo di aiutare le persone in Marocco che hanno meno possibilità di coltivare e perseguire i propri sogni attraverso lo sport e l’istruzione. L’istituzione si ispira a un motto dello stesso Achraf che cita l’importanza delle opportunità in grado di offrire ai bambini marocchini un futuro migliore: «Tutto è possibile quando ci si crede e si hanno i mezzi per raggiungerlo», sentenzia. «Sono riuscito a raggiungere numerosi traguardi importanti per un calciatore, ma il desiderio più grande resta quello di vincere un titolo con il mio Paese. E con il PSG voglio entrare nella storia conquistando la mia prima Champions League», dice, con il tono di uno che in cuor suo è convinto di farcela. A soli 25 anni, i suoi successi hanno dell’incredibile, ma altrettanto lo è tutto quello che deve ancora venire. Non ne dubita. CREDITI DI PRODUZIONE Foto di Mous Lamrabat Styling: Lisa Lapauw Grooming: Sandra Lamzabi, Nathan Nsuka Abbonati e regala GQ. Edizione digitale inclusa. Scopri le offerte! Tags GQ25 gq magazine GQ CONSIGLIA Stile Swatch (ri)celebra l'arte di Keith Haring con tre orologi imperdibili di Paola Montanaro Cultura Berlinguer – La grande ambizione non è un biopic, ma il Bignami di una pagina di storia italiana di Martina Barone Cultura In Joker: Folie à Deux, che senso ha il colpo di scena di Due Facce? di Jack King Cultura Lo confesso: Megalopolis mi è piaciuto un sacco di Valentina Caiani GQ Italia GQ Italia Scopri le ultime notizie Stile Cultura Lifestyle GQ Sports Recommends Motori Tech Video Condé Nast Italia AD La Cucina Italiana Vanity Fair Vogue Wired Condizioni d'utilizzo Redazione Privacy Pubblicità Abbonamenti Newsletter Gestisci le preferenze © EDIZIONI CONDÉ NAST S.P.A. - PIAZZA CADORNA 5 - 20121 MILANO CAP.SOC. 2.700.000 EURO I.V. C.F E P.IVA REG.IMPRESE TRIB. MILANO N. 00834980153 SOCIETÀ CON SOCIO UNICO Select international site Italia in one paragraph gime all the details in arabic pls
أشكرف حكيمي، لاعب كرة القدم المغربي، وُلد في 4 نوفمبر 1998 في Getafe، بالقرب من مدريد، لإبنين مهاجرين من المغرب. بدأ مسيرته الاحترافية في ريال مدريد، حيث تألق رغم التحديات، ثم انتقل إلى بوروسيا دورتموند وفي النهاية إلى باريس سان جيرمان. حكيمي يعتبر رمزًا للتنوع والقدرة على التكيف، حيث عاش في العديد من البلدان وواجه تمييزًا بسبب مظهره. يحمل إحساسًا عميقًا بالأهمية لثقافته ويعمل على دعم الأطفال في المغرب من خلال مؤسسته الخيرية. على الرغم من نجاحاته مع أندية كبيرة ومنتخب بلاده، إلا أنه يسعى لتحقيق المزيد من الألقاب، بما في ذلك دوري أبطال أوروبا.
931a18538066450e4a49cef0pls mention just the part when pics in gq
أشكرف حكيمي، لاعب كرة القدم، كان أيضًا موضوعًا لتصوير فوتوغرافي في مجلة GQ، حيث ظهر في جلسة تصوير يرتدي ملابس من علامة ديزل. خلال المقابلة، تحدث عن تجربته في كرة القدم، اتصاله بأصوله المغربية، وعلاقته بأسرته، بالإضافة إلى اهتمامه بالأزياء والعناية الشخصية. وقد تم تصويره في بيئة عصرية تعكس أسلوبه الفريد وثقافته.
f9a9adf54add1438562e74a2أشكرف حكيمي، لاعب كرة القدم، كان أيضًا موضوعًا لتصوير فوتوغرافي في مجلة GQ، حيث ظهر في جلسة تصوير يرتدي ملابس من علامة ديزل. خلال المقابلة، تحدث عن تجربته في كرة القدم، اتصاله بأصوله المغربية، وعلاقته بأسرته، بالإضافة إلى اهتمامه بالأزياء والعناية الشخصية. وقد تم تصويره في بيئة عصرية تعكس أسلوبه الفريد وثقافته. make it moroccan darija ann add two emojies in the beginng
🇲🇦⚽️ أشكرف حكيمي، لاعب كرة القدم، كان أيضًا موضوع تصوير فوتوغرافي في مجلة GQ، فين خرج بملابس من علامة ديزل. خلال الندوة، هضر على تجربتو في كرة القدم، وعلاقته بأصولو المغربية، وكفاش كيتعامل مع عائلتو، وزيد اهتمامو بالأزياء والعناية الشخصية. تصويرو كان في بلاصة عصرية تعكس ستيلو الفريد وثقافتو.
c918fade0aaa115fe7e48eb4Kids' WB Fall 2014 From October 3, the surrounding presentation (next bumpers and promo ends) will have arrows, The idents will have random skits that end in the logo forming, These include 1. Dentist: A dentist notices a girl has broken teeth, fixes them with a drill, turning them normal (and looking like the CN logo) Jack in the Box: 2 funny creatures pop out of a jack in the box, they get tangled and the boxes fall over, forming the logo Bunnies: 2 purple bunnies bash themselves with a mallet in a squash and stretch manner (squishing then reverting to normal instantly), This gets faster untill they turn into the logo, (with the iconic dizzy/birds flying over head gag thrown in for good measure) Parachute: 2 skydiving daredevil’s parachute forms the logo (one of the daredevils fall to the ground, the other lands perfectly) Transformers: 2 fighting mech robots turn into the logo Moon: A man on the moon plants seeds, hoping for trees, but gets the logo instead Cliff: 2 flying jets fly past a cliff with the logo carved into it Balloons: 2 monkeys bounce on a inflater, behind then a baloon with the logo inflates and bursts, leaving them humiliated Diving: A man dives, while juggling and having a cup of tea, Judges give him a score with the logo Magic: A magician peforms the famous cutting trick, the boxes are the logo Dynamite: A purple creature proposes to another, accidentally holding TNT instead of flowers, It explodes, forming the logo Fly squatter: A fly tries to suck juice., but gets whacked with a fly swatter, the swatter forms the B, fly forms the W and "Kids" part High Noon: 2 cowboys prepare to fight, but their guns shoot out the logo instead, Frankenstein: Frankenstein but with the logo instead. Kids WB Fall 2014 Schedule 7:00 AM - Pokémon: XY Join Ash and his friends in the Kalos region as they take on new challenges and discover new Pokémon! 7:30 AM - Looney Tunes Cartoons Laugh along with Bugs Bunny, Daffy Duck, and the rest of the Looney Tunes gang in zany, classic shorts. 8:00 AM - The Tom & Jerry Show Enjoy the timeless antics of the cat-and-mouse duo in their never-ending chase. 8:30 AM - Ben 10 Omniverse Although Ben's ready to work alone, Grandpa Max teams him with a new, by-the-book partner. Along the way, Ben discovers enemies from his past looking for a rematch as well as a new batch of aliens to battle. While Ben is busy dealing with the aliens, a mysterious hunter is hot on his trail. 9:00 AM - The Batman Dive into Gotham City with young Bruce Wayne as he fights crime and faces iconic villains. 9:30 AM - Teen Titans Go! Join the hilarious misadventures of the Teen Titans as they tackle everyday problems with a comical twist! 10:00 AM - Johnny Test More adventures with Johnny and Dukey 10:30 AM - The Amazing World of Gumball Explore the absurd and colorful life of Gumball Watterson and his family in the quirky town of Elmore! 11:00 AM - Adventure Time Join Finn and Jake in the magical Land of Ooo for epic quests and whimsical adventures! 11:30 AM - Regular Show Follow the everyday lives of Mordecai and Rigby as they hilariously navigate the challenges of working at the park! 7:00 AM - Pokémon: XY Join Ash and his friends as they continue their journey through the Kalos region, discovering new Pokémon and facing fresh challenges! 7:30 AM - Looney Tunes Cartoons Laugh along with Bugs, Daffy, and the entire Looney Tunes gang in zany shorts that will keep you in stitches! 8:00 AM - The Tom & Jerry Show Enjoy more classic antics as Tom chases Jerry in an endless battle of wits and humor! 8:30 AM - Viewtiful Joe Get ready for action-packed adventures as our hero, Joe, battles absurd villains and jumps into the world of movies to save his girlfriend. The return of Viewtiful Joe brings back all the thrills and comedy you love! 9:00 AM - The Batman Dive back into the shadowy world of Gotham City, where young Bruce Wayne confronts iconic villains and fights for justice! 9:30 AM - Teen Titans Go! Laugh with the Teen Titans as they take on everyday challenges with their signature humor and hijinks! 10:00 AM - Spider Riders The epic tales of Spider Riders return! Join Hunter, the fearless young hero, as he battles against the evil Underworld and discovers the power of friendship and teamwork. 10:30 AM - Johnny Test Follow Johnny and his genius dog Dukey on their outrageous adventures filled with gadgets, experiments, and mischief! 11:00 AM - The Amazing World of Gumball Explore the whimsical life of Gumball Watterson and his colorful family as they navigate the absurdities of their town! 11:30 AM - Adventure Time Join Finn and Jake in the magical Land of Ooo for more epic quests and whimsical adventures! 12:00 PM - Regular Show Hang out with Mordecai and Rigby as they tackle the everyday challenges of working at the park with their unique brand of humor! Write a conversation asking if this era is called the Arrow Era
**Title: The Arrow Era Conversation** **Characters: Alex and Jamie** --- **Alex:** Hey Jamie, have you noticed the new presentation style on Kids' WB this fall? **Jamie:** Oh, you mean the one with the arrows and all those fun skits? Yeah, it's pretty cool! **Alex:** Right? I love how each skit leads up to the logo forming. It’s really creative! **Jamie:** Totally! I'm especially a fan of that one with the bunnies. The way they squash and stretch is so classic and funny! **Alex:** I know! And what about the dentist one? It's hilarious how the logo ends up being like the CN logo with the drill! **Jamie:** It's like a nod to the Cartoon Network style. But do you think we should have a name for this era? What do you think about calling it the Arrow Era? **Alex:** The Arrow Era? I like that! It really captures the idea of the arrows being a big part of the presentation. **Jamie:** Exactly! Plus, it has a nice ring to it. It makes you think of direction and movement, just like those skits. **Alex:** Right! And the logo transitions are so dynamic, they definitely deserve a catchy name like that. **Jamie:** Should we start using that term with our friends? “Hey, have you seen the latest episode from the Arrow Era?” **Alex:** For sure! Let’s see if it catches on. It could be fun to refer to this whole vibe as the Arrow Era, especially with all those exciting bumpers! **Jamie:** Agreed! Let’s spread the word! Arrow Era it is! --- **End of conversation**
948b93e702e8284cc482ecbfKids' WB Fall 2014 From October 3, the surrounding presentation (next bumpers and promo ends) will have arrows, The idents will have random skits that end in the logo forming, These include 1. Dentist: A dentist notices a girl has broken teeth, fixes them with a drill, turning them normal (and looking like the Kids' WB logo) Jack in the Box: 2 funny creatures pop out of a jack in the box, they get tangled and the boxes fall over, forming the logo Bunnies: 2 purple bunnies bash themselves with a mallet in a squash and stretch manner (squishing then reverting to normal instantly), This gets faster untill they turn into the logo, (with the iconic dizzy/birds flying over head gag thrown in for good measure) Parachute: 2 skydiving daredevil’s parachute forms the logo (one of the daredevils fall to the ground, the other lands perfectly) Transformers: 2 fighting mech robots turn into the logo Moon: A man on the moon plants seeds, hoping for trees, but gets the logo instead Cliff: 2 flying jets fly past a cliff with the logo carved into it Balloons: 2 monkeys bounce on a inflater, behind then a baloon with the logo inflates and bursts, leaving them humiliated Diving: A man dives, while juggling and having a cup of tea, Judges give him a score with the logo Magic: A magician peforms the famous cutting trick, the boxes are the logo Dynamite: A purple creature proposes to another, accidentally holding TNT instead of flowers, It explodes, forming the logo Fly squatter: A fly tries to suck juice., but gets whacked with a fly swatter, the swatter forms the B, fly forms the W and "Kids" part High Noon: 2 cowboys prepare to fight, but their guns shoot out the logo instead, Frankenstein: Frankenstein but with the logo instead. Kids WB Fall 2014 Schedule 7:00 AM - Pokémon: XY Join Ash and his friends in the Kalos region as they take on new challenges and discover new Pokémon! 7:30 AM - Looney Tunes Cartoons Laugh along with Bugs Bunny, Daffy Duck, and the rest of the Looney Tunes gang in zany, classic shorts. 8:00 AM - The Tom & Jerry Show Enjoy the timeless antics of the cat-and-mouse duo in their never-ending chase. 8:30 AM - Ben 10 Omniverse Although Ben's ready to work alone, Grandpa Max teams him with a new, by-the-book partner. Along the way, Ben discovers enemies from his past looking for a rematch as well as a new batch of aliens to battle. While Ben is busy dealing with the aliens, a mysterious hunter is hot on his trail. 9:00 AM - The Batman Dive into Gotham City with young Bruce Wayne as he fights crime and faces iconic villains. 9:30 AM - Teen Titans Go! Join the hilarious misadventures of the Teen Titans as they tackle everyday problems with a comical twist! 10:00 AM - Johnny Test More adventures with Johnny and Dukey 10:30 AM - The Amazing World of Gumball Explore the absurd and colorful life of Gumball Watterson and his family in the quirky town of Elmore! 11:00 AM - Adventure Time Join Finn and Jake in the magical Land of Ooo for epic quests and whimsical adventures! 11:30 AM - Regular Show Follow the everyday lives of Mordecai and Rigby as they hilariously navigate the challenges of working at the park! 7:00 AM - Pokémon: XY Join Ash and his friends as they continue their journey through the Kalos region, discovering new Pokémon and facing fresh challenges! 7:30 AM - Looney Tunes Cartoons Laugh along with Bugs, Daffy, and the entire Looney Tunes gang in zany shorts that will keep you in stitches! 8:00 AM - The Tom & Jerry Show Enjoy more classic antics as Tom chases Jerry in an endless battle of wits and humor! 8:30 AM - Viewtiful Joe Get ready for action-packed adventures as our hero, Joe, battles absurd villains and jumps into the world of movies to save his girlfriend. The return of Viewtiful Joe brings back all the thrills and comedy you love! 9:00 AM - The Batman Dive back into the shadowy world of Gotham City, where young Bruce Wayne confronts iconic villains and fights for justice! 9:30 AM - Teen Titans Go! Laugh with the Teen Titans as they take on everyday challenges with their signature humor and hijinks! 10:00 AM - Spider Riders The epic tales of Spider Riders return! Join Hunter, the fearless young hero, as he battles against the evil Underworld and discovers the power of friendship and teamwork. 10:30 AM - Johnny Test Follow Johnny and his genius dog Dukey on their outrageous adventures filled with gadgets, experiments, and mischief! 11:00 AM - The Amazing World of Gumball Explore the whimsical life of Gumball Watterson and his colorful family as they navigate the absurdities of their town! 11:30 AM - Adventure Time Join Finn and Jake in the magical Land of Ooo for more epic quests and whimsical adventures! 12:00 PM - Regular Show Hang out with Mordecai and Rigby as they tackle the everyday challenges of working at the park with their unique brand of humor! Write a conversation asking which bumper is used most often
**Conversation Between Two Kids: Alex and Jamie** **Alex:** Hey, Jamie! Did you watch Kids' WB this morning? **Jamie:** Yeah, I did! I loved the skits they had with the logos. They were so funny! Which one was your favorite? **Alex:** I really liked the one with the bunnies! The way they squished themselves and turned into the logo was hilarious. What about you? **Jamie:** Oh, that was good! I think I laughed the most at the dentist one. It was so unexpected when the logo appeared after he fixed the girl’s teeth. **Alex:** True! But I feel like I keep seeing the fly swatter bumper. I think they use that one a lot. **Jamie:** You might be right! The fly one is super catchy. I noticed it playing a couple of times this week. **Alex:** Exactly! I wonder which bumper they use the most often. It feels like the fly squatter was everywhere. **Jamie:** Maybe we should keep track of them next time! Like count how many times we see each one throughout the week. **Alex:** That sounds like a fun idea! Let’s see if the fly swatter wins the most votes or if the bunnies take over! **Jamie:** Awesome! It's like our little Kids' WB competition. Can’t wait to see what happens!
02191715f4459bf043ed5399Write a tweet with the 2 most used ones
🐰💫 Just watched Kids' WB and it seems like the hilarious Fly Squatter bumper and the crazy Bunny skit are the two most used ones this week! 🎉 Which is your favorite? 🐝🍭 #KidsWB #AnimationFun
73333e69212fe1be07eb0d99{***************************************************************************}
{ TBaseGrid component }
{ for Delphi & C++Builder }
{ }
{ written by TMS Software }
{ copyright © 1996 - 2024 }
{ Email : info@tmssoftware.com }
{ Web : http://www.tmssoftware.com }
{ }
{ The source code is given as is. The author is not responsible }
{ for any possible damage done due to the use of this code. }
{ The component can be freely used in any application. The complete }
{ source code remains property of the author and may not be distributed, }
{ published, given or sold in any form as such. No parts of the source }
{ code can be included in any other component or application without }
{ written authorization of the author. }
{***************************************************************************}
unit BaseGrid;
{$I TMSDEFS.INC}
{$DEFINE TMSUNICODE}
interface
uses
Windows, SysUtils, Types, Classes, Graphics, Controls,
Grids, AdvObj
{$IFDEF DELPHIXE2_LVL}
, System.UITypes
{$ENDIF}
;
type
TBaseGrid = class;
TColumnCalcType = (acNONE, acSUM, acAVG, acCOUNT, acMIN, acMAX, acSPREAD, acCUSTOM, acDISTINCT, acSTDDEV);
{$IFDEF DELPHIXE2_LVL}
TIObjType = NativeUInt;
{$ENDIF}
{$IFNDEF DELPHIXE2_LVL}
TIObjType = Integer;
{$ENDIF}
{ TCellProperties }
TCellProperties = class(TPersistent)
private
FOwnerGrid: TBaseGrid;
FOwnerCol: Integer;
FOwnerRow: Integer;
FObject: TIObjType;
FGraphicObject: TObject;
FBrushStyle: TBrushStyle;
FBrushColor: TColor;
FBrushColorTo: TColor;
FFontHeight: Integer;
FFontColor: TColor;
FFontStyle: TFontStyles;
FCellSpanY: integer;
FCellSpanX: integer;
FBorderWidth: Integer;
FBorderColor: TColor;
FAlignment: TAlignment;
FVAlignment: TVAlignment;
FPaintID: Integer;
FWordWrap: Boolean;
FIsBaseCell: Boolean;
FCalcType: TColumnCalcType;
FCalcObject: TObject;
FNodeLevel: Integer;
FEditor: TEditorType;
FFontName: string;
FReadOnly: Boolean;
FGradientDirection: TCellGradientDirection;
FControl: TControl;
FMergeCollaps: Boolean;
procedure SetBrushColor(const Value: TColor);
procedure SetAlignment(const Value: TAlignment);
procedure SetVAlignment(const Value: TVAlignment);
procedure SetWordWrap(const Value: Boolean);
function GetBaseCell(c, r: Integer): TPoint;
procedure SetBrushColorTo(const Value: TColor);
function GetCellSpanY: Integer;
protected
property BaseCell[c,r: Integer]: TPoint read GetBaseCell;
property PaintID: Integer read FPaintID write FPaintID;
property GraphicObject: TObject read FGraphicObject write FGraphicObject;
public
property CalcType: TColumnCalcType read FCalcType write FCalcType;
property CalcObject: TObject read FCalcObject write FCalcObject;
constructor Create(AOwner: TBaseGrid; ACol, ARow:integer);
procedure Assign(Source: TPersistent); override;
property MergeCollaps: boolean read FMergeCollaps write FMergeCollaps;
published
property IsBaseCell: Boolean read FIsBaseCell write FIsBaseCell;
property CellSpanX: Integer read FCellSpanX write FCellSpanX;
property CellSpanY: Integer read GetCellSpanY write FCellSpanY;
property OwnerCol: Integer read FOwnerCol write FOwnerCol stored False;
property OwnerRow: Integer read FOwnerRow write FOwnerRow stored False;
property Alignment: TAlignment read FAlignment write SetAlignment;
property BorderColor: TColor read FBorderColor write FBorderColor;
property BorderWidth: integer read FBorderWidth write FBorderWidth;
property BrushColor: TColor read FBrushColor write SetBrushColor;
property BrushColorTo: TColor read FBrushColorTo write SetBrushColorTo;
property BrushStyle: TBrushStyle read FBrushStyle write FBrushStyle;
property CellObject: TIObjType read FObject write FObject;
property FontColor: TColor read FFontColor write FFontColor;
property FontName: string read FFontName write FFontName;
property FontSize: Integer read FFontHeight write FFontHeight;
property FontStyle: TFontStyles read FFontStyle write FFontStyle;
property Editor: TEditorType read FEditor write FEditor;
property GradientDirection: TCellGradientDirection read FGradientDirection write FGradientDirection;
property ReadOnly: Boolean read FReadOnly write FReadOnly;
property VAlignment: TVAlignment read FValignment write SetVAlignment;
property WordWrap: Boolean read FWordWrap write SetWordWrap;
property NodeLevel: Integer read FNodeLevel write FNodeLevel;
property Control: TControl read FControl write FControl;
end;
TGetDisplWideTextEvent = procedure(Sender: TObject; ACol,ARow: Integer; var Value: widestring) of object;
TUndoRedoItem = class(TCollectionItem)
private
FRow: Integer;
FCol: Integer;
FValue: string;
FOrigValue: string;
FSequenceStart: boolean;
FSequenceStop: boolean;
public
published
property Value: string read FValue write FValue;
property OrigValue: string read FOrigValue write FOrigValue;
property Col: Integer read FCol write FCol;
property Row: Integer read FRow write FRow;
property SequenceStart:boolean read FSequenceStart write FSequenceStart;
property SequenceStop:boolean read FSequenceStop write FSequenceStop;
end;
TUndoRedoCollection = class(TCollection)
private
public
constructor Create;
published
end;
TAdvGridUndoRedoEvent = procedure(Sender: TObject; Grid: TBaseGrid; Col,Row: integer; OrigValue,NewValue: string) of object;
{$IFDEF DELPHIXE2_LVL}
[ComponentPlatformsAttribute(pidWin32 or pidWin64)]
{$ENDIF}
TAdvGridUndoRedo = class(TComponent)
private
FItems: TUndoRedoCollection;
FGrid: TBaseGrid;
FLevel: Integer;
FMaxLevel: Integer;
FOnUndo: TAdvGridUndoRedoEvent;
FOnRedo: TAdvGridUndoRedoEvent;
protected
procedure Notification(AComponent: TComponent; AOperation: TOperation); override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure RegisterChange(ACol,ARow: Integer; OldValue, NewValue: string); virtual;
procedure StartSequence; virtual;
procedure StopSequence; virtual;
property Level: Integer read FLevel write FLevel;
property Items: TUndoRedoCollection read FItems write FItems;
property Grid: TBaseGrid read FGrid write FGrid;
procedure Undo;
procedure Redo;
procedure Reset;
function CanUndo: Boolean;
function CanRedo: Boolean;
published
property MaxLevel: Integer read FMaxLevel write FMaxLevel;
property OnUndo: TAdvGridUndoRedoEvent read FOnUndo write FOnUndo;
property OnRedo: TAdvGridUndoRedoEvent read FOnRedo write FOnRedo;
end;
TGridSelectionStyle = (ssDefault, ssVista, ssWin7, ssOffice2007);
THoverRowCell = (hcNormal, hcFixed, hcSelected, hcGroupHeader, hcGroupSummary);
THoverRowCells = set of THoverRowCell;
TCustomCellProps = record
AState: TGridDrawState;
Print: boolean;
Select: boolean;
Remap: boolean;
ABrush: TBrush;
AColorTo: TColor;
AMirrorColor: TColor;
AMirrorColorTo: TColor;
AFont: TFont;
HA: TAlignment;
VA: TVAlignment;
WW: Boolean;
GD: TCellGradientDirection
end;
TBaseGrid = class(TObjStringGrid)
private
{ Private declarations }
//FCustomCellProps: TCustomCellProps;
FDefaultDrawing: Boolean;
FGridLineWidth: Integer;
FGridLineColor: TColor;
FGridFixedLineColor: TColor;
FGridFixedLineWidth: Integer;
FPaintID: Integer;
FCustomSelect: Boolean;
FOnGetDisplText: TGetDisplTextEvent;
FOnGetDisplWideText: TGetDisplWideTextEvent;
FHideLastRow: Boolean;
FNormalRowCount: Integer;
FUndoRedo: TAdvGridUndoRedo;
FWordWrap: boolean;
FActiveRowShow: Boolean;
FActiveRowColor: TColor;
FActiveRowColorTo: TColor;
FActiveRowMirrorColor: TColor;
FActiveRowMirrorColorTo: TColor;
FSelectionStyle: TGridSelectionStyle;
FDefFont: TFont;
FDefBrush: TBrush;
function GetDefaultDrawing: boolean;
procedure SetDefaultDrawing(const Value: boolean);
function GetGridLineWidth: integer;
procedure SetGridLineWidth(const Value: integer);
procedure SetGridLineColor(const Value: TColor);
procedure SetGridFixedLineColor(const Value: TColor);
procedure SetObjectEx(c, r: integer; const Value: TObject);
function GetObjectEx(c, r: integer): TObject;
function GetCellEx(c, r: integer): String;
procedure SetCellEx(c, r: integer; const Value: String);
function GetGraphicObjectEx(c, r: Integer): TObject;
procedure SetGraphicObjectEx(c, r: Integer; const Value: TObject);
procedure RepaintFixedMergedCols;
procedure RepaintFixedMergedRows;
function GetGridObject(c, r: Integer): TObject;
procedure SetGridObject(c, r: Integer; const Value: TObject);
function GetGridCell(c, r: Integer): string;
procedure SetGridCell(c, r: Integer; const Value: string);
procedure SetUndoRedo(const Value: TAdvGridUndoRedo);
procedure SetActiveRowColor(const Value: TColor);
procedure SetActiveRowColorTo(const Value: TColor);
procedure SetActiveRowMirrorColor(const Value: TColor);
procedure SetActiveRowMirrorColorTo(const Value: TColor);
procedure SetSelectionStyle(const Value: TGridSelectionStyle);
procedure SetActiveRowShow(const Value: Boolean);
procedure SetGridFixedLineWidth(const Value: integer);
//function GetRowsEx(r: integer): TStrings;
//procedure SetRowsEx(r: integer; const Value: TStrings);
protected
FHoverRowIdx: integer;
FHoverRow: boolean;
FHoverRowCells: THoverRowCells;
FHoverRowColor: TColor;
FHoverRowColorTo: TColor;
FShowSel: Boolean;
FHasCellProps: Boolean;
FMergeCount: integer;
FEditCellSet: boolean;
function ControlDPIScale: single; virtual;
function GetCPGraphicObject(cp: TCellProperties): TObject;
{ Protected declarations }
procedure CopyRows(ARow1, ARow2: Integer);
procedure CopyCols(ACol1, ACol2: Integer);
procedure NilRow(ARow: Integer);
procedure NilCol(ACol: Integer);
procedure NilCell(ACol,ARow: Integer);
procedure SelectBaseCell;
function IsFixed(ACol, ARow: Integer): Boolean; virtual;
function IsSelected(ACol, ARow: Integer): Boolean;
function NodeIndent(ARow: Integer): Integer; virtual;
function HasNodes: Boolean; virtual;
function IsNode(ARow: Integer): Boolean; virtual; abstract;
function IsSummary(ARow: Integer): Boolean; virtual; abstract;
function FixedColsWidth: Integer;
function FixedRowsHeight: Integer;
procedure TopLeftChanged; override;
procedure DrawCell(ACol, ARow: Longint; ARect: TRect; AState: TGridDrawState); override;
procedure DrawGridCell(Canvas: TCanvas; ACol, ARow:longint; ARect:TRect; AState:TGridDrawState); virtual;
function HasCellProperties(ACol, ARow:integer): Boolean;
procedure ClearProps;
procedure ClearPropCell(ACol,ARow: Integer);
procedure ClearPropRow(ARow: Integer);
procedure ClearPropRect(ACol1,ARow1,ACol2,ARow2: Integer);
function SelectCell(ACol, ARow: Longint): Boolean; override;
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
function DoMouseWheelDown(Shift: TShiftState; MousePos: TPoint): Boolean; override;
function DoMouseWheelUp(Shift: TShiftState; MousePos: TPoint): Boolean; override;
procedure Paint; override;
procedure FloatFooterUpdate; virtual;
procedure SetEditText(ACol, ARow: Longint; const Value: string); override;
function GetEditText(ACol, ARow: Longint): string; override;
function IsBaseCellEx(ACol,ARow: Integer;var MCol,MRow: Integer): Boolean;
function GetCellRect(c, r: Integer): TRect;
function IsCheckCell(c, r: Integer): boolean; virtual; abstract;
procedure SetAsCheck(c, r: Integer; const v: string); virtual; abstract;
property PaintID: Integer read FPaintID;
property CustomSelect: Boolean read FCustomSelect write FCustomSelect;
//property RowProperties[r:integer]: TCellProperties read GetRowProperties write SetRowProperties;
//property ColumnProperties[c:integer]: TCellProperties read GetColProperties write SetColProperties;
property HideLastRow: Boolean read FHideLastRow write FHideLastRow;
property NormalRowCount: Integer read FNormalRowCount write FNormalRowCount;
property GridObjects[c,r: Integer]: TObject read GetGridObject write SetGridObject;
property EditCellSet: boolean read FEditCellSet;
procedure GetDisplText(c,r: Integer; var Value: string); virtual;
procedure GetDisplWideText(c,r: Integer; var Value: widestring); virtual;
procedure GetDefaultProps(ACol,ARow: Integer; AFont: TFont; ABrush: TBrush; var AColorTo, AMirrorColor, AMirrorColorTo: TColor;
var HA: TAlignment; var VA: TVAlignment; var WW: boolean; var GD: TCellGradientDirection); virtual;
function GetDefaultAlignment: TAlignment; virtual;
procedure Notification(AComponent: TComponent; AOperation: TOperation); override;
procedure ChangeScale(M, D: Integer); override;
procedure CellTextChange(ACol,ARow: integer); virtual;
//property CustomCellProps: TCustomCellProps read FCustomCellProps;
function HasCustomCellBorder:boolean; virtual;
procedure PaintCellInt(ACanvas: TCanvas; ACol, ARow: Longint; ARect: TRect; AState: TGridDrawState; Internal: boolean = true);
function UseVCLStyles: boolean; virtual;
function CreateCellProperties(Col,Row: integer): TCellProperties;
public
{ Public declarations }
constructor Create(aOwner: TComponent); override;
destructor Destroy; override;
procedure PaintCell(ACanvas: TCanvas; ACol, ARow: Longint; ARect: TRect; AState: TGridDrawState);
procedure PaintCellExt(ACanvas: TCanvas; ACol, ARow: Longint; ARect: TRect; AState: TGridDrawState);
function GetCellProperties(c, r: integer): TCellProperties;
procedure SetCellProperties(c, r: integer; const Value: TCellProperties);
property CellProperties[c,r: Integer]: TCellProperties read GetCellProperties write SetCellProperties;
property SelectionStyle: TGridSelectionStyle read FSelectionStyle write SetSelectionStyle;
procedure GetVisualProperties(ACol,ARow: Integer; var AState: TGridDrawState; Print, Select, Remap: Boolean;
ABrush: TBrush; var AColorTo, AMirrorColor, AMirrorColorTo: TColor; AFont: TFont; var HA: TAlignment; var VA: TVAlignment; var WW: Boolean;
var GD: TCellGradientDirection); virtual;
function CellRect(c,r:Integer): TRect;
function CellSize(c,r: Integer): TPoint;
function RealColIndex(ACol: Integer): Integer; virtual;
function DisplColIndex(ACol: Integer): Integer; virtual;
function IsBaseCell(ACol,ARow: Integer): Boolean;
function IsMergedCell(ACol,ARow: Integer): Boolean;
function IsMergedNonBaseCell(ACol,ARow: Integer): Boolean;
function IsXMergedCell(ACol,ARow: Integer): Boolean;
function IsYMergedCell(ACol,ARow: Integer): Boolean;
function BaseCell(ACol,ARow: Integer): TPoint;
function FullCell(c,r: Integer): TRect;
function CellSpan(ACol,ARow: Integer): TPoint;
function CellExt(ACol,ARow: Integer): TPoint;
function MinRowSpan(ARow: Integer): Integer;
function MaxRowSpan(ARow: Integer): Integer;
function RowSpanIdentical(ARow1,ARow2: Integer): Boolean;
function ColSpanIdentical(ACol1,ACol2: Integer): Boolean;
procedure MergeCells(c,r,spanx,spany: Integer); virtual;
procedure SplitCells(c,r: Integer); virtual;
procedure RepaintCell(c,r: Integer);
function TotalColCount: Integer; virtual;
property ActiveRowColorTo: TColor read FActiveRowColorTo write SetActiveRowColorTo default clNone;
property ActiveRowMirrorColor: TColor read FActiveRowMirrorColor write SetActiveRowMirrorColor default clNone;
property ActiveRowMirrorColorTo: TColor read FActiveRowMirrorColorTo write SetActiveRowMirrorColorTo default clNone;
property Objects[c,r: Integer]: TObject read GetObjectEx write SetObjectEx;
property GraphicObjects[c,r: Integer]: TObject read GetGraphicObjectEx write SetGraphicObjectEx;
property Cells[c,r: Integer]: String read GetCellEx write SetCellEx;
property GridCells[c,r: Integer]: string read GetGridCell write SetGridCell;
property WordWrap: boolean read FWordWrap write FWordWrap;
//property Rows[r: Integer]: TStrings read GetRowsEx write SetRowsEx;
published
{ Published declarations }
property ActiveRowShow: Boolean read FActiveRowShow write SetActiveRowShow default False;
property ActiveRowColor: TColor read FActiveRowColor write SetActiveRowColor default clInfoBk;
property DefaultDrawing: Boolean read GetDefaultDrawing write SetDefaultDrawing default False;
property GridLineWidth: Integer read GetGridLineWidth write SetGridLineWidth default 1;
property GridLineColor: TColor read FGridLineColor write SetGridLineColor default clSilver;
property GridFixedLineColor: TColor read FGridFixedLineColor write SetGridFixedLineColor default clGray;
property GridFixedLineWidth: integer read FGridFixedLineWidth write SetGridFixedLineWidth default 1;
property HoverRow: boolean read FHoverRow write FHoverRow default false;
property HoverRowColor: TColor read FHoverRowColor write FHoverRowColor default clInfoBk;
property HoverRowColorTo: TColor read FHoverRowColorTo write FHoverRowColorTo default clNone;
property HoverRowCells: THoverRowCells read FHoverRowCells write FHoverRowCells default [hcNormal, hcSelected];
property OnGetDisplText: TGetDisplTextEvent read FOnGetDisplText write FOnGetDisplText;
property OnGetDisplWideText: TGetDisplWideTextEvent read FOnGetDisplWideText write FOnGetDisplWideText;
property UndoRedo: TAdvGridUndoRedo read FUndoRedo write SetUndoRedo;
end;
implementation
uses
AdvUtil;
const
GRADIENT_DIRECTION = false;
{ TBaseGrid }
constructor TBaseGrid.Create(AOwner: TComponent);
begin
inherited;
GridLineWidth := 1;
FGridLineColor := clSilver;
FGridFixedLineColor := clGray;
FGridFixedLineWidth := 1;
DefaultDrawing := False;
CustomSelect := True;
FHideLastRow := False;
FActiveRowColor := clInfoBk;
FActiveRowShow := false;
FWordWrap := true;
FPaintID := 1;
FShowSel := true;
FMergeCount := 0;
FHoverRow := false;
FHoverRowIdx := -1;
FHoverRowColor := clInfoBk;
FHoverRowColorTo := clNone;
FActiveRowColorTo := clNone;
FActiveRowMirrorColor := clNone;
FActiveRowMirrorColorTo := clNone;
FHoverRowCells := [hcNormal, hcSelected];
FDefFont := TFont.Create;
FDefBrush := TBrush.Create;
end;
destructor TBaseGrid.Destroy;
begin
FDefFont.Free;
FDefBrush.Free;
ClearProps;
inherited;
end;
procedure TBaseGrid.Paint;
begin
inherited;
inc(FPaintID);
end;
procedure TBaseGrid.DrawGridCell(Canvas:TCanvas; ACol, ARow: Integer; ARect: TRect;
AState: TGridDrawState);
begin
DrawText(Canvas.Handle,PChar(Cells[ACol,ARow]),Length(Cells[ACol,ARow]),ARect,DT_CENTER or DT_VCENTER or DT_SINGLELINE);
end;
procedure TBaseGrid.PaintCell(ACanvas: TCanvas; ACol: Integer; ARow: Integer; ARect: TRect; AState: TGridDrawState);
begin
PaintCellInt(ACanvas, ACol, ARow, ARect, AState, true);
end;
procedure TBaseGrid.PaintCellExt(ACanvas: TCanvas; ACol, ARow: Integer;
ARect: TRect; AState: TGridDrawState);
begin
PaintCellInt(ACanvas, ACol, ARow, ARect, AState, false);
end;
procedure TBaseGrid.PaintCellInt(ACanvas: TCanvas; ACol: Integer; ARow: Integer; ARect: TRect; AState: TGridDrawState; internal: boolean = true);
var
hrgn: THandle;
CrL,CrT: Integer;
OutofBounds: Boolean;
MCol,MRow: Integer;
HA: TAlignment;
VA: TVAlignment;
WW: Boolean;
GLW: Integer;
AColorTo,AMirrorColor,AMirrorColorTo: TColor;
GD: TCellGradientDirection;
mode: TGradientPart;
ls,rs,ms,rc: integer;
SR: TRect;
dosel,dofix: boolean;
begin
hrgn := 0;
// Leave drawing of the last row to the floating last fixed row
if (ARow = RowCount - 1) and FHideLastRow then
begin
ACanvas.Brush.Color := Color;
ACanvas.Pen.Color := Color;
ACanvas.Rectangle(ARect.Left,ARect.Top, ARect.Right ,ARect.Bottom);
Exit;
end;
if (RowHeights[ARow] = 0) then
Exit;
// compensate for hidden cols
rc := RealColIndex(ACol);
// Redirect painting to base cell
if not IsBaseCellEx(rc,ARow,MCol,MRow) then
begin
if (CellProperties[MCol,MRow].PaintID <> FPaintID) then
begin
CellProperties[MCol,MRow].PaintID := FPaintID;
PaintCell(ACanvas,MCol,MRow,ARect,AState);
end;
Exit;
end;
if IsFixed(ACol,ARow) and internal then
AState := AState + [gdFixed] - [gdSelected];
if Internal then
ARect := CellRect(ACol,ARow);
CrL := 0;
CrT := 0;
if (ACol >= FixedCols) then
CrL := FixedColsWidth;
if (ARow >= FixedRows) then
CrT := FixedRowsHeight;
OutOfBounds := ((ACol >= FixedCols) and (FixedCols > 0) and (ARect.Left < CrL)) or
((ARow >= FixedRows) and (FixedRows > 0) and (ARect.Top < CrT));
if OutOfBounds then
begin
hrgn := CreateRectRgn(CrL, CrT, Width,Height);
SelectClipRgn(ACanvas.Handle, hrgn);
end;
ACanvas.Pen.Width := 1;
ACanvas.Font.Assign(Font);
// virtual method to get cell colors
GetVisualProperties(ACol,ARow,AState,False,True,True,ACanvas.Brush,AColorTo,AMirrorColor,AMirrorColorTo,ACanvas.Font,HA,VA,WW,GD);
ACanvas.Pen.Color := ACanvas.Brush.Color;
dosel := (gdSelected in AState) and not (hcSelected in HoverRowCells);
dofix := (gdFixed in AState) and not (hcFixed in HoverRowCells);
if HasNodes then
begin
if not (hcGroupHeader in HoverRowCells) then
begin
if IsNode(arow) then
dofix := true;
end;
if not (hcGroupSummary in HoverRowCells) then
begin
if IsSummary(arow) then
dofix := true;
end;
end;
// hover row color setting
if (ARow = FHoverRowIdx) and FHoverRow and not dosel and not dofix then
begin
ACanvas.Brush.Color := FHoverRowColor;
AColorTo := FHoverRowColorTo;
AMirrorColor := clNone;
AMirrorColorTo := clNone;
GD := GradientVertical;
end;
// active row color has priority on hover row color
if ((ActiveRowShow) and (ARow = Row) and not IsFixed(ACol,ARow) and
((ACol <> Col) or (not FShowSel) or (goRowSelect in Options)) and (ACol >= FixedCols)) or (not internal and (gdSelected in AState)) then
begin
ACanvas.Brush.Color := ActiveRowColor;
//AColorTo := ActiveRowColor;
//AMirrorColor := clNone;
//AMirrorColorTo := clNone;
AColorTo := ActiveRowColorTo;
AMirrorColor := ActiveRowMirrorColor;
AMirrorColorTo := ActiveRowMirrorColorTo;
end;
ACanvas.Pen.Color := ACanvas.Brush.Color;
// if cell is selected and a special selection style is choosen
if (gdSelected in AState) and (FSelectionStyle <> ssDefault) and FShowSel then
begin
ls := Selection.Left;
rs := Selection.Right;
if ls > rs then
begin
ms := rs;
rs := ls;
ls := ms;
end;
//if (ACol = ls) and (ACol = rs) then
mode := gpFull;
if (ACol = ls) and (ACol < rs) then
mode := gpLeft;
if (ACol = rs) and (ACol > ls) then
mode := gpRight;
if (ACol > ls) and (ACol < rs) then
mode := gpMiddle;
SR := ARect;
if not (goHorzLine in Options) then
SR.Bottom := SR.Bottom + 1;
if not (goVertLine in Options) then
SR.Right := SR.Right + 1;
if HasCustomCellBorder and (FSelectionStyle = ssDefault) and FShowSel then
begin
SR.Left := SR.Left + 1;
SR.Right := SR.Right - 1;
SR.Bottom := SR.Bottom - 1;
SR.Top := SR.Top + 1;
end;
if BiDiMode = bdRightToLeft then
begin
SR.Right := SR.Right + 1;
SR.Bottom := SR.Bottom + 1;
end;
if (GetFocus = Handle) or (goDrawFocusSelected in Options) then
begin
case FSelectionStyle of
ssVista:DrawSelectionGradient(ACanvas,$FDF8F1,$FCEFD5,clNone,clNone,$FDFBF6,$FDF5E7,$FDDE99,$FCEDCB,Color,SR,mode);
ssWin7:DrawSelectionGradient(ACanvas,$FCEBDC,$FCDBC1,clNone,clNone,$FDF4EB,$FDEADB,$CEA27D,$E0C5AE,Color,SR,mode);
ssOffice2007:DrawSelectionGradient(ACanvas,$D7FFFD,$58D4FC,$58D4FC,$B3F1FC,$F4FEFF,$CAF8FF,$8DD7D3,$C3D9DF,Color,SR,mode);
end;
end
else
begin
DrawSelectionGradient(ACanvas,$F8F8F8,$E5E5E5,clNone,clNone,$FBFAFA,$F0F0F0,$D9D9D9,$EFEFEF,Color, SR,mode);
end;
end
else
begin
if not (UseVCLStyles and (not HasCellProperties(ACol,ARow))) or (not (gdFixed in AState) and not (gdSelected in AState)) then
begin
if (AMirrorColorTo <> clNone) then
DrawVistaGradient(ACanvas,ARect,ACanvas.Brush.Color,AColorTo,AMirrorColor,AMirrorColorTo, true, clNone)
else
DrawGradient(ACanvas,ACanvas.Brush.Color,AColorTo,64,ARect,GD = GradientHorizontal)
end;
end;
if gdFixed in AState then
begin
if FGridFixedLineWidth > 0 then
ACanvas.Pen.Color := FGridFixedLineColor;
ACanvas.Pen.Width := FGridFixedLineWidth;
GLW := (FGridFixedLineWidth + 1) shr 1;
end
else
begin
if FGridLineWidth > 0 then
ACanvas.Pen.Color := FGridLineColor;
ACanvas.Pen.Width := FGridLineWidth;
GLW := (FGridLineWidth + 1) shr 1;
end;
if (ACol = 0) and (ARow >= FixedRows) then
begin
//if NodeIndent(ARow) > 0 then
// ARect.Left := ColWidths[0] + 1;
// ARect.Left := ARect.Left + NodeIndent(ARow);
end;
// if not (gdFixed in AState) or Ctl3D then
begin
// Draw grid borders
// if not ((MCol = 0) and not Ctl3D and (ARow >= FixedRows) and HasNodes) then
if ((goHorzLine in Options) and not (gdFixed in AState)) or
((goFixedHorzLine in Options) and (gdFixed in AState)) then
begin
ACanvas.MoveTo(ARect.Left - GLW ,ARect.Bottom - GLW);
ACanvas.LineTo(ARect.Right - GLW ,ARect.Bottom - GLW);
end;
if ((goVertLine in Options) and not (gdFixed in AState)) or
((goFixedVertLine in Options) and (gdFixed in AState)) then
begin
if UseRightToLeftAlignment then
begin
ACanvas.MoveTo(ARect.Right - GLW + 1,ARect.Bottom - GLW);
ACanvas.LineTo(ARect.Right - GLW + 1,ARect.Top - GLW);
end
else
begin
ACanvas.MoveTo(ARect.Right - GLW ,ARect.Bottom - GLW);
ACanvas.LineTo(ARect.Right - GLW ,ARect.Top -GLW);
end;
end;
end;
SR := ARect;
if gdFixed in AState then
begin
//Inflaterect(ARect,-1,-1);
ARect.Right := ARect.Right - 1;
ARect.Bottom := ARect.Bottom - 2;
end
else
begin
ARect.Left := ARect.Left + 1;
ARect.Top := ARect.Top + 1;
ARect.Right := ARect.Right - FGridLineWidth;
ARect.Bottom := ARect.Bottom - FGridLineWidth;
// Inflaterect(ARect, -FGridLineWidth, -FGridLineWidth);
end;
if internal then
begin
DrawGridCell(ACanvas,ACol,ARow,ARect,AState);
end;
ARect := SR;
// DrawText(Canvas.Handle,PChar(Cells[ACol,ARow]),Length(Cells[ACol,ARow]),ARect,DT_CENTER or DT_VCENTER or DT_SINGLELINE or DT_NOCLIP);
if OutOfBounds then
begin
SelectClipRgn(ACanvas.Handle, 0);
DeleteObject(hrgn);
end;
ACanvas.Brush.Style := bsSolid;
ACanvas.Pen.Style := psSolid;
end;
procedure TBaseGrid.DrawCell(ACol, ARow: Integer; ARect: TRect; AState: TGridDrawState);
begin
PaintCellInt(Canvas, ACol, ARow, ARect, AState);
end;
function TBaseGrid.GetDefaultAlignment: TAlignment;
begin
Result := taLeftJustify;
end;
function TBaseGrid.GetDefaultDrawing: boolean;
begin
Result := FDefaultDrawing;
end;
procedure TBaseGrid.GetDefaultProps(ACol, ARow: Integer; AFont: TFont;
ABrush: TBrush; var AColorTo, AMirrorColor, AMirrorColorTo: TColor; var HA: TAlignment;
var VA: TVAlignment; var WW: boolean; var GD: TCellGradientDirection);
begin
AFont.Assign(Font);
ABrush.Color := Color;
AColorTo := clNone;
AMirrorColor := clNone;
AMirrorColorTo := clNone;
HA := GetDefaultAlignment;
VA := vtaTop;
WW := WordWrap;
GD := GradientVertical;
end;
function TBaseGrid.GetGridLineWidth: integer;
begin
Result := FGridLineWidth;
end;
procedure TBaseGrid.SetObjectEx(c, r: integer; const Value: TObject);
var
EC: Boolean;
begin
EC := GridCells[c,r] = '';
if EC then
GridCells[c,r] := ' ';
//if not Assigned(inherited Objects[c,r]) then
// inherited Objects[c,r] := TCellProperties.Create(self,c,r);
//TCellProperties(inherited Objects[c,r]).CellObject := Value;
// set cellobject in a correct initialized cellproperties object
CellProperties[c,r].CellObject := TIObjType(Value);
if EC then
GridCells[c,r] := '';
end;
procedure TBaseGrid.SetSelectionStyle(const Value: TGridSelectionStyle);
begin
if (Value <> FSelectionStyle) then
begin
FSelectionStyle := Value;
Invalidate;
end;
end;
function TBaseGrid.GetObjectEx(c, r: integer): TObject;
begin
if Assigned(inherited Objects[c,r]) then
Result := TObject(TCellProperties(inherited Objects[c,r]).CellObject)
else
Result := nil;
end;
procedure TBaseGrid.SetDefaultDrawing(const Value: boolean);
begin
inherited DefaultDrawing := false;
FDefaultDrawing := value;
end;
procedure TBaseGrid.SetGridLineColor(const Value: TColor);
begin
if (FGridLineColor <> Value) then
begin
FGridLineColor := Value;
Invalidate;
end;
end;
procedure TBaseGrid.SetGridFixedLineColor(const Value: TColor);
begin
if FGridFixedLineColor <> Value then
begin
FGridFixedLineColor := Value;
Invalidate;
end;
end;
procedure TBaseGrid.SetGridFixedLineWidth(const Value: integer);
begin
if (FGridFixedLineWidth <> Value) then
begin
FGridFixedLineWidth := Value;
Invalidate;
end;
end;
procedure TBaseGrid.SetGridLineWidth(const Value: integer);
begin
FGridLineWidth := value;
inherited GridLineWidth := 0;
Invalidate;
end;
function TBaseGrid.GetCellRect(c,r: integer): TRect;
var
i,x,y: Integer;
ARect,tlr: TRect;
begin
x := 0;
y := 0;
for i := 1 to c do x := x + ColWidths[i - 1];
if BidiMode = bdRightToLeft then
x := Width - x;
for i := 1 to r do y := y + RowHeights[i - 1];
// absolute rectangle of cell
if BidiMode = bdRightToLeft then
ARect := Rect(x - ColWidths[c],y,x,y + RowHeights[r])
else
ARect := Rect(x,y,x + ColWidths[c],y + RowHeights[r]);
x := 0;
y := 0;
if c >= FixedCols then
for i := 1 to LeftCol do
x := x + ColWidths[i - 1];
if r >= FixedRows then
for i := 1 to TopRow do
y := y + RowHeights[i - 1];
OffsetRect(ARect, -x, -y);
tlr := inherited CellRect(LeftCol,TopRow);
if c < FixedCols then
tlr.Left := 0;
if r < FixedRows then
tlr.Top := 0;
OffsetRect(ARect,tlr.Left,tlr.Top);
if BidiMode = bdRightToLeft then
begin
if RowCount > VisibleRowCount then
OffsetRect(ARect, -GetSystemMetrics(SM_CXVSCROLL) - 4,0);
end;
Result := ARect;
end;
function TBaseGrid.GetCPGraphicObject(cp: TCellProperties): TObject;
begin
Result := cp.FGraphicObject;
end;
function TBaseGrid.CellRect(c,r: integer): TRect;
var
r1,r2: TRect;
BC: TPoint;
rc,ro: integer;
begin
rc := RealColIndex(c);
if HasCellProperties(rc,r) then
if (CellProperties[rc,r].CellSpanX <> -1) or (CellProperties[rc,r].CellSpanY > 0) then
begin
BC := CellProperties[rc,r].BaseCell[rc,r];
// compensate for hidden cols here
ro := DisplColIndex(BC.X);
r1 := GetCellRect(ro,BC.Y);
if r1.Left = r1.Right then
r1.Right := r1.Right + 1;
r2 := GetCellRect(ro + CellProperties[BC.X,BC.Y].CellSpanX,BC.Y + CellProperties[BC.X,BC.Y].CellSpanY);
if r2.Left = r2.Right then
r2.Left := r2.Left - 1;
UnionRect(r1, r1, r2);
Result := r1;
end
else
begin
if Assigned(CellProperties[c,r].Control) then
Result := GetCellRect(c,r)
else
begin
r1 := inherited CellRect(c,r);
Result := Rect(r1.Left,r1.Top,r1.Left + ColWidths[c],r1.Top + RowHeights[r]);
end;
end
else
begin
r1 := inherited CellRect(c,r);
Result := Rect(r1.Left,r1.Top,r1.Left + ColWidths[c],r1.Top + RowHeights[r]);
end;
end;
function TBaseGrid.CellSize(c,r: Integer): TPoint;
var
r1,r2: TRect;
BC: TPoint;
begin
if HasCellProperties(c,r) then
if (CellProperties[c,r].CellSpanX <> -1) or (CellProperties[c,r].CellSpanY > 0) then
begin
BC := CellProperties[c,r].BaseCell[c,r];
r1 := GetCellRect(BC.X,BC.Y);
r2 := GetCellRect(BC.X + CellProperties[BC.X,BC.Y].CellSpanX,BC.Y + CellProperties[BC.X,BC.Y].CellSpanY);
UnionRect(r1, r1, r2);
end
else
r1 := GetCellRect(c,r)
else
r1 := GetCellRect(c,r);
Result := Point(r1.Right-r1.Left,r1.Bottom - r1.Top);
end;
function TBaseGrid.CellSpan(ACol,ARow: Integer): TPoint;
var
BC: TPoint;
begin
Result := Point(0,0);
if HasCellProperties(ACol,ARow) then
if (CellProperties[ACol,ARow].CellSpanX <> -1) or (CellProperties[ACol,ARow].CellSpanY > 0) then
begin
BC := CellProperties[ACol,ARow].BaseCell[ACol,ARow];
Result := Point(CellProperties[BC.X,BC.Y].CellSpanX,CellProperties[BC.X,BC.Y].CellSpanY);
end;
end;
procedure TBaseGrid.CellTextChange(ACol, ARow: integer);
begin
//
end;
procedure TBaseGrid.ChangeScale(M, D: Integer);
begin
inherited;
{$IFNDEF DELPHI_UNICODE}
if not (csDesigning in ComponentState) then
begin
if M <> D then
DefaultRowHeight := MulDiv(DefaultRowHeight, M, D);
end;
{$ENDIF}
end;
function TBaseGrid.CellExt(ACol,ARow: Integer): TPoint;
var
BC: TPoint;
cp: TCellProperties;
begin
Result := Point(0,0);
if HasCellProperties(ACol,ARow) then
begin
cp := CellProperties[ACol,ARow];
if (cp.CellSpanX <> -1) and (cp.CellSpanY <> -1) then
begin
BC := cp.BaseCell[ACol,ARow];
Result := Point(BC.X - ACol + CellProperties[BC.X,BC.Y].CellSpanX,
BC.Y - ARow + CellProperties[BC.X,BC.Y].CellSpanY);
end;
end;
end;
function TBaseGrid.IsMergedCell(ACol,ARow: Integer): Boolean;
var
cp: TCellProperties;
begin
Result := False;
if HasCellProperties(ACol,ARow) then
begin
cp := CellProperties[ACol,ARow];
Result := (cp.CellSpanX > 0) or (cp.CellSpanY > 0);
end;
end;
function TBaseGrid.IsMergedNonBaseCell(ACol,ARow: Integer): Boolean;
var
cp: TCellProperties;
begin
Result := False;
if HasCellProperties(ACol,ARow) then
begin
cp := CellProperties[ACol,ARow];
Result := ((cp.CellSpanX > 0) or (cp.CellSpanY > 0)) and
not cp.IsBaseCell;
end;
end;
function TBaseGrid.IsXMergedCell(ACol, ARow: Integer): Boolean;
var
BC: TPoint;
begin
Result := False;
if HasCellProperties(ACol,ARow) then
begin
BC := CellProperties[ACol,ARow].BaseCell[ACol,ARow];
Result := (CellProperties[BC.X,BC.Y].CellSpanX > 0);
end;
end;
function TBaseGrid.IsYMergedCell(ACol, ARow: Integer): Boolean;
var
BC: TPoint;
begin
Result := False;
if HasCellProperties(ACol,ARow) then
begin
BC := CellProperties[ACol,ARow].BaseCell[ACol,ARow];
Result := (CellProperties[BC.X,BC.Y].CellSpanY > 0);
end;
end;
function TBaseGrid.CreateCellProperties(Col,Row: integer): TCellProperties;
var
HA: TAlignment;
VA: TVAlignment;
WW: Boolean;
GD: TCellGradientDirection;
AColorTo, AMirrorColor, AMirrorColorTo: TColor;
cp: TCellProperties;
begin
cp := TCellProperties.Create(Self,Col,Row);
cp.Alignment := GetDefaultAlignment;
inherited Objects[Col,Row] := cp;
// set default values here
WW := WordWrap;
GetDefaultProps(Col,Row,FDefFont,FDefBrush,AColorTo,AMirrorColor,AMirrorColorTo,HA,VA,WW,GD);
cp.FCalcType := acNone;
cp.FAlignment := HA;
cp.FVAlignment := VA;
cp.FWordWrap := WW;
cp.FFontName := FDefFont.Name;
cp.FFontHeight := FDefFont.Height; //Round(FDefFont.Height * ControlDPIScale);
cp.FFontStyle := FDefFont.Style;
cp.FFontColor := FDefFont.Color;
cp.FBrushColor := FDefBrush.Color;
cp.FBrushColorTo := AColorTo;
cp.FGradientDirection := GD;
Result := cp;
end;
function TBaseGrid.GetCellProperties(c, r: integer): TCellProperties;
var
cp: TCellProperties;
begin
if not Assigned(inherited Objects[c,r]) then
begin
cp := CreateCellProperties(c,r);
Result := cp;
end
else
Result := TCellProperties(inherited Objects[c,r]);
end;
procedure TBaseGrid.MergeCells(c, r, spanx, spany: Integer);
var
i,j: Integer;
cp: TCellProperties;
begin
inc(FMergeCount);
for i := c to c + spanx - 1 do
for j := r to r + spany - 1 do
begin
cp := CellProperties[i,j];
cp.IsBaseCell := (i = c) and (j = r);
if cp.IsBaseCell then
begin
cp.CellSpanX := SpanX - 1;
cp.CellSpanY := SpanY - 1;
end
else
begin
cp.CellSpanX := i - c;
cp.CellSpanY := j - r;
end;
end;
for i := c to c + spanx - 1 do
for j := r to r + spany - 1 do
begin
RepaintCell(i,j);
end;
end;
procedure TBaseGrid.SetCellProperties(c, r: integer; const Value: TCellProperties);
begin
if Assigned(inherited Objects[c,r]) then
TCellProperties(inherited Objects[c,r]).Free;
inherited Objects[c,r] := Value
end;
procedure TBaseGrid.SplitCells(c, r: integer);
var
i,j: integer;
spanx,spany: integer;
bc: TPoint;
begin
bc := CellProperties[c,r].BaseCell[c,r];
c := bc.X;
r := bc.Y;
SpanX := CellProperties[c,r].CellSpanX;
SpanY := CellProperties[c,r].CellSpanY;
for i := c to c + spanx do
for j := r to r + spany do
begin
CellProperties[i,j].IsBaseCell := True;
CellProperties[i,j].CellSpanX := -1;
CellProperties[i,j].CellSpanY := -1;
end;
for i := c to c + spanx do
for j := r to r + spany do
RepaintCell(i,j);
dec(FMergeCount);
end;
function TBaseGrid.HasCellProperties(ACol, ARow: integer): boolean;
begin
Result := false;
if (ACol > -1) and (ACol < TotalColCount) then
if (ARow > -1) {and (ARow < RowCount)} then
Result := Assigned(inherited Objects[ACol,ARow]);
end;
function TBaseGrid.HasCustomCellBorder: boolean;
begin
Result := false;
end;
function TBaseGrid.GetCellEx(c, r: integer): string;
var
BC: TPoint;
ws: widestring;
begin
if HasCellProperties(c,r) then
BC := CellProperties[c,r].BaseCell[c,r]
else
BC := Point(c,r);
Result := inherited Cells[BC.X,BC.Y];
if BC.Y < NormalRowCount then
begin
GetDisplText(BC.X,BC.Y,Result);
if Assigned(FOnGetDisplWideText) then
begin
ws := Result;
ws := DecodeWideStr(ws);
GetDisplWideText(BC.X,BC.Y,ws);
Result := EncodeWideStr(ws);
end;
end;
end;
procedure TBaseGrid.SetCellEx(c, r: integer; const Value: String);
var
BC: TPoint;
begin
if HasCellProperties(c,r) then
begin
BC := CellProperties[c,r].BaseCell[c,r];
inherited Cells[BC.X,BC.Y] := Value;
{$IFDEF DELPHI2006_LVL}
CellTextChange(BC.X,BC.Y);
{$ENDIF}
if Assigned(Parent) then
RepaintCell(c,r);
end
else
begin
FEditCellSet := true;
inherited Cells[c,r] := Value;
FEditCellSet := false;
end;
if HideLastRow and (r = RowCount - 1) then
FloatFooterUpdate;
end;
function TBaseGrid.SelectCell(ACol, ARow: Integer): Boolean;
begin
if BiDiMode = bdRightToLeft then
begin
Result := inherited SelectCell(Acol, ARow);
Invalidate;
end
else
begin
RepaintCell(Col,Row);
Result := inherited SelectCell(Acol, ARow);
RepaintCell(ACol,ARow);
end;
end;
procedure TBaseGrid.RepaintCell(c, r: integer);
var
ARect: TRect;
begin
if HandleAllocated Then
begin
ARect := CellRect(c,r);
InvalidateRect(Handle,@ARect,True);
end;
end;
function TBaseGrid.IsSelected(ACol, ARow: Integer): Boolean;
var
sr: TRect;
BC: TPoint;
begin
sr.Left := Selection.Left;
sr.Right := Selection.Right;
sr.Top := Selection.Top;
sr.Bottom := Selection.Bottom;
Result := (ACol >= sr.Left) and (ACol <= sr.Right) and (ARow <= sr.Bottom) and (ARow >= sr.Top);
if Result then Exit;
if HasCellProperties(ACol,ARow) then
begin
if (CellProperties[ACol,ARow].CellSpanX <> 0) or (CellProperties[ACol,ARow].CellSpanY <> 0) then
begin
BC := CellProperties[ACol,ARow].BaseCell[ACol,ARow];
with CellProperties[BC.X,BC.Y] do
Result := (Col >= BC.X) and (Col <= BC.X + CellSpanX) and
(Row >= BC.Y) and (Row <= BC.Y + CellSpanY);
end
end;
end;
procedure TBaseGrid.KeyDown(var Key: Word; Shift: TShiftState);
var
BC: TPoint;
begin
if HasCellProperties(Col,Row) then
BC := CellProperties[Col,Row].BaseCell[Col,Row];
case Key of
VK_LEFT:
begin
if HasCellProperties(Col,Row) then
with CellProperties[BC.X,BC.Y] do
begin
if (Col > BC.X) and (Col > FixedCols) and (BC.X > 0) then
Col := BC.X - CellSpanX;
end;
end;
VK_RIGHT:
begin
if HasCellProperties(Col,Row) then
with CellProperties[BC.X,BC.Y] do
begin
if (Col <= BC.X + CellSpanX) and (Col < ColCount - 1) and
(BC.X < ColCount -1) and (BC.X + CellSpanX < ColCount) then
Col := BC.X + CellSpanX;
end;
end;
VK_UP:
begin
if HasCellProperties(Col,Row) then
with CellProperties[BC.X,BC.Y] do
begin
if (Row > BC.Y) and (Row > FixedRows) and (BC.Y > 0) then
Row := BC.Y - 1;
end;
end;
VK_DOWN:
begin
if HasCellProperties(Col,Row) then
with CellProperties[BC.X,BC.Y] do
begin
if (Row <= BC.Y + CellSpanY) and (Row < RowCount - 1) and
(BC.Y < RowCount - 1) and (BC.Y + CellSpanY + 1 < RowCount) then
Row := BC.Y + CellSpanY + 1;
end;
end;
VK_NEXT:
begin
if (TopRow + VisibleRowCount - FixedRows = RowCount - 1) and
FHideLastRow and (RowCount > 1) then
Row := RowCount - 2;
end;
end;
inherited;
SelectBaseCell;
end;
function TBaseGrid.GetEditText(ACol, ARow: Integer): string;
begin
Result := inherited GetEditText(ACol,ARow);
end;
procedure TBaseGrid.SetEditText(ACol, ARow: Integer; const Value: string);
begin
inherited SetEditText(ACol,ARow,Value);
end;
function TBaseGrid.BaseCell(ACol,ARow: Integer): TPoint;
begin
if HasCellProperties(ACol,ARow) then
with CellProperties[ACol,ARow] do
begin
Result := BaseCell[ACol,ARow];
end
else
Result := Point(ACol,ARow);
end;
function TBaseGrid.IsBaseCellEx(ACol, ARow: Integer;var MCol,MRow: Integer): Boolean;
var
BC: TPoint;
begin
Result := True;
MCol := ACol;
MRow := ARow;
if HasCellProperties(ACol,ARow) then
with CellProperties[ACol,ARow] do
begin
Result := IsBaseCell;
if not Result then
begin
BC := BaseCell[ACol,ARow];
MCol := BC.X;
MRow := BC.Y;
end;
end;
end;
function TBaseGrid.IsBaseCell(ACol, ARow: Integer): Boolean;
begin
Result := True;
if HasCellProperties(ACol,ARow) then
Result := CellProperties[ACol,ARow].IsBaseCell;
end;
function TBaseGrid.NodeIndent(ARow: Integer): Integer;
begin
Result := 0;
end;
procedure TBaseGrid.GetVisualProperties(ACol, ARow: Integer;
var AState: TGridDrawState; Print, Select, Remap: Boolean; ABrush: TBrush; var AColorTo, AMirrorColor, AMirrorColorTo: TColor; AFont: TFont;
var HA: TAlignment; var VA: TVAlignment; var WW: Boolean;var GD: TCellGradientDirection);
begin
end;
function TBaseGrid.GetGraphicObjectEx(c, r: Integer): TObject;
begin
if Assigned(inherited Objects[c,r]) then
Result := TCellProperties(inherited Objects[c,r]).GraphicObject
else
Result := nil;
end;
procedure TBaseGrid.SetGraphicObjectEx(c, r: Integer;
const Value: TObject);
var
EC: Boolean;
AFont: TFont;
ABrush: TBrush;
cp: TCellProperties;
HA: TAlignment;
VA: TVAlignment;
WW: boolean;
GD: TCellGradientDirection;
AColorTo,AMirrorColor,AMirrorColorTo: TColor;
begin
if (csDestroying in ComponentState) then
begin
if (Value = nil) then
TCellProperties(inherited Objects[c,r]).GraphicObject := Value;
Exit;
end;
EC := GridCells[c,r] = '';
if EC then
Cells[c,r] := ' ';
if not Assigned(inherited Objects[c,r]) then
begin
cp := TCellProperties.Create(Self,c,r);
cp.Alignment := GetDefaultAlignment;
inherited Objects[c,r] := cp;
// assign default values
AFont := TFont.Create;
ABrush := TBrush.Create;
GetDefaultProps(c,r,AFont,ABrush,AColorTo,AMirrorColor,AMirrorColorTo,HA,VA,WW,GD);
cp.Alignment := HA;
cp.VAlignment := VA;
cp.WordWrap := WW;
cp.FFontName := AFont.Name;
cp.FFontHeight := AFont.Height;
cp.FFontStyle := AFont.Style;
cp.FFontColor := AFont.Color;
cp.BrushColor := ABrush.Color;
cp.BrushColorTo := AColorTo;
cp.GradientDirection := GD;
ABrush.Free;
AFont.Free;
end;
TCellProperties(inherited Objects[c,r]).GraphicObject := Value;
if EC then
Cells[c,r] := '';
end;
function TBaseGrid.FullCell(c, r: Integer): TRect;
var
pt: TPoint;
begin
pt := BaseCell(c,r);
Result.Left := pt.X;
Result.Top := pt.Y;
pt := CellSpan(c,r);
Result.Right := Result.Left + pt.X;
Result.Bottom := Result.Top + pt.Y;
end;
function TBaseGrid.DoMouseWheelDown(Shift: TShiftState;
MousePos: TPoint): Boolean;
begin
Result := inherited DoMouseWheelDown(Shift,MousePos);
if (Row - TopRow > VisibleRowCount ) and
(Row < RowCount - 1) and FHideLastRow then
TopRow := TopRow + 1;
SelectBaseCell;
end;
function TBaseGrid.DoMouseWheelUp(Shift: TShiftState;
MousePos: TPoint): Boolean;
begin
Result := inherited DoMouseWheelUp(Shift,MousePos);
SelectBaseCell;
end;
procedure TBaseGrid.SelectBaseCell;
var
BC: TPoint;
begin
if HasCellProperties(Col,Row) then
begin
BC := CellProperties[Col,Row].BaseCell[Col,Row];
Col := BC.X;
Row := BC.Y;
end;
end;
function TBaseGrid.FixedColsWidth: Integer;
var
i: Integer;
begin
Result := 0;
for i := 1 to FixedCols do
Result := Result + ColWidths[i - 1];
end;
function TBaseGrid.FixedRowsHeight: Integer;
var
i: Integer;
begin
Result := 0;
for i := 1 to FixedRows do
Result := Result + RowHeights[i - 1];
end;
procedure TBaseGrid.RepaintFixedMergedCols;
var
i,j: Integer;
begin
if FixedRows = 0 then
Exit;
for i := LeftCol to LeftCol + VisibleColCount do
for j := 1 to FixedRows do
if IsMergedCell(i, j - 1) then
RepaintCell(i, j - 1);
end;
procedure TBaseGrid.RepaintFixedMergedRows;
var
i,j: Integer;
begin
if FixedCols = 0 then
Exit;
for i := TopRow to TopRow + VisibleRowCount do
for j := 1 to FixedCols do
if IsMergedCell(j - 1,i) then
RepaintCell(j - 1,i);
end;
procedure TBaseGrid.TopLeftChanged;
begin
inherited;
RepaintFixedMergedRows;
RepaintFixedMergedCols;
end;
function TBaseGrid.TotalColCount: Integer;
begin
Result := ColCount;
end;
function TBaseGrid.UseVCLStyles: boolean;
begin
Result := False;
end;
function TBaseGrid.IsFixed(ACol, ARow: Integer): Boolean;
begin
Result := False;
end;
procedure TBaseGrid.CopyCols(ACol1, ACol2: Integer);
begin
Cols[ACol1] := Cols[ACol2];
end;
procedure TBaseGrid.CopyRows(ARow1, ARow2: Integer);
var
i: Integer;
begin
for i := 1 to ColCount do
begin
Cells[i - 1,ARow1] := Cells[i - 1,ARow2];
inherited Objects[i - 1,ARow1] := inherited Objects[i - 1,ARow2];
end;
end;
procedure TBaseGrid.NilCol(ACol: Integer);
var
i: Integer;
begin
for i := 1 to RowCount do
begin
inherited Objects[ACol,i - 1] := nil;
Cells[ACol,i - 1] := '';
end;
end;
procedure TBaseGrid.NilRow(ARow: Integer);
var
i: Integer;
begin
for i := 1 to ColCount do
begin
inherited Objects[i - 1,ARow] := nil;
Cells[i - 1,ARow] := '';
end;
end;
procedure TBaseGrid.NilCell(ACol, ARow: Integer);
begin
Cells[ACol,ARow] := '';
inherited Objects[ACol,ARow] := nil;
end;
function TBaseGrid.HasNodes: Boolean;
begin
Result := False;
end;
// gets the smallest row span for a given row
function TBaseGrid.MinRowSpan(ARow: Integer): Integer;
var
c,ms,ns: Integer;
begin
ms := RowCount;
for c := 1 to ColCount do
begin
ns := CellSpan(c - 1,ARow).Y;
if (ns > 0) and (ns < ms) then
ms := ns;
end;
Result := ms;
end;
function TBaseGrid.MaxRowSpan(ARow: Integer): Integer;
var
c,ms,ns: Integer;
begin
ms := 0;
for c := 1 to ColCount do
begin
ns := CellSpan(c - 1,ARow).Y;
if (ns > ms) then
ms := ns;
end;
Result := ms;
end;
function TBaseGrid.RowSpanIdentical(ARow1,ARow2: Integer): Boolean;
var
c: Integer;
IsMerged: Boolean;
begin
Result := True;
IsMerged := False;
for c := 1 to ColCount do
begin
if (CellSpan(c - 1,ARow1).Y > 0) and
(CellSpan(c - 1,ARow2).Y > 0) then
begin
IsMerged := True;
if (BaseCell(c - 1,ARow1).Y <> BaseCell(c - 1,ARow2).Y) then
begin
Result := False;
Break;
end;
end;
end;
Result := Result and IsMerged;
end;
function TBaseGrid.ColSpanIdentical(ACol1,ACol2: Integer): Boolean;
var
r: Integer;
IsMerged: Boolean;
begin
Result := True;
IsMerged := False;
for r := 1 to RowCount do
begin
if (CellSpan(ACol1,r - 1).X > 0) and
(CellSpan(ACol2,r - 1).X > 0) then
begin
if (BaseCell(ACol1,r - 1).X <> BaseCell(ACol1,r - 1).X) then
begin
Result := False;
Break;
end;
end
else
if (CellSpan(ACol1,r - 1).X <> CellSpan(ACol2,r - 1).X) then
begin
Result := False;
Break;
end;
end;
Result := Result and IsMerged;
end;
function TBaseGrid.ControlDPIScale: single;
begin
Result := 1;
end;
function TBaseGrid.GetGridObject(c, r: Integer): TObject;
begin
Result := inherited Objects[c,r]
end;
procedure TBaseGrid.SetGridObject(c, r: Integer; const Value: TObject);
begin
inherited Objects[c,r] := Value;
end;
procedure TBaseGrid.FloatFooterUpdate;
begin
end;
function TBaseGrid.GetGridCell(c, r: Integer): string;
begin
Result := inherited Cells[c,r];
end;
procedure TBaseGrid.SetGridCell(c, r: Integer; const Value: string);
begin
inherited Cells[c,r] := Value;
end;
procedure TBaseGrid.ClearPropRect(ACol1, ARow1, ACol2, ARow2: Integer);
var
c,r: Integer;
cp: TCellProperties;
begin
if not FHasCellProps then
Exit;
for c := ACol1 to ACol2 do
for r := ARow1 to ARow2 do
if Assigned(inherited Objects[c,r]) then
begin
cp := TCellProperties(inherited Objects[c,r]);
if Assigned(cp.GraphicObject) and (cp.GraphicObject.ClassName = 'TCellGraphic') then
cp.GraphicObject.Free;
TCellProperties(inherited Objects[c,r]).Free;
inherited Objects[c,r] := nil;
end;
end;
procedure TBaseGrid.ClearPropRow(ARow: Integer);
begin
ClearPropRect(0,ARow,ColCount - 1,ARow);
end;
procedure TBaseGrid.ClearPropCell(ACol, ARow: Integer);
begin
if Assigned(inherited Objects[ACol,ARow]) then
begin
TCellProperties(inherited Objects[ACol,ARow]).Free;
inherited Objects[ACol,ARow] := nil;
end;
end;
procedure TBaseGrid.ClearProps;
begin
ClearPropRect(0,0,ColCount - 1,RowCount - 1);
end;
procedure TBaseGrid.GetDisplText(c, r: Integer; var Value: string);
begin
if Assigned(OnGetDisplText) then
OnGetDisplText(Self,c,r,Value)
end;
procedure TBaseGrid.GetDisplWideText(c, r: Integer; var Value: widestring);
begin
if Assigned(OnGetDisplWideText) then
OnGetDisplWideText(Self,c,r,Value)
end;
procedure TBaseGrid.Notification(AComponent: TComponent;
AOperation: TOperation);
begin
if (AOperation = opRemove) and (AComponent = FUndoRedo) then
FUndoRedo := nil;
inherited;
end;
procedure TBaseGrid.SetUndoRedo(const Value: TAdvGridUndoRedo);
begin
FUndoRedo := Value;
if Assigned(FUndoRedo) then
FUndoRedo.Grid := Self;
end;
function TBaseGrid.DisplColIndex(ACol: Integer): Integer;
begin
Result := ACol;
end;
function TBaseGrid.RealColIndex(ACol: Integer): Integer;
begin
Result := ACol;
end;
procedure TBaseGrid.SetActiveRowColorTo(const Value: TColor);
begin
if (FActiveRowColorTo <> Value) then
begin
FActiveRowColorTo := Value;
Invalidate;
end;
end;
procedure TBaseGrid.SetActiveRowMirrorColor(const Value: TColor);
begin
if (FActiveRowMirrorColor <> Value) then
begin
FActiveRowMirrorColor := Value;
Invalidate;
end;
end;
procedure TBaseGrid.SetActiveRowMirrorColorTo(const Value: TColor);
begin
if (FActiveRowMirrorColorTo <> Value) then
begin
FActiveRowMirrorColorTo := Value;
Invalidate;
end;
end;
procedure TBaseGrid.SetActiveRowColor(const Value: TColor);
begin
if (FActiveRowColor <> Value) then
begin
FActiveRowColor := Value;
Invalidate;
end;
end;
procedure TBaseGrid.SetActiveRowShow(const Value: Boolean);
begin
if (FActiveRowShow <> Value) then
begin
FActiveRowShow := Value;
Invalidate;
end;
end;
{ TCellProperties }
procedure TCellProperties.Assign(Source: TPersistent);
begin
if (Source is TCellProperties) then
begin
FIsBaseCell := TCellProperties(Source).IsBaseCell;
FCellSpanX := TCellProperties(Source).CellSpanX;
FCellSpanY := TCellProperties(Source).CellSpanY;
FOwnerRow := TCellProperties(Source).OwnerRow;
FOwnerCol := TCellProperties(Source).OwnerCol;
FObject := TCellProperties(Source).CellObject;
FAlignment := TCellProperties(Source).Alignment;
FBorderColor := TCellProperties(Source).BorderColor;
FBorderWidth := TCellProperties(Source).BorderWidth;
FBrushColor := TCellProperties(Source).BrushColor;
FBrushStyle := TCellProperties(Source).BrushStyle;
FFontColor := TCellProperties(Source).FontColor;
FFontStyle := TCellProperties(Source).FontStyle;
FFontName := TCellProperties(Source).FontName;
FFontHeight := TCellProperties(Source).FontSize;
FReadOnly := TCellProperties(Source).ReadOnly;
FEditor := TCellProperties(Source).Editor;
FValignment := TCellProperties(Source).VAlignment;
FWordWrap := TCellProperties(Source).WordWrap;
FNodeLevel := TCellProperties(Source).NodeLevel;
FControl := TCellProperties(Source).Control;
FMergeCollaps := TCellProperties(Source).MergeCollaps;
end;
end;
constructor TCellProperties.Create(AOwner: TBaseGrid; ACol, ARow:integer);
begin
inherited Create;
FObject := 0;
FGraphicObject := nil;
FIsBaseCell := True;
FCellSpanX := -1;
FCellSpanY := -1;
FBrushColor := clNone;
FBrushColorTo := clNone;
FFontColor := clNone;
FReadOnly := False;
FOwnerGrid := AOwner;
FOwnerCol := ACol;
FOwnerRow := ARow;
FCalcObject := nil;
FWordWrap := AOwner.FWordWrap;
FNodeLevel := 0;
FMergeCollaps := False;
AOwner.FHasCellProps := True;
end;
function TCellProperties.GetBaseCell(c, r: Integer): TPoint;
begin
if IsBaseCell then
Result := Point(c,r)
else
begin
if (CellSpanX <> - 1) and (CellSpanY >= 0) then
Result := Point(c - CellSpanX,r - CellSpanY)
else
Result := Point(c,r)
end;
end;
function TCellProperties.GetCellSpanY: Integer;
begin
if not FMergeCollaps then
Result := FCellSpanY
else
Result := 0;
end;
procedure TCellProperties.SetAlignment(const Value: TAlignment);
begin
FAlignment := Value;
end;
procedure TCellProperties.SetBrushColor(const Value: TColor);
begin
FBrushColor := Value;
FOwnerGrid.RepaintCell(FOwnerCol, FOwnerRow);
end;
procedure TCellProperties.SetBrushColorTo(const Value: TColor);
begin
FBrushColorTo := Value;
FOwnerGrid.RepaintCell(FOwnerCol, FOwnerRow);
end;
procedure TCellProperties.SetVAlignment(const Value: TVAlignment);
begin
FValignment := Value;
FOwnerGrid.RepaintCell(FOwnerCol, FOwnerRow);
end;
procedure TCellProperties.SetWordWrap(const Value: Boolean);
begin
FWordWrap := Value;
FOwnerGrid.RepaintCell(FOwnerCol, FOwnerRow);
end;
{ TAdvGridUndoRedo }
function TAdvGridUndoRedo.CanRedo: Boolean;
begin
Result := (FLevel < FItems.Count);
end;
function TAdvGridUndoRedo.CanUndo: Boolean;
begin
Result := (FLevel > 0);
end;
constructor TAdvGridUndoRedo.Create(AOwner: TComponent);
begin
inherited;
FItems := TUndoRedoCollection.Create;
FLevel := 0;
end;
destructor TAdvGridUndoRedo.Destroy;
begin
FItems.Free;
inherited;
end;
procedure TAdvGridUndoRedo.Notification(AComponent: TComponent;
AOperation: TOperation);
begin
if (AOperation = opRemove) and (AComponent = FGrid) then
FGrid := nil;
inherited;
end;
procedure TAdvGridUndoRedo.Redo;
begin
if Assigned(Grid) then
begin
if (FLevel < FItems.Count) then
begin
inc(FLevel);
if TUndoRedoItem(FItems.Items[FLevel - 1]).SequenceStart then
begin
inc(FLevel);
while (FLevel < FItems.Count) and not (TUndoRedoItem(FItems.Items[FLevel - 1]).SequenceStop) do
begin
with TUndoRedoItem(FItems.Items[FLevel - 1]) do
begin
if Assigned(FOnRedo) then
FOnRedo(self, Grid, Col, Row, Grid.Cells[Col,Row], Value);
Grid.Cells[Col,Row] := Value;
Grid.Col := Grid.DisplColIndex(Col);
Grid.Row := Row;
end;
inc(FLevel);
end;
Grid.Invalidate;
end
else
with TUndoRedoItem(FItems.Items[FLevel - 1]) do
begin
if Assigned(FOnRedo) then
FOnRedo(self, Grid, Col, Row, Grid.Cells[Col,Row], Value);
Grid.Cells[Col,Row] := Value;
Grid.Col := Grid.DisplColIndex(Col);
Grid.Row := Row;
Grid.RepaintCell(Grid.Col,Grid.Row);
end;
end;
end;
end;
procedure TAdvGridUndoRedo.RegisterChange(ACol, ARow: Integer; OldValue,
NewValue: string);
begin
if (FItems.Count >= FMaxLevel) and (FMaxLevel > 0) then
FItems.Items[0].Free;
with TUndoRedoItem(FItems.Add) do
begin
Col := ACol;
Row := ARow;
Value := NewValue;
OrigValue := OldValue;
SequenceStart := false;
SequenceStop := false;
end;
FLevel := FItems.Count;
end;
procedure TAdvGridUndoRedo.Reset;
begin
while (FItems.Count > 0) do
FItems.Items[0].Free;
FLevel := 0;
end;
procedure TAdvGridUndoRedo.StartSequence;
begin
with TUndoRedoItem(FItems.Add) do
begin
Col := -1;
Row := -1;
Value := '';
OrigValue := '';
SequenceStart := true;
SequenceStop := false;
end;
FLevel := FItems.Count;
end;
procedure TAdvGridUndoRedo.StopSequence;
begin
with TUndoRedoItem(FItems.Add) do
begin
Col := -1;
Row := -1;
Value := '';
OrigValue := '';
SequenceStart := false;
SequenceStop := true;
end;
FLevel := FItems.Count;
end;
procedure TAdvGridUndoRedo.Undo;
begin
if Assigned(Grid) and (FLevel > 0) and (FLevel <= FItems.Count) then
begin
if TUndoRedoItem(FItems.Items[FLevel - 1]).SequenceStop then
begin
dec(FLevel);
while (FLevel > 0) and not (TUndoRedoItem(FItems.Items[FLevel - 1]).SequenceStart) do
begin
with TUndoRedoItem(FItems.Items[FLevel - 1]) do
begin
if Assigned(FOnUndo) then
FOnUndo(self, Grid, Col, Row, Grid.Cells[Col,Row], OrigValue);
Grid.Cells[Col,Row] := OrigValue;
Grid.Col := Grid.DisplColIndex(Col);
Grid.Row := Row;
end;
dec(FLevel);
end;
dec(FLevel);
Grid.Invalidate;
end
else
begin
with TUndoRedoItem(FItems.Items[FLevel - 1]) do
begin
if Assigned(FOnUndo) then
FOnUndo(self, Grid, Col, Row, Grid.Cells[Col,Row], OrigValue);
if Grid.IsCheckCell(Col, Row) then
Grid.SetAsCheck(Col ,Row, OrigValue)
else
Grid.Cells[Col, Row] := OrigValue;
Grid.Col := Grid.DisplColIndex(Col);
Grid.Row := Row;
Grid.RepaintCell(Grid.Col,Row);
end;
dec(FLevel);
end;
end;
end;
{ TUndoRedoCollection }
constructor TUndoRedoCollection.Create;
begin
inherited Create(TUndoRedoItem);
end;
end.
------------------------
unit interposer_class;
interface
uses
Vcl.Forms, Vcl.Controls, CommCtrl, Messages, sPanel, sEdit, sPageControl, System.Classes, AdvCGrid, Uni, pixel_classes;
{$TYPEINFO ON}
type
TZString = type string;
type
TForm = class(Vcl.Forms.TForm)
protected
procedure CreateParams(var Params: TCreateParams); override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
end;
TsPanel = class(sPanel.TsPanel)
protected
procedure CreateParams(var Params: TCreateParams); override;
end;
TsEdit = class(sEdit.TsEdit)
protected
procedure CreateParams(var Params: TCreateParams); override;
end;
TsPageControl = class(sPageControl.TsPageControl)
protected
procedure CreateParams(var Params: TCreateParams); override;
private
procedure TCMAdjustRect(var Msg: TMessage); message TCM_ADJUSTRECT;
end;
TAdvColumnGrid = class(AdvCGrid.TAdvColumnGrid)
private
FByPassAF: TArray<Boolean>;
FORMField: TArray<string>; // Added array for ORMField property
function GetCells(ACol, ARow: Integer): TZString;
procedure SetCells(ACol, ARow: Integer; const Value: TZString);
function GetBypassAF(ACol: Integer): Boolean;
procedure SetBypassAF(ACol: Integer; const Value: Boolean);
function GetORMField(ACol: Integer): string; // Getter for ORMField
procedure SetORMField(ACol: Integer; const Value: string); // Setter for ORMField
protected
procedure CreateParams(var Params: TCreateParams); override;
public
property Cells[ACol, ARow: Integer]: TZString read GetCells write SetCells;
property BypassAutoFit[ACol: Integer]: Boolean read GetBypassAF write SetBypassAF;
property ORMField[ACol: Integer]: string read GetORMField write SetORMField; // New ORMField property
published
function CriaLinhaObjeto(MyObject: TObject): Integer;
function CriaLinha: Integer;
function GetColumnIndexByName(const nome: string): Integer;
procedure SetBasicColumnConfig;
end;
implementation
uses
pixel_utils, System.Math, System.Types, Windows, System.SysUtils, TypInfo, Generics.Collections, Data.DB, Vcl.Graphics, ComCtrls, Vcl.Grids;
procedure TForm.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
StrPCopy(Params.WinClassName, 'ZPro');
end;
constructor TForm.Create(AOwner: TComponent);
begin
inherited;
end;
destructor TForm.Destroy;
begin
inherited;
end;
procedure TsPanel.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
StrPCopy(Params.WinClassName, 'Painel');
end;
procedure TsEdit.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
StrPCopy(Params.WinClassName, 'Editor');
end;
procedure TsPageControl.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
StrPCopy(Params.WinClassName, 'PagCtrl');
end;
procedure TsPageControl.TCMAdjustRect(var Msg: TMessage);
begin
inherited;
case TabPosition of
tpTop:
begin
PRect(Msg.LParam)^.Left := 0;
PRect(Msg.LParam)^.Right := ClientWidth;
PRect(Msg.LParam)^.Bottom := ClientHeight;
end;
end;
end;
procedure TAdvColumnGrid.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
StrPCopy(Params.WinClassName, 'Grid');
end;
function TAdvColumnGrid.GetCells(ACol, ARow: Integer): TZString;
begin
Result := Self.Cells[ACol, ARow];
end;
procedure TAdvColumnGrid.SetCells(ACol, ARow: Integer; const Value: TZString);
begin
Self.Cells[ACol, ARow] := string(Value);
end;
function TAdvColumnGrid.GetBypassAF(ACol: Integer): Boolean;
begin
Result := FByPassAF[ACol];
end;
procedure TAdvColumnGrid.SetBypassAF(ACol: Integer; const Value: Boolean);
begin
if Length(FByPassAF) < ACol + 1 then SetLength(FByPassAF, ACol + 1);
FByPassAF[ACol] := Value;
end;
function TAdvColumnGrid.GetORMField(ACol: Integer): string;
begin
if Length(FORMField) > ACol then
Result := FORMField[ACol]
else
Result := ''; // Return empty string if the column index is out of bounds
end;
procedure TAdvColumnGrid.SetORMField(ACol: Integer; const Value: string);
begin
if Length(FORMField) < ACol + 1 then SetLength(FORMField, ACol + 1);
FORMField[ACol] := Value; // Set the ORMField for the specific column
end;
function TAdvColumnGrid.CriaLinha: Integer;
begin
Self.RowCount := Self.RowCount + 1;
Self.ClearRows(Self.RowCount - 1, 1);
Result := Self.RowCount - 1;
end;
function TAdvColumnGrid.CriaLinhaObjeto(MyObject: TObject): Integer;
begin
Self.RowCount := Self.RowCount + 1;
Self.ClearRows(Self.RowCount - 1, 1);
Self.Objects[0, Self.RowCount - 1] := MyObject;
Result := Self.RowCount - 1;
end;
function TAdvColumnGrid.GetColumnIndexByName(const nome: string): Integer;
begin
Result := 0;
for var i := 1 to Pred(Self.ColCount) do
if Self.Columns[i].Name = nome then Exit(i);
end;
procedure TAdvColumnGrid.SetBasicColumnConfig;
var i: Integer;
begin
with Self do
begin
SuppressColumn(0);
for i := 1 to ColCount - 1 do
if Columns[i].Tag = 0 then
begin
Columns[i].HeaderAlignment := taCenter;
Columns[i].HeaderFont.Name := 'Tahoma';
Columns[i].HeaderFont.Size := MulDiv(8, 96, Self.CurrentPPI);
Columns[i].HeaderFont.Color := clWhite;
Columns[i].HeaderFont.Style := [fsBold];
end;
for i := 1 to ColCount - 1 do
if Columns[i].Tag = 0 then
begin
Columns[i].Font.Name := 'Verdana';
Columns[i].Font.Size := MulDiv(10, 96, Self.CurrentPPI);
Columns[i].Font.Style := [];
end;
for i := 1 to ColCount - 1 do
if Columns[i].Tag = 0 then
begin
Columns[i].ShowBands := True;
Colors[i, 0] := RGB($41, $3F, $42);
end;
for i := 1 to ColCount - 1 do Columns[i].Tag := 1; // Flag that default settings have been applied
Bands.PrimaryColor := $00EFEFEF;
Bands.SecondaryColor := $00F9F9F9;
MouseActions.DirectEdit := True;
MouseActions.DirectComboDrop := True;
Bands.Active := True;
ActiveCellShow := False;
Navigation.SkipDisabledRows := True;
Navigation.AutoComboSelect := False;
ShowSelection := True;
HideFocusRect := True;
Options := Options - [goRangeSelect] + [goRowSelect];
HoverRow := True;
HoverRowColor := clYellow;
ActiveRowShow := True;
ActiveRowColor := clLime;
SelectionColor := clLime;
SelectionTextColor := clBlack;
ColumnSize.Stretch := False;
ColumnSize.StretchColumn := -1; // Sets the rightmost column to stretch
ColumnSize.SynchWithGrid := False;
FixedRowAlways := True;
FixedRows := 1;
end;
end;
end.
----------------------------
How can I correclty interpose the original property Cells[ACol, ARow: Integer] ?
If my interposer_class code, the Delphi compiler gives an error: Field or method identifier expected
In Delphi, to correctly interpose an existing property like `Cells[ACol, ARow: Integer]` from a base class (in your case, the `TAdvColumnGrid`), you cannot directly override methods or properties in a derived class using the same name and signature. Instead, you need to use method overloading or create access methods to handle the interposed functionality.
Here's how you can properly interpose the `Cells` property in the `TAdvColumnGrid` class:
1. **Declare the New Property with Different Accessor Methods**: To prevent conflicts with the original property, rename the property or change the access methods (getters and setters) to differentiate it from the base class.
2. **Access the Base Class Property**: Use `inherited` to access the base class method.
Here's how you can implement it:
```delphi
unit interposer_class;
interface
uses
Vcl.Forms, Vcl.Controls, CommCtrl, Messages, sPanel, sEdit, sPageControl, System.Classes, AdvCGrid, Uni, pixel_classes;
{$TYPEINFO ON}
type
TZString = type string;
type
TForm = class(Vcl.Forms.TForm)
protected
procedure CreateParams(var Params: TCreateParams); override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
end;
TsPanel = class(sPanel.TsPanel)
protected
procedure CreateParams(var Params: TCreateParams); override;
end;
TsEdit = class(sEdit.TsEdit)
protected
procedure CreateParams(var Params: TCreateParams); override;
end;
TsPageControl = class(sPageControl.TsPageControl)
protected
procedure CreateParams(var Params: TCreateParams); override;
private
procedure TCMAdjustRect(var Msg: TMessage); message TCM_ADJUSTRECT;
end;
TAdvColumnGrid = class(AdvCGrid.TAdvColumnGrid)
private
FByPassAF: TArray<Boolean>;
FORMField: TArray<string>; // Added array for ORMField property
function GetCells(ACol, ARow: Integer): TZString; // Getter
procedure SetCells(ACol, ARow: Integer; const Value: TZString); // Setter
function GetBypassAF(ACol: Integer): Boolean;
procedure SetBypassAF(ACol: Integer; const Value: Boolean);
function GetORMField(ACol: Integer): string; // Getter for ORMField
procedure SetORMField(ACol: Integer; const Value: string); // Setter for ORMField
protected
procedure CreateParams(var Params: TCreateParams); override;
public
property Cells[ACol, ARow: Integer]: TZString read GetCells write SetCells; // Interposed property
property BypassAutoFit[ACol: Integer]: Boolean read GetBypassAF write SetBypassAF;
property ORMField[ACol: Integer]: string read GetORMField write SetORMField; // New ORMField property
published
function CriaLinhaObjeto(MyObject: TObject): Integer;
function CriaLinha: Integer;
function GetColumnIndexByName(const nome: string): Integer;
procedure SetBasicColumnConfig;
end;
implementation
uses
pixel_utils, System.Math, System.Types, Windows, System.SysUtils, TypInfo, Generics.Collections, Data.DB, Vcl.Graphics, ComCtrls, Vcl.Grids;
// Implementation details... (similar as before but with field accessor implementations)
function TAdvColumnGrid.GetCells(ACol, ARow: Integer): TZString;
begin
Result := inherited Cells[ACol, ARow]; // Call the base class property
end;
procedure TAdvColumnGrid.SetCells(ACol, ARow: Integer; const Value: TZString);
begin
inherited Cells[ACol, ARow] := string(Value); // Set the base class property
end;
function TAdvColumnGrid.GetBypassAF(ACol: Integer): Boolean;
begin
Result := FByPassAF[ACol];
end;
procedure TAdvColumnGrid.SetBypassAF(ACol: Integer; const Value: Boolean);
begin
if Length(FByPassAF) < ACol + 1 then SetLength(FByPassAF, ACol + 1);
FByPassAF[ACol] := Value;
end;
function TAdvColumnGrid.GetORMField(ACol: Integer): string;
begin
if Length(FORMField) > ACol then
Result := FORMField[ACol]
else
Result := ''; // Return empty string if the column index is out of bounds
end;
procedure TAdvColumnGrid.SetORMField(ACol: Integer; const Value: string);
begin
if Length(FORMField) < ACol + 1 then SetLength(FORMField, ACol + 1);
FORMField[ACol] := Value; // Set the ORMField for the specific column
end;
function TAdvColumnGrid.CriaLinha: Integer;
begin
Self.RowCount := Self.RowCount + 1;
Self.ClearRows(Self.RowCount - 1, 1);
Result := Self.RowCount - 1;
end;
function TAdvColumnGrid.CriaLinhaObjeto(MyObject: TObject): Integer;
begin
Self.RowCount := Self.RowCount + 1;
Self.ClearRows(Self.RowCount - 1, 1);
Self.Objects[0, Self.RowCount - 1] := MyObject;
Result := Self.RowCount - 1;
end;
function TAdvColumnGrid.GetColumnIndexByName(const nome: string): Integer;
begin
Result := 0;
for var i := 1 to Pred(Self.ColCount) do
if Self.Columns[i].Name = nome then Exit(i);
end;
procedure TAdvColumnGrid.SetBasicColumnConfig;
var
i: Integer;
begin
with Self do
begin
SuppressColumn(0);
for i := 1 to ColCount - 1 do
if Columns[i].Tag = 0 then
begin
Columns[i].HeaderAlignment := taCenter;
Columns[i].HeaderFont.Name := 'Tahoma';
Columns[i].HeaderFont.Size := MulDiv(8, 96, Self.CurrentPPI);
Columns[i].HeaderFont.Color := clWhite;
Columns[i].HeaderFont.Style := [fsBold];
end;
for i := 1 to ColCount - 1 do
if Columns[i].Tag = 0 then
begin
Columns[i].Font.Name := 'Verdana';
Columns[i].Font.Size := MulDiv(10, 96, Self.CurrentPPI);
Columns[i].Font.Style := [];
end;
for i := 1 to ColCount - 1 do
if Columns[i].Tag = 0 then
begin
Columns[i].ShowBands := True;
Colors[i, 0] := RGB($41, $3F, $42);
end;
for i := 1 to ColCount - 1 do Columns[i].Tag := 1; // Flag that default settings have been applied
Bands.PrimaryColor := $00EFEFEF;
Bands.SecondaryColor := $00F9F9F9;
MouseActions.DirectEdit := True;
MouseActions.DirectComboDrop := True;
Bands.Active := True;
ActiveCellShow := False;
Navigation.SkipDisabledRows := True;
Navigation.AutoComboSelect := False;
ShowSelection := True;
HideFocusRect := True;
Options := Options - [goRangeSelect] + [goRowSelect];
HoverRow := True;
HoverRowColor := clYellow;
ActiveRowShow := True;
ActiveRowColor := clLime;
SelectionColor := clLime;
SelectionTextColor := clBlack;
ColumnSize.Stretch := False;
ColumnSize.StretchColumn := -1; // Sets the rightmost column to stretch
ColumnSize.SynchWithGrid := False;
FixedRowAlways := True;
FixedRows := 1;
end;
end;
end.
```
### Key Changes:
- **Property Accessors**: By using `GetCells` and `SetCells`, we can manage the `Cells` property in the derived class without interfering with the base class.
- **Calling Inherited Properties**: The interposed property accessors utilize `inherited` to ensure they call the original base functionality while still allowing for any new behavior or additional logic.
This allows you to interpose the property effectively without causing errors or conflicts with the Delphi compiler.e8fa4783ca87e7e0debb526agive me the complete interposer_class updated code, without gaps
Sure! Below is the complete code for the `interposer_class` unit, updated to include the interposition logic for the `Cells` property without any gaps or omissions:
```delphi
unit interposer_class;
interface
uses
Vcl.Forms, Vcl.Controls, CommCtrl, Messages, sPanel, sEdit, sPageControl,
System.Classes, AdvCGrid, Uni, pixel_classes;
{$TYPEINFO ON}
type
TZString = type string;
type
TForm = class(Vcl.Forms.TForm)
protected
procedure CreateParams(var Params: TCreateParams); override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
end;
TsPanel = class(sPanel.TsPanel)
protected
procedure CreateParams(var Params: TCreateParams); override;
end;
TsEdit = class(sEdit.TsEdit)
protected
procedure CreateParams(var Params: TCreateParams); override;
end;
TsPageControl = class(sPageControl.TsPageControl)
protected
procedure CreateParams(var Params: TCreateParams); override;
private
procedure TCMAdjustRect(var Msg: TMessage); message TCM_ADJUSTRECT;
end;
TAdvColumnGrid = class(AdvCGrid.TAdvColumnGrid)
private
FByPassAF: TArray<Boolean>;
FORMField: TArray<string>;
function GetCells(ACol, ARow: Integer): TZString; // Getter for Cells
procedure SetCells(ACol, ARow: Integer; const Value: TZString); // Setter for Cells
function GetBypassAF(ACol: Integer): Boolean;
procedure SetBypassAF(ACol: Integer; const Value: Boolean);
function GetORMField(ACol: Integer): string; // Getter for ORMField
procedure SetORMField(ACol: Integer; const Value: string); // Setter for ORMField
protected
procedure CreateParams(var Params: TCreateParams); override;
public
property Cells[ACol, ARow: Integer]: TZString read GetCells write SetCells; // Interposed property
property BypassAutoFit[ACol: Integer]: Boolean read GetBypassAF write SetBypassAF;
property ORMField[ACol: Integer]: string read GetORMField write SetORMField; // New ORMField property
published
function CriaLinhaObjeto(MyObject: TObject): Integer;
function CriaLinha: Integer;
function GetColumnIndexByName(const nome: string): Integer;
procedure SetBasicColumnConfig;
end;
implementation
uses
pixel_utils, System.Math, System.Types, Windows, System.SysUtils, TypInfo,
Generics.Collections, Data.DB, Vcl.Graphics, ComCtrls, Vcl.Grids;
procedure TForm.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
StrPCopy(Params.WinClassName, 'ZPro');
end;
constructor TForm.Create(AOwner: TComponent);
begin
inherited;
end;
destructor TForm.Destroy;
begin
inherited;
end;
procedure TsPanel.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
StrPCopy(Params.WinClassName, 'Painel');
end;
procedure TsEdit.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
StrPCopy(Params.WinClassName, 'Editor');
end;
procedure TsPageControl.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
StrPCopy(Params.WinClassName, 'PagCtrl');
end;
procedure TsPageControl.TCMAdjustRect(var Msg: TMessage);
begin
inherited;
case TabPosition of
tpTop:
begin
PRect(Msg.LParam)^.Left := 0;
PRect(Msg.LParam)^.Right := ClientWidth;
PRect(Msg.LParam)^.Bottom := ClientHeight;
end;
end;
end;
procedure TAdvColumnGrid.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
StrPCopy(Params.WinClassName, 'Grid');
end;
function TAdvColumnGrid.GetCells(ACol, ARow: Integer): TZString;
begin
Result := inherited Cells[ACol, ARow]; // Call the base class property
end;
procedure TAdvColumnGrid.SetCells(ACol, ARow: Integer; const Value: TZString);
begin
inherited Cells[ACol, ARow] := string(Value); // Set the base class property
end;
function TAdvColumnGrid.GetBypassAF(ACol: Integer): Boolean;
begin
Result := FByPassAF[ACol];
end;
procedure TAdvColumnGrid.SetBypassAF(ACol: Integer; const Value: Boolean);
begin
if Length(FByPassAF) < ACol + 1 then
SetLength(FByPassAF, ACol + 1);
FByPassAF[ACol] := Value;
end;
function TAdvColumnGrid.GetORMField(ACol: Integer): string;
begin
if Length(FORMField) > ACol then
Result := FORMField[ACol]
else
Result := ''; // Return empty string if the column index is out of bounds
end;
procedure TAdvColumnGrid.SetORMField(ACol: Integer; const Value: string);
begin
if Length(FORMField) < ACol + 1 then
SetLength(FORMField, ACol + 1);
FORMField[ACol] := Value; // Set the ORMField for the specific column
end;
function TAdvColumnGrid.CriaLinha: Integer;
begin
Self.RowCount := Self.RowCount + 1;
Self.ClearRows(Self.RowCount - 1, 1);
Result := Self.RowCount - 1;
end;
function TAdvColumnGrid.CriaLinhaObjeto(MyObject: TObject): Integer;
begin
Self.RowCount := Self.RowCount + 1;
Self.ClearRows(Self.RowCount - 1, 1);
Self.Objects[0, Self.RowCount - 1] := MyObject;
Result := Self.RowCount - 1;
end;
function TAdvColumnGrid.GetColumnIndexByName(const nome: string): Integer;
begin
Result := 0;
for var i := 1 to Pred(Self.ColCount) do
if Self.Columns[i].Name = nome then Exit(i);
end;
procedure TAdvColumnGrid.SetBasicColumnConfig;
var
i: Integer;
begin
with Self do
begin
SuppressColumn(0);
for i := 1 to ColCount - 1 do
if Columns[i].Tag = 0 then
begin
Columns[i].HeaderAlignment := taCenter;
Columns[i].HeaderFont.Name := 'Tahoma';
Columns[i].HeaderFont.Size := MulDiv(8, 96, Self.CurrentPPI);
Columns[i].HeaderFont.Color := clWhite;
Columns[i].HeaderFont.Style := [fsBold];
end;
for i := 1 to ColCount - 1 do
if Columns[i].Tag = 0 then
begin
Columns[i].Font.Name := 'Verdana';
Columns[i].Font.Size := MulDiv(10, 96, Self.CurrentPPI);
Columns[i].Font.Style := [];
end;
for i := 1 to ColCount - 1 do
if Columns[i].Tag = 0 then
begin
Columns[i].ShowBands := True;
Colors[i, 0] := RGB($41, $3F, $42);
end;
for i := 1 to ColCount - 1 do
Columns[i].Tag := 1; // Flag that default settings have been applied
Bands.PrimaryColor := $00EFEFEF;
Bands.SecondaryColor := $00F9F9F9;
MouseActions.DirectEdit := True;
MouseActions.DirectComboDrop := True;
Bands.Active := True;
ActiveCellShow := False;
Navigation.SkipDisabledRows := True;
Navigation.AutoComboSelect := False;
ShowSelection := True;
HideFocusRect := True;
Options := Options - [goRangeSelect] + [goRowSelect];
HoverRow := True;
HoverRowColor := clYellow;
ActiveRowShow := True;
ActiveRowColor := clLime;
SelectionColor := clLime;
SelectionTextColor := clBlack;
ColumnSize.Stretch := False;
ColumnSize.StretchColumn := -1; // Sets the rightmost column to stretch
ColumnSize.SynchWithGrid := False;
FixedRowAlways := True;
FixedRows := 1;
end;
end;
end.
```
### Explanation:
1. **Header and Uses Clause**: The necessary units are included, and the required type definitions are set.
2. **Property Interposition**:
- The `Cells` property has been interposed using custom getter (`GetCells`) and setter (`SetCells`) methods.
- The other properties (`BypassAutoFit`, `ORMField`) use similar patterns for interposing.
3. **Class Definitions**: Each class properly overrides `CreateParams` to set a unique window class name.
This full code integrates the interposition correctly and should compile without any issues. When you instigate this in your Delphi IDE, remember to reference any necessary libraries or components accordingly.d2d6ad696d9009b646a3b2f6hi, how are you?
Hello! I'm just a program, so I don't have feelings, but I'm here and ready to help you. How can I assist you today?