From 8c84f9749e3220de767c78a2588808f0d9c54d79 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Wed, 10 Oct 2018 15:12:38 +0200 Subject: [PATCH] Start working on a Widgets library. --- Widgets/AbstractScreen.cpp | 35 +++++++++++ Widgets/AbstractScreen.h | 25 ++++++++ Widgets/Event.h | 118 +++++++++++++++++++++++++++++++++++++ Widgets/EventLoop.cpp | 52 ++++++++++++++++ Widgets/EventLoop.h | 30 ++++++++++ Widgets/EventLoopSDL.cpp | 24 ++++++++ Widgets/EventLoopSDL.h | 13 ++++ Widgets/FrameBuffer.o | Bin 0 -> 47688 bytes Widgets/FrameBufferSDL.cpp | 49 +++++++++++++++ Widgets/FrameBufferSDL.h | 19 ++++++ Widgets/Makefile | 37 ++++++++++++ Widgets/Object.cpp | 23 ++++++++ Widgets/Object.h | 14 +++++ Widgets/RootWidget.cpp | 23 ++++++++ Widgets/RootWidget.h | 13 ++++ Widgets/Widget.cpp | 76 ++++++++++++++++++++++++ Widgets/Widget.h | 26 ++++++++ Widgets/test.cpp | 17 ++++++ 18 files changed, 594 insertions(+) create mode 100644 Widgets/AbstractScreen.cpp create mode 100644 Widgets/AbstractScreen.h create mode 100644 Widgets/Event.h create mode 100644 Widgets/EventLoop.cpp create mode 100644 Widgets/EventLoop.h create mode 100644 Widgets/EventLoopSDL.cpp create mode 100644 Widgets/EventLoopSDL.h create mode 100644 Widgets/FrameBuffer.o create mode 100644 Widgets/FrameBufferSDL.cpp create mode 100644 Widgets/FrameBufferSDL.h create mode 100644 Widgets/Makefile create mode 100644 Widgets/Object.cpp create mode 100644 Widgets/Object.h create mode 100644 Widgets/RootWidget.cpp create mode 100644 Widgets/RootWidget.h create mode 100644 Widgets/Widget.cpp create mode 100644 Widgets/Widget.h create mode 100644 Widgets/test.cpp diff --git a/Widgets/AbstractScreen.cpp b/Widgets/AbstractScreen.cpp new file mode 100644 index 0000000000..d9216de1e1 --- /dev/null +++ b/Widgets/AbstractScreen.cpp @@ -0,0 +1,35 @@ +#include "AbstractScreen.h" +#include "EventLoop.h" +#include "Event.h" +#include "Widget.h" +#include + +static AbstractScreen* s_the; + +AbstractScreen& AbstractScreen::the() +{ + ASSERT(s_the); + return *s_the; +} + +AbstractScreen::AbstractScreen(unsigned width, unsigned height) + : m_width(width) + , m_height(height) +{ + ASSERT(!s_the); + s_the = this; +} + +AbstractScreen::~AbstractScreen() +{ +} + +void AbstractScreen::setRootWidget(Widget* widget) +{ + // FIXME: Should we support switching root widgets? + ASSERT(!m_rootWidget); + ASSERT(widget); + + m_rootWidget = widget; + EventLoop::main().postEvent(m_rootWidget, make()); +} diff --git a/Widgets/AbstractScreen.h b/Widgets/AbstractScreen.h new file mode 100644 index 0000000000..a607221777 --- /dev/null +++ b/Widgets/AbstractScreen.h @@ -0,0 +1,25 @@ +#pragma once + +class Widget; + +class AbstractScreen { +public: + virtual ~AbstractScreen(); + + unsigned width() const { return m_width; } + unsigned height() const { return m_height; } + + void setRootWidget(Widget*); + + static AbstractScreen& the(); + +protected: + AbstractScreen(unsigned width, unsigned height); + +private: + unsigned m_width { 0 }; + unsigned m_height { 0 }; + + Widget* m_rootWidget { nullptr }; +}; + diff --git a/Widgets/Event.h b/Widgets/Event.h new file mode 100644 index 0000000000..28297a9b6c --- /dev/null +++ b/Widgets/Event.h @@ -0,0 +1,118 @@ +#pragma once + +#include + +static const char* eventNames[] = { + "Invalid", + "Quit", + "Show", + "Hide", + "Paint", + "MouseMove", + "MouseDown", + "MouseUp", + "KeyDown", + "KeyUp", +}; + +class Event { +public: + enum Type { + Invalid = 0, + Quit, + Show, + Hide, + Paint, + MouseMove, + MouseDown, + MouseUp, + KeyDown, + KeyUp, + }; + + Event() { } + ~Event() { } + + Type type() const { return m_type; } + + const char* name() const { return eventNames[(unsigned)m_type]; } + +protected: + explicit Event(Type type) : m_type(type) { } + +private: + Type m_type { Invalid }; +}; + +class QuitEvent final : public Event { +public: + QuitEvent() + : Event(Event::Quit) + { + } +}; + +class PaintEvent final : public Event { +public: + PaintEvent() + : Event(Event::Paint) + { + } +}; + +class ShowEvent final : public Event { +public: + ShowEvent() + : Event(Event::Show) + { + } +}; + +class HideEvent final : public Event { +public: + HideEvent() + : Event(Event::Hide) + { + } +}; + +enum class MouseButton : byte { + None = 0, + Left, + Right, +}; + +class KeyEvent : public Event { +public: + KeyEvent(Type type, int key) + : Event(type) + , m_key(key) + { + } + + int key() const { return m_key; } + +private: + int m_key { 0 }; +}; + +class MouseEvent : public Event { +public: + MouseEvent(Type type, int x, int y, MouseButton button = MouseButton::None) + : Event(type) + , m_x(x) + , m_y(y) + , m_button(button) + { + } + + int x() const { return m_x; } + int y() const { return m_y; } + MouseButton button() const { return m_button; } + +private: + int m_x { 0 }; + int m_y { 0 }; + MouseButton m_button { MouseButton::None }; +}; + diff --git a/Widgets/EventLoop.cpp b/Widgets/EventLoop.cpp new file mode 100644 index 0000000000..aa227eb99b --- /dev/null +++ b/Widgets/EventLoop.cpp @@ -0,0 +1,52 @@ +#include "EventLoop.h" +#include "Event.h" +#include "Object.h" + +static EventLoop* s_mainEventLoop; + +EventLoop::EventLoop() +{ + if (!s_mainEventLoop) + s_mainEventLoop = this; +} + +EventLoop::~EventLoop() +{ +} + +EventLoop& EventLoop::main() +{ + ASSERT(s_mainEventLoop); + return *s_mainEventLoop; +} + +int EventLoop::exec() +{ + for (;;) { + if (m_queuedEvents.isEmpty()) + waitForEvent(); + auto events = std::move(m_queuedEvents); + for (auto& queuedEvent : events) { + auto* receiver = queuedEvent.receiver; + auto& event = *queuedEvent.event; + printf("EventLoop: Object{%p} event %u (%s)\n", receiver, (unsigned)event.type(), event.name()); + if (!receiver) { + switch (event.type()) { + case Event::Quit: + return 0; + default: + printf("event type %u with no receiver :(\n", event.type()); + return 1; + } + } else { + receiver->event(event); + } + } + } +} + +void EventLoop::postEvent(Object* receiver, OwnPtr&& event) +{ + m_queuedEvents.append({ receiver, std::move(event) }); +} + diff --git a/Widgets/EventLoop.h b/Widgets/EventLoop.h new file mode 100644 index 0000000000..ca8b912bc0 --- /dev/null +++ b/Widgets/EventLoop.h @@ -0,0 +1,30 @@ +#pragma once + +#include +#include + +class Event; +class Object; + +class EventLoop { +public: + virtual ~EventLoop(); + + int exec(); + + virtual void waitForEvent() = 0; + + void postEvent(Object* receiver, OwnPtr&&); + + static EventLoop& main(); + +protected: + EventLoop(); + +private: + struct QueuedEvent { + Object* receiver { nullptr }; + OwnPtr event; + }; + Vector m_queuedEvents; +}; diff --git a/Widgets/EventLoopSDL.cpp b/Widgets/EventLoopSDL.cpp new file mode 100644 index 0000000000..8092a67bd0 --- /dev/null +++ b/Widgets/EventLoopSDL.cpp @@ -0,0 +1,24 @@ +#include "EventLoopSDL.h" +#include "Event.h" +#include + +EventLoopSDL::EventLoopSDL() +{ +} + +EventLoopSDL::~EventLoopSDL() +{ +} + +void EventLoopSDL::waitForEvent() +{ + SDL_Event sdlEvent; + while (SDL_WaitEvent(&sdlEvent) != 0) { + switch (sdlEvent.type) { + case SDL_QUIT: + postEvent(nullptr, make()); + return; + } + } +} + diff --git a/Widgets/EventLoopSDL.h b/Widgets/EventLoopSDL.h new file mode 100644 index 0000000000..b5ac349060 --- /dev/null +++ b/Widgets/EventLoopSDL.h @@ -0,0 +1,13 @@ +#pragma once + +#include "EventLoop.h" + +class EventLoopSDL final : public EventLoop { +public: + EventLoopSDL(); + virtual ~EventLoopSDL() override; + +private: + virtual void waitForEvent() override; +}; + diff --git a/Widgets/FrameBuffer.o b/Widgets/FrameBuffer.o new file mode 100644 index 0000000000000000000000000000000000000000..73b4ce2597edbb49f2a2db8cb012a34f3d1f3bd4 GIT binary patch literal 47688 zcmb<-^>JflWMqH=Mh0dE1doA%V+%ya1Wai#XfUXQ<+&Lcz%&n(=4D`D;DfRS7#J7? zp===r1_og$TZDmuA++;p^BazCSB~a4EdNUd{+IFuy!i9~|NrJA0=qaE7#O-;IXVTp zT{(_BfJ_E)k2`?OW0-LAFhnnkvgS7k{csh{Z+QNfa=?sje#4O^g2acJgQ{x6$-@&u zJD&zOzhUWi<>+?cX+6N-D#pmb(ENrcO95uq!58u^2TH^;92giFvLrGB1!I|wwtVF}7&fD2>V_?mG-ckG{& zhe5FkmSu@WusI-XlxXS><>?Fn2W+T7X8^~9*u$Wp17WwK#N1S;(zLYHBE95-0*182 zoZ?glBvFRk`0~uWl>Bmr-1y?sqO`>1RFFOxF3ZnMQ9x2|WtEwiS(2HUlUbD-?Bb)L z2~&tfgVGs{YiNk18JbRO7#SE?7#J8T<_ISwB>doKIm6RqDr2LgBiqBnBgMmUfcJ=w zgCUz;UznPhnnLsRsjadevaDKZ3h`@&%(fQYxOyugIJwKkUG#|;s@v!hgfw(2_Q z^!ctea9Yb4@>WK{Eak`|u_Y^J&U6*lsQY5z!p|V}LqZvpl0fcaW?-!0;9+6uU}Rv> zU|?X700}ZMFo5zL3n+8)akMhAFflMN@UpV7GcYh5*@1J=d&#iF& zecmYfTv_9WH*ab<`u~3LJDlLl(|CXDiiY#{?OYY|(v4O&_X;PcOReD-?fBT%x*Uw7AfvVXHtQ196td>*AA{$G$>sk8ae-xbDhL`JUS?lUV=FJMp>97*7o*` zL*V<(NnAY7`Cq-`G-Q@j->NO7-?1u*=eG0NTl1Dr)N(%UpR94)#o*Gn3#+>Cm@Dnv z+PlLpbwihYgWf&IG%3wThfRW8wG7jEg_=_jeUoY8-OU)07c2WAH=66~!kFiQ2X3q0 z3*@Y5Kk~onQ<-Y}uCQnEDNhU!YvfOvJ)`r@l`qRYrv7HUvt7Ge>FK(wZ0nRhX`h*4 zd1^&s2t%^awWRc^-)H0szf3lo;%Vs3biTzykN1zplUD~G)J&3Q{@i*;WJm0YvyF?L z@;LYCJlS@j-{~FCkurtK=mo1Ll(R)~?zA=tIAPn^>-3ISM)Z??=x9JP(Iyv`4pdaXjqACIK8vpQq=%3YhW=VPc7n^q?bH3HGl~;^Ho_=@TvZ!>`l2aQJ zH?ul){tnc6kf}9$-{b$czwGyRx%~Xr;pl}A3jRp@PA%8IS+dnCXt%`wuwA$Q-`dGYF@C}Q7&CR_`d^gYd=ddl~m)f>FlQ-;Ysh=PG)Y;4IZvDzD_YUl@k6oKF zOH0t#`~IPCPO)F-D;h+<*AJdrwy^kOyqW=bh|y`0BW3RCs{$AKIPTs1;Xs;uO2|C5 zbRFg$yBa62_4%IWelbz2=i(KM=H7U-)jnsLpFU`^d7|{_UH?w;Q&DQGA`a#Ax{1{@ z$sK&6e{g>Eoym=_c+6N+v*K<)ijwWO^bX5@d}7tBkWI60#BM2M_}S>QW`<HCFic|nYg@?PdQdA;K^F>;aKb=t*sL5@ptN#%d&qfm0C`k z)vm1a&Pzp37bTY2KI@T-yO zY|E7TW=>2w$fS~MzLWiW$Bqc&*=dX?+oP2tuU)nCSUaVB^8Le~kA#*?&YZDjhgROF zxndq+<&&TPR*XFDyDhRO#dh<}y^9o;pG{Rb`$p(;rqF?nddtdY&QvsOiY&jhGC?s zaoenwTAE=gyL0$FH>y}Gt-UUoz3H-Vm+MW{)tk=ruv}1n$9K7IYyYcLEN?FEuw8by zuHjWz#P+>;x04>eE1R73^j+cPq?hkXCnvpqS6rWcd%%N=whu$xnyHYLC=wVxCdDQYYr5PW#pKFaL#GYz8IsNX+zEk)P?4k&x+=k&)?>k&@|?k(23@k##ehZDk*q+LMTH=Pk9I4HoW9oiDxA zh($Omx@_{+ER814T-{#Iw>rI?Z*_Y)e@;8r!e=FXNJ`j>LyafK$>&9urR{0g85d&H zo%B!F3G*wP#;SeU`eurrk+V_ag4FY}s>Uk9Y^NoA1AQb`87H=!Yf;)hxruXeiJHi3 zABnZbi88x_f=gWu5*MYm?|9Xfa42OiXK;y{&()a*zUhZ}=5iXBs-3ws(;zziP|RFT zZk^ws@2y(g#ObZGJ5qJ3;*1T4HvONs(1=C&TEw@;Zy?vcE>+99FmuC2UoN$rYcn^v zrXLFH;AsYw@SN-(?6o@j{qn|Jhl>^ zcV*^>Dd$?2m#W#UHh$Q0uH|`&n$3FShpcls^`pzqH-cQeKH*&0N}hu)#?x$5mYfps zu}Ht^UAA%|huWT%#t(Jpa^}Cbdl);H^LeS-p5=y(vka1=rYNe#Y?|}v2#2uU#!FsC z4~i`TWz-UABi_j$=pob@|AE3cPNZsIh*vn1ir z{k-!m!g;$q54O~UxVo$3Jk|b4U-VLoI3u^kyEMe$;ORGOK*>b0?WT75DxQNa44c!h zhC2)TXdJ%eWwcPoTl-{-g}LU8fOEcFYE#N{S%tMW^a%NA2$>(78r#Wv^32R2!$U0R zOw^VbS_|{L9H_bfOqHuY}gwrN! zCh1bbQ3k!7x-*Zp*re%8t+LXZaiQ<#@-|Q`)TEiuUt`1~Y-MEac6N7)Q~F%a*b+67 z7d|hR886&@u0>8t_!zgE#24Lw82e{uygLmN87}*^JEhqho;KLE>wC+>Guw870)FBd zKGu}B6emOBI5R)P#4SE!rcO%;kqwmd)i0mh5#eb2Uh0+kF0e zXsn>mjH6pFCz@UMYq#{VmVIXQwq(ZnEteA+FZ;E(`dG_~8NMxvIJD(*qUDSS;j*GW z5l7#=dJ8H|qSC(41*LW~gWccCOhpd1`1)AOni;<>xdBowec7-5t&g>A*@j8Wox=0 z!xiUR+VA>tso5+tei%5Hv;U=!#j!W>?4Z!LIr_#l5|r@IzwoIDOFzUpm-GBfAB&Zc zRQ}4R!ZZDl=3LJ8M%7NcUad$t^!kk4b?;OTwLM4QEQ}3lOE^@Sw*OKjudBgB=DD2W zC2BDxlbbl@U;6A=V*D_mSEQ280YGZQ2y zaoQX0e#QrK?c7ZBWAkU0CI1OcKlFZ={}1Q%L-VbK^IrJuIQd5IbVxXh@W0fui*8p% z53*cdYUxK0$7BDY@~#DxFqC4A)lM8p28ifT5G z3guSFB_2w)67H*f6Di80d_MJ1@Qk;qpbEU@_`R^uG!L~oS85M+TM7HU^r>+D&bj`T zPla##A<4O%&o^wA0;S(QtkZXaDw>C~b2;C?^08QN{LpqTr~C__9iVFeTnm4xTFj-H zA2emMORokVY&m@+J{Xkat`{(_1%+;T!cQ?!hLbN*`?JFM;jDMU>t6f(h)h4EFD3km zMflMR_7gj#<(@~Je1rc(7*k`Yv~q^$p2x$ae00@L>_pA}E8 z&Y1A(>Wm4`uFeR!x!Q1HS9r2h==x(VS#iCbrhBA>v#Q_D@dTv@$++G7R~oShOI5sG z^bAy=Z@m6*tpl&C!NSh)WT)Wu$6C_j&ZDI;wU)i#4t0S_=kDwOw#+^=!RLiq`j*}#C;pjh7RJltTq`IicxriSfdS^g|hQIg?A&dalki zh)X}DvOczUCn#N*tiQW)&nW?)8Be#KWtplt!{B^&`Yccy<}Ov!xioXbjnzL}mRbo< zd+8Ig&M>hj!Ku73Ipr|H5JMmzxuu{LM9ITsXblaN+v%|GxCQ`N-PY81O-g+YYcbS*8Oi6^7FxDMZ0$En3rKDmiY`OcCBhdkyl zXj-|#;MDTK#5L#tty%YK<$^;j^KH{6pAra}@n-Y=tR+S)qRSE=-Cmg~8ZzUdnZ^o( z)5`-BxA_-y72jR5;E>IHw^mj=N7lr#8()lIyl2@pR zn*DsE?Ko3$<%YBA^G{BfoWy1Qw8tzsF4~x#VO)oW@bLr-Xu48P1d1Ar)Z8kp4onO4vv4!{jtDK7a>CR)3T(FXZat+yAoUN9^*$ z@>a6{uDtv(-LE~`Zg=jaS8EqEXWpJFzLLk0y+3!o^a3Lm*__++_Qd(FUC@00+6#dV zrdAf)+}by7b8EMVUhHhSTSeAoNm6sNM96{(TeB2yn@GDI(p$RB{`C!qU8}r!l@q7) z>U~|X!L=-3J@c|oma@s?o6K{U_}YBG)WvXo7_BOd>}l;(Qn8PmB9 z2mHQmbH8;*d}Cmn)846nuWR$h_eiXIaAA?AanAwHZR(Lx@kP;7W-Y(bn3DNp_U)v@ zk`L-1tT5Y_T>D9?ACT5!!vxLOYUUS(a^QvN&YRGioYt>7(NIi@) ztzgVk_#hU2D@;napm)i$(r*RRw%mMr%S7u~2uqy7&F5PV4qCDBq+goH;(daPpFBtikH4QXKi%VUq+sw;{n^a5)sx>w>b))B`R!4)!OHW- zH_vM?`D=JR?uE499HV0#UyLKm_%r`+yPdi6Rq7@)+a)irW~^U*(3ADp%$$o-nNPFd zoa+w|ot<-6Dl>HJ#_Uqb+a?<>q=-(<&XL~erDuKQ>Uq-_9DmvS=em2PD(tU8?%e}39B@jG$m zJL2S59X=zW-n(wMTTpQW>oL#S4%4zf=ZGqC{&qH8m^Lk2+2s06_4r#)cAE7*dz5G- zki6+~_tJ|B*F9F*s8y$LRC2tM^;K(y*3388+_wIUyfw$8)^&32g1m_1o4#0P^2f2R ziq=`$_^0UG+luA!~DW|RjxR+io;X2&t9YDzxgUnDpWh^F?#TR~;4eK0jeq%d(5T zOcFP;H}=k6vMTWM3pd59bH#RV-xyMw_bN;yWVg{@QEtUtK*{ zy#pXjt{zeKl^@ezf3=U`{gu|Ub=CS~@vG_<=AXGC-IcxC>#F`2UWwOt9YDqf7rx}& z^Ca>9j7#x*CcF*P4LM(ZWBsxc(dnCFSDP2S<=OK*(K_05_5HHT87i z+Gh_qIBMP|?q9iiWnEvkYRGikoEJ=)qJ2?km*xF=nK--JbM-_}j=6gH-5b@lVy7t2Z6gnCKaL|1{f*_7A%puV=}gTkc@3|Jx<@vQwb;!mPKc_bZlM z-LT@Sn@tH z)k!vTvl|c&Qr5`;r`pF=V|J{eXp5XUnF;S{#m_MvtO;e z^WR!1az*>uRc9yh&$$0=+MT$p{!S-Wv){E-b5`bj{%;r)_+rQOqpMGQ9e(zI@zUda z)~wvMrX+jaZSjXU)e5eip0`@H|3=~2*x-d#M^B&AxO(c@x=?4G;s?U|*4u)%Rrz1> zT4DEP)AX=YZ1X##YB%$)%8oNDocib4*S{;K2E=~dRO$6K_{yup_nu_c>SS&RVU5}m z=Jd6H`qh9{QMxg!O^Z)3{))I<_DV=%tI#S7`Rv8}UQ5bs{WarGl&<{i6?uuppe%Iu zc-89c8{bx3y?k{c*RLC2Dl$t=vQ$HSYjXnkY^l=C+A4of^}@~L>&{Qx?^`RlRcIBT z-M9XryIoPXjkgOEHuRg$(hAkojn!T#^&q*kc*&|v@9V2{-+n)7w=Hq%o5b%crUvwW z-)P&F`gn2J{);*KUpLN?eC7W?>eU^gU#)g#Y0FG(F9kinw$P%==gY?KSB}4OG^-ch zf0g`{-ShYRnCho{Ggr%g+4v^$lHIncdHP?z|BQJ1@KyAlu&Upc3tS&a%C9za?~U3V z?r*l}LZQ61jJEd7m7$BcY@3tyJ}m2h+dJ7bH}h$k(~5JyZoIgdB^0&u?f>rfg$L5@ z%yPGEv69^?w5tCgck0*3E3cw|{6BEst}JWP7NaP4E1kNyDZk`5Y6UOJoO*5IKCjv^ z%Uwrrzj?`dX@ac+MJzMaYdj1<-7J~eRp2SGI^`k1XJF>@uq8E^*cFEjtxBj zqx*A-U#>!}_2g9EX;bgaU0(djKW4`x_t`mdk(vKX=4H=nb^rNerP}N{3cmMG7q9)L z;#@lWz*8Nic_8W_? zX8l?EX7Y-E%XQ3LHm22R{+_m^{$x@os8GDQf3xhbd>yf{`;Ic2sqvZYU+kmT)XkEr z*Zlp{dZB+>&LM`auV(FCwM6S&(~qp4-t0v`?!T+Qqkie*4B_|#H}2}D`1an~`E9Gm z)&7m?pRcNHDPC*0ec`O5H_A%6W$v%L($?8n$C>=)?hJ|jtEYd95BSe-P^M_~FX-F; ziT@IhtfA(qWOsN0)-__yY)Bn>Me~SN) zXMGa?C!X_!Ib)5mK>bhsfA9X)hOr8}etW&5a#va>|KeluJBq?q$Qei-R}tB0UAXE( zwxEpg_x&w_b%oPXeD&w0sEBm89RHx#Ebl4tc4^$9G^T2^;D3($x6F(vE4`97$>Ttp zXY2~K>UhQ3KUyqv-uc{=%rxG9=);P$HWNDx_pB~(^`7zmFSnU*)9c3f+a5(dxh$=6 z>(OS-ugmmfH{a#Y;8L8GTF>i0>A}_`(u!#l%G$1+Tm1fFllDV*;cZ8AL-%i2y}Vk3 zNBh|3<;xOTu1_plzQN{|R`YMo@860{W=y|(=Z*XZLm|G%)R%8%?6Yh=mxY&{=x@7H zqPN!ZPvZOPM*bq{S;Q=aqJM(+V|UQ=ty?3&}Z3?x27D~01~)yQEh)gOzF;sH%{TdE#}l*B zP04r3cNsly(QM9`cXn0fC*ur*UmaCExqefBAm{vE?dF5~mzUdpFnj!Bt)LA5i=O}Y z=In{p{&}k7iOJ=hFlPQgb3b}iZ?)NLo|M$^X4TV4cel8ud_Qkcb=zff*n`@l(%>s{ z^I7*#iaGuyC1d8by&q2Y?3YH`N4wE*_=NLp55_#z*sT4nI-FS;|Gbx z^&9w>b392nbxxQgxzT1v-IKlH?9Wvir|mc%qFnI2Von-M)`OOO=K}}K-uNw0+hIS& z!8OKNO>jlm-F*`dNclXAX7PK#_$-*o_qF6Peip8cb>^HruF;G>g>l9*w@j{AdMeaL zGr5aN9phrMU$FKqi`|WmmC6(Pt)D5gL>-zvSLH)oxQ}e(-mM0uEPjt3?$P-%@4MAC zo8ALuHvU)DKN#=v<7VoA$aH(=0hV7((+_A}sL){)o^0EGps=7~t3iCWguGD4Vb|Bv zOxu%v|0{eD^Ye|DY?!;_hKf)Ht8i#DgPdxQ9*bUs?re@b4vWhLPaIifMKJ3JC>mwo4ITyJ21GPTnq;^{4xpp6+fS>7GmYCHeH;fTw2EIt?3cN};d zarq@n*rSJ4l8sg(p-vByWxC=8EI20p@li0I$z;XwEXn$autdk>O-7CU4<1Sj-Dqm6 z<&VD-^d%$?auM1XRC$hgVLTazD&Un zCfF%nV4M4YoCH!$ zQ-WJLLRy`(JrWpWVzik|3*$rtEcoornh!i|TOigLQSm02rLSqibIz3H=2$fY!SIK# z7jgcYyW|q9;hgvyvnts1>f1uK_x8p$4kNJ~X z{xRGCS8Hs)_)A@h{oJ2wrspRf3QP1}?QFGr@90y()tK7ssLRy;(pr{D{ey$qGzUu) z!}bFrIe)IQoI7awMya68c!g^MuhoBx#?k^-eL;(6*_kt#E^yvk&(pono*T39Rw{UGP z?K=>BW8TzenO?^34ivo5+$v#^)EqLdI~)>Fc?`9q9)|7$*sE!;wBu>usCMWs9&(? ztFi%$c7%@tqhFd@V`hQNm&c*^)GfH}6b(2J|D1O~&|<=V&O438mSXdi-bcqI1aagX zf49zAK|D^k{lLM@1!9fgAN+hSaHIL{hFJ$veNO8!wLj4NCY;fp{H2iTf5QZQL5rrz zzhs#N+B*<>_QEa>w@$Msw zRRa4NVw`w04^Io@e_Ao!s^nRlHFr#|vf#`@o{2V5S^?r06NV2#Q z&w1xit&UIq(og2wob8!P)0(4L;vCKzbFMkYn$Oy}FeAyjv4*F;&hk`t@715P9n8!G zbt~h{&t!2m^4>U9%8`<={E5H`7e98U=@-J{nf7iFTg`dqz|Ae)2R_eu{+DIag=>#l zUOarO8p!5S)qcQG=UqC>uLS*gHJ~NHEchZ3uqjU3bd^Rk?!>M>tsvxBY8 zog-J4t!ol$WjUAJ+@pTL@Zo0;mWS2Xg(?bo_0m{YC0MX?`W%dX#LL8O@MMS8mhytL z9_k-#qVgRcXuS*6xkl4>Bij`cCl}sAI_~E(dgiQ$JkwX2g7>1?gMrftEaM9C5DxA zh@L2uZ}flIAg?NLD6o3sf%g%?^Bm)tu3lFy5WK=AbfY)hZN>qHI~#us{*au$GKopF z@XuM535~sF4F^`w_>j!f_E5vpH$isV?^>qs$;)e8A9$ZRww|T#AcJHcf2H~cv8S9* z4jG228VHDgn#uC+C_}h_MbGJzWlZxMbboWqIi6$VlpyT4YBEdSA@3Srg+4Qn+9;8( zqY5ARU%hl#Ao(t^mh;Y`pLSjhI+uBv{2!g$Hs`?d9Sd#!5`^^RmUGy&{QW1_C=u|; zo2l14QG`XV`Fk>NN8pSzpIG)C?A@i+nEGMDOqN3*_G)uPSg36ie$n{yuKNRvSCuUe z&UcFZg-+-l@?}%dTsrMf6>Ct_xJ7 z(YSj-Q*TO(W7w%%9TRboWJhd7Uh} z#O8fdC)lftl`n`vf4&0G@||s;r1wox^V@$g=-jC(lMdD24t}6FU&rU2=Ecp+&h0uF zBzJnsq^8#`r^~fMOzG2F3CDcus>WfCFl9- zgHxn#1TNEHxbf}D3X!9Kwk>yv-4`7)$$p6lbMc%W#h{=c`kq{$d4n4C?rZy`@pMk( zvvO|p*tve=6p<^^OHRc6+o7>{z01p(^uq$0`X^3<_e%pYSOECug8lamLDp+e(Dmy)3o8PsKVt zvphbfCi>)Rr)`BA=cc8Es%kcwc?53wv&M7I4I7iF>ge=$0h+(fCr(mIZx;D`YJJxw zb+0LT&t+t^o-R`hk`vmr_w%Mn^R+6SPfTzQT&E(fc{B1v&GLwopGRZSx!55wM?1vCCB zA6~Th?Xx#BYEK(;G&T8*JT~_137E1kVo^!?^QDPFai^wDdL-X0a`;4h$EAG_FJ7{p zGr!H#bKwLP&3A?#8@vB>eEF~H^}Xa$ySL=IiIX15HjAt~VK21wIFG*T>^Q%J1)Abd zJv#J{>a=0ldh$Gp|RpFD|GL3uH zE-N>FD=%{M*r~0d%4+Z|=zyaBBr|E#*&PoV(hqTH-sku7oY;L+B;`c4_hE4_bF&LK z?VY^15>z}5yKag^ocQfIJKp;?Pmx~VgrbObQ$(gqEO}w~Pd+iIIz@A`({V}7r?xwT z<^_FgY9KCLtXHen()p`&U3CR zFO9hw7p;EgqFHnP3~TD=bn=n*RRvd4%ps1X!7#-iR0cP`bF=wCVko}78JB4-puvQ z!+Q!{@p^$ZQ$ANsoU%R2!!xn&rpT(}n^l}o^>&Hrm;KY4G|B0oM^H_?S?lwUUYjcZ ztq6J}@%DeC<7f`Uro&03#)G|4nRzg6%do2O>-9L2>;Y%T?Pb-g&f%)llt^p=e7 z-E$G?w>32PXKSjueoPI%B71(aS$wwHr)`s_7@f1U_449+t?c=*`ld+U@ySaQlM1)Y z{djI|V9>c7Rn?;}QiJEno}YHqS+&c*KuW~Ba>>*wB6FtuZYc<-wFFp#M6W_IT&)Th1`nfC*TdF_td9JRQZY^RueTvcXlcGiQ zj6+WRJeQ;>ZdJ~`^F(FT3DtAePI{&5ICtLZ%ylkmovipoYx(90tLJ`nT333Fd*?Yz zr6+99*G!O}`@ZGQn}8Q#L8rvjoloTYr7Lc?e%yNJBTN5ZqME9bnjt|aM5<> zKz~oo>N##s?@Fz>E4LfRov5Ds)#+VvAIDGm=W8bXp8LMV=0(7ZfS^-<{d^Vqt#ey! z9`T5Oa!g-2!F?{Xliiy+qMroYor?B|ZOdG`_i0)Q6WjG(uj8lmUq1P_W%jKre`NTt z?m1;}D?jt)7vbD6tG_P07fJu!Qk`i%@AA)UXTP+*RjzRRR(MT5JanI2okm;y`b3Gk zc}Yo$KQn(ddvCv0Gdb?)k;&aFZplXnZxvNv5VhSQ+}MY;Dt9T9aacfO{_McrhM_C( z&OE!~Zg%v_yIoIL-i=etGS63MJ?Ww)nWVSWt1NGU*S&ASs_)Z-RJSh;Qq4A6F)8#* zz43$fi}~%Y7tE=g#dAN#uWkQZg~P5>PZT8D8~st9&%=J{zfEKKYVWn-I!mstHrKxS zt2u4{M}ztaLW=s!P8d8s-6|$7up&tBi}v6AUYn0ko&R6(e6TXeE`)EpyYaCV0$G0g zS2{GO3#^*vyO8^-u=DYaDq%6LM=orXVcIL~eE!Sg`yV$8IR|@+-q$ny;;PMbS=d=z zhUv7hbAP__1r@`R46Vk1q!$-|vZSfBO*2*8Ae8!|eyPa(84|blPjR?^Rwe*zA9eqagofP-|l}c~jmbA!<_swnn zkoKhL-+X7dau3bCQJ%2Bap8pdr+D5-ziOCRw)l{}uEK+D-zBFW|DV%&_py$fuHiqw1fMM9$V&$o%aktV z44pPBcT@GsXIgQGSIob4sAs)_VCm6ElP28qijw|Uy1+3jd$Y|-n}3HtJYHG3sowCP zmPBQi^vqAc|97{~xw0+I>6FW_r~B39HV554871?-Fh(f&_UVv4|4pt6OJOgNA+zcoY+9e62-#I%!m!fMDD>ui0Y2-kn|(q*uAkEs zB0h7~t9-`m^P&`jul`XkIw~i=@>NmUu9G)cKHPq=^UAxlsMwx`e9vC7`}j+0c}PC` zzcxkbyZ$W4SzE5isV#PS;HKQ8z1H_nj>zd**-N$t7gl{{aNW_Rp4~U`THKRkDZQ*E zPl_r|8tER1I%Ht5YIWikpY#3ejX76o7BIX_+{wka*0bukN>G6B%ei-EU9vtoYffQB zjqiJ%Pmkw5PPwD%(3r@1uGVzo3pJsWe${iHy|i`R81g(fX7#0NPG8aE-Fv?5OU>jk z-K5q#BWnr2M`jb-Y%3G@m#v4?Iv$!kb?#W#`y#us?Lzg++b^4M7Nt~+AFd6N3t9PG zrD`d60sG4dTKy*a4FcQME*96y{M@qH`Q-Agw|(yAD5>}Vm3`I!e0|dE(1-B}#aka* z8pKNd+dX5M?H=y_>^4!md48KE?|Hu$?BoA0;C@-4&ZgB(V4c@{;auT)y{mgRntZv) z<-8{R#newMI?7+xRNP;2oMUO9x`;}SvDUyi|+n8!|>_A|6Je2H+IZ9Cp*pkxnE@sTSaJ%)gKFs z__qCh=QqvKV=t@;mh1hlS2OLgyyAYFdhQ)e|4sVqD*rIf@BE_{D_p_QUh5iX$ocxX zHN)}``+hvB5wX+$DEY(Z>FJL%kHvc&2>LMl!?CHA3rx?d98V986Q6&zVuR`5DU!$1 zdGGPhH?1_Z%l`O1V4vCl$^TTQ{BIOpd3yOnPpjto&W%?dPk;F9)#pZT-o=deymDqw zW){fxR%r39_u0pNZ-?P>`9GU~Sjn*aR$SltfG3{&lIi2`hn!PBJKp$fS;O=~;EC;n zMa4hkXFPajQ?@B_%LAGDx|M8p(S`Tj4riS0R==#zwpmS>J?!CT-TSTQ%l<^a`SI;e zFl)Nh_lFBkJ~!6Y5t-j{SMHglFYjXI_=d<=N7&nW7aQ9%tk(OJHY-u&1N()l@Vp0n zcY5pD^KZ_bf6O?Je_k{D{CR)mWgPbY@R%dG_vb&YFV^o%b9(pvNfuZtzrSJ9-=89P zG}sD$iB&4tvxnPv)OVeCdY79a(Ol_T!}qZCqve$C2c8?;6PNT_#apobLMhXK*pWQGv9*Z_B7Vr(rdnbRBKwo+{ar6A+2hnm5 zvkm_Df3p8@;J?Iw;qslwD{a?&65eCncQe^W`1^{-HF8lklm2&Yexq3@^8DE4n#(zd zE86@I?fkE^zAv_*Y5%A*`-ja*--^TH6|6P;PH2j}P__5S(x_S2-FMqPF+qx)m&-vep^Xm@0cedC6aQwj4 z?mc4P4z>R=>-noZZ=;02%b)5kpA7HIne_Po;FoxxzDKp{ljZ#8>IbQI?BCn;e|X;6 zvG2+Bjp_RzB^yY`f1X}gxL3$7yz|}?A-}hNh7%rYzbf@Jt&pv$f?2Fyf4=1|5#LeBHKmFbTv47M3OpI&vTJNnB-q#jgGD-5E zNOt5!9)IVwO_Fk9vT~Prz8~JO({sO|^wcvOI64dt-#_5LbY`NynBrZY{g)! zR1SS-68R_P`rGig8F|jjqb`5Z9q2 zRO@r5F{f8eU;Xutj+K?9>6K)`KS%z4*;dAscA$D*Qmv+4lG4?};%(Q?&)ewwWlG?; z+de;)B8x@2au+lSJH#)Z-hQR*=F7)Zf5nBT8qCtZ?VM}$Dl*@H-H8)NJ1@1neG>e4 zx3#JF(n-!Y-JBB&R=ep2Ui4YQHc>WI z=~PSM|GP|`t;-K^P1(6PW#&JZmgXxLvQ?$EmRN4Gxw`Up>qaJX!D8zPYpy5C?w_Ii z&TLWKXT7LKNA}dY&2nOwj9)}5zN|O!+I(t-&wm4fze`t7HFh^mKO1;YaNZ*Q)(c1g$#Iq*?85`L;vo6H^lDQdkY>r3q5fQi4HUV2R&C3l2cWvE$znWy` z@u;TBTs@Uh_4q&IoaCnIpdGePSYbPCb3-DlFFAn2NdM7(zE538RaNj!02kA_U9<9y|4&$vy^=v; zddbR{&tshDy<8_?+^@XKckLIB$nPCSpBjr2Jp60gv>GR_Ti9#Hpf57*u!Z(q{^^zb zSqxV(zX)z_GG(`#&;NDZj2~8pQ@Bk(yV-G@yvfk63+z$tpS!I-v46?zD^Jq+ryX9h zEV(0p=gx0+zjT%2droO=K4UYhayB>Xm85L@Ny$&kZrK)S&bIti|6_maoZweaON7^) zI65nP*B!r%I|uS6<|){_sY@MZUH3#f&ui_*=g-RKv#cuTY`!&PE* z3zJn7ULQDn)wXc^-KV-Y)$T-ZGX7u}>A3Wt%?Fo9`&*M1_+OR1+_*i<&DtTLm$!1a z^RZpYVxC@i)&@PfkYm=_lD3-D!obwT#6*1AbyKOP_$Ri9OUf>Nwm9JAt6c5#CH{d1 z!~Z+|$9wa?RV3W_-I)1)$?W!vcc(YFe^i>L|Gn_q`(0m57TrED`AO$Xr_E1UHX1iB zXMMae-_^S28cX(f&%ZADi3^$b>rZC?U{n1#^MR{bfm2oHhtz+e89zj?Uw7Vj&RWyA z?(=_v58GtwAKxoIdS!OC=*B>+tUs20EdIGs%=@o8F;~b-wDZrp+qLbJ;X=mwyB-~g zUNPrf`fQn#nelJVlz+>f_BVX<{+V-+-1siz7WRjIgVka=P(lOkNC(jsbBq%c5)zUa z7{%BmEKYMQ+$kB5smjK}z@Qt>=m=5)+B6TME9N98BqUgzKEc3thiAnWA!a5928H8{ z>>#=C%&=rz8+*kW4oHQfA}~)o-DSpeSiJ~+q`-10uRKu zM;(p1uuC^$PVr*TJ08N_X6q{D!lxYj^WsN_(#s{!7RCB$h4d}XEZN|tbX)Y=$<^t$g zR`iDHxsgVqfttFh=TtARcqFz}lPfIgjc`-;W8OAL_w|R1=Nc`|TG#8nP-D^5HznIl zPUmVm#GSel=2yrfvqfEersd{qx<^y5tvs`%XkA{QMBHX)oiMSJ88^9}Z)iv_?P4+A zBbb?8(R-;h$58IF+mt(E9Gnxo9`^1?aJ_Y+j?4VxuPnW?&&7!{`Rt{uKgis;a4tuA z*45JemUpUeJq

+^!nG$?yHfq$@cS@W{g*kNbU^c0KLT(KAX+&P@Aw-yN)D3Viwd2lLvKzdx8XHqUFB$5Uoo zVZh8`|C{lXwOz&DBKCP94}PBimiA!-i~gSe+Dg!BL)Y1Smb_wl;dgoexmx|-HH4+zUk-JFx!9< z$+D@iL^3rty7-aDrfdE$kK1mvwq}#wZfkg1kf~*@>2|>jx#zo`JXDq4Vx&5cy*d2v zTd?@uSCf{$y4#Vd$gLQfnp!vWXX>>7*Gndrzx(!F)=G8Ze6`&w=kJ{P+0z#}N$%S@ z{%k{;-`$P2vS-@*^3Ok)ed%-kQ24(3MgKj&?R=`8FJ&=zx60?u%3PBbeE)ST9gli= zI)C>8@wPk34A)is-ix@LY-f%UcoctEwOYPbhQE5td292&t?u%b0?%I@+3$J3c>cWU z!RZ?#&c2L)_HMOt+`h9Py{qQ^HG6f3*}kaM%3Sc4yq~rFf3Y7M-Sa}Vc-2DSIqHuHX$S4Gzt?)zr8XW2igR7tPD`yX2@ORsjU zIAOM;P=4e|fBzNAYnnX2zR`7;d))pRzrRdKz2M<`&e_!C&@3tYwJ{H(XTD;; z5%Gk*zQ0NMRMFBkk3vPC9K83d(J!*-2J`p++u;#isk`e~Y<^tVaknlie17hjPz~3i z8o_x2xA=FRE7R6!SHC?sDst2P27U!jfobR3d95DWFRqY|PEoqwEUVLS=d$6=WBT`8 zeJ;HJaOk}mpW?*+E2}&Caz8a*65Lnokka{o-hMtKmTcC|p(O|PCr&Utanai9V7BjS zz7s|}Z?nqJS+=^J`E|p^JLSuj%U|g&oPU6;%Z8n+dawJ7Suqt6Moz+OjNhs+x3B)n zzWL*s&%akcEi(K1``d%3Cugr+<{YQd(7-F(}CM@V^`L&dBB`J~munf8ni0YR4Y#%aMn6 zPcV$>=}cRFFHD_rQLAov&{`EYEbN-Taq^Z)Q@{*HRfLq%WaJU!KX zCVySHwe-|U${bIoEQsB3|M&l++ss=-p7;g*-}6)AM}^P+oA)N%`|_`)?Ed+7i+SoB zf&%RO41zeS7TkH6*j=V`)?!11@0HSLcb2zvo1L$Ck(0DTxBlZ**wl z;y#!C$Ky%Y;)2#ExW9{rACQC zpxkP4@CN6<#WIU8f9UJ7_*qqPL$-EG(w?cm=Smz(lRo;pWY?G8LkaS7N=E|fODxtq zhHehEXyVHLd-dbAcL(IY=k`n7xvOZkoc)IHqy-nYr^w6dEjFoW|6{d>p{jDz{&yRz z+iJJ`C^)3&Ynbrkw1)b&vi@)r=C$fY)vq=sr5jqf`qtV-^&XG9?|IDQsd@Um$94y; z_BU3#^zMl`_e|lD?$-4ASvG|=@#%8aE5Cf$=k`@`UWNUiA1_Llw7%ZAc3)GU=Vd=3 z_59kp?R9r$%3fSgkWXAX`+-9 z$QzcppX*?p?%j>MYaYAycdmJD!Ix6kSv@cDZo}M2$4ARIzszz}=HB;zpS`f<)($yz`I)hRx_ z_J;DrJN^Z%uM^DX9qBZlx#pO6xm{bDp*e2?>zxbc?i@Yad7oY|{BCQuY5PM(=c|Gx z>(@w3mfGBK&@Hep?nCN)%?4}MmGW}mB`w5=ePd5 zAe+pd%gVUQqw%Nov2$|$AM5AeUH<&xou~P>CE~?BHe&bhJbiF8sh?|~SL*kN83Dz2 zEOgf}zU5-nk^6H~md`Nb>D9{BFZB=o51CuiaWz$v?}qHnkgoWr0zn#I{?;^Hc^@UT z`it$2w@eahvl?U-Hy=xMd9^65vc-MP0rS93%*mpSewqFs>K~*k@VyAx&QoRI^rh#E z;6%2ns#)voc>n!8f9|uE<>+f%cw+J`-J zQzshSi0NvhoHjuWG39XyvlY+Y%zBtmUbdl$=aoVBEAt%B zK8fImCqMJM-*C-8VLbP!&_=`9;6A~5l9QUF;~%amUsd((mSN$uZRz?OqkW2kuRfkA z`F|q&jm@9<3+F7H(`sM5sxIKOb4)6;XU>92ENV746pnwCnKW<55hte|yiONYwyk3O z%HTIKOx9xe1}W)MJMROjFX~D+7Iin9n$+(WJFq|a_y=je^=?mdO!oQqAOHSRtlQg3 zNyflSSjO~4W41p7&t8$Jc;T7)!nz`?DxxkbVy78lXk;G>BQSJmaWalV}-pUEV#%mtaG`^3vd!@KvkiBy zJ6Bl5t=u8x61>L8qHdwDH@~lP{B*UtBTPk>s+Nm3omPuKW6dPt?s)a_G3hUz?M?2i zuhMVcD6w|mBXUvoq(HFk^5Pl4e?H*b;?~j6Y0@U+9n~SESl4&mqtz}3tQ>`!G1Y(0)O^7EJ<53 zQ}pK6_sc!)IQzmb7wW%UV^U!-U-wSOa1(S5At6& z+Ro!vP&HTorv2lvueVkL|I(!zyo+C`8h-Y(FpFO^g>P4ByoCR}Q*Jx17;&CkX5glx zb3Z@e(>_J3i5IjVL^Or5$BXc!*xafPkv*8nt@!+mqQ;*q+jW$_%-r+W>Llv|M_GBd z4QkJqulD@9omKoe^VFiW1yd$}W60L)V~BgS`@t7;tIS8!)YMGF)&ELQW)5{j}cyN9_gi)dF@G zRU>sxHZNnk^~)zZYIb!);mP%e99OSB>S;BwZK-d5VHI?o?Z?acJ~=lTU)-7SzdT$1 z!3^g~a@QL@<{$fQeV1MHTEr{$(m$QWk)CCd6WsG3I@BH8*7!@ro-6b15y6u$m^wRz zG&2vlBy>&sV)l>sbv-X1yNueyWnUzgXdJ(>x!OCI=NoTR`4#&b9=?|kx2Qbae^_vC z)1QK0EwM-M*JbmY{P`BGT*jg3`cLr^2e+=qwOqv;b02gwFIvOzD;%=$!OxHxb5G22 zN>7-&kpJM;4O5vXKY1EuRGQ#3`|`Uc!{vUvPW4XzoVR4f>B_C%zE?$7Tm6^rHdlW2 z+WRq+#paj*-5vMWoMy;ea;JXo*|{tA*H~5CMD&_&{Iuc7wX$uVNfOaB&YV4VA*Suw zj-Sqnk&N@#o3eF_?|t55lm1bsWq17CgI>W|DYJY|@FstqUAF7!o%l1IbLG$e)r_>- zlna;~cuw0v|{8R~!u5A)T5tO~`l0YZh-kl@~4DtpyDN+yYFD zP9hAeR!1@WWvxwTG1bjT=`?X_>e%Cy#J6kroEybuXYa0!sQY-NUL-^+WSO)?+e4*T zwj`Yw(v59vc&)Xx*;^OQw`cW_Oi=nDKVA1Fmt}R_beWIx`#;LZ|LkW9{H@RX>48(T z>F-@>am~fa3m)mU8CRGp&D^%)^c3|acc!NPoNz)S<$;rPXxY`tXP7sBaArNS($90!(~7SBI#gk<`s zJSp}3$pkA3C)u$J~iZtX>AhFO#R-_pR;J! zguWLej1QsS%M9B{cV@y*;(_DEsp)YV6hbh+jpX0ZFb%{ID8 zMdQHZnfXkM5;^}LEqd13_p!#VjD5>ohP4TGAD$NIZ!|QLh_?`)eso@B+(s|;3(h;I zGwf2yg!HA@KIdr+FC8{f+t&+D&5x5KloaH)%K0I zj=MkE|CCqfT#Mk_I>y{}+bq(Pmy{GezHodNyQE3enmK=d&kK!Io}|L8ynEUHo+vNR z`(gPyma0M5GdDSJwBx#@w^VPl&@GFJ?@nnv6W$ z55?)Om3j-liiv5q+FbZ_I%@X&DTz7jIgV_|6AIlX7^MD6U~WKwf-rkWTkO~A^K2Ws zSdx<;)aN!Rv2H)2#naLxZ&4a28UAGBx+@J1$x1UPI_>CFpQ0$BvFh-D2D4|Ety>Lh zVteCr7RB)w@-%&4`!OSS$_JkFX5W4Vl&ZY=aq!gVIWHgZp1+y(YST84D~(rd`nDyr z%Kqb&@pCJZ=$+vuG4oZmqtBd$+4^$~6>~m|H$}CtpZol)aZItiMDu-@)@?sJ&LzC; zz1foxuhKLO|ANZ1VP_spoT9(f zTic|=cFIq?P|lnflZxgqb3N}Y7oEg%;MKcZ`ah!jRFeNS zuC?5Ebg@^eb9c~(cU-(DZy8+RvuJvIb^B(HsGcMxk3UWcyS#Y0GxE*3JYR7v{j*o) zS_p&LQKJhcQD>I)%nvBi;H}y$+}H4NN*>QsSMGO5YYgY{#)V9uE^05ck*O@{(6x2h zX3A=JA`ksy3ZEDvb!P=f zMEasg)Yg_+?axXpu76Xxcg*JSp0J|rT5KUcslO(;nfePEy@T<&{`#c)=3SO9xWbaHL%w0)<(9(ozAx^Sjs9?!|euQ)>83oq8ReYMa!zwGKo z_MGP1nX-#=AG__U<-N4sx`EtRr)i!$PnhMt!beCT@GB%*bCu1B;`$V>l;)-17- zPhL1L`OvEwB@$8V&-ZxGgbPKD3Ig9(p7<0H+j?Cj`vgaI$|@E{_RERcsZ$P~@7Wr? z#3?T3>FN55oK=&%XX!Ej+_7rAom%CJ%qE>m`=b4e*KM<(cT*##BKE3>n{A}?n{nlA%f@Y~xq3(465l^a_Y!FDRCD&!%!^3XOJnY+*gUyPAw-{tE9u&! zD7RBxlQ-J7)ttC;;H}iDiDCsmp0M=Z;h4}W-~EjlK58Rmi%*f{Y>5wlKQ+POLsQJ||+T1LXuB<5T62W()^4bx9A0y@2 zVSS}4J8yi?x!Jguqj`R%xnr#OmD7*zU-@+F#Gbd8eqCIo^w_Ll&+OOC7}<ngMt{ZijF7I0;u-V<$;O(Ox@ys2Tdk??%`^n{GdSpRHeB zU9CPlYFjJY6Pa2DOWnHF9egeZJR+e}*RZU3pcvX&GR0*1sbaBr@n!Nk85@GFW@kwU z%~q;^XL*giJzmDtAIprCwvS1h5ZfhEw^6S4phL)2!@!9QS*0=8 z*Y52&>($gE#y-FM-#$@ZsW-2Jj5bu1$J}al_@QI==2Gse#mhhTw`4U=4A3(W`d(i# zr8y*Ff5_&DTL!^mb)rAxGVZxJ1oKt$?9AEN_jbQT#paJQ(%k2jIB1!FXwXl4RB8HU za^U69`T~5NZsLV!e_QEsRLuPl?H?}u>C~=yvDR_I@lKak1kWs3G$%AG_jS}v>oBdw zpSn&7=yA+Ad-Y1FRKc1#yX%gp`w7IHUXt7qrgkar&cr?06?PA|&Yo93OG^3hAq(B- z_NKa_x4bm`W=xDeG%dd=A+MW3Q8Px7M`{VX>%`?du0-YuJk3$jWS?xMmb-XTP^d}s zPaV0iT;Q z9QnWI_?{Csw=Zrh_1Ef6?NJXg|5P+t`I@J)Rx;16RV&Qi?lPUWc@SEa`0UxjOmWiHQfJ zGk+|LKgyMHYK!d6?$n*17m37OVf#5{>It8CPxD9SZlU{%XIsl|6Iw7OT4TE^$5%)H zltZgJd!9-kwBh`A;lr+sS@EXpSmU=Y<=e5<@>0%*BV8MJYD#*3f6X{)p;^rKWsOOl zo31SGQMzK$_BOiv#2RlKr!w(mu6_qMgR}i19exE?J6_Gv51Z<>-AiPTfW`a*&fBhQ z6Al`NYZZTTl4zTqs+Os2(0t^{u9eYW*R}@tT1Vww47qY}1=F4!V_U<6m8%mYSI%&% ziIfrvKExI63+D&&a@zFH2s|-(;F#5_i_as%gow zqx)uXFLae_U0icxy~Fb*%Hm!+d7lkldz3jQf3NhBntjo8i|wp!&rkA|?N6Nc(DYhJ ze}eAhg|VDVW#`Uj{j~l=nDF6QOYb;kI#}6Vd303u+?7X5^Q(Ikdxe+nd+8Otc9UN3 zC%drUa+5X*J!k$j_xh^ZS+8C)e!c0wvy5fxNfT9V^<0zRT4l#}`p=%daLLg$jWanW zhYKrC9yasa==o^R3upCYrA>3E@oe?{_48=sqGN}9j8mU@O7BbmsCcaHnZQ)TNlDg{ zDm8tr4||?Y`T4=kId{VCG;!-29aEz>TW*oP<2EZHQ=B7_OFCNS>x%cSQpa7FKT-3Z zCSiM`ASG+J8*QB&c^2TrVAdn+zM3evy_(D`HqWgXKp>$-CxVmrmm?&tp&mM!M!4qkfJ_IdW%1u3zC z3yy1VXxOlQGFxWW?c}q^R&y@C`B|l7k*0w34>x6FH(M5lFy$hxGC{UzamByy4k)i+ z%l=+`yYbam*Q6KO@wd9QCMF)y4B1@Y@sagl=R-CNk4+9S>~%M~Mb{SHd@Wr#Kj~fB zh6UFio_Ms^ph0lt2Zk^%c7q#hBrNWuR?Gv*1**2e?TU}5T zmCAf$bKiN@M~f>b3Mz(Pz7f`cXJdw?*E&V!>Mf36+vnkrk~uYXds$xAD*SmIsqsww@^ ziWh#q>1n;z{)1iieB25C?^>pva}v9Au1Y(9UvIhU``x^}TH)xgY8Q$^wqAa!r{^{6 zFoSc@1k1uq=h?k=Pnfnhx*dpI6uV|iVVq}k!Lv*b%OBfYpa0=px3(-`*}V;}sWVt3 zmHw9JuK1??cjYyaq>|P5%A-`Z1j661>fkdiUli6aAinfT?8bHLykexaZ*5bV%5?O@ z4Jn&BjMWcJ536if2)l7IZP&vup07Js=>>3E9JsTs{!75o=>{D+&xLkxD`{R++IHgJ z;V|BZtC}P({F44?5cD}FEG^`+)|%D-**9)h(P40RcD7Q`aQ6$ock<1JtAPSC|8ARc15Q7HN69I$DiOAHV~%nYmu4p^RzAsH$HiU}nKZiWUFJ`ck@ zC?Di0L4=_U%7@7_AYDBIzWgLUD$36g`9cyy zW0c!WT+3VyE#u<@f?PvFBIDgc{hUKQ{r%$O8RDb-3{4!9ic5+TlS_h=i&9hboK0P` zvOp5v=rX3|nJFb1u4Pyy%`#Fm(=$pSvgkUUjUZ-*grUoT%t9A)HiW1~^%9a9$UX%d zfGmJrw~G;Wm%+u6jc_r9Dn=1B01Kw%1eAe;2PM2siZk-d!Sbk%#)t=oU>Bcw&%DeM zhWPlz;^NezlK8a5%p9<=b5UwyNoqLc(i)ID_tX*yFBp1%4M@;8u^`CZ39P{_Gbbk~ zHMs=L2`xy0>xQY1j|%ZbaVJB3R7jYgp+S6naz#aAQf8TXblF2Y7ni( zz%UU+>o9=J3?^L$hGQW091IL+q4XsveI2AukAdMah?Zwy0NwY(B*y?QD;PN#7=#!Z z7?|`K7<3pJ7(jeuC=DtrKzv(}ydDGiJ{Kkf28J}Kd@htOg3{$sbyGpKAp^r25N*W3 zun$BVL+eTdRNkBceD@9`FEm_O85ltK>wx$k zApfy3Fo5pR0r5*fe0Ip4Ga&u~5TA*G0dyA*hz}}D8JQsd2l0PEfWGVPJ5B@5|l20(sfX} z2TFtL5Rkbmp!{u6`UsT11f?H9>32~250vI&VqgI2mw?i0P}&4aJ3;9HC>;-_)1h<; zlx~F5eNg%wl)en5A3*81P?{CABo!2&P+AsBYeH!UDD4BKBcOCXl&)ZbxO)zzn1xo*c(yUw%cZoo0WhiX~ zr5&Mk0F;i0(s@w27E1R(=_ycpE|gvhrPo2}ZBTkYls*onFF@)0Q2HH|{tKmfxFPP8 zhSDZb+6hWWLg_3hT@0nGp>zwBo(!cILFtW9`T&$Z52f!x>9yJSe>!O0S2~JD~IdD18!2Uxd=Pp!7>9{R2v~ z^FrJy2BlS@v>lZ8fzruPx&%tsLg`j0-3O)TLg_V7dN-6l1*LC7=@(G?JCyzpr8)Q@ z?h$~}l2BR$N}EGzHz*wnrBk4EF_dnC(i5Td0w}!#N^gYHJE8O;D18b_Uxw1Rq4X0d z{TWI#@k87x2&EOEv_6#ffYM=5Iu}aULFslV-4CT_KBms|6O?8Y zfVhJbN((`0DJTuP3=veX8bSGvP&xog$3y8nC|wJsd!Y1eD7^|wZ-Uahq4Z%WeFjQj zfzo%O^iwGP4od%p(ma9?cS}QQEhudXrGub!0+cR?(j8EGB9xv9r58czjZpdkls*ro z??LIeQ2Gy)<`#muLl{cSKxq{ytqY}XptLuXj)KyeP`Uz2w?pY^Pb2Bq&o>E}@TJ(T_drP+lc?iGX5s!-YlN;^a87$}_ur5mC2Bq%)_N-u`eYoPRQ zD18b_--OaHp!9br%_ahIhbWYmh0!UUu7%P)PDN&D3zYr?rCB8*?&O8iVo+KYN}E7wXDA&6r4yla z6_oCP((|G81}MD~N*{#Mr=avrDE$ITe}~d+QV{ouLTME!Z49NYp|lH>_JPu&P&x%l z7enbLC_NEMFM!hPq4Yi|eHKdJfznT)^jj$X6-xhu(rnTYck)ANaVV_-rS+k-9hCNk z(lJmv8%no8=}Ay}C6wL;r4K{t(@^>flzt4QKS60m8HjrXptL-c)`QZvP}&tr`$6e2 zC>;-_^PqGsl0tIolsg5N-IKXEhudX zr9Gf@IFwF<(xp(k4@%F0(wm|55h#5YN?(Q2_n`D!DE$XYbIU>8B?YB5p|k~*c8Ajb zP&xuiCqU^;C|v=i+oAL{D7_R)Z-LT>q4Xsv{SZojfYLvpG^0GkU7S!_2ue#qX=Ny_ z4W&(>v@?_rg3^glx&TVoL+Ke%dKr}73#HFN>FZGXK9qg|rN2XIHU)_LM4_|_ls1Oa zPEa}!N=HKJBq*H)rHi3-6O^6^r58Zy^-y{rls*fk??CC-Q2G~?W>SQ>iyKM{LunZ( ztpcTWp|mNKwu92XP&x)mXG7^KDBTIA7eVO_Q2IEOz5%5lLg|-K`V*99RD!rq07}b4 zX+0=y3#EOabTpJshSE7ux&%tsLg^kTJsV1|g3>#o^a&_^9ZElg(qEx8i!#JrJWyH` zO3OlNH7KnIrOlzVJ(Tu<(&11#4N8|n=@uwG8A`8#(z~GaMJW9UO23BEpP}?0D9x<` zai!jZ?t;>jp!94gy&6jIg3>3U^bIKe z97=zK(yW>gcZoo0Whku;rA?r;4U~3;(!NkS3`)mA>2xSv2Blk}^b{z)7)oz~(x;*H zO(^{VN;7If+{Fc@g`l)Fl-7dMmQdOQN{2(~G$>sPrCXqM50st?rRPHFWl(w>ls*Qf zuR-Z&Q2HyBX3>VYPZ&xoL1{xMZ3(5FptKj14u;avP&x%l=RoOFDBS|3CqwB)PYP2}5ZmC~XL(9iX%aln#W_kx)7bN@qdoVklh=rCXr%WGKA| zN^gYH2cYzMDE$ITzlYLHdJy+6=jc4V3-@rP+-k?%{{hN>Ex0O4~wdS126;r4yiZ zF_f-`(tS{R8kAlMr8h$9BT)Jbl)ew8pF`)_J-2IP&y4t z=RxTTN6gVJeGIuA;>LFqmy zy$njPgVM*K^f@T~3`)O)(rji>`=PWNl-7gNZcy3}N~b~TJSg1;rTd`tGAO+cN*{#M zC!zEmDE$OVe}~flp|p@W#640_S{F*2LTL{u9RQ`1p>#Hsu7lETP3dL`*%D%} z0+iN((hgAC14<`A=?o~{0Hr&i^a3co0!kl+(r2OcD=7U5O7mMm>=lR7`cT>&O8Z0U za44MxrHi0+E0peq(hH#U3MjoBN*{*O*P!%0DE$#i|Af*!))4oIKxuU-tq-N0ptKj1 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 XmMDk?!3CQb7(i$2L3ofGPeE(|cv-$g literal 0 HcmV?d00001 diff --git a/Widgets/FrameBufferSDL.cpp b/Widgets/FrameBufferSDL.cpp new file mode 100644 index 0000000000..cc43c41706 --- /dev/null +++ b/Widgets/FrameBufferSDL.cpp @@ -0,0 +1,49 @@ +#include "FrameBufferSDL.h" +#include + +FrameBufferSDL::FrameBufferSDL(unsigned width, unsigned height) + : AbstractScreen(width, height) +{ + initializeSDL(); +} + +FrameBufferSDL::~FrameBufferSDL() +{ + SDL_DestroyWindow(m_window); + m_surface = nullptr; + m_window = nullptr; + + SDL_Quit(); +} + +void FrameBufferSDL::show() +{ +} + +void FrameBufferSDL::initializeSDL() +{ + if (m_window) + return; + + if (SDL_Init(SDL_INIT_VIDEO) < 0) { + ASSERT_NOT_REACHED(); + } + + m_window = SDL_CreateWindow( + "FrameBuffer", + SDL_WINDOWPOS_UNDEFINED, + SDL_WINDOWPOS_UNDEFINED, + width(), + height(), + SDL_WINDOW_SHOWN); + + ASSERT(m_window); + + m_surface = SDL_GetWindowSurface(m_window); + ASSERT(m_surface); + + SDL_FillRect(m_surface, nullptr, SDL_MapRGB(m_surface->format, 0xff, 0xff, 0xff)); + + SDL_UpdateWindowSurface(m_window); +} + diff --git a/Widgets/FrameBufferSDL.h b/Widgets/FrameBufferSDL.h new file mode 100644 index 0000000000..9d58894427 --- /dev/null +++ b/Widgets/FrameBufferSDL.h @@ -0,0 +1,19 @@ +#pragma once + +#include "AbstractScreen.h" +#include + +class FrameBufferSDL final : public AbstractScreen { +public: + FrameBufferSDL(unsigned width, unsigned height); + virtual ~FrameBufferSDL() override; + + void show(); + +private: + void initializeSDL(); + + SDL_Window* m_window { nullptr }; + SDL_Surface* m_surface { nullptr }; +}; + diff --git a/Widgets/Makefile b/Widgets/Makefile new file mode 100644 index 0000000000..58c3678f0c --- /dev/null +++ b/Widgets/Makefile @@ -0,0 +1,37 @@ +PROGRAM = test + +AK_OBJS = \ + ../AK/String.o \ + ../AK/StringImpl.o \ + ../AK/SimpleMalloc.o \ + ../AK/kmalloc.o + +VFS_OBJS = \ + AbstractScreen.o \ + FrameBufferSDL.o \ + EventLoop.o \ + EventLoopSDL.o \ + Object.o \ + Widget.o \ + RootWidget.o \ + test.o + +OBJS = $(AK_OBJS) $(VFS_OBJS) + +CXXFLAGS = -std=c++17 -O0 -W -Wall -Wextra -Wconversion -I. -I.. -g `sdl2-config --cflags` + +LDFLAGS = `sdl2-config --libs` + +#test.o: BlockDevice.h FileBackedBlockDevice.h FileSystem.h Ext2FileSystem.h VirtualFileSystem.h FileHandle.h + +all: $(PROGRAM) + +.cpp.o: + $(CXX) $(CXXFLAGS) -o $@ -c $< + +clean: + rm -f $(OBJS) $(PROGRAM) + +$(PROGRAM): $(OBJS) + $(CXX) $(LDFLAGS) -o $@ $(OBJS) + diff --git a/Widgets/Object.cpp b/Widgets/Object.cpp new file mode 100644 index 0000000000..bf7fa7469b --- /dev/null +++ b/Widgets/Object.cpp @@ -0,0 +1,23 @@ +#include "Object.h" +#include "Event.h" +#include + +Object::Object(Object* parent) + : m_parent(parent) +{ +} + +Object::~Object() +{ +} + +void Object::event(Event& event) +{ + switch (event.type()) { + case Event::Invalid: + ASSERT_NOT_REACHED(); + break; + default: + break; + } +} diff --git a/Widgets/Object.h b/Widgets/Object.h new file mode 100644 index 0000000000..4b0d0a64f9 --- /dev/null +++ b/Widgets/Object.h @@ -0,0 +1,14 @@ +#pragma once + +class Event; + +class Object { +public: + Object(Object* parent = nullptr); + virtual ~Object(); + + virtual void event(Event&); + +private: + Object* m_parent { nullptr }; +}; diff --git a/Widgets/RootWidget.cpp b/Widgets/RootWidget.cpp new file mode 100644 index 0000000000..b1b54a5682 --- /dev/null +++ b/Widgets/RootWidget.cpp @@ -0,0 +1,23 @@ +#include "RootWidget.h" +#include + +RootWidget::RootWidget() +{ +} + +RootWidget::~RootWidget() +{ +} + +void RootWidget::onPaint(PaintEvent& event) +{ + printf("RootWidget::onPaint\n"); + Widget::onPaint(event); +} + +void RootWidget::onMouseMove(MouseEvent& event) +{ + printf("RootWidget::onMouseMove: x=%d, y=%d\n", event.x(), event.y()); + Widget::onMouseMove(event); +} + diff --git a/Widgets/RootWidget.h b/Widgets/RootWidget.h new file mode 100644 index 0000000000..c025ed688d --- /dev/null +++ b/Widgets/RootWidget.h @@ -0,0 +1,13 @@ +#pragma once + +#include "Widget.h" + +class RootWidget final : public Widget { +public: + RootWidget(); + virtual ~RootWidget() override; + +private: + virtual void onPaint(PaintEvent&) override; + virtual void onMouseMove(MouseEvent&) override; +}; diff --git a/Widgets/Widget.cpp b/Widgets/Widget.cpp new file mode 100644 index 0000000000..3a1ec8e0f8 --- /dev/null +++ b/Widgets/Widget.cpp @@ -0,0 +1,76 @@ +#include "Widget.h" +#include "Event.h" +#include "EventLoop.h" +#include + +Widget::Widget(Widget* parent) + : Object(parent) +{ +} + +Widget::~Widget() +{ +} + +void Widget::event(Event& event) +{ + switch (event.type()) { + case Event::Paint: + return onPaint(static_cast(event)); + case Event::Show: + return onShow(static_cast(event)); + case Event::Hide: + return onHide(static_cast(event)); + case Event::KeyDown: + return onKeyDown(static_cast(event)); + case Event::KeyUp: + return onKeyUp(static_cast(event)); + case Event::MouseMove: + return onMouseMove(static_cast(event)); + case Event::MouseDown: + return onMouseDown(static_cast(event)); + case Event::MouseUp: + return onMouseUp(static_cast(event)); + default: + return Object::event(event); + } +} + +void Widget::onPaint(PaintEvent&) +{ +} + +void Widget::onShow(ShowEvent&) +{ + update(); +} + +void Widget::onHide(HideEvent&) +{ +} + +void Widget::onKeyDown(KeyEvent&) +{ +} + +void Widget::onKeyUp(KeyEvent&) +{ +} + +void Widget::onMouseDown(MouseEvent&) +{ +} + +void Widget::onMouseUp(MouseEvent&) +{ +} + +void Widget::onMouseMove(MouseEvent&) +{ +} + +void Widget::update() +{ + EventLoop::main().postEvent(this, make()); +} + diff --git a/Widgets/Widget.h b/Widgets/Widget.h new file mode 100644 index 0000000000..be6966300d --- /dev/null +++ b/Widgets/Widget.h @@ -0,0 +1,26 @@ +#pragma once + +#include "Event.h" +#include "Object.h" + +class Widget : public Object { +public: + explicit Widget(Widget* parent = nullptr); + virtual ~Widget(); + + virtual void event(Event&); + virtual void onPaint(PaintEvent&); + virtual void onShow(ShowEvent&); + virtual void onHide(HideEvent&); + virtual void onKeyDown(KeyEvent&); + virtual void onKeyUp(KeyEvent&); + virtual void onMouseMove(MouseEvent&); + virtual void onMouseDown(MouseEvent&); + virtual void onMouseUp(MouseEvent&); + + void update(); + +private: + int m_x { 0 }; + int m_y { 0 }; +}; diff --git a/Widgets/test.cpp b/Widgets/test.cpp new file mode 100644 index 0000000000..b42c7a8275 --- /dev/null +++ b/Widgets/test.cpp @@ -0,0 +1,17 @@ +#include "FrameBufferSDL.h" +#include "EventLoopSDL.h" +#include "RootWidget.h" +#include + +int main(int c, char** v) +{ + FrameBufferSDL fb(800, 600); + fb.show(); + + EventLoopSDL loop; + + RootWidget w; + fb.setRootWidget(&w); + + return loop.exec(); +}