From c733a41d10cbbedb6c57ee93539f29a2e2551353 Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Thu, 28 Apr 2022 11:43:27 +0200 Subject: [PATCH 01/28] Add design documentation for improved memory management --- .../docs/development/wrapper_cache.drawio.svg | 451 ++++++++++++++++++ website/docs/development/wrapper_caching.md | 25 + .../development/wrapper_keep_alive_seq.png | Bin 0 -> 96150 bytes .../development/wrapper_keep_alive_seq.puml | 94 ++++ 4 files changed, 570 insertions(+) create mode 100644 website/docs/development/wrapper_cache.drawio.svg create mode 100644 website/docs/development/wrapper_caching.md create mode 100644 website/docs/development/wrapper_keep_alive_seq.png create mode 100644 website/docs/development/wrapper_keep_alive_seq.puml diff --git a/website/docs/development/wrapper_cache.drawio.svg b/website/docs/development/wrapper_cache.drawio.svg new file mode 100644 index 000000000..bc6303e04 --- /dev/null +++ b/website/docs/development/wrapper_cache.drawio.svg @@ -0,0 +1,451 @@ + + + + + + + +
+
+
+ + QScreen + +
+ <<cpp>> +
+
+
+
+ + QScreen... + +
+
+ + + + + + +
+
+
+ + QClipboard + +
+ <<ts>> +
+
+
+
+ + QClipboard... + +
+
+ + + + + + +
+
+
+ + QScreen + +
+ <<ts>> +
+
+
+
+ + QScreen... + +
+
+ + + + + + + + +
+
+
+ + WrapperCache + +
+ <<ts>> +
+
+
+
+ + WrapperCache... + +
+
+ + + + +
+
+
+ + WrapperCache + +
+ <<cpp>> +
+
+
+
+ + WrapperCache... + +
+
+ + + + + +
+
+
+ QPointer instance +
+
+
+
+ + QPointer instance + +
+
+ + + + +
+
+
+ + QScreenWrap + +
+ <<Napi>> +
+
+
+
+ + QScreenWrap... + +
+
+ + + + + + +
+
+
+ + JS / TS + +
+
+
+
+ + JS / TS + +
+
+ + + + +
+
+
+ + V8 bindings (C++) + +
+
+
+
+ + V8 bindings (... + +
+
+ + + + +
+
+
+ + Qt + +
+
+
+
+ + Qt + +
+
+ + + + +
+
+
+ + "Wrapper Keep Alive" case (Instance diagram) + +
+
+
+
+ + "Wrapper Keep Alive" case (Insta... + +
+
+ + + + + +
+
+
+ QPointer instance +
+
+
+
+ + QPointer instance + +
+
+ + + + +
+
+
+ + QClipboardWrap + +
+ <<Napi>> +
+
+
+
+ + QClipboardWrap... + +
+
+ + + + +
+
+
+ + QClipboard + +
+ <<cpp>> +
+
+
+
+ + QClipboard... + +
+
+ + + + +
+
+
+ Map QObject +
+ <-> +
+ Cpp Wrapper +
+
+
+
+ + Map QObject... + +
+
+ + + + + + + + +
+
+
+ Map QObject +
+ <-> +
+ Cpp Wrapper +
+
+
+
+ + Map QObject... + +
+
+ + + + + + + + + +
+
+
+ QObject destroyed +
+ signal +
+
+
+
+ + QObject destroyed... + +
+
+ + + + + +
+
+
+ Object destroyed +
+ callback +
+
+
+
+ + Object destroyed... + +
+
+ + + + + +
+
+
+ QObject destroyed +
+ signal +
+
+
+
+ + QObject destroyed... + +
+
+ + + + + + + + +
+
+
+ JS strong reference +
+
+
+
+ + JS strong reference + +
+
+ + + + +
+
+
+ Cpp reference/pointer +
+
+
+
+ + Cpp reference/pointer + +
+
+
+ + + + + Viewer does not support full SVG 1.1 + + + +
\ No newline at end of file diff --git a/website/docs/development/wrapper_caching.md b/website/docs/development/wrapper_caching.md new file mode 100644 index 000000000..b7ba9aa7c --- /dev/null +++ b/website/docs/development/wrapper_caching.md @@ -0,0 +1,25 @@ +# Wrapper caching and memory management + + + +## "Wrapper Keep Alive" case + +The goal of the "Wrapper Keep Alive" case is to maintain and "keep alive" wrappers for the life-time of a `QObject` whose life-cycle is under complete control by Qt itself. i.e. Qt may expose the object, but it creates the instance itself and also destroys it later on. This situation applies to `QScreen` and `QClipboard` for example. A common use case for keeping a wrapper alive is to receive and relay signals from a `QObject` back to JS during the object's life-time. + +![Wrapper cache diagram](wrapper_cache.drawio.svg) + +The WrapperCache (C++) holds strong JS references to the Napi wrapper instances. This keeps them alive. When the core QObject is destroyed the "destroyed" signal is emitted and received by WrapperCache (C++). It then removes the Napi wrapper from its cache and uses a callback function to inform the WrapperCache (JS) about the destruction. WrapperCache (JS) can also perform clean up and null out references to the Napi wrappers. If someone then tries to use a JS side wrapper, then will get a JS side null pointer exception with stacktrace. + +**Life-cycle Sequence** + +This sequence diagram shows the events when the application calls `QWindow.screen()` to fetch the `QScreen` for the window. The `QScreen` instance is fully created and managed by Qt. Here you can see how the wrapper creation interacts with the JS and C++ side cache classes. You can also see how the wrappers are gracefully shutdown when the core Qt object is destroyed. Any JS side use of the destroyed wrapper / Qt object results in a neat JS side null pointer exception. This is much better than null pointer segfault on the C++ side. + +![Wrapper keep alive sequence diagram](wrapper_keep_alive_seq.png) + + +## "Wrapper Recycle" case + +A related use case is where we want to "recycle" wrappers and ensure that for a QObject we only have one coresponding JS wrapper active at the same time. For example, repeated calls to `QObject.parent()` should return the same value/object. + +Another goal of this use case is to ensure that the unexpected destruction of the underlying QObject is handled in a more graceful and helpful way than just segfaulting the whole application. This requires the tracking of the QObject via its "destroy" signal and using that to communicate back to JS what has happened. + diff --git a/website/docs/development/wrapper_keep_alive_seq.png b/website/docs/development/wrapper_keep_alive_seq.png new file mode 100644 index 0000000000000000000000000000000000000000..0bbc0adf40c3cd319e3dc61d378d584349d92553 GIT binary patch literal 96150 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ⅈ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 i)my}g4uGl0#5I> #E3C800 +participant "QWindow.ts" as qwindowts << ts>> #E3C800 +participant "QScreen.ts" as qscreents << ts>> #E3C800 +participant "WrapperCache" as wrappercachets << ts>> #E3C800 +participant "QWindowWrap" as qwindowwrap << cpp >> +participant "QScreenWrap" as qscreenwrap << cpp >> +participant "WrapperCache" as wrappercachecpp << cpp >> +participant "QWindow" as qwindow << cpp >> #D5E8D4 +participant "QScreen" as qscreen << cpp >> #D5E8D4 + + +== Wrapper construction == + +activate qscreen +app --> qwindowts: QWindow.screen() +qwindowts --> qwindowwrap: screen() +qwindowwrap --> qwindow: screen() +qwindow --> qwindowwrap: QScreen instance +qwindowwrap --> wrappercachecpp: get() +wrappercachecpp --> qscreenwrap: new() +activate qscreenwrap +qscreenwrap --> wrappercachecpp: QScreenWrap instance +wrappercachecpp --> qscreen: connect to destroy signal +wrappercachecpp --> qwindowwrap: QScreenWrap instance +qwindowwrap --> qwindowts: QScreenWrap instance +qwindowts --> wrappercachets: get(QScreenWrap instance) +wrappercachets --> qscreents: new(QScreenWrap instance) +activate qscreents +qscreents --> wrappercachets: QScreen.ts instance +wrappercachets --> qwindowts: QScreen.ts instance +qwindowts --> app: QScreen.ts instance + +note across: The app can use the QScreen wrap and run. + +== Qt object destruction == +note over qscreen + Qt decides to destroy + the QScreen instance +end note +qscreen --> wrappercachecpp: destroy signal +destroy qscreen +wrappercachecpp --> wrappercachets: destroy callback + +note over wrappercachecpp + WrapperCache removes + references to the wrapper + and Qt object from cache. +end note + +wrappercachets --> qscreents: null the ref to QScreenWrap +note over wrappercachets + WrapperCache.ts removes + references to the QScreen.ts + instance and QScreenWrap +end note + +destroy qscreenwrap +note over qscreenwrap + V8's GC will destroy + this automatically +end note + +app --> qscreents +note over app + Any use of QScreen.ts + will hit the null reference + and throw a JS exception. +end note +app --> qscreents + +destroy qscreents +note over qscreents + V8's GC will destroy + this automatically +end note + +@enduml From 4f40510248592400391eb5bf8f88adcf55a5401a Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Thu, 28 Apr 2022 21:18:16 +0200 Subject: [PATCH 02/28] Document and design the case of object creation --- website/docs/development/wrapper_caching.md | 5 ++ .../development/wrapper_keep_alive_seq.png | Bin 96150 -> 98437 bytes .../development/wrapper_keep_alive_seq.puml | 3 ++ .../docs/development/wrapper_recycle_seq.png | Bin 0 -> 32278 bytes .../docs/development/wrapper_recycle_seq.puml | 46 ++++++++++++++++++ 5 files changed, 54 insertions(+) create mode 100644 website/docs/development/wrapper_recycle_seq.png create mode 100644 website/docs/development/wrapper_recycle_seq.puml diff --git a/website/docs/development/wrapper_caching.md b/website/docs/development/wrapper_caching.md index b7ba9aa7c..30a98da9b 100644 --- a/website/docs/development/wrapper_caching.md +++ b/website/docs/development/wrapper_caching.md @@ -23,3 +23,8 @@ A related use case is where we want to "recycle" wrappers and ensure that for a Another goal of this use case is to ensure that the unexpected destruction of the underlying QObject is handled in a more graceful and helpful way than just segfaulting the whole application. This requires the tracking of the QObject via its "destroy" signal and using that to communicate back to JS what has happened. +The object creation sequence runs quite differently than in the "Wrapper Keep Alive" case because the application initiates the creation of the object and NodeGui then creates the different wrappers on the JS and C++ sides. + +![Wrapper recycle sequence diagram](wrapper_recycle_seq.png) + +The destruction sequence in the case of the C++ object being destroyed is basically the same as the "Wrapper Keep Alive" case. \ No newline at end of file diff --git a/website/docs/development/wrapper_keep_alive_seq.png b/website/docs/development/wrapper_keep_alive_seq.png index 0bbc0adf40c3cd319e3dc61d378d584349d92553..b39fa16006be9dc19f30713cd9d332c62dbd908a 100644 GIT binary patch literal 98437 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 literal 96150 zcmd?R1yI#(w?2#_peUl!AfQM{O9;{`A>G~G-3@|BivpXF66uz1P|3aN?vj%3*yML_ zjK}9a@B5r@<~!e+`OkmPI2+*?cdWS9wbr@=r6pfrpcA4aAt7Oi2n)y}AzfJq|E#ZG z2EXZb3>gAn)b@hP_Ig&<#qq>AKuAwzs$DWMs59*RiyBurO!P zv$DATh~q9260(ZDk8zGqP@Iw)dvwb)tp9xG3MR6N{AX?7t27@TrRE!d z+U9q&CobO;UTb%}I#6=%VU%GK{}$V1Ssl&;|M?79Vj^BQD6?swQvH z7w9#7j9LLwRJ^e_VvVy0R6$ot_?ybo#S^NsH?jT2hcP((uh~jSL=vXc|132 zM=`8?soHS-fkP>-k;=?&SU6~4-?c-aEhc_xG^Ui!qzILc>U#vOhtAIS=JNOL53wJl z@~NB8B&Dv`z7$Ok70sHF{k)VlK~dp+|A~DYo$;5uTwJxX{kPC7?V|J6B&BKAD@T3! zooDB&7AhZC)N~Zl-Fm`I=~GlbV!DQ*18aveuRd@_-=~w-xPhjeP3WT?yO(p&U`bY% z;q{;lZBa%OnNXGKRjp9StAJ!W+e`1IPy*Gy5mw3hnk|*fS!;ZjZCcLC-YqU4i2N`( zsEZ#YmvB%*@oCa1MM=XlSx%FLo;d%eo|$l|@wY6cy_GBL%#`vXp_S`K?Gqu9SA`!V z`>yB;YqSIgJWcyp&28tDekl3Gp_YHK7ly|jmcxQJ$fJwRXtjp%YGTty)b_>~^F)Qd z_bo-d%1y2) zkr5Wf;0sBk9rMYy1%JTG^=K!hGZYr_&N^3W|wa=PSGoer{PPaPEXgr3GpsJ%%mA*HEY^W zHLsos`_0(lem!^<_+`HQE0WSTKU(Sq<>!x_Yp98NNmtdiSzd^bFq2yOh_T%_F@NL( z3kWv3ig}>r^v37@?Y>BHCU&f6q@*4~^ww6`C&-DF0j0z~E`dl$-bf+>&*YsoR};{j zvFG=jsqVidzomMIoRa)icQF3bG^`+Pq-*zxv1Q~xsn@pRq?KP0cz^HXjOdG?t7KO* zZ{3o< z)h|BMnQ!~A{rb<-sn0NkNkM!b>i-}0bN6LxOc$GpDu=DDt+TT;SgK*BW3%t!eg$GK zJKlJz;ETk!Fd$o2T>J(-36HBhlOR{jsXbQMT_s0HHVblYZuQQZlkK)hm!-7mIdNrW ze1pzJ9$F*B{cFn5Y3vq8vB0QWlBrqiYJU$bqgWK(Z3_PZbwvg@ zH-uC;->qo|Uz_+}p_#=lnWEWE7Gq^7SFW&HO`h~;$te|RdYo*vq;a!TWV;=#Q%or* zKlh_oD?8cnIv=a|@=D_Mcv!Ffa|!-*1*4@k#@J^X*xgSd4Q>-nB;k6Lf93@9@Y%r zky^h|dq84 zzVkc`NA+Z-p#I~>kF9EFhqGbrs+B0D31C~k4tbpJ4e8npo4NhueuxyyRjQQEg=Cs6Tp$7hLf1Ih4fd7?a<<)LlllE+ zP1eUND_zQUOvG<0M#hvj?l;AN!F~DiMgDZ^{EQ0s{CMiTmyBZmny!P33<^R2`b2d! zqn4(7Q(@%6y4GH5ePC$l-p)?7JKQ#w*?^GEJSNWQff$5lZ>Nh-j+c{DHIbTauZ7fW zuArSaN?D#*P+2*KMM0CHFmn_OjPf(luty~d_+cG)M!$cATb^Rz<0E1HvAK{tGN<#= zTK#_G<9!)Y5d~NWf-gewpY`F=Dc=)qSB1S;Bvti;!Fs)MO|EZW8L-JR9?T_B0Gi>k zGDyGecA~#!qhceSm6a74%jrN9`r^%95wGL@HQKI{O5%mWMr8-={oLGaSX-JqHewh# z(|f2u{aUo+L$Xs<#l^)_n+9@}+6XA}R7*cDS2?Wo`*DYdhqrbZ8X18di_1+vnHTys zjAe}GZyn{G^>k+B6eBRSMWCr?pXq662nVii(M9C#`x<9u}5}Tveb2 z0+8@$&z=<)76Q=(<9MJqn5V|>GO@QZB<3>pR=~?`f0cSMwlp%VldlAQt5izg*z0fx zZ3`mov{x#HLBy82Tx8J3pjCIW*?ElR)L1+&)ro1*LYi;+sllj4z z8I|(Y3w4`-oMoIaXN;9wMHJs58vmr@8{bu0AGO>A_gB2{8AA0W445{n$r=@vQeFlM zAm%0LYhdx)!Nc36I!}*>476P4aX23E5~tehP5nV^8c34AeWnedYjd%Qai_(S(K=R7bS>559vQ`cw) zjaH9PQa()$&*k9JnK|DaWF|0*MK;Q-e^ObV_gjei2f8Gu*0MBUkh9K@h zeExTTepCTDT^pjclKjr3<9uq=5P$y{k8!ele~(Df!25%O}NwJd{n zM;U!^3#OG0J@wc5m?z9O%aKD~$7}4RgD4|qYdKr9axJ0!&i5!KoZB=e%+vyg;|=Hp1F*VviYZm5mKglFcA^LKkft(>a^$HrQMWt66WDjP?cb8cDpVN9Tto!r7+iOo1 zu_ES*(({nM%C6TG6b4tC478FQwzEAb41R$@DyB%!mWO@w#}M8S+|lu%|7dWs>k%sw zL7C;$cK1--oyWhS+1nLn{SZ(39cNiwX~@;ED<(NnYR^Pr`YW{0U&TGk&h}G8>fpIk z)9Pxt`yG3w;aLSK-`OG2IqdkTVkj>m?EdWGym+7J%;vDin=g5*-<3p_wE~Rq%4J9@ zfH`*if;rYPeMqEnuJjIy>>i3eu_Lb#28-Ai((104kUiJ$HOMvoB#lFMn_#u%zqFyqe}=g-Y8#YdP8vM33%kNt zln5@<+$^YR-nYtrRE&L6czjn`rNF$BVUXYM>`Q~1(SI5p}|QF3z+E-NY?Pix?^ z9tdxetq>@yY@nRO%*@Zz(f{vxp~8y-$==4~n}=Du=9{52{Cm4u zM2vXS$zHTMU2Jxg|LrO}^k>rLiO5k+TuX5BKCph~-u1dgD$U5(>IP|chSUVucl1*= z6_2u5mP@ob9-9o;-@B1JzuUV3cEZPN{&AU?oL_9(G?3EIFx&vLv+#CghcrDc(J&_n z?1gYLMXGECbc8;F6 z>j=I77)Vi1804`K)k9ye`MuX(T&^>%tNH z*xM#0;?Ea-(=uw3kYUfAwO#;E)5uX3m669}=-PW#oCkVdtxxd8<7sd^bo=m@(cEw-K;@CnX!n8Jd-dqs-SzN{of~wUAm_PSs&i z0HcnDjg3u2#BMdo4BHrU`quNJy3ArMkumW5&_-5Y24mlJ6P{Mui;_u<4U~0*O;{cXHhbcL*k3 zKYT>7m?wN4oklTP*H7j8WcrDce>oKeU+?leMRyT_t}~vSiCj;8jkG*plk~W<$KS9L zmQlt=?0L)(EZ?bcx`re)@P9C|C+vJz7eq!vJ3?H8JDVAB6#i(2I~&j?Kp~0yUV&|liin;Cy6_8E#AxB zZ5@#k%C|hN(%+XSa$@FY5WFwz&F7e;Crc})Bv_g)sznEkWdH+Xp3Ax9Sr$nz5#yYc zS)Y8+)rccWi` z{Uk4zhf1-m8?ijJv|@M_rKSV$lbr%BPk3o&COWBCjmjJmn|YD>i0TSlqk2Db<6hts z&l7iJW05*?pZttCHVJWYbN*SXB=@Lh7*rDjEJ;e`%*B!rs;M;mSQ5OGxU1Xp17=EE zadn2>Z=W3qO;zhp=)Uv%Ami&oyQtFTRigF+o}L!4(dCY(T69J0&NJM6nH?bswZ~~T zNf}4o${Zu`&0K6hu}f#bsfgs6_o2}#39^2mC9h)ROgKPg3wnL6x2Sw4!@!H4K86N^ zh)xg^%}KLNoCa7(mBiJ-Cjtu;^1b&hZ|>*1IyF6yBKkg$)yC5x0U8{ zTg?L9x9&7SU#oN#sHOy&?+erv8<&037ZflcO)IG?<#QG--IMkf7svIrb z`ISLEQBK_|1!NbV@4uNg8_Q0{(H^P$8QiOP&pt=dLaogG(4W*Z**!}(?O>xzR)W`V zVbR3rHwEX#Rv@DhAS=@CWY6T|k@@84r^Xa_S=#dDMkdtneFd7=Z;O$ITd4h+T% zJ30&_tiy`@QolW!=M^zq-RHJpCG9jVh7A4s*lMCiCCBguEaELykxPe0TnF5+O1g|U`35;a3gYkg>g`kni3 zPd*envA+uaV5&OW%RY%O2JMJ*LP0|V(T7uCI@nx)Hy*N`L|dj&0ABP zJL7hYCg*!BHEq4(c6wqR!MR4PWkno98&?bfVsToTiYz>CEbpq_ro#Ycvb)#|^PRY; zXR1f^{t{Z5?A{vO3X=dXC7M5SWFu`Y-NE@-$qRm)pkB%;*KEr=coNxlhvN1r+8&;k zJ?k`_O5?cs0molfM3dHxh4LokYn!qs={I;w8ni&nAzSRrv#7Dl_V*#B8ayLVgu@A| z#+fRf36)zKnI>vbT3%B8X-WqTzXQ*DtyV=P&gOe}tmTBOzkf8XMwR$be(lY>PXwW{ zEK@0BYc{i#F9a2?UcDL;R=}+DRZW*yu9tt4p{@Kqk&r2XcPX`yQi9h@7ZYYUWaq8x z9EXfQ;GiSRm0yxgsN$>I8I}~4e9sd&K0$;vRl$BV>HXQe;xOm|Rp_mq*zgv9BI?~N zghrq#4z6547S~%^U0>Ky`{hs&SjCQ3Ei*-0StV|3wV1K)>Ln`RI17&0IS9**cPIVr@^;*zvorkE zF%9~nBsYLbyP2Ci#E&r0yZ7o60Zz)yKnITNvf`kdjB}p3vU1~OZS0^+U8?`IM%2y6 zM!Wi=br^_6G@@;bw@gn>n$~iuU7nhINTkVj`m_oR#D&}aA&Om$IMnx_5i@!LgudoW zHJ$PLyJ_IXT+535cz%qv_BRG|e#~zx9ETt_$ey0ROrvd3i}$H$6m6sEL*)w} zFjEBl1~=**vn#}?p#S5P{#(%Z?Qn{AWg0C$H8q)#Pa=U;nWthR$W2BEX`czK^^A1424DFT*?Qw_V5Tdt{WUh+mtTaom^^of-RqCq+}VqJmIG z_0F?8-DrLQ20p#uU2!Yw>>BJ_+HkSi_Bo;rcq|= zwe0@V(im$OUw6HVbdsi}gx*hIWFb%5Fdc-VA~;LJ2UD}kryDlIfiK~qT{+niw zlP6D@wg@Ze+|f%=aF7pY40YI$A+Fxeq$H7rSY9jPXEyhY&S@L8-V_j$V&Aown&YwHD$_Vxy0a2`$c8Y?pNeEV zXnNHe(o_`&T%`PdxL`iBYQY^6;xuAX5de43_TA;PH554EkhIbIIM!uScm$e#c||Ez z^`a4FjjHyRWy6D^BG~WM*AwYYu}HO`r9+(_EA7p-k$q0TC*+Q=8Gb$UlaWE~>B+Wp z{3P|`Og$6l?cx4Sw?UDesc@1SEuIdjb>(T~Oc8{~=G*g*_oZ&T-;W2BjwO@o#1RCM zQqG`|XSbS|GcOUo-iczbQqpfZ<35EwoZ zj}kN2BNE%&Q|@+$Yvp}+?hqvEFXiW_^&z+Gkc4*(Nh9)&k`?Cr+R(Z4cNxF}<^j^av zj(I1dZ)gHw)Eav`s{s=1L{wE&RD+ET?B@H(lh&hzr1f*1DZD9SOY1g(p!NhDDglNBIPaFv;}p%1A=YU;o&e^8usOL5Y45*vSe< zoAwNA)`&0Mg_AL>KxE+C4oeuhXmGk3>b3$klUKHU{Tpo6=jeYTT&UCSUq$0soZvf*W;A>T+Q|quayL%hzn*Vr0rq*gDbj4)!*aiHH+eR{E_h zM)Tz3w?hm1qX%~|h8a+!)nTubXyG*mHGE(j8NnQOdM?v;DN_HtcYDdiO zrbQi#R?+#!eL2n+w(xBme~dEw09!$W;W64mkGQ-}`>a|GS-&<#$JV#(s->nGqOykH zyKl29S6CYq8`95n6MX9LUmD0Bc*_#T-D@-RRe>WYSiWthT}!6^%r`liqTwr9mE)Sr z_ih50v;HhQU0oW~D_5GEnz|BCtz77XL?R3uo10|<&m#F9dIt1a;3%z)z z25=l7jDDDIgv+T4N2P1Hq)3$p8fiOBBF(%0Nhf8jbmfD(48i`ssQHv(^r-nG7o50i zec}_^0-p2zZ}pnSJ?WJ+BC*l0YXy9rqU**g1RronNm}j3rR2yLkQt4ZSn)WGRJUNK zN21!{*4ugcRwYx2MPe`>8<)S)GFlH`l#1uL&&kGl@6o+7*;O^Wj8-$5kXYub=S}E9 zP-fHL;6U?^%U=n;g4%KN4$9nkqxnRZEm!>LWuC1F!Q@*XvWJ<&APQA2c=#~)RA(pveewEEKzcL|md|%RJNt~Lq z=rc5Y=so+0ZKb%GLAn~aJKshy%Qkm+p1Ey$C5(Q@B#w3R(bV=sT_5H-jG#=pj_s(u z6fIRYF|>h?$*y&GFI% zUc%x!b?-dWWXiKF5R1J~geZm-zBA?1g@J(__8uH-$;ngxs_&`wtdw?wL%9G5r-xJ+ z^0@6U^BhFtDTwG8q@sFL@`2jB&KI; zlO`I?>Aa3);ApU#+Wv0GzYW4jl^y;S)~pnoRDa~VA-OT(_^6hD=;m5=30_*s{Kg9q z(Ns9zhv4R`+#3ZILa!>O?tny0C^EI?ye8V{>{ud8 z$7eRYQ+FC9=zSGKH{9c`X35$p(qky8b63-w z;BlOvL}=ueI}eku>;dsNm2N3|7~MJ&bi9Ktbx?AcW9O2TvVTxsbAF;exh6gD<=A@P zN?IWB)?R{|8{oOxmV2H-=;SwHO=OoM&b?+j>#4x=2&#G@kCXdsm z53D&*7mHz$NA3sFIGum7o$g37AyXx8!erU~>7}_ewIRK;n&!$G z+Iogyr9da!%$F-5{SoWg(5&K^c-C9*Fq;v^7v+Su7idHpy_oY=OtzaOidrpwB4uqd z=CHX4qwVIoy>g->a0o1CJQJ>Q_TFZFL#@H&3)x*tuwW3~21ya_PzcGcTu_0duy8k* zCFn`hTv;!g+w?xfD(n+bntGmty*aazY_^67@TjnpNBD10tfLB_S&VQBm#f zNsRtA&u%kv>)3>!Rtd8Ri5+iSE{8!5x!i>E$ zB@Ans&&vf?MRh_mnz=d^Jxp!nTT^iGR;CO!GU|WNRl^|*nVrgR0GIdr_4DaS;0WAYjYG+LkK_vY|Ylx#68r}9>xv7_A2#0bGK7VV< zX}Yp_u(`X`w$1N;ymot3URn7tp-( z%)C`?If46*s@km9^36ccJ1mB9G>u!w^QCXxy~P7LoQ|*oVkj)O8DsM_?-| zmOkd-U+;IJrA=zdU5i>7MJ7sntKByBsm8`y`b>$Iy5Xp&UfFaDl~`4UG@_=8V3NzwfkM1A#DBOT||_jjlXCF!Fo#s#~kdGQA$uE^J4WPppvy8TV%{ z?R1^nZA`Ya7@gT|&k4?-jjdR}e#yDf{ z*sbqU15asW@K`RKnqvz2geYWf4HBV|-Tvs8tufrtDBVWW<(nwX*L4T!j=K7?3ib-y z9dsFs!R!$bpj_C}>@rHD)&x!~1L#4}R^93bbYbnuwt}_rqf>e!Ljp7uH0V^bKCx!_ za~!LV1ldYe1E%!aQX>OM@LW_m>8K%3C?iw2DjI?otx?>cHf*D6WbWHxiB;R-W1&>3 zeY}4Ec;kJ@lksW`|aU3eoEI)d#a;brmL&pHlj^D;U zBPinO%On_qDm&HbRCh091leU4Z94~c^`Y#vL=EiFFf=VCcZck-+4=>K!NU!qVb?J$-pBm#)44g$6KKK+CEv|3FDago&x8br(nmpy7i@PT4{l%ehAyl)X70Jr(Yc?Id4RTo6g8VhS=iqAL{C z`FRRz5iDTQ&rdfnArx?oW^90uHu@GtwmdjM&Zjr#3^ov7J&|Q#?`Y<@ z*MMZNC9P5)})Cu*hGbDqs=j zTl8FcP2rZ1RgI|nT27Tow75bFubV0@FYct3b?mU@5vqAUE!B!X37LBZ(ctFyD4Of7 zfkp|6!YJkq4mR=VHdy36bsZan%Sg#6VcYYv+ts*BgswgIZC(N0hD)%+Izp5|S=1?f zhMZ_=F;}LBZwrW{!{#+EC?c2AbCfdZypTyqGTc1<7%#dVJnf2Hsay}G> z#;(R{u0CZG$Z;K3hydcwv~EgWjJNw8b_G7{k5x!#t25QpjGQ051*#;R;ix=0CMA(r zH{QGH##idz^~pRCp<8+RK(|uSqw`h+vG7a>stSy{JOO&;vs*Aa8Uv|59GXTzCOzo7 zzjE06fOxFTg3$;BugC2yjJs=GPdkN!%*+P(TVn--d3Edd197RTqa&4OtZJA#r>3-O z4s81~u?aCrc{Sm;oJ#%4zGs^F+8-u)l-1hKo5D_&)>2O-4HW=+OWc8Vhp;^!ewMF+ zCY4aN3s{rzh-zSk)FO?eVbNjg71jzu&0+ffqvcY#E(1OET6OvMOU!*4T|D;R+g~DQ z2*aC0<2dM;78zbd19GYvW|~4SXIqCRnOLJ-Fp1osq*lJ3t~mihU|-Crwx|o^mxeHY zgMgy?$&bin2mwxn&7*n?Y#i8q<7ayfr?>c-u} z-zhAqJaWJr-{!uCMK3GMKrONHR)+uk6#JIp0`O45%>{2f74{y&Hp8(2RbsWx6~Q-E z41d~r7CPlVSSNNoM*{sQaO^InUs>5UIpJoCIdWD;JQh?V8j8t#MKEFudGX6dK1C6xa664&_tQxDQq{4IC*L-%ASN=fxpUnu)X+*BJP5-4mpff zqfhEf5gQ{r!{u2b-2L2q8LM%vkEvkJNT^Q#wmMu;A{RaAS)XI`KQd@LIre}zM zO~ibQa}f3+6Upr)#=`dTvR>xNvaigFXNnQq_j@VTMxWkot*p8J4d8Q%AhpSl@sY-r zeVOWF1R#jaog8)PP06Dl+9Fp{M_Fn*bELADAGBvafvL8JV%Xegg-;><_o07(!i7JRWb>VS+K-1{<&$jF4(<^2g3r9R`7>k9F_D(u3!6=)p0 zw7k)1z0u9v*wj?N`SsRTUK!b>msj9n#~syRR%{Wo5op6(f~(iAQ7dHI1Kvj|_ptxR zGTa0-c?e`cNF+Vdj-BT%#9=Gx+?|KFj;2&yppj>;3YrxZURw*ZsRH)$H}n=NT%23K z)Ws*VUMM`d;*mxJaRgZ|j%VY%#B821@dTW%#?sPE^LUR%B$ZWyw)$Ek;xMk>2nY<8 zImPe#&Q8zQEJyw!V7tXxAa}$R9vXyEJ=o`b+9_osPB4)2ut7|gPOX0To#a|;QEy?3 zVvxrIX;*-i74FtP8cUPZQn#wTF_}poDu>H<=9l|lD8wM<;~#rY21uXKsaQ2~KKSWD zqcEY%K`pUALp`ddspG8q?f%J)7W^l_d4Ffxl`q<7Jo=)3oa2Q>u;F4V-+aZj(>oyq z&x@)?%kU88JL1lw`aBKFDwwE1xoK7}$YluvfbCyLUoSt1VDY19r$hOXxp91iry~wE zyr|~c`NsI(vNFr|(9U6U_;(`b675RuW+bEodfYsnnfaaHzf(E7{Z=Ot5~9wBlAGdp zosZ;Ext_}u{#^nbxWfX&imcAHU&TA6#O=SK-b~RU<+WecN9dr^#}6$p7uw*0{2Amx zI$vc746=MGn!FCuK`!Tp-v3lL_&A&-%A=bhhGQjH` zjq;=Z3Kb-X{%2m;@?CL1$sm_epd^I!;Pu6RbTtjxJuwHVs2l!Z%(FuFMNzkB-U$=* z34$s#n^|jxHTdtEso0(rxm--N8P9mGgCB)pCt7}w9rZO~kAByirN41~q?c2_R~lfr zrK1{LYBrSpUrNrlX2Q#HJFgZh-kCAfPeqe-GmBBRL?QL8aG&`K8N~Cu8a+E)7;n;- zo`a}Co51uZTZ!%OFE>8V!$hAkbU&OiJ%c!%%-Og}u9va#H3$3A;=Wfz_Xj(1!_vU3 zGCYB^YNW!eDTJ6X&!sWMD+T&yEh*~&%6cdd3g6^FDcRZ0jJeB$<|8r8hQ=ZtL`azRf^(THols%3h`>lWO6?tN}&unGHp>>_GJvXpJu&%Q74ys z><$W^m$4tlPs>*!2_O@Cv+Z1atHE;b@!MxC71yq``&~tO332f5oVs^29xbC6 ztgA8CZ=+wPT|si6`43mvp(}&(R|nBcT93Iu72SNaXxIGq-z{Pw2g)3%Wc?q$=<|yl z3}nf)>rYufTry@!LK=CDEQ?IQ>Khj$_jEFMTcH7&_WIA&a7C2L4s8Bz2Jt4D`8l4S z7kqf(Tntmfz|5rszi=7>m09>mtDiiM9UWT0FRX9=eBKI@ooC(n&pApycNDz*`KDgW z8wID3*w1{a7yGb){r2a(I6ucv9a#ul(`X=lyhL?du?(nB1Cn%istA^{$_YQZe)kPa zUCB!>KVF=R+zyXtB7Xv5KAyZ~u?^$Dy$meFIEo_f@P&wt|FNFd zc*-NsMJKK1g_m;|FN%-Z|5)7drbI|+U|{lzl9mSrE(%- z^ke^}v<_y(zIw-P8bS&PNt9L4Vs>`sUthUUMC&_liun0$1&T=w6k%gjeW z!^mTkUIG2^hzOI*64giLJ@1(fK*6~}5H>X#<=dsS)cSh9yuC&&skynifSQ<-_38~! z&|VH|6-&_J`ZBi40HDL#V_D2VasQn=&na95U=Nk#*L;KEJBvd(N(K7Ra2p#NyTwi% z==sSapH&^)a3EX3*Vor%0#y9U2t_usO}Q*4fJi~6R5F1xj@=43jj`_Vqs?q{2>`ZY z<)FF)G(&8=6U+-ma;4|0GOBK*#@y4ZjWYB9jQn3W`$2ssqPN0Q$HIVxg@szmaC>{c z4UbWiPUfQkXjwTr*pM<@1??@YFK^IDd@xZu-xp(@0kqaOu5sLy=kc1~bv(naM2P{= zZW2@zGY-T*BqU_EC9Ll$Y)7?IK0`7=G#I2BQqc%G?H`6_NG0W~%ame@Hd@RzHa3Dz z6H*@6-4UZC9C&}fJPebN^&uBmTsSKw?L$%BxLVh}kFu(&grQJ|AlarM921+R-n3n7 zv!Q&8o{xUEI82I$kz7K-o}QlB*L2OTsMahLLo~Rqkmwj7rgR`fq*7G098C;zpSP8rM?+mLG<*wuXG0h)4{}abq$M)+ZyK=>8xy>@EkH z3h@wV*)eus>ZPFGpe%j}VbG{D?)eD%UMLFA4x+Y|3OgSui1zoV0g=_8sj^>so(4oBD0Nu)?7f%QC4@9V zwGz0TBsrditW7x0=X^^~t7yr54!^}#=+qGLMpDg4%?$L9!)-tJa5tU%SqKQe<6>i7P7b#m z*G7B30r5`A3c~aQ|ACMkH3njVW+;pP%y+heOl5(G_@aKd5s%u7Ts#xz3+gkpIxPi(;38>y(2YzLSkY$nptN<4R3v}@>Za_sFIJSQ^;o1f-CA5Jmf0p>^VG)iFZp-g;0b-s6?knPA zqiY-30WT-*4N!+2dTX3QovE|70r4Y;WqAj5Y{{P<6f7p&OGrl(aI}{I>T0LHXQc>7 ztg(YPM-t0#gRhJj#)vv_u-G36#v9`=Z~x^NIQ0H-$G{Q;cl?z85-noi5J2ufJrbCr zPuFsDIZ@it|Me<9Ez4hzM7SztC6}Y6i~;ItkCMoQQT_=g!^`JyFaJ+~60rP8-*5jr z9P)R-`gfR6?n!hfUKG#U_$hL?A@8LkGt^X6W@A)#rVQ^ImHC|4pos6%f_o?a|K>#} z?v?ky{5!z;*VZE}KlnTi`{mPr{2!_N!Ov0ug1Ng_f64&;UEy$>PI*yLQU9C7jZdhl zO?p#BP*#54cm3kFmM5rCG3TY7c_%Z84aYjmO2;)-XJ=~k<&mafJg4P;k=Xkfpjk1$-TB&r{AIU)e$y(Ckz^vbNV@%Ki3#3z z46lc)v-2Tnd&(40v;dewcNAC&&@Ah91~)1^obe~6Nyyv5Z-xPP<^i-F*6xFH-SuES z54_7QM z#_CxYhYR&|zkc<*-sH`uP-$zx6g5(0Aol$Eb8BnsP{PMi^lFshU`mUbGAX*cy2i!8 zB;FQrZ3L!D@WqQ`IK1cE+E_W2c#Je?=3_R1-N1h|Jz8p}`@XiOb~Y$Dn9E@~690Np zQIYXEgn&_JL;f=Ae+h5?k~U)P4Gw-uSp%rC3~L{$*U4=H0vF)+3G2^}R@O#K-PTHn zj8A66_bFd%) zCE$XY0^kXngGJ~h>bpgd_7aK3J75{gQyVHak|GpOn$0Z>nXwt!b0sjx{A zrYWc94?7&v@`47>2~wbd_Ir2DB0F^eMwr!6uhOrjIcc; z10XdvE`^}^6Er`ceSV2-axxbo1(5yT+3`knPEl#G5&YZiEC_!Z55M=M*iJ5JsE{!+ z*?>jDy0ihLSFOyPT6FO33yK!na^4ZuI44BDt)aNM7((z8A=k^3wbdsknqLqa zy|$^nd?a^I1V zfhm}?ad5btpPd59C8s4KAfOJXrly{IC6&aRca)opf7N(#$p)$c8iPGR&+Rtm@^IT2 zS3ZE4(5XO*@7>A1Cn)kiM@{g{lW_ujeW#vQjF+C3Ro-*w(=@Q40P5-sn8bq~f4%uG zC}&9#Fd&4i#^8(1n(){)GBq?VeVUS>6=8DjDX zxE!Co>e&O4=<5?U;-V3w~NP;zR z(89oD6v;%<4_7{3!gv}7ztWmd@RqRkzhWA>@4`}2m{+g9C0|N(TaSHW^RXkY2&qWFD5$6_B4l2BXq ze)~6s*&j-K(-~kPD0V1ljBVb<(@O{gF&{m3KyYwMJt(D^EHR1TsHgcX@n86~Uoh+) zIMf53{=thk*f&AYUPP~25)c+vpi;a5td_Z_{Z9;#(C`y4zI=9zw+swSB909Rygjg$ zhm5Qs&H^u8g!a4m%>;f5-Fv8u$eyt=}8_NfiAPK>J^1%pNWNW_td=P-cgTk&%(0 zP%6MiRu-VF2=u`Vyyi{toA)`40bA|o?{8#a5ZDBKTtGko5xXUJ{EyCbakRgHI|4u3 zyU_ryVjP^PVL%Ch8+>~n7E;iiXZ%_CAH+9r>a{?5MiDrq103-oV+hV)=&p9MGH6!% zuE?rQ{?B07EyET>f7h;E12q|-m{+;XJXRQhjieNz&>+B7dEHxRk9`mxPTmp6&dA9* z+SL_?YX!nCov*Jz4`UR_jD7aL1p17y`c~&n_5h|E%2i<@Cr{OBcny5zZ8$g{0rXr4 z7T%+!rRC+-jNQW77eM~(`wx==#NWQ8fxbS%B7wrl*w|R=sp|<(YykEl<7mH*$8dv$ zTbUdhOi4v`zS}3IYXiU_;G;k>aXUB;;&^X`UBC4fuT+lH`Zx!mUfS0Hl6}u=Lbg5k zu|TVyq51Orry^i!hOsb^Fn#`{xBt}E3;K4L3xY!11fq~7OYz@L2TA!}Sd~r#Dm)3fsFZC3MuV55kQ0@Vkk@{7b$(4{1RNLw zO1Gp{R6l7yE6}WsB)Cv`?dQLE;743gDD?PXquynQQe~vIRrsB_h=_=|IJd`9$#QWK zJZFBPGoGUu7#nar#883ORJBvVi7)5=_I~avFs1-AXVN)*?|yc6ndZlnRsVW2pe?ch zkp!?VK)kN5Rl;XmEu?@(3w!g1(vHh%UHzTBOAl}bUGE>~09Own5(Xiwa=9gOQn`@< zbnCUhf6^11=X4}|p4?<)-@s87aJe5ENd1=vCIT?Gzcv=kgaI(B{HL2pNRl?-_?(iG z5^&~0CW078r}`@d{CiBMf^cZS1Y0AKZS)1-MH4VQUL2Dr$I`!sKgUE2Z&& z?|GeS>h|_UN zND?6skc?nqc|b-6f;bs#03~8B|CM+^LLx2%fi1xA)GXjp;7lteLvR=m`QO06Pr~V9 zh~34jhy!to^aGiTwZHgG*1FNM_+8}@!(c_E=Kg8Hh4ul(NKQ_E1$3@v%IJY8m<%`~ zF96SJC@Ehv#Qo2DB5Hw0vdG0R|4y?3Q1_=wV&RWGc<=ym5Z2B@M|-9@WJW3;3GD`WRJ zDKUHp}1w!|RuV1s}vx)!%^p4yO@C+S3SoE5^1@&j)c+g-`bU?AdxkKk2Ai;k` zgurs8wqujwXT2Qx&pEXVq%|$=xSa|5`QI{zw+@ch(B`P;D(0y=I+ig%_!JF{dbQI= zo%PIf0}~M4frN>yA^Po`X{ZaA{w6&LJ8~}xFaxK@2U9gJ5xM62`l-U{sj1|Yl!?3^ zs(UIUCj+*2fGZeDmxu!y9KaB4OjIkKJtGFejiO`EM?qpPNBJm(ig;ZD2M@)d{~`0< z?jYWi1CiGB^z^G&uXcCs-yukk*O;Uv#KaN{j^IEpvaIcoh5{HeC4skoVs4Snu)w@YPhQG^vE9LTDi}8b%SaH+D{8VlAx>qZnG zyz(soqvkJO48InV3o39_tq7xDbIfiAiRa?zhiK>#AF?Mq^ZphbU0CF%>m7kWT^}t7 zWi!k8yK;6ZDJfwUXXWLogUCBb#V31a*40@cX6z(JSK<%1@;?Sd)io70iDrhql(w)V zeN~Vo!wztj!#y7~T;v`A&OQG=SPBrO@h6T`d28=&db4_;uic55zOD*c`fp)TY0OT&cV@a%xcQjvJ2pu!ffjI-aP*!7J=mJ0M6fZ}lok|VIW|j-R z-;~UsqB$V4JHOnfVb93O=rmXMO7UAoKy$#%)J@ zf_VLlEa{593y#sN+EmZDIKDxejs(n|`CB(KdU!>DLjxr&B*e7qnYmFQo~jNoKxiq} z?L28HN56+Fe*rO5IyWfo&-Snw$*8IE$rqcmC`eDrC6>z^7FrXw_r{+T6b*{D z^1W!96tqv;fLSOgIJ$$;U#BZF{M=Kp`lvjz?4PSwd*6?JP`Bm2e>DRBtfaQ`C$lVP zU`WT7ixz0GW@M-a<49*HWBw%i{U1}z(ZRO+;<5?kG#SNV%eMLa`esK*2UcBn%`w$@ zeWjn)F;slr1?V3neE5gJe)w>o|N5-KTTE1RSpa~N*RKVcL-<)(=3YXP1Pu`5#*JV4 zds+Zow7w5n?vv24$$+s{TtY&kI^A{zh(l(Uu(0s0lY)Y?`8;_auu%hOutaub`N&&( z%bZV~E)*33Vl?++%~m|;O&m;_HFJCi)gSbyB6f#kjv%6L*0^kLpkA}a0*Q~$1Zf^( z%x>Je1=ljj5z9|kX(CmhZ4ey;MFH<-vf*%5*d!<4ftC?VHWcxxhYlUOJa-Ym^|uYJ z+=o35TO!_IN`2tTX`l=-M?E*lawP;9fmYB2TO+yFu=wkX^1X=qJ~q1La1Ixu6ernb zuBUwH>S{VXXl}Cq1(6dPCLghqMV{P_^3EPZg$R&nA3yq|Z>XbD5ToLVj8u9G6-Uxt zYzj}CR6NbXnSE-o<^G0Gu3D3P$W3*!q)8imY{RQ4xg{HcT-Hca29GW=hf2s1Pr^7 z^!zaS%jK)34-$Wr^sYm`7c|Q*?Lh%cGlms%reCQ%X&w~J+ZdI!jg|QjX-n48mbqLR z%EGEj88?qTIw_cAANO#zh*_zkc9wgs*iX)~g*qQMyC%w|<*)isw8MW_h{N%ScM{9O zSI2cM($M*^wNWwmnDA`bZ#6NV8h1X3)dW4&_*B{6K-E&&RoRv{RB4&#d5WznwFzl? z&U|3e122Ul#5h1iOH0ej%1Tqy|AzG0MD*ZL`$+L=$CM$8`TqU;8yRTN42{%=T&qmC zP1mVt?L|?79p*+Zh(ryQvLsd(mfLwuUP{)r>}WaTEc*-%^05_yyNqa^VaNaZwj6&b zZ<~NX?e><2Y?muCO>;Lb8YHbWhN6%Y4qqFB842b^uo>FD?X)z%Dt<=VL$?V4PeJYQMKCqj7RqeV5HWoinBBJ(RzI5phVAI#G z%`G%~?QoeUq_^S)1Mh_n7X|gDdy$kS5}W_&)%7=DQ5p#hb{zb^ueC**NnKU-$SJFL zch~RI&bb@F-YR@u)NQ}2Y9+ACq@*Ol5s2R!J&W>;ZJM@a+vuYF1Iks{d(_k5?*2sX}k^>oV^{w*9?CK||O7ZpRL(%AINuE8Ex%?`=;x*a|wL;H-3PU&|d@uE_X!*EmwBD$`C>cxg+c3vXn$|7X>Qs`Uz1Yv`(F3uyV`u& za~|wVQ>^#TI>^*=iTkbnOL0Pr09ArU%a=|7n5wil*h8seeJ%gbN5u!k-a3CVTVd4>KWeQBpf*%8Ie@l4nF zuJBOznNU_Ck5G2EdRJNscInpq%Lvj<;4&x|bN~uw4Gzxlb=8yOuTY`X&5DZ(6Eb?C z7k7)ZRT#1$A3n>{#`xxTo4&mkH+pyaCPcAl>F(OF;Xs9^L{8%6wC$&6{ygF0$V?Rw zPWg51F431E#qZu*lHbvQ6_1xLTehJ;j$`3ZLhA6;))sGG^K+ebnP^Ks{|r%e zOU~2`oSQo5=Ms^8wKCuw1+$t|i&qDAu^j}hlVtTXTDxXsV3uZRYaHL#*Y{#9o|4p8vTes~D3EWODl0!Mru8T%&q=P(xekeEJ2sTq@c#%8 z4+mj$OJJo9%mz)XVrxBo`Tf3bQdPtv@vWt*8503hU!}vpe4~Gst=0W}pb zht~X1{?vmVj?=W@cHcWgjZ#@EG4< zmgY(M{P~0dlNgQNk8nbj9HK)rWX##*S@giVbA_b;OGTR==Y2v@5LiwfD$gUuID?KU z)6vl(1-=i(CW8NkR^A(2r(te#`T`(~Ov4`Gt9x~-HC3$*0OGy6L~nxt!C(p}gGZehFU(^c)C1kCntWoq9LkIU+JLkn2D_k4sHz zd)k^uPAUVmLbA65jFHF3B1K4-UUdZc$LkbzODTIN3^BIXG_)!*my1& zhCXHa7KuhplJ_U_S=G0N2_Jj32#a1>SsCYqtD9TjWro3h485WK{T9l%ZZbHoJ~Oxb zMRMI?rqc&TaLWL{PJu6uMbNb%wLUSjUZB(n@06-P?gV_pE=a#RrA#jltgkU3$|McB z8D0CB2EvD1Ylc~oe+IP(mT11f2(Mw$C4~-RM$$7f(GW_{&7WkGW*nX+@LY>}$)V($ zbtQotLd$%;YmQ{)Eh|B zs-(o!mi75W$6fB_?`XoTWX-o~scmm?ms%zfKznz0$1GLt85d&*7D*e>N8h32y>JF{ z!Lw(dw#7szuHrp8w)E&lm1uIfwVfwa1?yUEF3Wn%E_n(-5m;S$#S@;XZO%URzjj};P{GdQp@+w5Jv~p5Lmg|$gY(FlD6*jpb^I~9O^+%X_SwE3 z`!%ERUH``4XOnfMxVwRu5ejd~})6V81`3x9;9TrL;+zqWvTetqGy-XF$M=FpUoz0?z zoS(G(0mtc5P{(n6pl5M-#>Z2T`sa^5T!K_BsF^co4odCQIqo}9xg)C{XZn(%s;Vj| zBIvl!oy08yDdt`H2oWzp;UFHC@5RbFxVv#Z4uQZ72p);voaZVkq{4%f{{D2U=>kiM zY!)@S@?n-AuY5G5r0%)7VV`+lUal-JA8*_w-E7qokzn)vw#LyflD7Rava;`eMg~vm zDJT#jT{qTH-wsGk9m2Z}ⅈ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 i)my}g4uGl0#5I qwindowwrap: screen() qwindowwrap --> qwindow: screen() qwindow --> qwindowwrap: QScreen instance qwindowwrap --> wrappercachecpp: get() +note over wrappercachecpp + Checks wrapper cache +end note wrappercachecpp --> qscreenwrap: new() activate qscreenwrap qscreenwrap --> wrappercachecpp: QScreenWrap instance diff --git a/website/docs/development/wrapper_recycle_seq.png b/website/docs/development/wrapper_recycle_seq.png new file mode 100644 index 0000000000000000000000000000000000000000..fbf26d5a333848c2f863953ab83f75a774619750 GIT binary patch literal 32278 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 z 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 #E3C800 +participant "QObject.ts" as qobjectts << ts>> #E3C800 + +participant "WrapperCache" as wrappercachets << ts>> #E3C800 +participant "QObjectWrap" as qobjectwrap << cpp >> +participant "WrapperCache" as wrappercachecpp << cpp >> +participant "QObject" as qobject << cpp >> #D5E8D4 + +== Wrapper construction == + +app --> qobjectts: new() +activate qobjectts +qobjectts --> qobjectwrap: new() +activate qobjectwrap +qobjectwrap --> qobject: new() +activate qobject +qobject --> qobjectwrap: QObject instance + +qobjectwrap --> wrappercachecpp: store(QObject, QObjectWrap) +wrappercachecpp --> qobject: connect to destroy signal + +qobjectwrap --> qobjectts: QOjectWrap instance +qobjectts --> wrappercachets: store(QObject.ts) +qobjectts --> app: QObject instance + + +note across: The app can use the QObject and run. + +@enduml From c6d30f8f9f5ec22fbdbdf640abeccd62d7ae7136 Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Fri, 29 Apr 2022 13:30:39 +0200 Subject: [PATCH 03/28] Combine `NodeObject`+`QObject`; put `native` field in `Component` --- src/index.ts | 10 ++++- src/lib/QtCore/QAbstractItemModel.ts | 10 ++--- src/lib/QtCore/QDate.ts | 12 +++--- src/lib/QtCore/QDateTime.ts | 10 ++--- src/lib/QtCore/QItemSelectionModel.ts | 6 +-- src/lib/QtCore/QMimeData.ts | 8 ++-- src/lib/QtCore/QModelIndex.ts | 10 ++--- src/lib/QtCore/QObject.ts | 41 ++++++++----------- src/lib/QtCore/QPoint.ts | 16 ++++---- src/lib/QtCore/QPointF.ts | 24 +++++------ src/lib/QtCore/QRect.ts | 17 ++++---- src/lib/QtCore/QRectF.ts | 17 ++++---- src/lib/QtCore/QSettings.ts | 6 +-- src/lib/QtCore/QSize.ts | 17 ++++---- src/lib/QtCore/QSizeF.ts | 19 ++++----- src/lib/QtCore/QTime.ts | 14 +++---- src/lib/QtCore/QUrl.ts | 30 +++++--------- src/lib/QtCore/QVariant.ts | 10 ++--- src/lib/QtGui/QApplication.ts | 6 +-- src/lib/QtGui/QBrush.ts | 20 ++++----- src/lib/QtGui/QClipboard.ts | 11 ++--- src/lib/QtGui/QColor.ts | 14 +++---- src/lib/QtGui/QCursor.ts | 8 ++-- src/lib/QtGui/QDrag.ts | 19 ++++----- src/lib/QtGui/QFont.ts | 12 +++--- src/lib/QtGui/QFontDatabase.ts | 6 +-- src/lib/QtGui/QFontMetrics.ts | 10 ++--- src/lib/QtGui/QFontMetricsF.ts | 10 ++--- src/lib/QtGui/QIcon.ts | 10 ++--- src/lib/QtGui/QImage.ts | 20 ++++----- src/lib/QtGui/QKeySequence.ts | 10 ++--- src/lib/QtGui/QMovie.ts | 10 ++--- src/lib/QtGui/QPalette.ts | 8 +--- src/lib/QtGui/QPen.ts | 6 +-- src/lib/QtGui/QPicture.ts | 10 ++--- src/lib/QtGui/QPixmap.ts | 10 ++--- src/lib/QtGui/QScreen.ts | 11 ++--- src/lib/QtGui/QStyle.ts | 7 +--- src/lib/QtGui/QWindow.ts | 12 ++---- src/lib/QtWidgets/QAction.ts | 8 ++-- src/lib/QtWidgets/QBoxLayout.ts | 2 - src/lib/QtWidgets/QButtonGroup.ts | 8 ++-- src/lib/QtWidgets/QCalendarWidget.ts | 6 +-- src/lib/QtWidgets/QCheckBox.ts | 2 - src/lib/QtWidgets/QColorDialog.ts | 6 +-- src/lib/QtWidgets/QComboBox.ts | 4 +- src/lib/QtWidgets/QDateEdit.ts | 4 +- src/lib/QtWidgets/QDateTimeEdit.ts | 3 -- src/lib/QtWidgets/QDial.ts | 4 +- src/lib/QtWidgets/QDialog.ts | 2 - src/lib/QtWidgets/QDoubleSpinBox.ts | 4 +- src/lib/QtWidgets/QErrorMessage.ts | 4 +- src/lib/QtWidgets/QFileDialog.ts | 6 +-- src/lib/QtWidgets/QFontDialog.ts | 4 +- src/lib/QtWidgets/QFrame.ts | 4 +- src/lib/QtWidgets/QGraphicsBlurEffect.ts | 8 ++-- .../QtWidgets/QGraphicsDropShadowEffect.ts | 8 ++-- src/lib/QtWidgets/QGraphicsEffect.ts | 6 +-- src/lib/QtWidgets/QGridLayout.ts | 2 - src/lib/QtWidgets/QGroupBox.ts | 4 +- src/lib/QtWidgets/QHeaderView.ts | 4 +- src/lib/QtWidgets/QInputDialog.ts | 7 +--- src/lib/QtWidgets/QLCDNumber.ts | 7 +--- src/lib/QtWidgets/QLabel.ts | 8 +--- src/lib/QtWidgets/QLayout.ts | 6 +-- src/lib/QtWidgets/QLineEdit.ts | 5 --- src/lib/QtWidgets/QListView.ts | 4 +- src/lib/QtWidgets/QListWidget.ts | 5 +-- src/lib/QtWidgets/QListWidgetItem.ts | 10 +---- src/lib/QtWidgets/QMainWindow.ts | 11 +++-- src/lib/QtWidgets/QMenu.ts | 4 -- src/lib/QtWidgets/QMenuBar.ts | 8 +--- src/lib/QtWidgets/QMessageBox.ts | 8 +--- src/lib/QtWidgets/QPainter.ts | 8 +--- src/lib/QtWidgets/QPainterPath.ts | 7 +--- src/lib/QtWidgets/QPlainTextEdit.ts | 6 +-- src/lib/QtWidgets/QProgressBar.ts | 6 +-- src/lib/QtWidgets/QProgressDialog.ts | 7 +--- src/lib/QtWidgets/QPushButton.ts | 9 +--- src/lib/QtWidgets/QRadioButton.ts | 7 +--- src/lib/QtWidgets/QScrollArea.ts | 6 +-- src/lib/QtWidgets/QScrollBar.ts | 8 +--- src/lib/QtWidgets/QShortcut.ts | 10 ++--- src/lib/QtWidgets/QSlider.ts | 12 ++---- src/lib/QtWidgets/QSpinBox.ts | 7 +--- src/lib/QtWidgets/QSplitter.ts | 6 +-- src/lib/QtWidgets/QStackedWidget.ts | 5 --- src/lib/QtWidgets/QStandardItem.ts | 10 ++--- src/lib/QtWidgets/QStandardItemModel.ts | 9 +--- src/lib/QtWidgets/QStatusBar.ts | 7 +--- src/lib/QtWidgets/QSvgWidget.ts | 4 +- src/lib/QtWidgets/QSystemTrayIcon.ts | 12 ++---- src/lib/QtWidgets/QTabBar.ts | 5 --- src/lib/QtWidgets/QTabWidget.ts | 11 ++--- src/lib/QtWidgets/QTableView.ts | 5 --- src/lib/QtWidgets/QTableWidget.ts | 2 - src/lib/QtWidgets/QTableWidgetItem.ts | 6 +-- src/lib/QtWidgets/QTextBrowser.ts | 4 +- src/lib/QtWidgets/QTextEdit.ts | 7 +--- src/lib/QtWidgets/QTimeEdit.ts | 7 +--- src/lib/QtWidgets/QToolButton.ts | 8 +--- src/lib/QtWidgets/QTreeWidget.ts | 9 ++-- src/lib/QtWidgets/QTreeWidgetItem.ts | 22 ++++++---- src/lib/QtWidgets/QWidget.ts | 2 - src/lib/core/Component.ts | 11 +++-- src/lib/core/EventWidget.ts | 3 +- src/lib/core/FlexLayout.ts | 7 +--- src/lib/core/YogaWidget.ts | 6 +-- src/lib/core/__test__/CacheTestQObject.ts | 5 +-- tsconfig.json | 1 + .../development/signal_and_event_handling.md | 4 +- 111 files changed, 349 insertions(+), 615 deletions(-) diff --git a/src/index.ts b/src/index.ts index d059c8c60..135722327 100644 --- a/src/index.ts +++ b/src/index.ts @@ -153,7 +153,7 @@ export { QDateTime } from './lib/QtCore/QDateTime'; export { QItemSelectionModel, SelectionFlag } from './lib/QtCore/QItemSelectionModel'; export { QModelIndex } from './lib/QtCore/QModelIndex'; export { QMimeData } from './lib/QtCore/QMimeData'; -export { QObject, QObjectSignals, NodeObject } from './lib/QtCore/QObject'; +export { QObject, QObjectSignals } from './lib/QtCore/QObject'; export { QVariant } from './lib/QtCore/QVariant'; export { QSize } from './lib/QtCore/QSize'; export { QSizeF } from './lib/QtCore/QSizeF'; @@ -163,7 +163,13 @@ export { QPoint } from './lib/QtCore/QPoint'; export { QPointF } from './lib/QtCore/QPointF'; export { QColor } from './lib/QtGui/QColor'; export { QTime } from './lib/QtCore/QTime'; -export { QUrl, ParsingMode } from './lib/QtCore/QUrl'; +export { + QUrl, + ParsingMode, + UserInputResolutionOption, + UrlFormattingOption, + ComponentFormattingOption, +} from './lib/QtCore/QUrl'; export { QSettings, QSettingsFormat, QSettingsScope } from './lib/QtCore/QSettings'; // Layouts: export { QBoxLayout, QBoxLayoutSignals } from './lib/QtWidgets/QBoxLayout'; diff --git a/src/lib/QtCore/QAbstractItemModel.ts b/src/lib/QtCore/QAbstractItemModel.ts index 7a5834b78..9825fa207 100644 --- a/src/lib/QtCore/QAbstractItemModel.ts +++ b/src/lib/QtCore/QAbstractItemModel.ts @@ -1,18 +1,14 @@ import addon from '../utils/addon'; -import { NativeElement } from '../core/Component'; -import { NodeObject, QObjectSignals } from '../QtCore/QObject'; +import { QObject, QObjectSignals } from '../QtCore/QObject'; import { QModelIndex } from './QModelIndex'; import { QVariant } from './QVariant'; import { ItemDataRole, ItemFlag, Orientation } from '../QtEnums'; export type QAbstractItemSignals = QObjectSignals; -export class QAbstractItemModel extends NodeObject { - native: NativeElement; +export class QAbstractItemModel extends QObject { constructor() { - const native = new addon.QAbstractItemModel(); - super(native); - this.native = native; + super(new addon.QAbstractItemModel()); const dispatcher = (methodName: string, ...args: any[]): any => { switch (methodName) { case 'index': diff --git a/src/lib/QtCore/QDate.ts b/src/lib/QtCore/QDate.ts index 71aa8f391..edc0f69b6 100644 --- a/src/lib/QtCore/QDate.ts +++ b/src/lib/QtCore/QDate.ts @@ -5,17 +5,17 @@ import { QVariant } from './QVariant'; import { DateFormat } from '../QtEnums'; export class QDate extends Component { - native: NativeElement; constructor(arg?: NativeElement | number, month?: number, day?: number) { - super(); const count = arguments.length; + let native: NativeElement; if (count == 3) { - this.native = new addon.QDate(arg, month, day); - } else if (count == 1 && checkIfNativeElement(arg)) { - this.native = arg as NativeElement; + native = new addon.QDate(arg, month, day); + } else if (checkIfNativeElement(arg)) { + native = arg as NativeElement; } else { - this.native = new addon.QDate(); + native = new addon.QDate(); } + super(native); } addDays(ndays: number): QDate { return new QDate(this.native.addDays(ndays)); diff --git a/src/lib/QtCore/QDateTime.ts b/src/lib/QtCore/QDateTime.ts index a4eecb57d..1653f6b6f 100644 --- a/src/lib/QtCore/QDateTime.ts +++ b/src/lib/QtCore/QDateTime.ts @@ -7,17 +7,17 @@ import { QTime } from './QTime'; import { TimeSpec, DateFormat } from '../QtEnums'; export class QDateTime extends Component { - native: NativeElement; constructor(arg?: NativeElement, time?: NativeElement) { - super(); const count = arguments.length; + let native: NativeElement; if (arg && time) { - this.native = new addon.QDateTime(arg.native, time.native); + native = new addon.QDateTime(arg.native, time.native); } else if (count == 1 && checkIfNativeElement(arg)) { - this.native = arg as NativeElement; + native = arg as NativeElement; } else { - this.native = new addon.QDateTime(); + native = new addon.QDateTime(); } + super(native); } addDays(ndays: number): QDateTime { return new QDateTime(this.native.addDays(ndays)); diff --git a/src/lib/QtCore/QItemSelectionModel.ts b/src/lib/QtCore/QItemSelectionModel.ts index d468a156c..665c4c47f 100644 --- a/src/lib/QtCore/QItemSelectionModel.ts +++ b/src/lib/QtCore/QItemSelectionModel.ts @@ -1,13 +1,12 @@ import addon from '../utils/addon'; import { NativeElement } from '../core/Component'; -import { NodeObject, QObjectSignals } from '../QtCore/QObject'; +import { QObject, QObjectSignals } from '../QtCore/QObject'; import { QModelIndex } from './QModelIndex'; import { checkIfNativeElement } from '../utils/helpers'; export type QItemSelectionModelSignals = QObjectSignals; -export class QItemSelectionModel extends NodeObject { - native: NativeElement; +export class QItemSelectionModel extends QObject { constructor(arg?: NativeElement) { let native = null; if (arg == null) { @@ -18,7 +17,6 @@ export class QItemSelectionModel extends NodeObject throw new Error('QItemSelectionModel cannot be initialised this way.'); } super(native); - this.native = native; } // *** Public Functions *** diff --git a/src/lib/QtCore/QMimeData.ts b/src/lib/QtCore/QMimeData.ts index f824839f5..a97457ac4 100644 --- a/src/lib/QtCore/QMimeData.ts +++ b/src/lib/QtCore/QMimeData.ts @@ -6,14 +6,14 @@ import { QUrl } from './QUrl'; * description */ export class QMimeData extends Component { - native: NativeElement; constructor(arg?: NativeElement) { - super(); + let native: NativeElement; if (checkIfNativeElement(arg)) { - this.native = arg as NativeElement; + native = arg as NativeElement; } else { - this.native = new addon.QMimeData(); + native = new addon.QMimeData(); } + super(native); } /** diff --git a/src/lib/QtCore/QModelIndex.ts b/src/lib/QtCore/QModelIndex.ts index f210baf13..92f7e90be 100644 --- a/src/lib/QtCore/QModelIndex.ts +++ b/src/lib/QtCore/QModelIndex.ts @@ -6,18 +6,16 @@ import { ItemDataRole } from '../QtEnums/ItemDataRole'; import { ItemFlag } from '../QtEnums/ItemFlag'; export class QModelIndex extends Component { - native: NativeElement; - constructor(); - constructor(nativeElement: NativeElement); constructor(arg?: NativeElement) { - super(); + let native: NativeElement; if (!arg) { - this.native = new addon.QModelIndex(); + native = new addon.QModelIndex(); } else if (checkIfNativeElement(arg)) { - this.native = arg as NativeElement; + native = arg as NativeElement; } else { throw new Error('QModelIndex cannot be initialised this way.'); } + super(native); } column(): number { return this.native.column(); diff --git a/src/lib/QtCore/QObject.ts b/src/lib/QtCore/QObject.ts index e87c9a4b2..fcd53452b 100644 --- a/src/lib/QtCore/QObject.ts +++ b/src/lib/QtCore/QObject.ts @@ -5,7 +5,22 @@ import addon from '../utils/addon'; import { QVariant, QVariantType } from './QVariant'; import { TimerType } from '../QtEnums/TimerType'; -export abstract class NodeObject extends EventWidget { +export class QObject extends EventWidget { + constructor(nativeElementOrParent?: NativeElement | QObject) { + let native; + let parent; + if (checkIfNativeElement(nativeElementOrParent)) { + native = nativeElementOrParent as NativeElement; + } else if (nativeElementOrParent) { + parent = nativeElementOrParent as QObject; + native = new addon.QObject(parent.native); + } else { + native = new addon.QObject(); + } + super(native); + this.setNodeParent(parent); + } + inherits(className: string): boolean { return this.native.inherits(className); } @@ -28,7 +43,7 @@ export abstract class NodeObject extends EventWi dumpObjectInfo(): void { this.native.dumpObjectInfo(); } - setParent(parent: NodeObject): void { + setParent(parent: QObject): void { if (parent != null) { const extern = parent.native.__external_qobject__(); this.native.setParent(extern); @@ -47,25 +62,3 @@ export abstract class NodeObject extends EventWi export interface QObjectSignals { objectNameChanged: (objectName: string) => void; } - -export class QObject extends NodeObject { - native: NativeElement; - constructor(); - constructor(nativeElement: NativeElement); - constructor(parent: NodeObject); - constructor(arg?: NodeObject | NativeElement) { - let native; - let parent; - if (checkIfNativeElement(arg)) { - native = arg as NativeElement; - } else if (arg) { - parent = arg as NodeObject; - native = new addon.QObject(parent.native); - } else { - native = new addon.QObject(); - } - super(native); - this.setNodeParent(parent); - this.native = native; - } -} diff --git a/src/lib/QtCore/QPoint.ts b/src/lib/QtCore/QPoint.ts index cc4d4d4d0..f8cadfbcb 100644 --- a/src/lib/QtCore/QPoint.ts +++ b/src/lib/QtCore/QPoint.ts @@ -7,19 +7,19 @@ import { QVariant } from './QVariant'; * The QPoint class defines a point in the plane using integer precision. */ export class QPoint extends Component { - native: NativeElement; constructor(); constructor(nativeElement: NativeElement); constructor(x?: number, y?: number); - constructor(arg?: NativeElement | number, y = 0) { - super(); - if (checkIfNativeElement(arg)) { - this.native = arg as NativeElement; - } else if (typeof arg === 'number') { - this.native = new addon.QPoint(arg, y); + constructor(nativeOrX?: NativeElement | number, y = 0) { + let native: NativeElement; + if (checkIfNativeElement(nativeOrX)) { + native = nativeOrX as NativeElement; + } else if (typeof nativeOrX === 'number') { + native = new addon.QPoint(nativeOrX, y); } else { - this.native = new addon.QPoint(); + native = new addon.QPoint(); } + super(native); } setX(value: number): void { this.native.setX(value); diff --git a/src/lib/QtCore/QPointF.ts b/src/lib/QtCore/QPointF.ts index 36680e4f7..436b31bbb 100644 --- a/src/lib/QtCore/QPointF.ts +++ b/src/lib/QtCore/QPointF.ts @@ -11,22 +11,18 @@ import { QPoint } from './QPoint'; * In addition, the QPointF class provides a constructor converting a QPoint object into a QPointF object, and a corresponding toPoint() function which returns a QPoint copy of this point. */ export class QPointF extends Component { - native: NativeElement; - constructor(); - constructor(nativeElement: NativeElement); - constructor(x?: number, y?: number); - constructor(point: QPoint); - constructor(arg?: NativeElement | number | QPoint, y = 0) { - super(); - if (checkIfNativeElement(arg)) { - this.native = arg as NativeElement; - } else if (typeof arg === 'number') { - this.native = new addon.QPointF(arg, y); - } else if (arg instanceof QPoint) { - this.native = new addon.QPointF(arg.x(), arg.y()); + constructor(nativeOrXOrQPoint?: NativeElement | number | QPoint, y = 0) { + let native: NativeElement; + if (checkIfNativeElement(nativeOrXOrQPoint)) { + native = nativeOrXOrQPoint as NativeElement; + } else if (typeof nativeOrXOrQPoint === 'number') { + native = new addon.QPointF(nativeOrXOrQPoint, y); + } else if (nativeOrXOrQPoint instanceof QPoint) { + native = new addon.QPointF(nativeOrXOrQPoint.x(), nativeOrXOrQPoint.y()); } else { - this.native = new addon.QPointF(); + native = new addon.QPointF(); } + super(native); } /** * Sets the x coordinate of this point to the given x coordinate. diff --git a/src/lib/QtCore/QRect.ts b/src/lib/QtCore/QRect.ts index 49de66ca1..7714ba0dd 100644 --- a/src/lib/QtCore/QRect.ts +++ b/src/lib/QtCore/QRect.ts @@ -4,20 +4,17 @@ import { checkIfNativeElement } from '../utils/helpers'; import { QVariant } from './QVariant'; export class QRect extends Component { - native: NativeElement; - constructor(); - constructor(nativeElement: NativeElement); - constructor(x?: number, y?: number, width?: number, height?: number); - constructor(arg?: NativeElement | number, y = 0, width = 0, height = 0) { - super(); + constructor(nativeOrX?: NativeElement | number, y = 0, width = 0, height = 0) { const count = arguments.length; + let native: NativeElement; if (count > 1) { - this.native = new addon.QRect(arg, y, width, height); - } else if (count == 1 && checkIfNativeElement(arg)) { - this.native = arg as NativeElement; + native = new addon.QRect(nativeOrX, y, width, height); + } else if (checkIfNativeElement(nativeOrX)) { + native = nativeOrX as NativeElement; } else { - this.native = new addon.QRect(); + native = new addon.QRect(); } + super(native); } setWidth(width: number): void { return this.native.setWidth(width); diff --git a/src/lib/QtCore/QRectF.ts b/src/lib/QtCore/QRectF.ts index b5d3fec51..8e58135f3 100644 --- a/src/lib/QtCore/QRectF.ts +++ b/src/lib/QtCore/QRectF.ts @@ -8,20 +8,17 @@ import { QRect } from './QRect'; * description */ export class QRectF extends Component { - native: NativeElement; - constructor(); - constructor(nativeElement: NativeElement); - constructor(x?: number, y?: number, width?: number, height?: number); - constructor(arg?: NativeElement | number, y = 0, width = 0, height = 0) { - super(); + constructor(nativeOrX?: NativeElement | number, y = 0, width = 0, height = 0) { const count = arguments.length; + let native: NativeElement; if (count > 1) { - this.native = new addon.QRectF(arg, y, width, height); - } else if (count == 1 && checkIfNativeElement(arg)) { - this.native = arg as NativeElement; + native = new addon.QRectF(nativeOrX, y, width, height); + } else if (count == 1 && checkIfNativeElement(nativeOrX)) { + native = nativeOrX as NativeElement; } else { - this.native = new addon.QRectF(); + native = new addon.QRectF(); } + super(native); } /** diff --git a/src/lib/QtCore/QSettings.ts b/src/lib/QtCore/QSettings.ts index 4e4056f8a..e117d7aa4 100644 --- a/src/lib/QtCore/QSettings.ts +++ b/src/lib/QtCore/QSettings.ts @@ -1,4 +1,4 @@ -import { NativeElement, Component } from '../core/Component'; +import { Component } from '../core/Component'; import addon from '../utils/addon'; import { QVariant } from './QVariant'; @@ -16,10 +16,8 @@ export enum QSettingsScope { } export class QSettings extends Component { - native: NativeElement; constructor(organization: string, application: string) { - super(); - this.native = new addon.QSettings(organization, application); + super(new addon.QSettings(organization, application)); } sync(): void { this.native.sync(); diff --git a/src/lib/QtCore/QSize.ts b/src/lib/QtCore/QSize.ts index bcbf36b6a..bfac0905c 100644 --- a/src/lib/QtCore/QSize.ts +++ b/src/lib/QtCore/QSize.ts @@ -4,19 +4,18 @@ import { checkIfNativeElement } from '../utils/helpers'; import { QVariant } from './QVariant'; export class QSize extends Component { - native: NativeElement; - constructor(); constructor(nativeElement: NativeElement); constructor(width?: number, height?: number); - constructor(arg?: number | NativeElement, height?: number) { - super(); - if (!arg) { - this.native = new addon.QSize(); - } else if (checkIfNativeElement(arg)) { - this.native = arg as NativeElement; + constructor(nativeOrWidth?: number | NativeElement, height?: number) { + let native: NativeElement; + if (!nativeOrWidth) { + native = new addon.QSize(); + } else if (checkIfNativeElement(nativeOrWidth)) { + native = nativeOrWidth as NativeElement; } else { - this.native = new addon.QSize(arg, height); + native = new addon.QSize(nativeOrWidth, height); } + super(native); } setWidth(width: number): void { return this.native.setWidth(width); diff --git a/src/lib/QtCore/QSizeF.ts b/src/lib/QtCore/QSizeF.ts index bb5acd124..aee07943a 100644 --- a/src/lib/QtCore/QSizeF.ts +++ b/src/lib/QtCore/QSizeF.ts @@ -4,19 +4,16 @@ import { checkIfNativeElement } from '../utils/helpers'; import { QVariant } from './QVariant'; export class QSizeF extends Component { - native: NativeElement; - constructor(); - constructor(nativeElement: NativeElement); - constructor(width?: number, height?: number); - constructor(arg?: number | NativeElement, height?: number) { - super(); - if (!arg) { - this.native = new addon.QSizeF(); - } else if (checkIfNativeElement(arg)) { - this.native = arg as NativeElement; + constructor(nativeOrWidth?: number | NativeElement, height?: number) { + let native: NativeElement; + if (!nativeOrWidth) { + native = new addon.QSizeF(); + } else if (checkIfNativeElement(nativeOrWidth)) { + native = nativeOrWidth as NativeElement; } else { - this.native = new addon.QSizeF(arg, height); + native = new addon.QSizeF(nativeOrWidth, height); } + super(native); } setWidth(width: number): void { return this.native.setWidth(width); diff --git a/src/lib/QtCore/QTime.ts b/src/lib/QtCore/QTime.ts index b67616b9e..2a190f651 100644 --- a/src/lib/QtCore/QTime.ts +++ b/src/lib/QtCore/QTime.ts @@ -5,17 +5,17 @@ import { QVariant } from './QVariant'; import { DateFormat } from '../QtEnums'; export class QTime extends Component { - native: NativeElement; - constructor(arg?: NativeElement | number, m?: number, s = 0, ms = 0) { - super(); + constructor(nativeOrHours?: NativeElement | number, m?: number, s = 0, ms = 0) { const count = arguments.length; + let native: NativeElement; if (count > 1) { - this.native = new addon.QTime(arg, m, s, ms); - } else if (count == 1 && checkIfNativeElement(arg)) { - this.native = arg as NativeElement; + native = new addon.QTime(nativeOrHours, m, s, ms); + } else if (checkIfNativeElement(nativeOrHours)) { + native = nativeOrHours as NativeElement; } else { - this.native = new addon.QTime(); + native = new addon.QTime(); } + super(native); } addMSecs(ms: number): QTime { return new QTime(this.native.addMSecs(ms)); diff --git a/src/lib/QtCore/QUrl.ts b/src/lib/QtCore/QUrl.ts index 7cfbd2f3a..8e5d922da 100644 --- a/src/lib/QtCore/QUrl.ts +++ b/src/lib/QtCore/QUrl.ts @@ -3,7 +3,7 @@ import addon from '../utils/addon'; import { checkIfNativeElement } from '../utils/helpers'; import { QVariant } from './QVariant'; -enum ComponentFormattingOption { +export enum ComponentFormattingOption { /** The component is returned in a "pretty form", with most percent-encoded characters decoded. The exact behavior of PrettyDecoded varies from component to component and may also change from Qt release to Qt release. This is the default. */ PrettyDecoded = 0x000000, /** Leave space characters in their encoded form ("%20"). */ @@ -29,7 +29,7 @@ export enum ParsingMode { /** QUrl will interpret the URL component in the fully-decoded form, where percent characters stand for themselves, not as the beginning of a percent-encoded sequence. This mode is only valid for the setters setting components of a URL; it is not permitted in the QUrl constructor, in fromEncoded() or in setUrl(). For more information on this mode, see the documentation for QUrl::FullyDecoded.*/ DecodedMode = 2, } -enum UrlFormattingOption { +export enum UrlFormattingOption { None = 0x0, RemoveScheme = 0x1, RemovePassword = 0x2, @@ -44,7 +44,7 @@ enum UrlFormattingOption { StripTrailingSlash = 0x400, NormalizePathSegments = 0x1000, } -enum UserInputResolutionOption { +export enum UserInputResolutionOption { /** The default resolution mechanism is to check whether a local file exists, in the working directory given to fromUserInput, and only return a local path in that case. Otherwise a URL is assumed. */ DefaultResolution = 0, /** This option makes fromUserInput() always return a local path unless the input contains a scheme, such as http://file.pl. This is useful for applications such as text editors, which are able to create the file if it doesn't exist. */ @@ -52,27 +52,19 @@ enum UserInputResolutionOption { } export class QUrl extends Component { - static readonly ComponentFormattingOption = ComponentFormattingOption; - static readonly ParsingMode = ParsingMode; - static readonly UrlFormattingOption = UrlFormattingOption; - static readonly UserInputResolutionOption = UserInputResolutionOption; - readonly ComponentFormattingOption = ComponentFormattingOption; - readonly ParsingMode = ParsingMode; - readonly UrlFormattingOption = UrlFormattingOption; - readonly UserInputResolutionOption = UserInputResolutionOption; - native: NativeElement; constructor(); constructor(nativeElement: NativeElement); constructor(url: string, parsingMode?: ParsingMode); - constructor(arg?: string | NativeElement, parsingMode: ParsingMode = ParsingMode.TolerantMode) { - super(); - if (!arg) { - this.native = new addon.QUrl(); - } else if (checkIfNativeElement(arg)) { - this.native = arg as NativeElement; + constructor(nativeOrString?: string | NativeElement, parsingMode: ParsingMode = ParsingMode.TolerantMode) { + let native: NativeElement; + if (!nativeOrString) { + native = new addon.QUrl(); + } else if (checkIfNativeElement(nativeOrString)) { + native = nativeOrString as NativeElement; } else { - this.native = new addon.QUrl(arg, parsingMode); + native = new addon.QUrl(nativeOrString, parsingMode); } + super(native); } static fromQVariant(variant: QVariant): QUrl { diff --git a/src/lib/QtCore/QVariant.ts b/src/lib/QtCore/QVariant.ts index d1f7d6345..1708bffa8 100644 --- a/src/lib/QtCore/QVariant.ts +++ b/src/lib/QtCore/QVariant.ts @@ -5,19 +5,19 @@ import { checkIfNativeElement } from '../utils/helpers'; export type QVariantType = NativeElement | string | string[] | number | boolean; export class QVariant extends Component { - native: NativeElement; constructor(); constructor(nativeElement: NativeElement); constructor(variant: QVariantType); constructor(arg?: QVariantType | NativeElement) { - super(); + let native: NativeElement; if (checkIfNativeElement(arg) && arg instanceof addon.QVariant) { - this.native = arg as NativeElement; + native = arg as NativeElement; } else if (arg) { - this.native = new addon.QVariant.convertToQVariant(arg); + native = new addon.QVariant.convertToQVariant(arg); } else { - this.native = new addon.QVariant(); + native = new addon.QVariant(); } + super(native); } toString(): string { return this.native.toString(); diff --git a/src/lib/QtGui/QApplication.ts b/src/lib/QtGui/QApplication.ts index c4200db03..eedf26587 100644 --- a/src/lib/QtGui/QApplication.ts +++ b/src/lib/QtGui/QApplication.ts @@ -3,7 +3,7 @@ import { NativeElement } from '../core/Component'; import { checkIfNativeElement } from '../utils/helpers'; import { QClipboard } from './QClipboard'; import { QStyle } from './QStyle'; -import { QObjectSignals, NodeObject } from '../QtCore/QObject'; +import { QObjectSignals, QObject } from '../QtCore/QObject'; import { QPalette } from './QPalette'; import { StyleSheet } from '../core/Style/StyleSheet'; import memoizeOne from 'memoize-one'; @@ -27,8 +27,7 @@ const qApp = QApplication.instance(); qApp.quit(); ``` */ -export class QApplication extends NodeObject { - native: NativeElement; +export class QApplication extends QObject { constructor(); constructor(native: NativeElement); constructor(arg?: NativeElement) { @@ -39,7 +38,6 @@ export class QApplication extends NodeObject { native = new addon.QApplication(); } super(native); - this.native = native; this.setStyleSheet = memoizeOne(this.setStyleSheet); } diff --git a/src/lib/QtGui/QBrush.ts b/src/lib/QtGui/QBrush.ts index b13ba953a..4c484015f 100644 --- a/src/lib/QtGui/QBrush.ts +++ b/src/lib/QtGui/QBrush.ts @@ -21,18 +21,18 @@ const brush = new QBrush(); ``` */ export class QBrush extends Component { - native: NativeElement; - constructor(arg?: NativeElement | GlobalColor | QColor, style = BrushStyle.SolidPattern) { - super(); - if (checkIfNativeElement(arg)) { - this.native = arg as NativeElement; - } else if (typeof arg === 'number') { - this.native = new addon.QBrush(arg, style); - } else if (arg == null) { - this.native = new addon.QBrush(); + constructor(nativeOrGlobalColor?: NativeElement | GlobalColor | QColor, style = BrushStyle.SolidPattern) { + let native: NativeElement; + if (checkIfNativeElement(nativeOrGlobalColor)) { + native = nativeOrGlobalColor as NativeElement; + } else if (typeof nativeOrGlobalColor === 'number') { + native = new addon.QBrush(nativeOrGlobalColor, style); + } else if (nativeOrGlobalColor == null) { + native = new addon.QBrush(); } else { - this.native = new addon.QBrush(arg?.native, style); + native = new addon.QBrush(nativeOrGlobalColor?.native, style); } + super(native); } isOpaque(): boolean { return this.native.isOpaque(); diff --git a/src/lib/QtGui/QClipboard.ts b/src/lib/QtGui/QClipboard.ts index e7df4e94c..5799a741b 100644 --- a/src/lib/QtGui/QClipboard.ts +++ b/src/lib/QtGui/QClipboard.ts @@ -1,6 +1,6 @@ import { NativeElement } from '../core/Component'; import { checkIfNativeElement, registerNativeWrapFunction } from '../utils/helpers'; -import { NodeObject, QObjectSignals } from '../QtCore/QObject'; +import { QObject, QObjectSignals } from '../QtCore/QObject'; import { QPixmap } from './QPixmap'; import { wrapperCache } from '../core/WrapperCache'; @@ -23,15 +23,12 @@ const clipboard = QApplication.clipboard(); const text = clipboard.text(QClipboardMode.Clipboard); ``` */ -export class QClipboard extends NodeObject { - native: NativeElement; +export class QClipboard extends QObject { constructor(native: NativeElement) { - super(native); - if (checkIfNativeElement(native)) { - this.native = native; - } else { + if (!checkIfNativeElement(native)) { throw new Error('QClipboard cannot be initialised this way. Use QApplication::clipboard()'); } + super(native); } clear(mode = QClipboardMode.Clipboard): void { this.native.clear(mode); diff --git a/src/lib/QtGui/QColor.ts b/src/lib/QtGui/QColor.ts index 898bd23fc..f2d026779 100644 --- a/src/lib/QtGui/QColor.ts +++ b/src/lib/QtGui/QColor.ts @@ -5,28 +5,28 @@ import { QVariant } from '../QtCore/QVariant'; import { GlobalColor } from '../QtEnums'; export class QColor extends Component { - native: NativeElement; constructor(); constructor(nativeElement: NativeElement); constructor(colorString: string); constructor(color: GlobalColor); constructor(r?: number, g?: number, b?: number, a?: number); constructor(arg?: NativeElement | number | string, g = 0, b = 0, a = 255) { - super(); + let native: NativeElement; if (checkIfNativeElement(arg)) { - this.native = arg as NativeElement; + native = arg as NativeElement; } else if (typeof arg === 'number') { if (arguments.length === 1) { // This is for QGlobalColor enum - this.native = new addon.QColor(arg); + native = new addon.QColor(arg); } else { - this.native = new addon.QColor(arg, g, b, a); + native = new addon.QColor(arg, g, b, a); } } else if (typeof arg === 'string') { - this.native = new addon.QColor(arg); + native = new addon.QColor(arg); } else { - this.native = new addon.QColor(); + native = new addon.QColor(); } + super(native); } setRed(value: number): void { this.native.setRed(value); diff --git a/src/lib/QtGui/QCursor.ts b/src/lib/QtGui/QCursor.ts index 331b2f6b2..a5884c1b6 100644 --- a/src/lib/QtGui/QCursor.ts +++ b/src/lib/QtGui/QCursor.ts @@ -17,17 +17,17 @@ const cursor = new QCursor(); ``` */ export class QCursor extends Component { - native: NativeElement; constructor(); constructor(native: NativeElement); constructor(shape: CursorShape); constructor(arg?: NativeElement | CursorShape) { - super(); + let native: NativeElement; if (arg) { - this.native = new addon.QCursor(arg); + native = new addon.QCursor(arg); } else { - this.native = new addon.QCursor(); + native = new addon.QCursor(); } + super(native); } pos(): { x: number; y: number } { return this.native.pos(); diff --git a/src/lib/QtGui/QDrag.ts b/src/lib/QtGui/QDrag.ts index 869ac640e..3ab6d142a 100644 --- a/src/lib/QtGui/QDrag.ts +++ b/src/lib/QtGui/QDrag.ts @@ -11,21 +11,18 @@ import { QMimeData } from '../QtCore/QMimeData'; * description */ export class QDrag extends Component { - native: NativeElement; constructor(arg?: NativeElement | QObject) { - super(); + let native: NativeElement; if (!arg) { - this.native = new addon.QDrag(); + native = new addon.QDrag(); + } else if (checkIfNativeElement(arg)) { + native = arg as NativeElement; + } else if (arg.native) { + native = new addon.QDrag(arg.native); } else { - const isNative = checkIfNativeElement(arg); - if (isNative) { - this.native = arg as NativeElement; - } else if (arg.native) { - this.native = new addon.QDrag(arg.native); - } else { - this.native = new addon.QDrag(); - } + native = new addon.QDrag(); } + super(native); } /** diff --git a/src/lib/QtGui/QFont.ts b/src/lib/QtGui/QFont.ts index 645ea0057..eeb00c4cc 100644 --- a/src/lib/QtGui/QFont.ts +++ b/src/lib/QtGui/QFont.ts @@ -4,22 +4,22 @@ import { QVariant } from '../QtCore/QVariant'; import { checkIfNativeElement } from '../utils/helpers'; export class QFont extends Component { - native: NativeElement; constructor(); constructor(font: QFont); constructor(native: NativeElement); constructor(family: string, pointSize?: number, weight?: QFontWeight, italic?: boolean); constructor(arg?: QFont | string | NativeElement, pointSize = -1, weight = -1, italic = false) { - super(); + let native: NativeElement; if (checkIfNativeElement(arg)) { - this.native = arg as NativeElement; + native = arg as NativeElement; } else if (arg instanceof QFont) { - this.native = arg.native; + native = arg.native; } else if (typeof arg === 'string') { - this.native = new addon.QFont(arg, pointSize, weight, italic); + native = new addon.QFont(arg, pointSize, weight, italic); } else { - this.native = new addon.QFont(); + native = new addon.QFont(); } + super(native); } bold(): boolean { return this.native.bold(); diff --git a/src/lib/QtGui/QFontDatabase.ts b/src/lib/QtGui/QFontDatabase.ts index d38218aac..8e5414fbd 100644 --- a/src/lib/QtGui/QFontDatabase.ts +++ b/src/lib/QtGui/QFontDatabase.ts @@ -1,5 +1,5 @@ import addon from '../utils/addon'; -import { Component, NativeElement } from '../core/Component'; +import { Component } from '../core/Component'; export enum WritingSystem { Any = 0, @@ -40,10 +40,8 @@ export enum WritingSystem { } export class QFontDatabase extends Component { - native: NativeElement; constructor() { - super(); - this.native = new addon.QFontDatabase(); + super(new addon.QFontDatabase()); } families(ws: WritingSystem = WritingSystem.Any): string[] { return this.native.families(ws); diff --git a/src/lib/QtGui/QFontMetrics.ts b/src/lib/QtGui/QFontMetrics.ts index 84dde5468..128f9b089 100644 --- a/src/lib/QtGui/QFontMetrics.ts +++ b/src/lib/QtGui/QFontMetrics.ts @@ -7,19 +7,19 @@ import { TextElideMode, TextFlag } from '../QtEnums'; import { QRect } from '../..'; export class QFontMetrics extends Component { - native: NativeElement; constructor(native: NativeElement); constructor(qfont: QFont); constructor(qfontmetrics: QFontMetrics); constructor(arg: QFont | QFontMetrics | NativeElement) { - super(); + let native: NativeElement; if (checkIfNativeElement(arg)) { - this.native = arg as NativeElement; + native = arg as NativeElement; } else if (arg instanceof QFontMetrics) { - this.native = arg.native; + native = arg.native; } else { - this.native = new addon.QFontMetrics(arg.native); + native = new addon.QFontMetrics(arg.native); } + super(native); } // *** Public Functions *** diff --git a/src/lib/QtGui/QFontMetricsF.ts b/src/lib/QtGui/QFontMetricsF.ts index f5c840d8c..2b8d594dc 100644 --- a/src/lib/QtGui/QFontMetricsF.ts +++ b/src/lib/QtGui/QFontMetricsF.ts @@ -7,19 +7,19 @@ import { TextElideMode, TextFlag } from '../QtEnums'; import { QRect } from '../..'; export class QFontMetricsF extends Component { - native: NativeElement; constructor(native: NativeElement); constructor(qfont: QFont); constructor(qfontmetricsf: QFontMetricsF); constructor(arg: QFont | QFontMetricsF | NativeElement) { - super(); + let native: NativeElement; if (checkIfNativeElement(arg)) { - this.native = arg as NativeElement; + native = arg as NativeElement; } else if (arg instanceof QFontMetricsF) { - this.native = arg.native; + native = arg.native; } else { - this.native = new addon.QFontMetricsF(arg.native); + native = new addon.QFontMetricsF(arg.native); } + super(native); } // *** Public Functions *** diff --git a/src/lib/QtGui/QIcon.ts b/src/lib/QtGui/QIcon.ts index 66e699c7d..bc074f0bb 100644 --- a/src/lib/QtGui/QIcon.ts +++ b/src/lib/QtGui/QIcon.ts @@ -20,20 +20,20 @@ const icon = new QIcon(imageUrl); ``` */ export class QIcon extends Component { - native: NativeElement; constructor(); constructor(native: NativeElement); constructor(filePath: string); constructor(arg?: string | NativeElement) { - super(); + let native: NativeElement; if (typeof arg === 'string') { const imagePath = arg; - this.native = new addon.QIcon(imagePath); + native = new addon.QIcon(imagePath); } else if (checkIfNativeElement(arg)) { - this.native = arg as NativeElement; + native = arg as NativeElement; } else { - this.native = new addon.QIcon(); + native = new addon.QIcon(); } + super(native); } pixmap(width: number, height: number, mode?: QIconMode, state?: QIconState): QPixmap { let nativePixmap; diff --git a/src/lib/QtGui/QImage.ts b/src/lib/QtGui/QImage.ts index 615cb70a8..8fed74577 100644 --- a/src/lib/QtGui/QImage.ts +++ b/src/lib/QtGui/QImage.ts @@ -24,19 +24,13 @@ const image = new QImage(); ``` */ export class QImage extends Component { - native!: NativeElement; - /** Constructs a null image */ constructor(); - constructor(native: NativeElement); - /** Constructs an image and tries to load the image from the file with the given fileName */ constructor(filename: string); - /** Constructs an image with the given width, height and format */ constructor(width: number, height: number, format: QImageFormat); - /** Constructs an image with the given size and format */ constructor(size: QSize, format: QImageFormat); constructor( @@ -44,19 +38,19 @@ export class QImage extends Component { formatOrHeight?: QImageFormat | string | number, format?: QImageFormat, ) { - super(); - + let native: NativeElement; if (checkIfNativeElement(arg)) { - this.native = arg as NativeElement; + native = arg as NativeElement; } else if (typeof arg === 'string') { - this.native = new addon.QImage(arg); + native = new addon.QImage(arg); } else if (typeof arg === 'number') { - this.native = new addon.QImage(arg, formatOrHeight, format); + native = new addon.QImage(arg, formatOrHeight, format); } else if (arg instanceof QSize) { - this.native = new addon.QImage(arg.native, formatOrHeight); + native = new addon.QImage(arg.native, formatOrHeight); } else { - this.native = new addon.QImage(); + native = new addon.QImage(); } + super(native); } /** diff --git a/src/lib/QtGui/QKeySequence.ts b/src/lib/QtGui/QKeySequence.ts index 158ad191f..efcef2775 100644 --- a/src/lib/QtGui/QKeySequence.ts +++ b/src/lib/QtGui/QKeySequence.ts @@ -18,20 +18,20 @@ const keySequence = new QKeySequence(`Ctrl+L`); ``` */ export class QKeySequence extends Component { - native: NativeElement; constructor(); constructor(native: NativeElement); constructor(keySequence: string); constructor(arg?: string | NativeElement) { - super(); + let native: NativeElement; if (typeof arg === 'string') { const keySequence = arg; - this.native = new addon.QKeySequence(keySequence); + native = new addon.QKeySequence(keySequence); } else if (checkIfNativeElement(arg)) { - this.native = arg as NativeElement; + native = arg as NativeElement; } else { - this.native = new addon.QKeySequence(); + native = new addon.QKeySequence(); } + super(native); } count(): number { return this.native.count(); diff --git a/src/lib/QtGui/QMovie.ts b/src/lib/QtGui/QMovie.ts index f9c25871b..14639dd0e 100644 --- a/src/lib/QtGui/QMovie.ts +++ b/src/lib/QtGui/QMovie.ts @@ -1,16 +1,15 @@ import addon from '../utils/addon'; import { NativeElement } from '../core/Component'; import { checkIfNativeElement } from '../utils/helpers'; -import { NodeObject, QObjectSignals } from '../QtCore/QObject'; +import { QObject, QObjectSignals } from '../QtCore/QObject'; import { QSize } from '../QtCore/QSize'; import { QPixmap } from './QPixmap'; -export class QMovie extends NodeObject { - native: NativeElement; +export class QMovie extends QObject { constructor(); constructor(native: NativeElement); - constructor(parent: NodeObject); - constructor(arg?: NodeObject | NativeElement) { + constructor(parent: QObject); + constructor(arg?: QObject | NativeElement) { let native: NativeElement; if (arg) { if (checkIfNativeElement(arg)) { @@ -22,7 +21,6 @@ export class QMovie extends NodeObject { native = new addon.QMovie(); } super(native); - this.native = native; } //Methods setFileName(fileName: string): void { diff --git a/src/lib/QtGui/QPalette.ts b/src/lib/QtGui/QPalette.ts index d8365ec31..377ac911a 100644 --- a/src/lib/QtGui/QPalette.ts +++ b/src/lib/QtGui/QPalette.ts @@ -1,4 +1,4 @@ -import { Component, NativeElement } from '../core/Component'; +import { Component } from '../core/Component'; import { QColor } from './QColor'; export enum ColorGroup { @@ -33,12 +33,6 @@ export enum ColorRole { } export class QPalette extends Component { - native: NativeElement; - constructor(native: NativeElement) { - super(); - this.native = native; - } - color(group: ColorGroup, role: ColorRole): QColor { return new QColor(this.native.color(group, role)); } diff --git a/src/lib/QtGui/QPen.ts b/src/lib/QtGui/QPen.ts index 69f0f33de..119db3d56 100644 --- a/src/lib/QtGui/QPen.ts +++ b/src/lib/QtGui/QPen.ts @@ -1,4 +1,4 @@ -import { Component, NativeElement } from '../core/Component'; +import { Component } from '../core/Component'; import addon from '../utils/addon'; import { GlobalColor, PenStyle, PenCapStyle } from '../QtEnums'; import { QColor } from './QColor'; @@ -18,10 +18,8 @@ const pen = new QPen(); ``` */ export class QPen extends Component { - native: NativeElement; constructor() { - super(); - this.native = new addon.QPen(); + super(new addon.QPen()); } setColor(color: QColor | GlobalColor): void { if (typeof color === 'number') { diff --git a/src/lib/QtGui/QPicture.ts b/src/lib/QtGui/QPicture.ts index 11e1e8a89..a420416a0 100644 --- a/src/lib/QtGui/QPicture.ts +++ b/src/lib/QtGui/QPicture.ts @@ -18,20 +18,20 @@ const picture = new QPicture(); ``` */ export class QPicture extends Component { - native: NativeElement; constructor(); constructor(native: NativeElement); constructor(formatVersion: number); constructor(arg?: number | NativeElement) { - super(); + let native: NativeElement; if (typeof arg === 'number') { const formatVersion = arg; - this.native = new addon.QPicture(formatVersion); + native = new addon.QPicture(formatVersion); } else if (checkIfNativeElement(arg)) { - this.native = arg as NativeElement; + native = arg as NativeElement; } else { - this.native = new addon.QPicture(); + native = new addon.QPicture(); } + super(native); } setBoundingRect(r: QRect): void { this.native.setBoundingRect(r.native); diff --git a/src/lib/QtGui/QPixmap.ts b/src/lib/QtGui/QPixmap.ts index 3cabe183e..8999810cc 100644 --- a/src/lib/QtGui/QPixmap.ts +++ b/src/lib/QtGui/QPixmap.ts @@ -23,20 +23,20 @@ const pixMap = new QPixmap(imageUrl); ``` */ export class QPixmap extends Component { - native: NativeElement; constructor(); constructor(native: NativeElement); constructor(filePath: string); constructor(arg?: string | NativeElement) { - super(); + let native: NativeElement; if (typeof arg === 'string') { const imagePath = arg; - this.native = new addon.QPixmap(imagePath); + native = new addon.QPixmap(imagePath); } else if (checkIfNativeElement(arg)) { - this.native = arg as NativeElement; + native = arg as NativeElement; } else { - this.native = new addon.QPixmap(); + native = new addon.QPixmap(); } + super(native); } load(imagePath: string): boolean { return this.native.load(imagePath); diff --git a/src/lib/QtGui/QScreen.ts b/src/lib/QtGui/QScreen.ts index 39f3611ba..68debebcb 100644 --- a/src/lib/QtGui/QScreen.ts +++ b/src/lib/QtGui/QScreen.ts @@ -1,21 +1,18 @@ import { NativeElement } from '../core/Component'; import { checkIfNativeElement, registerNativeWrapFunction } from '../utils/helpers'; -import { NodeObject, QObjectSignals } from '../QtCore/QObject'; +import { QObject, QObjectSignals } from '../QtCore/QObject'; import { QRect } from '../QtCore/QRect'; import { QSizeF } from '../QtCore/QSizeF'; import { QSize } from '../QtCore/QSize'; import { wrapperCache } from '../core/WrapperCache'; import { QPixmap } from './QPixmap'; -export class QScreen extends NodeObject { - native: NativeElement; +export class QScreen extends QObject { constructor(native: NativeElement) { - super(native); - if (checkIfNativeElement(native)) { - this.native = native; - } else { + if (!checkIfNativeElement(native)) { throw new Error('QScreen cannot be initialised this way.'); } + super(native); } availableGeometry(): QRect { diff --git a/src/lib/QtGui/QStyle.ts b/src/lib/QtGui/QStyle.ts index 2db30408c..363d94940 100644 --- a/src/lib/QtGui/QStyle.ts +++ b/src/lib/QtGui/QStyle.ts @@ -3,14 +3,11 @@ import { Component, NativeElement } from '../core/Component'; import { checkIfNativeElement } from '../utils/helpers'; export class QStyle extends Component { - native: NativeElement; constructor(native: NativeElement) { - super(); - if (checkIfNativeElement(native)) { - this.native = native; - } else { + if (!checkIfNativeElement(native)) { throw new Error('QStyle cannot be initialised this way. Use QApplication::style()'); } + super(native); } pixelMetric(metric: QStylePixelMetric): number { diff --git a/src/lib/QtGui/QWindow.ts b/src/lib/QtGui/QWindow.ts index 7adcc620e..c8f98b8e4 100644 --- a/src/lib/QtGui/QWindow.ts +++ b/src/lib/QtGui/QWindow.ts @@ -1,20 +1,16 @@ import { NativeElement } from '../core/Component'; import { checkIfNativeElement, registerNativeWrapFunction } from '../utils/helpers'; -import { NodeObject, QObjectSignals } from '../QtCore/QObject'; +import { QObject, QObjectSignals } from '../QtCore/QObject'; import { QScreen } from './QScreen'; import { wrapperCache } from '../core/WrapperCache'; import { Edge, Visibility, WindowState } from '../QtEnums'; -export class QWindow extends NodeObject { - native: NativeElement; +export class QWindow extends QObject { constructor(native: NativeElement) { - super(native); - - if (checkIfNativeElement(native)) { - this.native = native; - } else { + if (!checkIfNativeElement(native)) { throw new Error('QWindow cannot be initialised this way.'); } + super(native); } screen(): QScreen { diff --git a/src/lib/QtWidgets/QAction.ts b/src/lib/QtWidgets/QAction.ts index 28772a8e7..9c19f36d9 100644 --- a/src/lib/QtWidgets/QAction.ts +++ b/src/lib/QtWidgets/QAction.ts @@ -6,7 +6,7 @@ import { QIcon } from '../QtGui/QIcon'; import { QFont } from '../QtGui/QFont'; import { QKeySequence } from '../QtGui/QKeySequence'; import { ShortcutContext } from '../QtEnums'; -import { NodeObject, QObjectSignals } from '../QtCore/QObject'; +import { QObject, QObjectSignals } from '../QtCore/QObject'; import { checkIfNativeElement } from '../utils/helpers'; import { QVariant } from '../QtCore/QVariant'; @@ -30,13 +30,12 @@ menuAction.addEventListener("triggered", () => { menu.addAction(menuAction); ``` */ -export class QAction extends NodeObject { - native: NativeElement; +export class QAction extends QObject { constructor(); constructor(native: NativeElement); constructor(parent: NodeWidget); constructor(parent?: NativeElement | NodeWidget) { - let native; + let native: NativeElement; if (checkIfNativeElement(parent)) { native = parent as NativeElement; } else if (parent) { @@ -45,7 +44,6 @@ export class QAction extends NodeObject { native = new addon.QAction(); } super(native); - this.native = native; } setText(text: string): void { this.native.setText(text); diff --git a/src/lib/QtWidgets/QBoxLayout.ts b/src/lib/QtWidgets/QBoxLayout.ts index 39df53f36..03621edc4 100644 --- a/src/lib/QtWidgets/QBoxLayout.ts +++ b/src/lib/QtWidgets/QBoxLayout.ts @@ -26,7 +26,6 @@ centralWidget.setLayout(boxLayout); ``` */ export class QBoxLayout extends NodeLayout { - native: NativeElement; childLayouts: Set>; constructor(dir: Direction); constructor(dir: Direction, parent: NodeWidget); @@ -39,7 +38,6 @@ export class QBoxLayout extends NodeLayout { } super(native); this.setNodeParent(parent); - this.native = native; this.childLayouts = new Set(); } addLayout(layout: NodeLayout, stretch = 0): void { diff --git a/src/lib/QtWidgets/QButtonGroup.ts b/src/lib/QtWidgets/QButtonGroup.ts index 817aaaed9..da7a16c68 100644 --- a/src/lib/QtWidgets/QButtonGroup.ts +++ b/src/lib/QtWidgets/QButtonGroup.ts @@ -1,15 +1,14 @@ import addon from '../utils/addon'; import { NodeWidget } from './QWidget'; -import { NativeElement, NativeRawPointer } from '../core/Component'; -import { NodeObject, QObjectSignals } from '../QtCore/QObject'; +import { NativeRawPointer } from '../core/Component'; +import { QObject, QObjectSignals } from '../QtCore/QObject'; import { QAbstractButton, QAbstractButtonSignals } from './QAbstractButton'; export interface QButtonGroupSignals extends QObjectSignals { buttonClicked: (id?: number) => void; } -export class QButtonGroup extends NodeObject { - native: NativeElement; +export class QButtonGroup extends QObject { constructor(); constructor(parent: NodeWidget); constructor(parent?: NodeWidget) { @@ -20,7 +19,6 @@ export class QButtonGroup extends NodeObject { native = new addon.QButtonGroup(); } super(native); - this.native = native; parent && parent.nodeChildren.add(this); } addButton(button: QAbstractButton, id = -1): void { diff --git a/src/lib/QtWidgets/QCalendarWidget.ts b/src/lib/QtWidgets/QCalendarWidget.ts index b8ef50dcf..76b857096 100644 --- a/src/lib/QtWidgets/QCalendarWidget.ts +++ b/src/lib/QtWidgets/QCalendarWidget.ts @@ -5,7 +5,7 @@ import { QDate } from '../QtCore/QDate'; import { DayOfWeek } from '../QtEnums'; /** - + > Create and control a selectable monthly calendar. * **This class is a JS wrapper around Qt's [QCalendarWidget class](https://doc.qt.io/qt-5/qcalendarwidget.html)** @@ -22,18 +22,16 @@ const calendarWidget = new QCalendarWidget(); ``` */ export class QCalendarWidget extends NodeWidget { - native: NativeElement; constructor(); constructor(parent: NodeWidget); constructor(parent?: NodeWidget) { - let native; + let native: NativeElement; if (parent) { native = new addon.QCalendarWidget(parent.native); } else { native = new addon.QCalendarWidget(); } super(native); - this.native = native; this.setNodeParent(parent); } setDateEditAcceptDelay(delay: number): void { diff --git a/src/lib/QtWidgets/QCheckBox.ts b/src/lib/QtWidgets/QCheckBox.ts index 73d8b5c0d..66e6a33be 100644 --- a/src/lib/QtWidgets/QCheckBox.ts +++ b/src/lib/QtWidgets/QCheckBox.ts @@ -23,7 +23,6 @@ checkbox.setText("Hello"); ``` */ export class QCheckBox extends QAbstractButton { - native: NativeElement; constructor(); constructor(parent: NodeWidget); constructor(rawPointer: NativeRawPointer, disableNativeDeletion?: boolean); @@ -42,7 +41,6 @@ export class QCheckBox extends QAbstractButton { native = new addon.QCheckBox(); } super(native); - this.native = native; parent && this.setNodeParent(parent); } setTristate(y = true): void { diff --git a/src/lib/QtWidgets/QColorDialog.ts b/src/lib/QtWidgets/QColorDialog.ts index a4784d3e5..aa7c1637f 100644 --- a/src/lib/QtWidgets/QColorDialog.ts +++ b/src/lib/QtWidgets/QColorDialog.ts @@ -5,7 +5,7 @@ import { NodeDialog, QDialogSignals } from './QDialog'; import { QColor } from '../QtGui/QColor'; /** - + > Create and control color dialogs. * **This class is a JS wrapper around Qt's [QColorDialog class](https://doc.qt.io/qt-5/qcolordialog.html)** @@ -27,18 +27,16 @@ console.log(color.red(), color.green(), color.blue()); ``` */ export class QColorDialog extends NodeDialog { - native: NativeElement; constructor(); constructor(parent: NodeWidget); constructor(parent?: NodeWidget) { - let native; + let native: NativeElement; if (parent) { native = new addon.QColorDialog(parent.native); } else { native = new addon.QColorDialog(); } super(native); - this.native = native; parent && this.setNodeParent(parent); } setCurrentColor(color: QColor): void { diff --git a/src/lib/QtWidgets/QComboBox.ts b/src/lib/QtWidgets/QComboBox.ts index 77149bd9a..2b7788993 100644 --- a/src/lib/QtWidgets/QComboBox.ts +++ b/src/lib/QtWidgets/QComboBox.ts @@ -37,18 +37,16 @@ comboBox.addEventListener('currentIndexChanged', (index) => { ``` */ export class QComboBox extends NodeWidget { - native: NativeElement; constructor(); constructor(parent: NodeWidget); constructor(parent?: NodeWidget) { - let native; + let native: NativeElement; if (parent) { native = new addon.QComboBox(parent.native); } else { native = new addon.QComboBox(); } super(native); - this.native = native; this.setNodeParent(parent); } // *** Public Functions *** diff --git a/src/lib/QtWidgets/QDateEdit.ts b/src/lib/QtWidgets/QDateEdit.ts index 1aa329f50..1b67f0d63 100644 --- a/src/lib/QtWidgets/QDateEdit.ts +++ b/src/lib/QtWidgets/QDateEdit.ts @@ -21,18 +21,16 @@ const dateEdit = new QDateEdit(); ``` */ export class QDateEdit extends NodeDateTimeEdit { - native: NativeElement; constructor(); constructor(parent: NodeWidget); constructor(parent?: NodeWidget) { - let native; + let native: NativeElement; if (parent) { native = new addon.QDateEdit(parent.native); } else { native = new addon.QDateEdit(); } super(native); - this.native = native; this.setNodeParent(parent); } } diff --git a/src/lib/QtWidgets/QDateTimeEdit.ts b/src/lib/QtWidgets/QDateTimeEdit.ts index 951a1a677..2183cec62 100644 --- a/src/lib/QtWidgets/QDateTimeEdit.ts +++ b/src/lib/QtWidgets/QDateTimeEdit.ts @@ -1,6 +1,5 @@ import addon from '../utils/addon'; import { NodeWidget } from './QWidget'; -import { NativeElement } from '../core/Component'; import { QAbstractSpinBox, QAbstractSpinBoxSignals } from './QAbstractSpinBox'; import { QCalendarWidget } from './QCalendarWidget'; import { QDate } from '../QtCore/QDate'; @@ -86,7 +85,6 @@ dateTimeEdit.setTime(time); ``` */ export class QDateTimeEdit extends NodeDateTimeEdit { - native: NativeElement; constructor(); constructor(parent: NodeWidget); constructor(parent?: NodeWidget) { @@ -97,7 +95,6 @@ export class QDateTimeEdit extends NodeDateTimeEdit { native = new addon.QDateTimeEdit(); } super(native); - this.native = native; this.setNodeParent(parent); } } diff --git a/src/lib/QtWidgets/QDial.ts b/src/lib/QtWidgets/QDial.ts index 928e72923..6ba0112a0 100644 --- a/src/lib/QtWidgets/QDial.ts +++ b/src/lib/QtWidgets/QDial.ts @@ -20,18 +20,16 @@ const dial = new QDial(); ``` */ export class QDial extends QAbstractSlider { - native: NativeElement; constructor(); constructor(parent: NodeWidget); constructor(parent?: NodeWidget) { - let native; + let native: NativeElement; if (parent) { native = new addon.QDial(parent.native); } else { native = new addon.QDial(); } super(native); - this.native = native; this.setNodeParent(parent); } notchSize(): number { diff --git a/src/lib/QtWidgets/QDialog.ts b/src/lib/QtWidgets/QDialog.ts index a5958ac3d..dc6f41bf8 100644 --- a/src/lib/QtWidgets/QDialog.ts +++ b/src/lib/QtWidgets/QDialog.ts @@ -43,7 +43,6 @@ export abstract class NodeDialog extends NodeWid It is inherited by QFileDialog and QMessageBox (n/a QColorDialog, QErrorMessage, QFontDialog, QInputDialog, QMessageBox, QProgressDialog, and QWizard) */ export class QDialog extends NodeDialog { - native: NativeElement; constructor(arg?: NodeDialog | NativeElement) { let native; let parent; @@ -57,7 +56,6 @@ export class QDialog extends NodeDialog { } super(native); this.setNodeParent(parent); - this.native = native; } } diff --git a/src/lib/QtWidgets/QDoubleSpinBox.ts b/src/lib/QtWidgets/QDoubleSpinBox.ts index 38d08e5a2..d3d194724 100644 --- a/src/lib/QtWidgets/QDoubleSpinBox.ts +++ b/src/lib/QtWidgets/QDoubleSpinBox.ts @@ -20,18 +20,16 @@ const doublespinBox = new QDoubleSpinBox(); ``` */ export class QDoubleSpinBox extends QAbstractSpinBox { - native: NativeElement; constructor(); constructor(parent: NodeWidget); constructor(parent?: NodeWidget) { - let native; + let native: NativeElement; if (parent) { native = new addon.QDoubleSpinBox(parent.native); } else { native = new addon.QDoubleSpinBox(); } super(native); - this.native = native; parent && this.setNodeParent(parent); } cleanText(): string { diff --git a/src/lib/QtWidgets/QErrorMessage.ts b/src/lib/QtWidgets/QErrorMessage.ts index adef87987..073df1e1d 100644 --- a/src/lib/QtWidgets/QErrorMessage.ts +++ b/src/lib/QtWidgets/QErrorMessage.ts @@ -21,18 +21,16 @@ const errorMessage = new QErrorMessage(); ``` */ export class QErrorMessage extends NodeDialog { - native: NativeElement; constructor(); constructor(parent: NodeWidget); constructor(parent?: NodeWidget) { - let native; + let native: NativeElement; if (parent) { native = new addon.QErrorMessage(parent.native); } else { native = new addon.QErrorMessage(); } super(native); - this.native = native; parent && this.setNodeParent(parent); } showMessage(message: string): void { diff --git a/src/lib/QtWidgets/QFileDialog.ts b/src/lib/QtWidgets/QFileDialog.ts index 4f5b94f62..7954a9b76 100644 --- a/src/lib/QtWidgets/QFileDialog.ts +++ b/src/lib/QtWidgets/QFileDialog.ts @@ -5,7 +5,7 @@ import { AcceptMode, DialogLabel, FileMode, Option, ViewMode } from '../QtEnums' import { NodeDialog, QDialogSignals } from './QDialog'; /** - + > Create and control file dialogs. * **This class is a JS wrapper around Qt's [QFileDialog class](https://doc.qt.io/qt-5/qfiledialog.html)** @@ -28,18 +28,16 @@ console.log(selectedFiles); ``` */ export class QFileDialog extends NodeDialog { - native: NativeElement; constructor(); constructor(parent: NodeWidget, caption?: string, directory?: string, filter?: string); constructor(parent?: NodeWidget, caption = 'Select File', directory = '', filter = '') { - let native; + let native: NativeElement; if (parent) { native = new addon.QFileDialog(parent.native, caption, directory, filter); } else { native = new addon.QFileDialog(); } super(native); - this.native = native; this.setNodeParent(parent); } supportedSchemes(): string[] { diff --git a/src/lib/QtWidgets/QFontDialog.ts b/src/lib/QtWidgets/QFontDialog.ts index cb553a276..ad6ec76cd 100644 --- a/src/lib/QtWidgets/QFontDialog.ts +++ b/src/lib/QtWidgets/QFontDialog.ts @@ -25,18 +25,16 @@ console.log(font); ``` */ export class QFontDialog extends NodeDialog { - native: NativeElement; constructor(); constructor(parent: NodeWidget); constructor(parent?: NodeWidget) { - let native; + let native: NativeElement; if (parent) { native = new addon.QFontDialog(parent.native); } else { native = new addon.QFontDialog(); } super(native); - this.native = native; parent && this.setNodeParent(parent); } setCurrentFont(font: QFont): void { diff --git a/src/lib/QtWidgets/QFrame.ts b/src/lib/QtWidgets/QFrame.ts index c1cce1c8d..69a69dcbb 100644 --- a/src/lib/QtWidgets/QFrame.ts +++ b/src/lib/QtWidgets/QFrame.ts @@ -80,9 +80,8 @@ const frame = new QFrame(); ``` */ export class QFrame extends NodeFrame { - native: NativeElement; constructor(arg?: NodeWidget | NativeElement) { - let native; + let native: NativeElement; let parent; if (checkIfNativeElement(arg)) { native = arg as NativeElement; @@ -94,6 +93,5 @@ export class QFrame extends NodeFrame { } super(native); this.setNodeParent(parent); - this.native = native; } } diff --git a/src/lib/QtWidgets/QGraphicsBlurEffect.ts b/src/lib/QtWidgets/QGraphicsBlurEffect.ts index 2a5c18a24..ce2bacf7e 100644 --- a/src/lib/QtWidgets/QGraphicsBlurEffect.ts +++ b/src/lib/QtWidgets/QGraphicsBlurEffect.ts @@ -1,7 +1,7 @@ import addon from '../utils/addon'; import { NativeElement } from '../core/Component'; import { checkIfNativeElement } from '../utils/helpers'; -import { NodeObject } from '../QtCore/QObject'; +import { QObject } from '../QtCore/QObject'; import { QGraphicsEffect, QGraphicsEffectSignals } from './QGraphicsEffect'; /** @@ -22,11 +22,10 @@ blur.setBlurRadius(8); ``` */ export class QGraphicsBlurEffect extends QGraphicsEffect { - native: NativeElement; constructor(); constructor(native: NativeElement); - constructor(parent: NodeObject); - constructor(arg?: NodeObject | NativeElement) { + constructor(parent: QObject); + constructor(arg?: QObject | NativeElement) { let native: NativeElement; if (arg) { if (checkIfNativeElement(arg)) { @@ -38,7 +37,6 @@ export class QGraphicsBlurEffect extends QGraphicsEffect { - native: NativeElement; constructor(); constructor(native: NativeElement); - constructor(parent: NodeObject); - constructor(arg?: NodeObject | NativeElement) { + constructor(parent: QObject); + constructor(arg?: QObject | NativeElement) { let native: NativeElement; if (arg) { if (checkIfNativeElement(arg)) { @@ -39,7 +38,6 @@ export class QGraphicsDropShadowEffect extends QGraphicsEffect This is the abstract base class of graphicseffect, providing their functionality. * **This class is a JS wrapper around Qt's [QGraphicsEffect class](https://doc.qt.io/qt-5/qgraphicseffect.html)** @@ -10,7 +10,7 @@ The QGraphicsEffect class is an abstract class and therefore, technically, no fu It is inherited by QGraphicsBlurEffect, QGraphicsColorizeEffect, QGraphicsDropShadowEffect, and QGraphicsOpacityEffect. */ -export abstract class QGraphicsEffect extends NodeObject { +export abstract class QGraphicsEffect extends QObject { setEnabled(enable: boolean): void { this.setProperty('enabled', enable); } diff --git a/src/lib/QtWidgets/QGridLayout.ts b/src/lib/QtWidgets/QGridLayout.ts index 8f477b738..c5a6ca729 100644 --- a/src/lib/QtWidgets/QGridLayout.ts +++ b/src/lib/QtWidgets/QGridLayout.ts @@ -30,7 +30,6 @@ layout.addWidget(label2); */ export class QGridLayout extends NodeLayout { - native: NativeElement; constructor(); constructor(parent: NodeWidget); constructor(parent?: NodeWidget) { @@ -42,7 +41,6 @@ export class QGridLayout extends NodeLayout { } super(native); this.setNodeParent(parent); - this.native = native; } addLayout( diff --git a/src/lib/QtWidgets/QGroupBox.ts b/src/lib/QtWidgets/QGroupBox.ts index 0db6a035e..50f91e966 100644 --- a/src/lib/QtWidgets/QGroupBox.ts +++ b/src/lib/QtWidgets/QGroupBox.ts @@ -40,18 +40,16 @@ win.show(); ``` */ export class QGroupBox extends NodeWidget { - native: NativeElement; constructor(); constructor(parent: NodeWidget); constructor(parent?: NodeWidget) { - let native; + let native: NativeElement; if (parent) { native = new addon.QGroupBox(parent.native); } else { native = new addon.QGroupBox(); } super(native); - this.native = native; this.setNodeParent(parent); } setAlignment(alignment: AlignmentFlag): void { diff --git a/src/lib/QtWidgets/QHeaderView.ts b/src/lib/QtWidgets/QHeaderView.ts index 48a6c99d3..3f8131688 100644 --- a/src/lib/QtWidgets/QHeaderView.ts +++ b/src/lib/QtWidgets/QHeaderView.ts @@ -205,9 +205,8 @@ export abstract class NodeHeaderView extends } export class QHeaderView extends NodeHeaderView { - native: NativeElement; constructor(orientationOrNative: Orientation | NativeElement, parent: NodeWidget | null = null) { - let native; + let native: NativeElement; if (checkIfNativeElement(orientationOrNative)) { native = orientationOrNative as NativeElement; } else { @@ -218,7 +217,6 @@ export class QHeaderView extends NodeHeaderView { } } super(native); - this.native = native; parent && this.setNodeParent(parent); } } diff --git a/src/lib/QtWidgets/QInputDialog.ts b/src/lib/QtWidgets/QInputDialog.ts index 43e623818..dc8207d30 100644 --- a/src/lib/QtWidgets/QInputDialog.ts +++ b/src/lib/QtWidgets/QInputDialog.ts @@ -1,11 +1,10 @@ import addon from '../utils/addon'; import { NodeWidget } from './QWidget'; -import { NativeElement } from '../core/Component'; import { NodeDialog, QDialogSignals } from './QDialog'; import { EchoMode } from './QLineEdit'; /** - + > Create and control input modal dialogs. * **This class is a JS wrapper around Qt's [QInputDialog class](https://doc.qt.io/qt-5/qinputdialog.html)** @@ -23,9 +22,6 @@ dialog.exec(); ``` */ export class QInputDialog extends NodeDialog { - native: NativeElement; - constructor(); - constructor(parent: NodeWidget); constructor(parent?: NodeWidget) { let native; if (parent) { @@ -34,7 +30,6 @@ export class QInputDialog extends NodeDialog { native = new addon.QInputDialog(); } super(native); - this.native = native; this.setNodeParent(parent); } setCancelButtonText(text: string): void { diff --git a/src/lib/QtWidgets/QLCDNumber.ts b/src/lib/QtWidgets/QLCDNumber.ts index 9e875dbb1..8e9d08a59 100644 --- a/src/lib/QtWidgets/QLCDNumber.ts +++ b/src/lib/QtWidgets/QLCDNumber.ts @@ -1,9 +1,8 @@ import addon from '../utils/addon'; import { NodeWidget, QWidgetSignals } from './QWidget'; -import { NativeElement } from '../core/Component'; /** - + > Create and control number. * **This class is a JS wrapper around Qt's [QLCDNumber class](https://doc.qt.io/qt-5/qlcdnumber.html)** @@ -21,9 +20,6 @@ const lcd = new QLCDNumber(); */ export class QLCDNumber extends NodeWidget { - native: NativeElement; - constructor(); - constructor(parent: NodeWidget); constructor(parent?: NodeWidget) { let native; if (parent) { @@ -32,7 +28,6 @@ export class QLCDNumber extends NodeWidget { native = new addon.QLCDNumber(); } super(native); - this.native = native; parent && this.setNodeParent(parent); } setDigitCount(numDigits: number): void { diff --git a/src/lib/QtWidgets/QLabel.ts b/src/lib/QtWidgets/QLabel.ts index ed65bea94..c15337288 100644 --- a/src/lib/QtWidgets/QLabel.ts +++ b/src/lib/QtWidgets/QLabel.ts @@ -1,7 +1,6 @@ import addon from '../utils/addon'; import { NodeWidget } from './QWidget'; import { NodeFrame, QFrameSignals } from './QFrame'; -import { NativeElement } from '../core/Component'; import { QPixmap } from '../QtGui/QPixmap'; import { QMovie } from '../QtGui/QMovie'; import { AlignmentFlag } from '../QtEnums/AlignmentFlag'; @@ -10,7 +9,7 @@ import { TextInteractionFlag } from '../QtEnums'; import { QPicture } from '../QtGui/QPicture'; /** - + > Create and control text. * **This class is a JS wrapper around Qt's [QLabel class](https://doc.qt.io/qt-5/qlabel.html)** @@ -28,13 +27,11 @@ label.setText("Hello"); */ export class QLabel extends NodeFrame { - native: NativeElement; private _picture?: QPicture; private _pixmap?: QPixmap; private _movie?: QMovie; private _buddy?: NodeWidget | null; - constructor(); - constructor(parent: NodeWidget); + constructor(parent?: NodeWidget) { let native; if (parent) { @@ -43,7 +40,6 @@ export class QLabel extends NodeFrame { native = new addon.QLabel(); } super(native); - this.native = native; this.setNodeParent(parent); } setAlignment(alignment: AlignmentFlag): void { diff --git a/src/lib/QtWidgets/QLayout.ts b/src/lib/QtWidgets/QLayout.ts index 018accb2e..734ffe13e 100644 --- a/src/lib/QtWidgets/QLayout.ts +++ b/src/lib/QtWidgets/QLayout.ts @@ -1,10 +1,10 @@ import { NodeWidget } from './QWidget'; -import { NodeObject, QObjectSignals } from '../QtCore/QObject'; +import { QObject, QObjectSignals } from '../QtCore/QObject'; // All Layouts should extend this abstract class. /** - + > Abstract class to add functionalities common to all Layout. **This class implements all methods, properties of Qt's [QLayout class](https://doc.qt.io/qt-5/qlayout.html) so that it can be inherited by all layouts** @@ -32,7 +32,7 @@ addChildToLayout(new FlexLayout(), new QPushButton()); addChildToLayout(new GridLayout(), new QWidget()); ``` */ -export abstract class NodeLayout extends NodeObject { +export abstract class NodeLayout extends QObject { type = 'layout'; abstract addWidget(childWidget: NodeWidget, ...args: any[]): void; abstract removeWidget(childWidget: NodeWidget): void; diff --git a/src/lib/QtWidgets/QLineEdit.ts b/src/lib/QtWidgets/QLineEdit.ts index 00e89d3c8..ec49056f6 100644 --- a/src/lib/QtWidgets/QLineEdit.ts +++ b/src/lib/QtWidgets/QLineEdit.ts @@ -1,6 +1,5 @@ import addon from '../utils/addon'; import { NodeWidget, QWidgetSignals } from './QWidget'; -import { NativeElement } from '../core/Component'; import { AlignmentFlag } from '../QtEnums/AlignmentFlag'; import { CursorMoveStyle } from '../QtEnums/CursorMoveStyle'; import { QPoint } from '../QtCore/QPoint'; @@ -23,9 +22,6 @@ const lineEdit = new QLineEdit(); */ export class QLineEdit extends NodeWidget { - native: NativeElement; - constructor(); - constructor(parent: NodeWidget); constructor(parent?: NodeWidget) { let native; if (parent) { @@ -34,7 +30,6 @@ export class QLineEdit extends NodeWidget { native = new addon.QLineEdit(); } super(native); - this.native = native; this.setNodeParent(parent); } // TODO: void addAction(QAction *action, QLineEdit::ActionPosition position) diff --git a/src/lib/QtWidgets/QListView.ts b/src/lib/QtWidgets/QListView.ts index c1a1bcb70..d0649d919 100644 --- a/src/lib/QtWidgets/QListView.ts +++ b/src/lib/QtWidgets/QListView.ts @@ -144,18 +144,16 @@ export enum ListViewMode { } export class QListView extends NodeListView { - native: NativeElement; constructor(); constructor(parent: NodeWidget); constructor(parent?: NodeWidget) { - let native; + let native: NativeElement; if (parent) { native = new addon.QListView(parent.native); } else { native = new addon.QListView(); } super(native); - this.native = native; parent && this.setNodeParent(parent); } } diff --git a/src/lib/QtWidgets/QListWidget.ts b/src/lib/QtWidgets/QListWidget.ts index d4fb1ca36..ed67a3015 100644 --- a/src/lib/QtWidgets/QListWidget.ts +++ b/src/lib/QtWidgets/QListWidget.ts @@ -33,10 +33,8 @@ for (let i = 0; i < 30; i++) { ``` */ export class QListWidget extends NodeListView { - native: NativeElement; items: Set; - constructor(); - constructor(parent: NodeWidget); + constructor(parent?: NodeWidget) { let native; if (parent) { @@ -45,7 +43,6 @@ export class QListWidget extends NodeListView { native = new addon.QListWidget(); } super(native); - this.native = native; parent && this.setNodeParent(parent); this.items = new Set(); } diff --git a/src/lib/QtWidgets/QListWidgetItem.ts b/src/lib/QtWidgets/QListWidgetItem.ts index b4be0fc2c..b9997b86d 100644 --- a/src/lib/QtWidgets/QListWidgetItem.ts +++ b/src/lib/QtWidgets/QListWidgetItem.ts @@ -10,7 +10,7 @@ import { CheckState } from '../QtEnums'; import { ItemFlag } from '../QtEnums/ItemFlag'; /** - + > Creates an item for QListWidget. * **This class is a JS wrapper around Qt's [QListWidgetItem class](https://doc.qt.io/qt-5/qlistwidgetitem.html)** @@ -35,11 +35,6 @@ for (let i = 0; i < 30; i++) { ``` */ export class QListWidgetItem extends Component { - native: NativeElement; - constructor(); - constructor(other: QListWidgetItem); - constructor(native: NativeElement); - constructor(text: string); constructor(arg?: QListWidgetItem | NativeElement | string) { let native; if (typeof arg === 'string') { @@ -49,8 +44,7 @@ export class QListWidgetItem extends Component { } else { native = new addon.QListWidgetItem(); } - super(); - this.native = native; + super(native); } setBackground(brush: QBrush): void { this.native.setBackground(brush.native); diff --git a/src/lib/QtWidgets/QMainWindow.ts b/src/lib/QtWidgets/QMainWindow.ts index fbbd974eb..c5e1734ff 100644 --- a/src/lib/QtWidgets/QMainWindow.ts +++ b/src/lib/QtWidgets/QMainWindow.ts @@ -1,12 +1,12 @@ import addon from '../utils/addon'; import { NodeWidget, QWidgetSignals } from './QWidget'; -import { NativeElement } from '../core/Component'; import { NodeLayout } from './QLayout'; import { QMenuBar } from './QMenuBar'; import { QStatusBar } from './QStatusBar'; +import { NativeElement } from '../core/Component'; /** - + > Create and control windows. * **This class is a JS wrapper around Qt's [QMainWindow class](https://doc.qt.io/qt-5/qmainwindow.html)** @@ -32,21 +32,20 @@ QMainWindow needs to have a central widget set before other widgets can be added Once a central widget is set you can add children/layout to the central widget. */ export class QMainWindow extends NodeWidget { - native: NativeElement; public centralWidget?: NodeWidget | null; private _menuBar?: QMenuBar; private _statusBar?: QStatusBar | null; + constructor(); constructor(parent: NodeWidget); constructor(parent?: NodeWidget) { - let native; + let native: NativeElement; if (parent) { native = new addon.QMainWindow(parent.native); } else { native = new addon.QMainWindow(); } super(native); - this.native = native; this.setNodeParent(parent); this.setLayout = (parentLayout: NodeLayout): void => { @@ -115,7 +114,7 @@ export class QMainWindow extends NodeWidget { * Returns the status bar for the main window. */ statusBar(): QStatusBar { - return this.native.statusBar(); + return new QStatusBar(this.native.statusBar()); } } diff --git a/src/lib/QtWidgets/QMenu.ts b/src/lib/QtWidgets/QMenu.ts index 14346496b..9211708eb 100644 --- a/src/lib/QtWidgets/QMenu.ts +++ b/src/lib/QtWidgets/QMenu.ts @@ -19,9 +19,6 @@ const menu = new QMenu(); ``` */ export class QMenu extends NodeWidget { - native: NativeElement; - constructor(); - constructor(parent: NodeWidget); constructor(parent?: NodeWidget) { let native; if (parent) { @@ -30,7 +27,6 @@ export class QMenu extends NodeWidget { native = new addon.QMenu(); } super(native); - this.native = native; this.setNodeParent(parent); } clear(): void { diff --git a/src/lib/QtWidgets/QMenuBar.ts b/src/lib/QtWidgets/QMenuBar.ts index 15f065865..b82305c57 100644 --- a/src/lib/QtWidgets/QMenuBar.ts +++ b/src/lib/QtWidgets/QMenuBar.ts @@ -6,7 +6,7 @@ import { checkIfNativeElement } from '../utils/helpers'; import { QAction } from './QAction'; /** - + > The QMenuBar class provides a menu widget for use in menu bars, context menus, and other popup menus. * **This class is a JS wrapper around Qt's [QMenuBar class](https://doc.qt.io/qt-5/qmenu.html)** @@ -24,11 +24,8 @@ global.win = win; ``` */ export class QMenuBar extends NodeWidget { - native: NativeElement; _menus: Set; - constructor(); - constructor(parent: NodeWidget); - constructor(native: NativeElement); + constructor(arg?: NodeWidget | NativeElement) { let native; let parent; @@ -41,7 +38,6 @@ export class QMenuBar extends NodeWidget { native = new addon.QMenuBar(); } super(native); - this.native = native; this._menus = new Set(); this.setNodeParent(parent); } diff --git a/src/lib/QtWidgets/QMessageBox.ts b/src/lib/QtWidgets/QMessageBox.ts index 3a2817c94..4fb4cc5ee 100644 --- a/src/lib/QtWidgets/QMessageBox.ts +++ b/src/lib/QtWidgets/QMessageBox.ts @@ -1,6 +1,6 @@ import addon from '../utils/addon'; import { NodeWidget } from './QWidget'; -import { NativeElement, NativeRawPointer } from '../core/Component'; +import { NativeRawPointer } from '../core/Component'; import { NodeDialog, QDialogSignals } from './QDialog'; import { QAbstractButton, QAbstractButtonSignals } from './QAbstractButton'; import { QPushButton } from './QPushButton'; @@ -19,7 +19,7 @@ export enum ButtonRole { } /** - + > Create and control classic modal dialogs. * **This class is a JS wrapper around Qt's [QMessageBox class](https://doc.qt.io/qt-5/qmessagebox.html)** @@ -40,9 +40,6 @@ messageBox.exec(); ``` */ export class QMessageBox extends NodeDialog { - native: NativeElement; - constructor(); - constructor(parent: NodeWidget); constructor(parent?: NodeWidget) { let native; if (parent) { @@ -51,7 +48,6 @@ export class QMessageBox extends NodeDialog { native = new addon.QMessageBox(); } super(native); - this.native = native; this.setNodeParent(parent); } accept(): void { diff --git a/src/lib/QtWidgets/QPainter.ts b/src/lib/QtWidgets/QPainter.ts index 481d250ac..97673b2f6 100644 --- a/src/lib/QtWidgets/QPainter.ts +++ b/src/lib/QtWidgets/QPainter.ts @@ -46,18 +46,14 @@ win.show(); https://github.com/nodegui/examples/blob/master/nodegui/custom-native-widget-qpainter */ export class QPainter extends Component { - native: NativeElement; - constructor(); - constructor(device: Component); constructor(device?: Component) { - let native; + let native: NativeElement; if (device) { native = new addon.QPainter(device.native); } else { native = new addon.QPainter(); } - super(); - this.native = native; + super(native); } // *** Public Functions *** diff --git a/src/lib/QtWidgets/QPainterPath.ts b/src/lib/QtWidgets/QPainterPath.ts index 358bd22cc..8b13bbd93 100644 --- a/src/lib/QtWidgets/QPainterPath.ts +++ b/src/lib/QtWidgets/QPainterPath.ts @@ -1,5 +1,5 @@ import addon from '../utils/addon'; -import { Component, NativeElement } from '../core/Component'; +import { Component } from '../core/Component'; import { SizeMode, FillRule } from '../QtEnums'; import { QFont } from '../QtGui/QFont'; @@ -12,11 +12,8 @@ import { QFont } from '../QtGui/QFont'; */ export class QPainterPath extends Component { - native: NativeElement; constructor() { - super(); - const native = new addon.QPainterPath(); - this.native = native; + super(new addon.QPainterPath()); } moveTo(x: number, y: number): void { diff --git a/src/lib/QtWidgets/QPlainTextEdit.ts b/src/lib/QtWidgets/QPlainTextEdit.ts index 2db011c96..dd024c846 100644 --- a/src/lib/QtWidgets/QPlainTextEdit.ts +++ b/src/lib/QtWidgets/QPlainTextEdit.ts @@ -32,19 +32,15 @@ const plainTextEdit = new QPlainTextEdit(); ``` */ export class QPlainTextEdit extends QAbstractScrollArea { - native: NativeElement; placeholderText?: string; - constructor(); - constructor(parent: NodeWidget); constructor(parent?: NodeWidget) { - let native; + let native: NativeElement; if (parent) { native = new addon.QPlainTextEdit(parent.native); } else { native = new addon.QPlainTextEdit(); } super(native); - this.native = native; this.setNodeParent(parent); } setPlainText(text: string | number): void { diff --git a/src/lib/QtWidgets/QProgressBar.ts b/src/lib/QtWidgets/QProgressBar.ts index bc82fc840..0f60d9b14 100644 --- a/src/lib/QtWidgets/QProgressBar.ts +++ b/src/lib/QtWidgets/QProgressBar.ts @@ -20,18 +20,14 @@ const progressBar = new QProgressBar(); ``` */ export class QProgressBar extends NodeWidget { - native: NativeElement; - constructor(); - constructor(parent: NodeWidget); constructor(parent?: NodeWidget) { - let native; + let native: NativeElement; if (parent) { native = new addon.QProgressBar(parent.native); } else { native = new addon.QProgressBar(); } super(native); - this.native = native; this.setNodeParent(parent); } setAlignment(alignment: AlignmentFlag): void { diff --git a/src/lib/QtWidgets/QProgressDialog.ts b/src/lib/QtWidgets/QProgressDialog.ts index fbd86fc6c..9fd608f49 100644 --- a/src/lib/QtWidgets/QProgressDialog.ts +++ b/src/lib/QtWidgets/QProgressDialog.ts @@ -1,10 +1,9 @@ import addon from '../utils/addon'; import { NodeWidget } from './QWidget'; -import { NativeElement } from '../core/Component'; import { NodeDialog, QDialogSignals } from './QDialog'; /** - + > Create and control progress dialogs. * **This class is a JS wrapper around Qt's [QProgressDialog class](https://doc.qt.io/qt-5/qprogressdialog.html)** @@ -21,9 +20,6 @@ const progressDialog = new QProgressDialog(); ``` */ export class QProgressDialog extends NodeDialog { - native: NativeElement; - constructor(); - constructor(parent: NodeWidget); constructor(parent?: NodeWidget) { let native; if (parent) { @@ -32,7 +28,6 @@ export class QProgressDialog extends NodeDialog { native = new addon.QProgressDialog(); } super(native); - this.native = native; parent && this.setNodeParent(parent); } setAutoClose(close: boolean): void { diff --git a/src/lib/QtWidgets/QPushButton.ts b/src/lib/QtWidgets/QPushButton.ts index 67131110f..8c591e030 100644 --- a/src/lib/QtWidgets/QPushButton.ts +++ b/src/lib/QtWidgets/QPushButton.ts @@ -6,7 +6,7 @@ import { checkIfNativeElement, checkIfNapiExternal } from '../utils/helpers'; import { QMenu } from './QMenu'; /** - + > Create and control buttons. * **This class is a JS wrapper around Qt's [QPushButton class](https://doc.qt.io/qt-5/qpushbutton.html)** @@ -23,12 +23,8 @@ button.setText("Hello"); ``` */ export class QPushButton extends QAbstractButton { - native: NativeElement; private _menu?: QMenu | null; - constructor(); - constructor(parent: NodeWidget); - constructor(native: NativeElement); - constructor(rawPointer: NativeRawPointer, disableNativeDeletion?: boolean); + constructor(arg?: NodeWidget | NativeRawPointer | NativeElement, disableNativeDeletion = true) { let native; let parent: Component | undefined; @@ -44,7 +40,6 @@ export class QPushButton extends QAbstractButton { native = new addon.QPushButton(); } super(native); - this.native = native; parent && this.setNodeParent(parent); } setAutoDefault(auto: boolean): void { diff --git a/src/lib/QtWidgets/QRadioButton.ts b/src/lib/QtWidgets/QRadioButton.ts index 1f7f332c0..6813c63ad 100644 --- a/src/lib/QtWidgets/QRadioButton.ts +++ b/src/lib/QtWidgets/QRadioButton.ts @@ -5,7 +5,7 @@ import { QAbstractButton, QAbstractButtonSignals } from './QAbstractButton'; import { checkIfNativeElement, checkIfNapiExternal } from '../utils/helpers'; /** - + > Create and control radio button. * **This class is a JS wrapper around Qt's [QRadioButton class](https://doc.qt.io/qt-5/qradiobutton.html)** @@ -23,10 +23,6 @@ radioButton.setText("Hello"); */ export class QRadioButton extends QAbstractButton { - native: NativeElement; - constructor(); - constructor(parent: NodeWidget); - constructor(rawPointer: NativeRawPointer, disableNativeDeletion?: boolean); constructor(arg?: NodeWidget | NativeRawPointer | NativeElement, disableNativeDeletion = true) { let native; let parent: Component | undefined; @@ -42,7 +38,6 @@ export class QRadioButton extends QAbstractButton { native = new addon.QRadioButton(); } super(native); - this.native = native; parent && this.setNodeParent(parent); } } diff --git a/src/lib/QtWidgets/QScrollArea.ts b/src/lib/QtWidgets/QScrollArea.ts index bdd4fbb5c..e91d2fdf7 100644 --- a/src/lib/QtWidgets/QScrollArea.ts +++ b/src/lib/QtWidgets/QScrollArea.ts @@ -29,19 +29,15 @@ scrollArea.setWidget(imageLabel); ``` */ export class QScrollArea extends QAbstractScrollArea { - native: NativeElement; contentWidget?: NodeWidget | null; - constructor(); - constructor(parent: NodeWidget); constructor(parent?: NodeWidget) { - let native; + let native: NativeElement; if (parent) { native = new addon.QScrollArea(parent.native); } else { native = new addon.QScrollArea(); } super(native); - this.native = native; this.setNodeParent(parent); } setAlignment(alignment: AlignmentFlag): void { diff --git a/src/lib/QtWidgets/QScrollBar.ts b/src/lib/QtWidgets/QScrollBar.ts index b06fa38e9..d8b150503 100644 --- a/src/lib/QtWidgets/QScrollBar.ts +++ b/src/lib/QtWidgets/QScrollBar.ts @@ -4,7 +4,7 @@ import { NativeElement } from '../core/Component'; import { QAbstractSlider, QAbstractSliderSignals } from './QAbstractSlider'; /** - + > Create and control scollbar widgets. * **This class is a JS wrapper around Qt's [QScrollBar class](https://doc.qt.io/qt-5/qscrollbar.html)** @@ -20,18 +20,14 @@ const scrollbar = new QScrollBar(); ``` */ export class QScrollBar extends QAbstractSlider { - native: NativeElement; - constructor(); - constructor(parent: NodeWidget); constructor(parent?: NodeWidget) { - let native; + let native: NativeElement; if (parent) { native = new addon.QScrollBar(parent.native); } else { native = new addon.QScrollBar(); } super(native); - this.native = native; this.setNodeParent(parent); } } diff --git a/src/lib/QtWidgets/QShortcut.ts b/src/lib/QtWidgets/QShortcut.ts index 6e2ddbc4b..32e306ab0 100644 --- a/src/lib/QtWidgets/QShortcut.ts +++ b/src/lib/QtWidgets/QShortcut.ts @@ -1,9 +1,8 @@ import addon from '../utils/addon'; import { NodeWidget } from './QWidget'; -import { NativeElement } from '../core/Component'; import { QKeySequence } from '../QtGui/QKeySequence'; import { ShortcutContext } from '../QtEnums'; -import { NodeObject, QObjectSignals } from '../QtCore/QObject'; +import { QObject, QObjectSignals } from '../QtCore/QObject'; /** @@ -29,12 +28,9 @@ global.win = win; global.shortcut = shortcut; ``` */ -export class QShortcut extends NodeObject { - native: NativeElement; +export class QShortcut extends QObject { constructor(parent: NodeWidget) { - const native = new addon.QShortcut(parent.native); - super(native); - this.native = native; + super(new addon.QShortcut(parent.native)); } setEnabled(enabled: boolean): void { this.native.setEnabled(enabled); diff --git a/src/lib/QtWidgets/QSlider.ts b/src/lib/QtWidgets/QSlider.ts index f3fde92db..9b2667c62 100644 --- a/src/lib/QtWidgets/QSlider.ts +++ b/src/lib/QtWidgets/QSlider.ts @@ -1,10 +1,10 @@ import addon from '../utils/addon'; -import { NodeWidget } from './QWidget'; +import { QWidget } from './QWidget'; import { NativeElement } from '../core/Component'; import { QAbstractSlider, QAbstractSliderSignals } from './QAbstractSlider'; /** - + > Create and control slider widgets. * **This class is a JS wrapper around Qt's [QSlider class](https://doc.qt.io/qt-5/qslider.html)** @@ -20,18 +20,14 @@ const slider = new QSlider(); ``` */ export class QSlider extends QAbstractSlider { - native: NativeElement; - constructor(); - constructor(parent: NodeWidget); - constructor(parent?: NodeWidget) { - let native; + constructor(parent?: QWidget) { + let native: NativeElement; if (parent) { native = new addon.QSlider(parent.native); } else { native = new addon.QSlider(); } super(native); - this.native = native; this.setNodeParent(parent); } setTickInterval(ti: number): void { diff --git a/src/lib/QtWidgets/QSpinBox.ts b/src/lib/QtWidgets/QSpinBox.ts index 7cbaee719..87bb300ca 100644 --- a/src/lib/QtWidgets/QSpinBox.ts +++ b/src/lib/QtWidgets/QSpinBox.ts @@ -1,10 +1,9 @@ import addon from '../utils/addon'; import { NodeWidget } from './QWidget'; -import { NativeElement } from '../core/Component'; import { QAbstractSpinBox, QAbstractSpinBoxSignals, StepType } from './QAbstractSpinBox'; /** - + > Create and control spin box widgets. * **This class is a JS wrapper around Qt's [QSpinBox class](https://doc.qt.io/qt-5/qspinbox.html)** @@ -20,9 +19,6 @@ const spinBox = new QSpinBox(); ``` */ export class QSpinBox extends QAbstractSpinBox { - native: NativeElement; - constructor(); - constructor(parent: NodeWidget); constructor(parent?: NodeWidget) { let native; if (parent) { @@ -32,7 +28,6 @@ export class QSpinBox extends QAbstractSpinBox { } super(native); this.setNodeParent(parent); - this.native = native; } cleanText(): string { return this.property('cleanText').toString(); diff --git a/src/lib/QtWidgets/QSplitter.ts b/src/lib/QtWidgets/QSplitter.ts index 177706c6a..82dad87c2 100644 --- a/src/lib/QtWidgets/QSplitter.ts +++ b/src/lib/QtWidgets/QSplitter.ts @@ -35,18 +35,14 @@ splitterHorizontal.addWidget(right); */ export class QSplitter extends NodeFrame { - native: NativeElement; - constructor(); - constructor(parent: NodeWidget); constructor(parent?: NodeWidget) { - let native; + let native: NativeElement; if (parent) { native = new addon.QSplitter(parent.native); } else { native = new addon.QSplitter(); } super(native); - this.native = native; this.setNodeParent(parent); } addWidget(widget: NodeWidget): void { diff --git a/src/lib/QtWidgets/QStackedWidget.ts b/src/lib/QtWidgets/QStackedWidget.ts index 13e1d2f45..46da1a545 100644 --- a/src/lib/QtWidgets/QStackedWidget.ts +++ b/src/lib/QtWidgets/QStackedWidget.ts @@ -1,7 +1,6 @@ import addon from '../utils/addon'; import { NodeWidget } from './QWidget'; import { NodeFrame, QFrameSignals } from './QFrame'; -import { NativeElement } from '../core/Component'; /** @@ -45,9 +44,6 @@ win.show(); ``` */ export class QStackedWidget extends NodeFrame { - native: NativeElement; - constructor(); - constructor(parent: NodeWidget); constructor(parent?: NodeWidget) { let native; if (parent) { @@ -57,7 +53,6 @@ export class QStackedWidget extends NodeFrame { } super(native); this.setNodeParent(parent); - this.native = native; } // *** Public Function *** diff --git a/src/lib/QtWidgets/QStandardItem.ts b/src/lib/QtWidgets/QStandardItem.ts index bb9be5d81..c43fcf2be 100644 --- a/src/lib/QtWidgets/QStandardItem.ts +++ b/src/lib/QtWidgets/QStandardItem.ts @@ -5,21 +5,21 @@ import { ItemFlag } from '../QtEnums/ItemFlag'; import { CheckState } from '../QtEnums'; export class QStandardItem extends Component { - native: NativeElement; constructor(); constructor(parent: QStandardItem, text?: string); constructor(native: NativeElement); constructor(parent?: NativeElement | QStandardItem, text?: string) { - super(); + let native: NativeElement; if (checkIfNativeElement(parent)) { - this.native = parent as NativeElement; + native = parent as NativeElement; } else { if (text) { - this.native = new addon.QStandardItem(text); + native = new addon.QStandardItem(text); } else { - this.native = new addon.QStandardItem(); + native = new addon.QStandardItem(); } } + super(native); } setCheckState(state: CheckState): void { this.native.setCheckState(state); diff --git a/src/lib/QtWidgets/QStandardItemModel.ts b/src/lib/QtWidgets/QStandardItemModel.ts index b09db9406..27b000d80 100644 --- a/src/lib/QtWidgets/QStandardItemModel.ts +++ b/src/lib/QtWidgets/QStandardItemModel.ts @@ -1,17 +1,13 @@ import addon from '../utils/addon'; import { NodeWidget } from './QWidget'; -import { NativeElement } from '../core/Component'; -import { NodeObject, QObjectSignals } from '../QtCore/QObject'; +import { QObject, QObjectSignals } from '../QtCore/QObject'; import { QStandardItem } from './QStandardItem'; export interface QStandardItemModelSignals extends QObjectSignals { itemChanged: (item: QStandardItem) => void; } -export class QStandardItemModel extends NodeObject { - native: NativeElement; - constructor(); - constructor(parent: NodeWidget); +export class QStandardItemModel extends QObject { constructor(parent?: NodeWidget) { let native; if (parent) { @@ -20,7 +16,6 @@ export class QStandardItemModel extends NodeObject { native = new addon.QStandardItemModel(); } super(native); - this.native = native; parent && parent.nodeChildren.add(this); } item(row: number, column = 0): QStandardItem | void { diff --git a/src/lib/QtWidgets/QStatusBar.ts b/src/lib/QtWidgets/QStatusBar.ts index d3571b45a..be36eb713 100644 --- a/src/lib/QtWidgets/QStatusBar.ts +++ b/src/lib/QtWidgets/QStatusBar.ts @@ -7,7 +7,7 @@ export interface QStatusBarSignals extends QWidgetSignals { } /** - + > Create and control progress bar widgets. * **This class is a JS wrapper around Qt's [QStatusBar class](https://doc.qt.io/qt-5/qstatusbar.html)** @@ -23,11 +23,9 @@ const progressBar = new QStatusBar(); ``` */ export class QStatusBar extends NodeWidget { - native: NativeElement; permanentWidgets: Set; widgets: Set; - constructor(); - constructor(parent: NodeWidget); + constructor(parent?: NodeWidget) { let native; if (parent) { @@ -37,7 +35,6 @@ export class QStatusBar extends NodeWidget { } super(native); - this.native = native; this.setNodeParent(parent); this.permanentWidgets = new Set(); diff --git a/src/lib/QtWidgets/QSvgWidget.ts b/src/lib/QtWidgets/QSvgWidget.ts index 6ed0af1f3..acf5f258a 100644 --- a/src/lib/QtWidgets/QSvgWidget.ts +++ b/src/lib/QtWidgets/QSvgWidget.ts @@ -27,18 +27,16 @@ fs.readFile("icon.svg", (err, buffer) => { */ export class QSvgWidget extends NodeWidget { - native: NativeElement; constructor(); constructor(parent: NodeWidget); constructor(parent?: NodeWidget) { - let native; + let native: NativeElement; if (parent) { native = new addon.QSvgWidget(parent.native); } else { native = new addon.QSvgWidget(); } super(native); - this.native = native; parent && this.setNodeParent(parent); } load(file: string | Buffer): void { diff --git a/src/lib/QtWidgets/QSystemTrayIcon.ts b/src/lib/QtWidgets/QSystemTrayIcon.ts index 220027257..f9c5cf2ae 100644 --- a/src/lib/QtWidgets/QSystemTrayIcon.ts +++ b/src/lib/QtWidgets/QSystemTrayIcon.ts @@ -1,12 +1,11 @@ import addon from '../utils/addon'; import { NodeWidget } from './QWidget'; -import { NativeElement } from '../core/Component'; import { QIcon } from '../QtGui/QIcon'; import { QMenu } from './QMenu'; -import { NodeObject, QObjectSignals } from '../QtCore/QObject'; +import { QObject, QObjectSignals } from '../QtCore/QObject'; /** - + > Create and control system tray icon. * **This class is a JS wrapper around Qt's [QSystemTrayIcon class](https://doc.qt.io/qt-5/qsystemtrayicon.html)** @@ -28,11 +27,9 @@ tray.show(); global.tray = tray; // prevents garbage collection of tray ``` */ -export class QSystemTrayIcon extends NodeObject { - native: NativeElement; +export class QSystemTrayIcon extends QObject { contextMenu?: QMenu; - constructor(); - constructor(parent: NodeWidget); + constructor(parent?: NodeWidget) { let native; if (parent) { @@ -41,7 +38,6 @@ export class QSystemTrayIcon extends NodeObject { native = new addon.QSystemTrayIcon(); } super(native); - this.native = native; } show(): void { this.native.show(); diff --git a/src/lib/QtWidgets/QTabBar.ts b/src/lib/QtWidgets/QTabBar.ts index d6862175e..797e68c38 100644 --- a/src/lib/QtWidgets/QTabBar.ts +++ b/src/lib/QtWidgets/QTabBar.ts @@ -1,6 +1,5 @@ import addon from '../utils/addon'; import { NodeWidget, QWidgetSignals } from './QWidget'; -import { NativeElement } from '../core/Component'; import { QIcon } from '../QtGui/QIcon'; import { TextElideMode } from '../QtEnums'; import { QSize } from '../QtCore/QSize'; @@ -27,9 +26,6 @@ const tabBar = new QTabBar(); ``` */ export class QTabBar extends NodeWidget { - native: NativeElement; - constructor(); - constructor(parent: NodeWidget); constructor(parent?: NodeWidget) { let native; if (parent) { @@ -38,7 +34,6 @@ export class QTabBar extends NodeWidget { native = new addon.QTabBar(); } super(native); - this.native = native; parent && this.setNodeParent(parent); } setAutoHide(hide: boolean): void { diff --git a/src/lib/QtWidgets/QTabWidget.ts b/src/lib/QtWidgets/QTabWidget.ts index 2ddffe107..44ef10d1d 100644 --- a/src/lib/QtWidgets/QTabWidget.ts +++ b/src/lib/QtWidgets/QTabWidget.ts @@ -5,12 +5,12 @@ import { QIcon } from '../QtGui/QIcon'; import { TabPosition } from '../QtEnums'; /** - + > Create and control a stack of tabbed widgets. * **This class is a JS wrapper around Qt's [QTabWidget class](https://doc.qt.io/qt-5/qtabwidget.html)** -A 'QTabWidget' provides a tab bar and a "page area" that is used to display pages related to each tab. +A 'QTabWidget' provides a tab bar and a "page area" that is used to display pages related to each tab. ### Example @@ -25,12 +25,10 @@ tabWidget.addTab(new QCalendarWidget(), new QIcon(), 'Tab 2'); ``` */ export class QTabWidget extends NodeWidget { - native: NativeElement; tabs: NodeWidget[]; - constructor(); - constructor(parent: NodeWidget); + constructor(parent?: NodeWidget) { - let native; + let native: NativeElement; if (parent) { native = new addon.QTabWidget(parent.native); } else { @@ -39,7 +37,6 @@ export class QTabWidget extends NodeWidget { super(native); this.setNodeParent(parent); this.tabs = []; - this.native = native; } addTab(page: NodeWidget, icon: QIcon, label: string): number { diff --git a/src/lib/QtWidgets/QTableView.ts b/src/lib/QtWidgets/QTableView.ts index d629903c1..8f80d4da4 100644 --- a/src/lib/QtWidgets/QTableView.ts +++ b/src/lib/QtWidgets/QTableView.ts @@ -1,6 +1,5 @@ import addon from '../utils/addon'; import { NodeWidget } from './QWidget'; -import { NativeElement } from '../core/Component'; import { SortOrder, PenStyle } from '../QtEnums'; import { QAbstractItemView, QAbstractItemViewSignals } from './QAbstractItemView'; import { QHeaderView } from './QHeaderView'; @@ -179,9 +178,6 @@ export abstract class NodeTableView extends Q } export class QTableView extends NodeTableView { - native: NativeElement; - constructor(); - constructor(parent: NodeWidget); constructor(parent?: NodeWidget) { let native; if (parent) { @@ -190,7 +186,6 @@ export class QTableView extends NodeTableView { native = new addon.QTableView(); } super(native); - this.native = native; parent && this.setNodeParent(parent); } } diff --git a/src/lib/QtWidgets/QTableWidget.ts b/src/lib/QtWidgets/QTableWidget.ts index b6ff25d0f..546cbac9f 100644 --- a/src/lib/QtWidgets/QTableWidget.ts +++ b/src/lib/QtWidgets/QTableWidget.ts @@ -38,7 +38,6 @@ win.show(); ``` */ export class QTableWidget extends QAbstractScrollArea { - native: NativeElement; items: Set; constructor(rows: number, columns: number, parent?: NodeWidget) { let native; @@ -48,7 +47,6 @@ export class QTableWidget extends QAbstractScrollArea { native = new addon.QTableWidget(rows, columns); } super(native); - this.native = native; this.setNodeParent(parent); this.items = new Set(); } diff --git a/src/lib/QtWidgets/QTableWidgetItem.ts b/src/lib/QtWidgets/QTableWidgetItem.ts index 910a4b31a..79137ae49 100644 --- a/src/lib/QtWidgets/QTableWidgetItem.ts +++ b/src/lib/QtWidgets/QTableWidgetItem.ts @@ -41,13 +41,12 @@ win.show(); */ export class QTableWidgetItem extends Component { - native: NativeElement; constructor(); constructor(other: QTableWidgetItem); constructor(native: NativeElement); constructor(text: string); constructor(arg?: QTableWidgetItem | NativeElement | string) { - let native; + let native: NativeElement; if (typeof arg === 'string') { native = new addon.QTableWidgetItem(arg); } else if (checkIfNativeElement(arg)) { @@ -55,8 +54,7 @@ export class QTableWidgetItem extends Component { } else { native = new addon.QTableWidgetItem(); } - super(); - this.native = native; + super(native); } setBackground(brush: QBrush): void { this.native.setBackground(brush.native); diff --git a/src/lib/QtWidgets/QTextBrowser.ts b/src/lib/QtWidgets/QTextBrowser.ts index 35a10ae3e..906156c24 100644 --- a/src/lib/QtWidgets/QTextBrowser.ts +++ b/src/lib/QtWidgets/QTextBrowser.ts @@ -22,18 +22,16 @@ const textBrowser = new QTextBrowser(); */ export class QTextBrowser extends NodeTextEdit { - native: NativeElement; constructor(); constructor(parent: NodeWidget); constructor(parent?: NodeWidget) { - let native; + let native: NativeElement; if (parent) { native = new addon.QTextBrowser(parent.native); } else { native = new addon.QTextBrowser(); } super(native); - this.native = native; parent && this.setNodeParent(parent); } setOpenExternalLinks(open: boolean): void { diff --git a/src/lib/QtWidgets/QTextEdit.ts b/src/lib/QtWidgets/QTextEdit.ts index e014bdb51..f7e9d2a20 100644 --- a/src/lib/QtWidgets/QTextEdit.ts +++ b/src/lib/QtWidgets/QTextEdit.ts @@ -1,13 +1,12 @@ import addon from '../utils/addon'; import { NodeWidget } from './QWidget'; -import { NativeElement } from '../core/Component'; import { QAbstractScrollArea, QAbstractScrollAreaSignals } from './QAbstractScrollArea'; import { AlignmentFlag, TextInteractionFlag } from '../QtEnums'; import { QFont } from '../QtGui/QFont'; import { QColor } from '../QtGui/QColor'; /** - + > Create and control editable text field. * **This class is a JS wrapper around Qt's [QTextEdit class](https://doc.qt.io/qt-5/qtextedit.html)** @@ -240,9 +239,6 @@ export enum WrapMode { } export class QTextEdit extends NodeTextEdit { - native: NativeElement; - constructor(); - constructor(parent: NodeWidget); constructor(parent?: NodeWidget) { let native; if (parent) { @@ -251,7 +247,6 @@ export class QTextEdit extends NodeTextEdit { native = new addon.QTextEdit(); } super(native); - this.native = native; parent && this.setNodeParent(parent); } } diff --git a/src/lib/QtWidgets/QTimeEdit.ts b/src/lib/QtWidgets/QTimeEdit.ts index 18d3c97a9..7b38d39d3 100644 --- a/src/lib/QtWidgets/QTimeEdit.ts +++ b/src/lib/QtWidgets/QTimeEdit.ts @@ -1,10 +1,9 @@ import addon from '../utils/addon'; import { NodeWidget } from './QWidget'; -import { NativeElement } from '../core/Component'; import { NodeDateTimeEdit } from './QDateTimeEdit'; /** - + > Creates a widget to edit dates with spin box layout. WIP! * **This class is a JS wrapper around Qt's [QTimeEdit class](https://doc.qt.io/qt-5/qtimeedit.html)** @@ -21,9 +20,6 @@ const timeEdit = new QTimeEdit(); ``` */ export class QTimeEdit extends NodeDateTimeEdit { - native: NativeElement; - constructor(); - constructor(parent: NodeWidget); constructor(parent?: NodeWidget) { let native; if (parent) { @@ -32,7 +28,6 @@ export class QTimeEdit extends NodeDateTimeEdit { native = new addon.QTimeEdit(); } super(native); - this.native = native; this.setNodeParent(parent); } } diff --git a/src/lib/QtWidgets/QToolButton.ts b/src/lib/QtWidgets/QToolButton.ts index 629f76fcd..3a8cf9729 100644 --- a/src/lib/QtWidgets/QToolButton.ts +++ b/src/lib/QtWidgets/QToolButton.ts @@ -9,7 +9,7 @@ import { QMenu } from './QMenu'; import { checkIfNativeElement, checkIfNapiExternal } from '../utils/helpers'; /** - + > Create and control buttons to use inside a QToolBar. * **This class is a JS wrapper around Qt's [QToolButton class](https://doc.qt.io/qt-5/qtoolbutton.html)** @@ -26,12 +26,9 @@ tool.setText('Help'); ``` */ export class QToolButton extends QAbstractButton { - native: NativeElement; private _defaultAction?: QAction | null; private _menu?: QMenu | null; - constructor(); - constructor(parent: NodeWidget); - constructor(rawPointer: NativeRawPointer, disableNativeDeletion?: boolean); + constructor(arg?: NodeWidget | NativeRawPointer | NativeElement, disableNativeDeletion = true) { let native; let parent: Component | undefined; @@ -47,7 +44,6 @@ export class QToolButton extends QAbstractButton { native = new addon.QToolButton(); } super(native); - this.native = native; parent && this.setNodeParent(parent); } setArrowType(type: ArrowType): void { diff --git a/src/lib/QtWidgets/QTreeWidget.ts b/src/lib/QtWidgets/QTreeWidget.ts index 4eb5e5d5a..1e60d70eb 100644 --- a/src/lib/QtWidgets/QTreeWidget.ts +++ b/src/lib/QtWidgets/QTreeWidget.ts @@ -6,8 +6,8 @@ import { QTreeWidgetItem } from './QTreeWidgetItem'; import { MatchFlag } from '../..'; /** - -> Creates a tree view that uses a predefined tree model. + +> Creates a tree view that uses a predefined tree model. * **This class is a JS wrapper around Qt's [QTreeWidget class](https://doc.qt.io/qt-5/qtreewidget.html)** @@ -49,11 +49,9 @@ win.show(); (global as any).win = win;``` */ export class QTreeWidget extends QAbstractScrollArea { - native: NativeElement; topLevelItems: Set; itemWidgets: Map; - constructor(); - constructor(parent: NodeWidget); + constructor(parent?: NodeWidget) { let native; if (parent) { @@ -62,7 +60,6 @@ export class QTreeWidget extends QAbstractScrollArea { native = new addon.QTreeWidget(); } super(native); - this.native = native; this.setNodeParent(parent); this.topLevelItems = new Set(); this.itemWidgets = new Map(); diff --git a/src/lib/QtWidgets/QTreeWidgetItem.ts b/src/lib/QtWidgets/QTreeWidgetItem.ts index a654951bd..c8e931c28 100644 --- a/src/lib/QtWidgets/QTreeWidgetItem.ts +++ b/src/lib/QtWidgets/QTreeWidgetItem.ts @@ -46,7 +46,6 @@ win.show(); ``` */ export class QTreeWidgetItem extends Component { - native: NativeElement; items: Set; constructor(); constructor(parent: QTreeWidgetItem, strings?: string[]); @@ -54,26 +53,31 @@ export class QTreeWidgetItem extends Component { constructor(native: NativeElement); constructor(strings: string[]); constructor(parent?: NativeElement | QTreeWidgetItem | QTreeWidget | string[], strings?: string[]) { - super(); - this.items = new Set(); + let native: NativeElement; + let parentTreeWidgetItem: QTreeWidgetItem | QTreeWidget = null; if (checkIfNativeElement(parent)) { - this.native = parent as NativeElement; + native = parent as NativeElement; } else { if (parent instanceof QTreeWidgetItem || parent instanceof QTreeWidget) { - this.setNodeParent(parent); const type = parent instanceof QTreeWidgetItem ? 'item' : 'tree'; + parentTreeWidgetItem = parent; if (strings) { - this.native = new addon.QTreeWidgetItem(parent.native, strings, type); + native = new addon.QTreeWidgetItem(parent.native, strings, type); } else { - this.native = new addon.QTreeWidgetItem(parent.native, type); + native = new addon.QTreeWidgetItem(parent.native, type); } } else if (Array.isArray(parent)) { const strings = parent; - this.native = new addon.QTreeWidgetItem(strings); + native = new addon.QTreeWidgetItem(strings); } else { - this.native = new addon.QTreeWidgetItem(); + native = new addon.QTreeWidgetItem(); } } + super(native); + this.items = new Set(); + if (parentTreeWidgetItem != null) { + this.setNodeParent(parentTreeWidgetItem); + } } setText(column: number, text: string): void { this.native.setText(column, text); diff --git a/src/lib/QtWidgets/QWidget.ts b/src/lib/QtWidgets/QWidget.ts index dc8126459..99f776552 100644 --- a/src/lib/QtWidgets/QWidget.ts +++ b/src/lib/QtWidgets/QWidget.ts @@ -679,7 +679,6 @@ view.setLayout(new FlexLayout()); ``` */ export class QWidget extends NodeWidget { - native: NativeElement; constructor(arg?: NodeWidget | NativeElement) { let native; let parent; @@ -693,6 +692,5 @@ export class QWidget extends NodeWidget { } super(native); this.setNodeParent(parent); - this.native = native; } } diff --git a/src/lib/core/Component.ts b/src/lib/core/Component.ts index d1ed5e52a..d5dbe5407 100644 --- a/src/lib/core/Component.ts +++ b/src/lib/core/Component.ts @@ -7,10 +7,10 @@ export type NativeRawPointer = Record; > Abstract class that is root most base class for all widgets and layouts in the NodeGui World. **This class is used to add core properties to all widgets, layouts etc in NodeGui world. - Currently it helps us maintain references to the native C++ instance of the widget or layout. + Currently it helps us maintain references to the native C++ instance of the widget or layout. It also helps in preventing gc of child elements of a layout or widget** -`Component` is an abstract class and hence no instances of the same should be created. +`Component` is an abstract class and hence no instances of the same should be created. It exists so that we can add core functionalities to all widgets and layouts easily. This is an internal class. Its the root base class in NodeGui world. @@ -20,12 +20,15 @@ Its the root base class in NodeGui world. export abstract class Component { nodeChildren: Set; nodeParent?: Component; - constructor() { + + native: NativeElement | null; + + constructor(native: NativeElement) { + this.native = native; this.nodeChildren = new Set(); } setNodeParent(parent?: Component): void { this.nodeParent = parent; parent?.nodeChildren.add(this); } - abstract native: NativeElement; } diff --git a/src/lib/core/EventWidget.ts b/src/lib/core/EventWidget.ts index b41950104..583a5e5aa 100644 --- a/src/lib/core/EventWidget.ts +++ b/src/lib/core/EventWidget.ts @@ -36,8 +36,9 @@ view.addEventListener(WidgetEventTypes.MouseMove, () => { export abstract class EventWidget extends Component { private emitter: EventEmitter; private _isEventProcessed = false; + constructor(native: NativeElement) { - super(); + super(native); if (native.initNodeEventEmitter == null) { throw new Error('initNodeEventEmitter not implemented on native side'); } diff --git a/src/lib/core/FlexLayout.ts b/src/lib/core/FlexLayout.ts index 6ed19989b..580221a99 100644 --- a/src/lib/core/FlexLayout.ts +++ b/src/lib/core/FlexLayout.ts @@ -2,12 +2,11 @@ import addon from '../utils/addon'; import { NodeWidget } from '../QtWidgets/QWidget'; import { NodeLayout, QLayoutSignals } from '../QtWidgets/QLayout'; import { FlexNode } from './YogaWidget'; -import { NativeElement } from './Component'; export type FlexLayoutSignals = QLayoutSignals; /** - + > Custom layout to help layout child widgets using flex layout. * **This class is a JS wrapper around custom Qt layout implemented using [Yoga](https://github.com/facebook/yoga)** @@ -33,11 +32,8 @@ layout.addWidget(label2); ``` */ export class FlexLayout extends NodeLayout { - native: NativeElement; protected flexNode?: FlexNode; - constructor(); - constructor(parent: NodeWidget); constructor(parent?: NodeWidget) { let native; if (parent) { @@ -46,7 +42,6 @@ export class FlexLayout extends NodeLayout { native = new addon.FlexLayout(); } super(native); - this.native = native; if (parent) { this.setFlexNode(parent.getFlexNode()); } diff --git a/src/lib/core/YogaWidget.ts b/src/lib/core/YogaWidget.ts index c3cb0fad2..f3123c160 100644 --- a/src/lib/core/YogaWidget.ts +++ b/src/lib/core/YogaWidget.ts @@ -1,10 +1,10 @@ -import { NodeObject, QObjectSignals } from '../QtCore/QObject'; +import { QObject, QObjectSignals } from '../QtCore/QObject'; import { NativeRawPointer } from './Component'; export type FlexNode = NativeRawPointer<'YGNodeRef'>; /** - + > Abstract class to add common functionality related to Flex layout to all Widgets. **This class implements methods related to flex layout required to be present in all widgets** @@ -22,7 +22,7 @@ const flexNode = view.getFlexNode(); YogaWidget helps in storing all flex properties of a widget. */ -export abstract class YogaWidget extends NodeObject { +export abstract class YogaWidget extends QObject { getFlexNode(): FlexNode { return this.native.getFlexNode(); } diff --git a/src/lib/core/__test__/CacheTestQObject.ts b/src/lib/core/__test__/CacheTestQObject.ts index 79e42305a..b3235bfa8 100644 --- a/src/lib/core/__test__/CacheTestQObject.ts +++ b/src/lib/core/__test__/CacheTestQObject.ts @@ -1,10 +1,9 @@ import addon from '../../utils/addon'; import { NativeElement } from '../Component'; -import { NodeObject, QObjectSignals } from '../../QtCore/QObject'; +import { QObject, QObjectSignals } from '../../QtCore/QObject'; import { wrapperCache } from '../../core/WrapperCache'; -export class CacheTestQObject extends NodeObject { - native: NativeElement; +export class CacheTestQObject extends QObject { constructor(arg?: NativeElement) { let native; if (native == null) { diff --git a/tsconfig.json b/tsconfig.json index 5d65b5e7a..dd79bd9a2 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,6 +6,7 @@ "sourceMap": false, "outDir": "./dist", "strict": true, + "strictNullChecks": false, "moduleResolution": "node", "esModuleInterop": true, "resolveJsonModule": true diff --git a/website/docs/development/signal_and_event_handling.md b/website/docs/development/signal_and_event_handling.md index 93fe8e4ba..2cca815a9 100644 --- a/website/docs/development/signal_and_event_handling.md +++ b/website/docs/development/signal_and_event_handling.md @@ -64,9 +64,8 @@ export const QPushButtonEvents = Object.freeze({ }); export class QPushButton extends NodeWidget { - native: NativeElement; constructor(parent?: NodeWidget) { - let native; + let native: NativeElement; if (parent) { native = new addon.QPushButton(parent.native); } else { @@ -74,7 +73,6 @@ export class QPushButton extends NodeWidget { } super(native); this.parent = parent; - this.native = native; } setText(text: string | number) { From 38b12759c68d5c8f1598c0c7d63b8ce568d97820 Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Fri, 29 Apr 2022 19:36:46 +0200 Subject: [PATCH 04/28] Remove `NodeWidget`, just use `QWidget` --- src/index.ts | 2 +- src/lib/QtGui/QStyle.ts | 6 +- src/lib/QtWidgets/QAbstractButton.ts | 6 +- src/lib/QtWidgets/QAbstractScrollArea.ts | 6 +- src/lib/QtWidgets/QAbstractSlider.ts | 6 +- src/lib/QtWidgets/QAbstractSpinBox.ts | 6 +- src/lib/QtWidgets/QAction.ts | 6 +- src/lib/QtWidgets/QBoxLayout.ts | 12 ++-- src/lib/QtWidgets/QButtonGroup.ts | 6 +- src/lib/QtWidgets/QCalendarWidget.ts | 8 +-- src/lib/QtWidgets/QCheckBox.ts | 10 +-- src/lib/QtWidgets/QColorDialog.ts | 6 +- src/lib/QtWidgets/QComboBox.ts | 8 +-- src/lib/QtWidgets/QDateEdit.ts | 8 +-- src/lib/QtWidgets/QDateTimeEdit.ts | 8 +-- src/lib/QtWidgets/QDial.ts | 8 +-- src/lib/QtWidgets/QDialog.ts | 6 +- src/lib/QtWidgets/QDoubleSpinBox.ts | 8 +-- src/lib/QtWidgets/QErrorMessage.ts | 8 +-- src/lib/QtWidgets/QFileDialog.ts | 6 +- src/lib/QtWidgets/QFontDialog.ts | 8 +-- src/lib/QtWidgets/QFrame.ts | 10 +-- src/lib/QtWidgets/QGridLayout.ts | 10 ++- src/lib/QtWidgets/QGroupBox.ts | 10 ++- src/lib/QtWidgets/QHeaderView.ts | 4 +- src/lib/QtWidgets/QInputDialog.ts | 4 +- src/lib/QtWidgets/QLCDNumber.ts | 6 +- src/lib/QtWidgets/QLabel.ts | 10 +-- src/lib/QtWidgets/QLayout.ts | 9 ++- src/lib/QtWidgets/QLineEdit.ts | 6 +- src/lib/QtWidgets/QListView.ts | 8 +-- src/lib/QtWidgets/QListWidget.ts | 6 +- src/lib/QtWidgets/QMainWindow.ts | 16 ++--- src/lib/QtWidgets/QMenu.ts | 6 +- src/lib/QtWidgets/QMenuBar.ts | 8 +-- src/lib/QtWidgets/QMessageBox.ts | 8 +-- src/lib/QtWidgets/QPlainTextEdit.ts | 6 +- src/lib/QtWidgets/QProgressBar.ts | 8 +-- src/lib/QtWidgets/QProgressDialog.ts | 4 +- src/lib/QtWidgets/QPushButton.ts | 6 +- src/lib/QtWidgets/QRadioButton.ts | 6 +- src/lib/QtWidgets/QScrollArea.ts | 14 ++-- src/lib/QtWidgets/QScrollBar.ts | 4 +- src/lib/QtWidgets/QShortcut.ts | 6 +- src/lib/QtWidgets/QSpinBox.ts | 4 +- src/lib/QtWidgets/QSplitter.ts | 10 +-- src/lib/QtWidgets/QStackedWidget.ts | 10 +-- src/lib/QtWidgets/QStandardItemModel.ts | 4 +- src/lib/QtWidgets/QStatusBar.ts | 6 +- src/lib/QtWidgets/QSvgWidget.ts | 10 ++- src/lib/QtWidgets/QSystemTrayIcon.ts | 4 +- src/lib/QtWidgets/QTabBar.ts | 8 +-- src/lib/QtWidgets/QTabWidget.ts | 14 ++-- src/lib/QtWidgets/QTableView.ts | 4 +- src/lib/QtWidgets/QTableWidget.ts | 6 +- src/lib/QtWidgets/QTextBrowser.ts | 8 +-- src/lib/QtWidgets/QTextEdit.ts | 4 +- src/lib/QtWidgets/QTimeEdit.ts | 4 +- src/lib/QtWidgets/QToolButton.ts | 6 +- src/lib/QtWidgets/QTreeWidget.ts | 4 +- src/lib/QtWidgets/QWidget.ts | 89 ++++++++---------------- src/lib/core/FlexLayout.ts | 18 ++--- src/lib/core/Style/StyleSheet.ts | 4 +- 63 files changed, 237 insertions(+), 303 deletions(-) diff --git a/src/index.ts b/src/index.ts index 135722327..0e989d741 100644 --- a/src/index.ts +++ b/src/index.ts @@ -39,7 +39,7 @@ export { QScreen } from './lib/QtGui/QScreen'; export { QWindow } from './lib/QtGui/QWindow'; export { WidgetEventTypes } from './lib/core/EventWidget'; // Abstract: -export { NodeWidget, QWidget, QWidgetSignals } from './lib/QtWidgets/QWidget'; +export { QWidget, QWidgetSignals } from './lib/QtWidgets/QWidget'; export { NodeLayout, QLayoutSignals, SizeConstraint } from './lib/QtWidgets/QLayout'; export { QAbstractScrollArea } from './lib/QtWidgets/QAbstractScrollArea'; export { QAbstractSlider, QAbstractSliderSignals, SliderAction } from './lib/QtWidgets/QAbstractSlider'; diff --git a/src/lib/QtGui/QStyle.ts b/src/lib/QtGui/QStyle.ts index 363d94940..df5080cd9 100644 --- a/src/lib/QtGui/QStyle.ts +++ b/src/lib/QtGui/QStyle.ts @@ -1,4 +1,4 @@ -import { NodeWidget } from '../..'; +import { QWidget } from '../..'; import { Component, NativeElement } from '../core/Component'; import { checkIfNativeElement } from '../utils/helpers'; @@ -13,10 +13,10 @@ export class QStyle extends Component { pixelMetric(metric: QStylePixelMetric): number { return this.native.pixelMetric(metric); } - polish(widget: NodeWidget): void { + polish(widget: QWidget): void { this.native.polish(widget.native); } - unpolish(widget: NodeWidget): void { + unpolish(widget: QWidget): void { this.native.unpolish(widget.native); } } diff --git a/src/lib/QtWidgets/QAbstractButton.ts b/src/lib/QtWidgets/QAbstractButton.ts index b2e61b295..f62b11e8a 100644 --- a/src/lib/QtWidgets/QAbstractButton.ts +++ b/src/lib/QtWidgets/QAbstractButton.ts @@ -1,10 +1,10 @@ -import { NodeWidget, QWidgetSignals } from './QWidget'; +import { QWidget, QWidgetSignals } from './QWidget'; import { QIcon } from '../QtGui/QIcon'; import { QSize } from '../QtCore/QSize'; import { QKeySequence } from '../QtGui/QKeySequence'; /** - + > This is the abstract base class of button widgets, providing their functionality. * **This class is a JS wrapper around Qt's [QAbstractButton class](https://doc.qt.io/qt-5/qabstractbutton.html)** @@ -13,7 +13,7 @@ The QAbstractButton class is an abstract class and therefore, technically, no fu It is inherited by QCheckBox, QPushButton, QRadioButton, and QToolButton. */ -export abstract class QAbstractButton extends NodeWidget { +export abstract class QAbstractButton extends QWidget { animateClick(msec: number): void { this.native.animateClick(msec); } diff --git a/src/lib/QtWidgets/QAbstractScrollArea.ts b/src/lib/QtWidgets/QAbstractScrollArea.ts index cff280855..e1a02471a 100644 --- a/src/lib/QtWidgets/QAbstractScrollArea.ts +++ b/src/lib/QtWidgets/QAbstractScrollArea.ts @@ -1,4 +1,4 @@ -import { NodeWidget, QWidget } from './QWidget'; +import { QWidget } from './QWidget'; import { NodeFrame, QFrameSignals } from './QFrame'; import { ScrollBarPolicy } from '../QtEnums/ScrollBarPolicy'; import { QSize } from '../QtCore/QSize'; @@ -18,8 +18,8 @@ QAbstractScrollArea will list all methods and properties that are common to all */ export abstract class QAbstractScrollArea extends NodeFrame { - viewportWidget?: NodeWidget; - setViewport(widget: NodeWidget): void { + viewportWidget?: QWidget; + setViewport(widget: QWidget): void { this.viewportWidget = widget; this.native.setViewport(widget.native); } diff --git a/src/lib/QtWidgets/QAbstractSlider.ts b/src/lib/QtWidgets/QAbstractSlider.ts index 17a89f19a..be8521482 100644 --- a/src/lib/QtWidgets/QAbstractSlider.ts +++ b/src/lib/QtWidgets/QAbstractSlider.ts @@ -1,8 +1,8 @@ -import { NodeWidget, QWidgetSignals } from './QWidget'; +import { QWidget, QWidgetSignals } from './QWidget'; import { Orientation } from '../QtEnums'; /** - + > Abstract class to add functionalities common to all slider based widgets. **This class implements all methods, properties of Qt's [QAbstractSlider class](https://doc.qt.io/qt-5/qabstractslider.html) so that it can be inherited by all slider based widgets** @@ -14,7 +14,7 @@ import { Orientation } from '../QtEnums'; QAbstractSlider will list all methods and properties that are common to all slider widgets in the NodeGui world. */ -export abstract class QAbstractSlider extends NodeWidget { +export abstract class QAbstractSlider extends QWidget { triggerAction(action: SliderAction): void { this.native.triggerAction(action); } diff --git a/src/lib/QtWidgets/QAbstractSpinBox.ts b/src/lib/QtWidgets/QAbstractSpinBox.ts index fdbd7fb40..6433c9ff9 100644 --- a/src/lib/QtWidgets/QAbstractSpinBox.ts +++ b/src/lib/QtWidgets/QAbstractSpinBox.ts @@ -1,8 +1,8 @@ -import { NodeWidget, QWidgetSignals } from './QWidget'; +import { QWidget, QWidgetSignals } from './QWidget'; import { AlignmentFlag } from '../QtEnums'; /** - + > This is the abstract base class of button widgets, providing their functionality. * **This class is a JS wrapper around Qt's [QAbstractSpinBox class](https://doc.qt.io/qt-5/qabstractspinbox.html)** @@ -11,7 +11,7 @@ The QAbstractSpinBox class is an abstract class and therefore, technically, no f It is inherited by QDateTimeEdit and QSpinBox. (n/a QDoubleSpinBox) */ -export abstract class QAbstractSpinBox extends NodeWidget { +export abstract class QAbstractSpinBox extends QWidget { selectAll(): void { this.native.selectAll(); } diff --git a/src/lib/QtWidgets/QAction.ts b/src/lib/QtWidgets/QAction.ts index 9c19f36d9..d79e8ef90 100644 --- a/src/lib/QtWidgets/QAction.ts +++ b/src/lib/QtWidgets/QAction.ts @@ -1,5 +1,5 @@ import addon from '../utils/addon'; -import { NodeWidget } from './QWidget'; +import { QWidget } from './QWidget'; import { NativeElement } from '../core/Component'; import { QMenu } from './QMenu'; import { QIcon } from '../QtGui/QIcon'; @@ -33,8 +33,8 @@ menu.addAction(menuAction); export class QAction extends QObject { constructor(); constructor(native: NativeElement); - constructor(parent: NodeWidget); - constructor(parent?: NativeElement | NodeWidget) { + constructor(parent: QWidget); + constructor(parent?: NativeElement | QWidget) { let native: NativeElement; if (checkIfNativeElement(parent)) { native = parent as NativeElement; diff --git a/src/lib/QtWidgets/QBoxLayout.ts b/src/lib/QtWidgets/QBoxLayout.ts index 03621edc4..daffb431f 100644 --- a/src/lib/QtWidgets/QBoxLayout.ts +++ b/src/lib/QtWidgets/QBoxLayout.ts @@ -1,5 +1,5 @@ import addon from '../utils/addon'; -import { NodeWidget } from './QWidget'; +import { QWidget } from './QWidget'; import { NodeLayout, QLayoutSignals } from './QLayout'; import { NativeElement } from '../core/Component'; import { AlignmentFlag, Direction } from '../QtEnums'; @@ -27,9 +27,7 @@ centralWidget.setLayout(boxLayout); */ export class QBoxLayout extends NodeLayout { childLayouts: Set>; - constructor(dir: Direction); - constructor(dir: Direction, parent: NodeWidget); - constructor(dir: Direction, parent?: NodeWidget) { + constructor(dir: Direction, parent?: QWidget) { let native: NativeElement; if (parent) { native = new addon.QBoxLayout(dir, parent.native); @@ -53,11 +51,11 @@ export class QBoxLayout extends NodeLayout { addStrut(size: number): void { this.native.addStrut(size); } - addWidget(widget: NodeWidget, stretch = 0, alignment: AlignmentFlag = 0): void { + addWidget(widget: QWidget, stretch = 0, alignment: AlignmentFlag = 0): void { this.native.addWidget(widget.native, stretch, alignment); this.nodeChildren.add(widget); } - insertWidget(index: number, widget: NodeWidget, stretch = 0): void { + insertWidget(index: number, widget: QWidget, stretch = 0): void { this.native.insertWidget(index, widget.native, stretch); this.nodeChildren.add(widget); } @@ -74,7 +72,7 @@ export class QBoxLayout extends NodeLayout { insertStretch(index: number, stretch = 0): void { this.native.insertStretch(index, stretch); } - removeWidget(widget: NodeWidget): void { + removeWidget(widget: QWidget): void { this.native.removeWidget(widget.native); this.nodeChildren.delete(widget); } diff --git a/src/lib/QtWidgets/QButtonGroup.ts b/src/lib/QtWidgets/QButtonGroup.ts index da7a16c68..acfccc633 100644 --- a/src/lib/QtWidgets/QButtonGroup.ts +++ b/src/lib/QtWidgets/QButtonGroup.ts @@ -1,5 +1,5 @@ import addon from '../utils/addon'; -import { NodeWidget } from './QWidget'; +import { QWidget } from './QWidget'; import { NativeRawPointer } from '../core/Component'; import { QObject, QObjectSignals } from '../QtCore/QObject'; import { QAbstractButton, QAbstractButtonSignals } from './QAbstractButton'; @@ -9,9 +9,7 @@ export interface QButtonGroupSignals extends QObjectSignals { } export class QButtonGroup extends QObject { - constructor(); - constructor(parent: NodeWidget); - constructor(parent?: NodeWidget) { + constructor(parent?: QWidget) { let native; if (parent) { native = new addon.QButtonGroup(parent.native); diff --git a/src/lib/QtWidgets/QCalendarWidget.ts b/src/lib/QtWidgets/QCalendarWidget.ts index 76b857096..82c4f026f 100644 --- a/src/lib/QtWidgets/QCalendarWidget.ts +++ b/src/lib/QtWidgets/QCalendarWidget.ts @@ -1,5 +1,5 @@ import addon from '../utils/addon'; -import { NodeWidget, QWidgetSignals } from './QWidget'; +import { QWidget, QWidgetSignals } from './QWidget'; import { NativeElement } from '../core/Component'; import { QDate } from '../QtCore/QDate'; import { DayOfWeek } from '../QtEnums'; @@ -21,10 +21,8 @@ const calendarWidget = new QCalendarWidget(); // more will follow when .selectedDate() et cetera are implemented ``` */ -export class QCalendarWidget extends NodeWidget { - constructor(); - constructor(parent: NodeWidget); - constructor(parent?: NodeWidget) { +export class QCalendarWidget extends QWidget { + constructor(parent?: QWidget) { let native: NativeElement; if (parent) { native = new addon.QCalendarWidget(parent.native); diff --git a/src/lib/QtWidgets/QCheckBox.ts b/src/lib/QtWidgets/QCheckBox.ts index 66e6a33be..8507ade5f 100644 --- a/src/lib/QtWidgets/QCheckBox.ts +++ b/src/lib/QtWidgets/QCheckBox.ts @@ -1,12 +1,12 @@ import addon from '../utils/addon'; -import { NodeWidget } from './QWidget'; +import { QWidget } from './QWidget'; import { NativeElement, NativeRawPointer, Component } from '../core/Component'; import { QAbstractButton, QAbstractButtonSignals } from './QAbstractButton'; import { checkIfNativeElement, checkIfNapiExternal } from '../utils/helpers'; import { CheckState } from '../QtEnums'; /** - + > Create and control checkbox. * **This class is a JS wrapper around Qt's [QCheckBox class](https://doc.qt.io/qt-5/qcheckbox.html)** @@ -24,9 +24,9 @@ checkbox.setText("Hello"); */ export class QCheckBox extends QAbstractButton { constructor(); - constructor(parent: NodeWidget); + constructor(parent: QWidget); constructor(rawPointer: NativeRawPointer, disableNativeDeletion?: boolean); - constructor(arg?: NodeWidget | NativeRawPointer | NativeElement, disableNativeDeletion = true) { + constructor(arg?: QWidget | NativeRawPointer | NativeElement, disableNativeDeletion = true) { let native; let parent: Component | undefined; if (checkIfNativeElement(arg)) { @@ -34,7 +34,7 @@ export class QCheckBox extends QAbstractButton { } else if (checkIfNapiExternal(arg)) { native = new addon.QCheckBox(arg, disableNativeDeletion); } else if (arg) { - const parentWidget = arg as NodeWidget; + const parentWidget = arg as QWidget; native = new addon.QCheckBox(parentWidget.native); parent = parentWidget; } else { diff --git a/src/lib/QtWidgets/QColorDialog.ts b/src/lib/QtWidgets/QColorDialog.ts index aa7c1637f..bf7bb9ee1 100644 --- a/src/lib/QtWidgets/QColorDialog.ts +++ b/src/lib/QtWidgets/QColorDialog.ts @@ -1,5 +1,5 @@ import addon from '../utils/addon'; -import { NodeWidget } from './QWidget'; +import { QWidget } from './QWidget'; import { NativeElement } from '../core/Component'; import { NodeDialog, QDialogSignals } from './QDialog'; import { QColor } from '../QtGui/QColor'; @@ -27,9 +27,7 @@ console.log(color.red(), color.green(), color.blue()); ``` */ export class QColorDialog extends NodeDialog { - constructor(); - constructor(parent: NodeWidget); - constructor(parent?: NodeWidget) { + constructor(parent?: QWidget) { let native: NativeElement; if (parent) { native = new addon.QColorDialog(parent.native); diff --git a/src/lib/QtWidgets/QComboBox.ts b/src/lib/QtWidgets/QComboBox.ts index 2b7788993..f25812da8 100644 --- a/src/lib/QtWidgets/QComboBox.ts +++ b/src/lib/QtWidgets/QComboBox.ts @@ -1,5 +1,5 @@ import addon from '../utils/addon'; -import { NodeWidget, QWidgetSignals } from './QWidget'; +import { QWidget, QWidgetSignals } from './QWidget'; import { NativeElement } from '../core/Component'; import { SizeAdjustPolicy } from '../QtEnums'; import { QIcon } from '../QtGui/QIcon'; @@ -36,10 +36,8 @@ comboBox.addEventListener('currentIndexChanged', (index) => { }); ``` */ -export class QComboBox extends NodeWidget { - constructor(); - constructor(parent: NodeWidget); - constructor(parent?: NodeWidget) { +export class QComboBox extends QWidget { + constructor(parent?: QWidget) { let native: NativeElement; if (parent) { native = new addon.QComboBox(parent.native); diff --git a/src/lib/QtWidgets/QDateEdit.ts b/src/lib/QtWidgets/QDateEdit.ts index 1b67f0d63..faf9b4766 100644 --- a/src/lib/QtWidgets/QDateEdit.ts +++ b/src/lib/QtWidgets/QDateEdit.ts @@ -1,10 +1,10 @@ import addon from '../utils/addon'; -import { NodeWidget } from './QWidget'; +import { QWidget } from './QWidget'; import { NativeElement } from '../core/Component'; import { NodeDateTimeEdit } from './QDateTimeEdit'; /** - + > Creates a widget to edit dates with spin box layout. WIP! * **This class is a JS wrapper around Qt's [QDateEdit class](https://doc.qt.io/qt-5/qdateedit.html)** @@ -21,9 +21,7 @@ const dateEdit = new QDateEdit(); ``` */ export class QDateEdit extends NodeDateTimeEdit { - constructor(); - constructor(parent: NodeWidget); - constructor(parent?: NodeWidget) { + constructor(parent?: QWidget) { let native: NativeElement; if (parent) { native = new addon.QDateEdit(parent.native); diff --git a/src/lib/QtWidgets/QDateTimeEdit.ts b/src/lib/QtWidgets/QDateTimeEdit.ts index 2183cec62..c93c40d79 100644 --- a/src/lib/QtWidgets/QDateTimeEdit.ts +++ b/src/lib/QtWidgets/QDateTimeEdit.ts @@ -1,5 +1,5 @@ import addon from '../utils/addon'; -import { NodeWidget } from './QWidget'; +import { QWidget } from './QWidget'; import { QAbstractSpinBox, QAbstractSpinBoxSignals } from './QAbstractSpinBox'; import { QCalendarWidget } from './QCalendarWidget'; import { QDate } from '../QtCore/QDate'; @@ -62,7 +62,7 @@ export abstract class NodeDateTimeEdit extends QAbstractSpinBox Creates and controls a widget for editing dates and times with spin box layout. * **This class is a JS wrapper around Qt's [QDateTimeEdit class](https://doc.qt.io/qt-5/qdatetimeedit.html)** @@ -85,9 +85,7 @@ dateTimeEdit.setTime(time); ``` */ export class QDateTimeEdit extends NodeDateTimeEdit { - constructor(); - constructor(parent: NodeWidget); - constructor(parent?: NodeWidget) { + constructor(parent?: QWidget) { let native; if (parent) { native = new addon.QDateTimeEdit(parent.native); diff --git a/src/lib/QtWidgets/QDial.ts b/src/lib/QtWidgets/QDial.ts index 6ba0112a0..5fa4c8abd 100644 --- a/src/lib/QtWidgets/QDial.ts +++ b/src/lib/QtWidgets/QDial.ts @@ -1,10 +1,10 @@ import addon from '../utils/addon'; -import { NodeWidget } from './QWidget'; +import { QWidget } from './QWidget'; import { NativeElement } from '../core/Component'; import { QAbstractSlider, QAbstractSliderSignals } from './QAbstractSlider'; /** - + > Create and control dial slider widgets. * **This class is a JS wrapper around Qt's [QDial class](https://doc.qt.io/qt-5/qdial.html)** @@ -21,8 +21,8 @@ const dial = new QDial(); */ export class QDial extends QAbstractSlider { constructor(); - constructor(parent: NodeWidget); - constructor(parent?: NodeWidget) { + constructor(parent: QWidget); + constructor(parent?: QWidget) { let native: NativeElement; if (parent) { native = new addon.QDial(parent.native); diff --git a/src/lib/QtWidgets/QDialog.ts b/src/lib/QtWidgets/QDialog.ts index dc6f41bf8..9ef4d2eaa 100644 --- a/src/lib/QtWidgets/QDialog.ts +++ b/src/lib/QtWidgets/QDialog.ts @@ -2,12 +2,12 @@ import addon from '../utils/addon'; import { NativeElement } from '../core/Component'; import { checkIfNativeElement } from '../utils/helpers'; -import { NodeWidget, QWidgetSignals } from './QWidget'; +import { QWidget, QWidgetSignals } from './QWidget'; import { DialogCode } from '../QtEnums'; // All Dialogs should extend from NodeDialog // Implement all native QDialog methods here so that all dialogs get access to those aswell -export abstract class NodeDialog extends NodeWidget { +export abstract class NodeDialog extends QWidget { setResult(i: number): void { this.native.setResult(i); } @@ -35,7 +35,7 @@ export abstract class NodeDialog extends NodeWid } /** - + > This is the base class of dialog windows. * **This class is a JS wrapper around Qt's [QDialog class](https://doc.qt.io/qt-5/qdialog.html)** diff --git a/src/lib/QtWidgets/QDoubleSpinBox.ts b/src/lib/QtWidgets/QDoubleSpinBox.ts index d3d194724..589c96805 100644 --- a/src/lib/QtWidgets/QDoubleSpinBox.ts +++ b/src/lib/QtWidgets/QDoubleSpinBox.ts @@ -1,10 +1,10 @@ import addon from '../utils/addon'; -import { NodeWidget } from './QWidget'; +import { QWidget } from './QWidget'; import { NativeElement } from '../core/Component'; import { QAbstractSpinBox, QAbstractSpinBoxSignals, StepType } from './QAbstractSpinBox'; /** - + > Create and control double spin box widgets. * **This class is a JS wrapper around Qt's [QDoubleSpinBox class](https://doc.qt.io/qt-5/qdoublespinbox.html)** @@ -20,9 +20,7 @@ const doublespinBox = new QDoubleSpinBox(); ``` */ export class QDoubleSpinBox extends QAbstractSpinBox { - constructor(); - constructor(parent: NodeWidget); - constructor(parent?: NodeWidget) { + constructor(parent?: QWidget) { let native: NativeElement; if (parent) { native = new addon.QDoubleSpinBox(parent.native); diff --git a/src/lib/QtWidgets/QErrorMessage.ts b/src/lib/QtWidgets/QErrorMessage.ts index 073df1e1d..1c2dcbe0e 100644 --- a/src/lib/QtWidgets/QErrorMessage.ts +++ b/src/lib/QtWidgets/QErrorMessage.ts @@ -1,10 +1,10 @@ import addon from '../utils/addon'; -import { NodeWidget } from './QWidget'; +import { QWidget } from './QWidget'; import { NativeElement } from '../core/Component'; import { NodeDialog, QDialogSignals } from './QDialog'; /** - + > Create and control error message dialogs. * **This class is a JS wrapper around Qt's [QErrorMessage class](https://doc.qt.io/qt-5/qerrormessage.html)** @@ -21,9 +21,7 @@ const errorMessage = new QErrorMessage(); ``` */ export class QErrorMessage extends NodeDialog { - constructor(); - constructor(parent: NodeWidget); - constructor(parent?: NodeWidget) { + constructor(parent?: QWidget) { let native: NativeElement; if (parent) { native = new addon.QErrorMessage(parent.native); diff --git a/src/lib/QtWidgets/QFileDialog.ts b/src/lib/QtWidgets/QFileDialog.ts index 7954a9b76..cfc77dbf7 100644 --- a/src/lib/QtWidgets/QFileDialog.ts +++ b/src/lib/QtWidgets/QFileDialog.ts @@ -1,5 +1,5 @@ import addon from '../utils/addon'; -import { NodeWidget } from './QWidget'; +import { QWidget } from './QWidget'; import { NativeElement } from '../core/Component'; import { AcceptMode, DialogLabel, FileMode, Option, ViewMode } from '../QtEnums'; import { NodeDialog, QDialogSignals } from './QDialog'; @@ -29,8 +29,8 @@ console.log(selectedFiles); */ export class QFileDialog extends NodeDialog { constructor(); - constructor(parent: NodeWidget, caption?: string, directory?: string, filter?: string); - constructor(parent?: NodeWidget, caption = 'Select File', directory = '', filter = '') { + constructor(parent: QWidget, caption?: string, directory?: string, filter?: string); + constructor(parent?: QWidget, caption = 'Select File', directory = '', filter = '') { let native: NativeElement; if (parent) { native = new addon.QFileDialog(parent.native, caption, directory, filter); diff --git a/src/lib/QtWidgets/QFontDialog.ts b/src/lib/QtWidgets/QFontDialog.ts index ad6ec76cd..9bc642adf 100644 --- a/src/lib/QtWidgets/QFontDialog.ts +++ b/src/lib/QtWidgets/QFontDialog.ts @@ -1,11 +1,11 @@ import addon from '../utils/addon'; -import { NodeWidget } from './QWidget'; +import { QWidget } from './QWidget'; import { NativeElement } from '../core/Component'; import { NodeDialog, QDialogSignals } from './QDialog'; import { QFont } from '../QtGui/QFont'; /** - + > Create and control font dialogs. * **This class is a JS wrapper around Qt's [QFontDialog class](https://doc.qt.io/qt-5/qfontdialog.html)** @@ -25,9 +25,7 @@ console.log(font); ``` */ export class QFontDialog extends NodeDialog { - constructor(); - constructor(parent: NodeWidget); - constructor(parent?: NodeWidget) { + constructor(parent?: QWidget) { let native: NativeElement; if (parent) { native = new addon.QFontDialog(parent.native); diff --git a/src/lib/QtWidgets/QFrame.ts b/src/lib/QtWidgets/QFrame.ts index 69a69dcbb..a292c2c7f 100644 --- a/src/lib/QtWidgets/QFrame.ts +++ b/src/lib/QtWidgets/QFrame.ts @@ -1,10 +1,10 @@ import addon from '../utils/addon'; -import { NodeWidget, QWidgetSignals } from './QWidget'; +import { QWidget, QWidgetSignals } from './QWidget'; import { NativeElement } from '../core/Component'; import { checkIfNativeElement } from '../utils/helpers'; import { QRect } from '../QtCore/QRect'; -export abstract class NodeFrame extends NodeWidget { +export abstract class NodeFrame extends QWidget { setFrameRect(r: QRect): void { this.setProperty('frameRect', r.native); } @@ -80,13 +80,13 @@ const frame = new QFrame(); ``` */ export class QFrame extends NodeFrame { - constructor(arg?: NodeWidget | NativeElement) { + constructor(arg?: QWidget | NativeElement) { let native: NativeElement; let parent; if (checkIfNativeElement(arg)) { native = arg as NativeElement; - } else if (arg as NodeWidget) { - parent = arg as NodeWidget; + } else if (arg as QWidget) { + parent = arg as QWidget; native = new addon.QFrame(parent.native); } else { native = new addon.QFrame(); diff --git a/src/lib/QtWidgets/QGridLayout.ts b/src/lib/QtWidgets/QGridLayout.ts index c5a6ca729..d2bbe1fd4 100644 --- a/src/lib/QtWidgets/QGridLayout.ts +++ b/src/lib/QtWidgets/QGridLayout.ts @@ -1,5 +1,5 @@ import addon from '../utils/addon'; -import { NodeWidget } from './QWidget'; +import { QWidget } from './QWidget'; import { NodeLayout, QLayoutSignals } from './QLayout'; import { NativeElement } from '../core/Component'; import { AlignmentFlag } from '../QtEnums'; @@ -30,9 +30,7 @@ layout.addWidget(label2); */ export class QGridLayout extends NodeLayout { - constructor(); - constructor(parent: NodeWidget); - constructor(parent?: NodeWidget) { + constructor(parent?: QWidget) { let native: NativeElement; if (parent) { native = new addon.QGridLayout(parent.native); @@ -54,11 +52,11 @@ export class QGridLayout extends NodeLayout { this.native.addLayout(layout.native, row, column, rowSpan, columnSpan, alignment); } - addWidget(widget: NodeWidget, row = 0, col = 0, rowSpan = 1, colSpan = 1, alignment: AlignmentFlag = 0): void { + addWidget(widget: QWidget, row = 0, col = 0, rowSpan = 1, colSpan = 1, alignment: AlignmentFlag = 0): void { this.native.addWidget(widget.native, row, col, rowSpan, colSpan, alignment); this.nodeChildren.add(widget); } - removeWidget(widget: NodeWidget): void { + removeWidget(widget: QWidget): void { this.native.removeWidget(widget.native); this.nodeChildren.delete(widget); } diff --git a/src/lib/QtWidgets/QGroupBox.ts b/src/lib/QtWidgets/QGroupBox.ts index 50f91e966..13f590a32 100644 --- a/src/lib/QtWidgets/QGroupBox.ts +++ b/src/lib/QtWidgets/QGroupBox.ts @@ -1,10 +1,10 @@ import addon from '../utils/addon'; -import { NodeWidget, QWidgetSignals } from './QWidget'; +import { QWidget, QWidgetSignals } from './QWidget'; import { NativeElement } from '../core/Component'; import { AlignmentFlag } from '../QtEnums/AlignmentFlag'; /** - + > Create and control a group of checkboxes including a title. * **This class is a JS wrapper around Qt's [QGroupBox class](https://doc.qt.io/qt-5/qgroupbox.html)** @@ -39,10 +39,8 @@ win.show(); (global as any).win = win; ``` */ -export class QGroupBox extends NodeWidget { - constructor(); - constructor(parent: NodeWidget); - constructor(parent?: NodeWidget) { +export class QGroupBox extends QWidget { + constructor(parent?: QWidget) { let native: NativeElement; if (parent) { native = new addon.QGroupBox(parent.native); diff --git a/src/lib/QtWidgets/QHeaderView.ts b/src/lib/QtWidgets/QHeaderView.ts index 3f8131688..28d7b662f 100644 --- a/src/lib/QtWidgets/QHeaderView.ts +++ b/src/lib/QtWidgets/QHeaderView.ts @@ -1,5 +1,5 @@ import addon from '../utils/addon'; -import { NodeWidget } from './QWidget'; +import { QWidget } from './QWidget'; import { NativeElement } from '../core/Component'; import { QAbstractItemView, QAbstractItemViewSignals } from './QAbstractItemView'; import { AlignmentFlag, checkIfNativeElement, Orientation, QPoint, SortOrder } from '../..'; @@ -205,7 +205,7 @@ export abstract class NodeHeaderView extends } export class QHeaderView extends NodeHeaderView { - constructor(orientationOrNative: Orientation | NativeElement, parent: NodeWidget | null = null) { + constructor(orientationOrNative: Orientation | NativeElement, parent: QWidget | null = null) { let native: NativeElement; if (checkIfNativeElement(orientationOrNative)) { native = orientationOrNative as NativeElement; diff --git a/src/lib/QtWidgets/QInputDialog.ts b/src/lib/QtWidgets/QInputDialog.ts index dc8207d30..b40620df4 100644 --- a/src/lib/QtWidgets/QInputDialog.ts +++ b/src/lib/QtWidgets/QInputDialog.ts @@ -1,5 +1,5 @@ import addon from '../utils/addon'; -import { NodeWidget } from './QWidget'; +import { QWidget } from './QWidget'; import { NodeDialog, QDialogSignals } from './QDialog'; import { EchoMode } from './QLineEdit'; @@ -22,7 +22,7 @@ dialog.exec(); ``` */ export class QInputDialog extends NodeDialog { - constructor(parent?: NodeWidget) { + constructor(parent?: QWidget) { let native; if (parent) { native = new addon.QInputDialog(parent.native); diff --git a/src/lib/QtWidgets/QLCDNumber.ts b/src/lib/QtWidgets/QLCDNumber.ts index 8e9d08a59..79ee70293 100644 --- a/src/lib/QtWidgets/QLCDNumber.ts +++ b/src/lib/QtWidgets/QLCDNumber.ts @@ -1,5 +1,5 @@ import addon from '../utils/addon'; -import { NodeWidget, QWidgetSignals } from './QWidget'; +import { QWidget, QWidgetSignals } from './QWidget'; /** @@ -19,8 +19,8 @@ const lcd = new QLCDNumber(); ``` */ -export class QLCDNumber extends NodeWidget { - constructor(parent?: NodeWidget) { +export class QLCDNumber extends QWidget { + constructor(parent?: QWidget) { let native; if (parent) { native = new addon.QLCDNumber(parent.native); diff --git a/src/lib/QtWidgets/QLabel.ts b/src/lib/QtWidgets/QLabel.ts index c15337288..66f10ff15 100644 --- a/src/lib/QtWidgets/QLabel.ts +++ b/src/lib/QtWidgets/QLabel.ts @@ -1,5 +1,5 @@ import addon from '../utils/addon'; -import { NodeWidget } from './QWidget'; +import { QWidget } from './QWidget'; import { NodeFrame, QFrameSignals } from './QFrame'; import { QPixmap } from '../QtGui/QPixmap'; import { QMovie } from '../QtGui/QMovie'; @@ -30,9 +30,9 @@ export class QLabel extends NodeFrame { private _picture?: QPicture; private _pixmap?: QPixmap; private _movie?: QMovie; - private _buddy?: NodeWidget | null; + private _buddy?: QWidget | null; - constructor(parent?: NodeWidget) { + constructor(parent?: QWidget) { let native; if (parent) { native = new addon.QLabel(parent.native); @@ -108,11 +108,11 @@ export class QLabel extends NodeFrame { selectionStart(): number { return this.native.selectionStart(); } - setBuddy(buddy: NodeWidget): void { + setBuddy(buddy: QWidget): void { this.native.setBuddy(buddy.native); this._buddy = buddy; } - buddy(): NodeWidget | null { + buddy(): QWidget | null { if (this._buddy) { return this._buddy; } diff --git a/src/lib/QtWidgets/QLayout.ts b/src/lib/QtWidgets/QLayout.ts index 734ffe13e..ec0879526 100644 --- a/src/lib/QtWidgets/QLayout.ts +++ b/src/lib/QtWidgets/QLayout.ts @@ -1,4 +1,4 @@ -import { NodeWidget } from './QWidget'; +import { QWidget } from './QWidget'; import { QObject, QObjectSignals } from '../QtCore/QObject'; // All Layouts should extend this abstract class. @@ -16,7 +16,6 @@ import { QObject, QObjectSignals } from '../QtCore/QObject'; ```javascript const { NodeLayout, - NodeWidget, FlexLayout, GridLayout, QPushButton, @@ -24,7 +23,7 @@ const { } = require("@nodegui/nodegui"); // addChildToLayout can accept any layout since it expects NodeLayout -const addChildToLayout = (layout: NodeLayout, widget: NodeWidget) => { +const addChildToLayout = (layout: NodeLayout, widget: QWidget) => { layout.addWidget(widget); }; @@ -34,8 +33,8 @@ addChildToLayout(new GridLayout(), new QWidget()); */ export abstract class NodeLayout extends QObject { type = 'layout'; - abstract addWidget(childWidget: NodeWidget, ...args: any[]): void; - abstract removeWidget(childWidget: NodeWidget): void; + abstract addWidget(childWidget: QWidget, ...args: any[]): void; + abstract removeWidget(childWidget: QWidget): void; setSizeConstraint(constraint: SizeConstraint): void { this.setProperty('sizeConstraint', constraint); } diff --git a/src/lib/QtWidgets/QLineEdit.ts b/src/lib/QtWidgets/QLineEdit.ts index ec49056f6..9fb2bc46d 100644 --- a/src/lib/QtWidgets/QLineEdit.ts +++ b/src/lib/QtWidgets/QLineEdit.ts @@ -1,5 +1,5 @@ import addon from '../utils/addon'; -import { NodeWidget, QWidgetSignals } from './QWidget'; +import { QWidget, QWidgetSignals } from './QWidget'; import { AlignmentFlag } from '../QtEnums/AlignmentFlag'; import { CursorMoveStyle } from '../QtEnums/CursorMoveStyle'; import { QPoint } from '../QtCore/QPoint'; @@ -21,8 +21,8 @@ const lineEdit = new QLineEdit(); ``` */ -export class QLineEdit extends NodeWidget { - constructor(parent?: NodeWidget) { +export class QLineEdit extends QWidget { + constructor(parent?: QWidget) { let native; if (parent) { native = new addon.QLineEdit(parent.native); diff --git a/src/lib/QtWidgets/QListView.ts b/src/lib/QtWidgets/QListView.ts index d0649d919..618d36848 100644 --- a/src/lib/QtWidgets/QListView.ts +++ b/src/lib/QtWidgets/QListView.ts @@ -1,12 +1,12 @@ import addon from '../utils/addon'; -import { NodeWidget } from './QWidget'; +import { QWidget } from './QWidget'; import { NativeElement } from '../core/Component'; import { QAbstractItemView, QAbstractItemViewSignals } from './QAbstractItemView'; import { QSize } from '../QtCore/QSize'; import { AlignmentFlag } from '../..'; /** - + > The QListView class provides a list or icon view onto a model. * **This class is a JS wrapper around Qt's [QListView class](https://doc.qt.io/qt-5/qlistview.html)** @@ -144,9 +144,7 @@ export enum ListViewMode { } export class QListView extends NodeListView { - constructor(); - constructor(parent: NodeWidget); - constructor(parent?: NodeWidget) { + constructor(parent?: QWidget) { let native: NativeElement; if (parent) { native = new addon.QListView(parent.native); diff --git a/src/lib/QtWidgets/QListWidget.ts b/src/lib/QtWidgets/QListWidget.ts index ed67a3015..858e299b5 100644 --- a/src/lib/QtWidgets/QListWidget.ts +++ b/src/lib/QtWidgets/QListWidget.ts @@ -1,5 +1,5 @@ import addon from '../utils/addon'; -import { NodeWidget, QWidget } from './QWidget'; +import { QWidget } from './QWidget'; import { NativeElement, Component } from '../core/Component'; import { QListWidgetItem } from './QListWidgetItem'; import { NodeListView, QListViewSignals } from './QListView'; @@ -35,7 +35,7 @@ for (let i = 0; i < 30; i++) { export class QListWidget extends NodeListView { items: Set; - constructor(parent?: NodeWidget) { + constructor(parent?: QWidget) { let native; if (parent) { native = new addon.QListWidget(parent.native); @@ -132,7 +132,7 @@ export class QListWidget extends NodeListView { setCurrentItem(item: QListWidgetItem): void { this.native.setCurrentItem(item.native); } - setItemWidget(item: QListWidgetItem, widget: NodeWidget): void { + setItemWidget(item: QListWidgetItem, widget: QWidget): void { this.native.setItemWidget(item.native, widget.native); } sortItems(order = SortOrder.AscendingOrder): void { diff --git a/src/lib/QtWidgets/QMainWindow.ts b/src/lib/QtWidgets/QMainWindow.ts index c5e1734ff..f782508c5 100644 --- a/src/lib/QtWidgets/QMainWindow.ts +++ b/src/lib/QtWidgets/QMainWindow.ts @@ -1,5 +1,5 @@ import addon from '../utils/addon'; -import { NodeWidget, QWidgetSignals } from './QWidget'; +import { QWidget, QWidgetSignals } from './QWidget'; import { NodeLayout } from './QLayout'; import { QMenuBar } from './QMenuBar'; import { QStatusBar } from './QStatusBar'; @@ -31,14 +31,12 @@ global.win = win; // prevent's gc of win QMainWindow needs to have a central widget set before other widgets can be added as a children/nested children. Once a central widget is set you can add children/layout to the central widget. */ -export class QMainWindow extends NodeWidget { - public centralWidget?: NodeWidget | null; +export class QMainWindow extends QWidget { + public centralWidget?: QWidget | null; private _menuBar?: QMenuBar; private _statusBar?: QStatusBar | null; - constructor(); - constructor(parent: NodeWidget); - constructor(parent?: NodeWidget) { + constructor(parent?: QWidget) { let native: NativeElement; if (parent) { native = new addon.QMainWindow(parent.native); @@ -57,12 +55,12 @@ export class QMainWindow extends NodeWidget { } }; } - setCentralWidget(widget: NodeWidget): void { + setCentralWidget(widget: QWidget): void { this.native.setCentralWidget(widget.native); this.centralWidget = widget; this.centralWidget.setFlexNodeSizeControlled(true); } - takeCentralWidget(): NodeWidget | null { + takeCentralWidget(): QWidget | null { const centralWidget = this.centralWidget; this.centralWidget = null; if (centralWidget) { @@ -79,7 +77,7 @@ export class QMainWindow extends NodeWidget { menuBar(): QMenuBar | undefined { return this._menuBar; } - setMenuWidget(menuWidget: NodeWidget): void { + setMenuWidget(menuWidget: QWidget): void { this.native.setMenuWidget(menuWidget.native); } get layout(): NodeLayout | undefined { diff --git a/src/lib/QtWidgets/QMenu.ts b/src/lib/QtWidgets/QMenu.ts index 9211708eb..c9569ed06 100644 --- a/src/lib/QtWidgets/QMenu.ts +++ b/src/lib/QtWidgets/QMenu.ts @@ -1,5 +1,5 @@ import { NativeElement } from '../core/Component'; -import { NodeWidget, QWidgetSignals } from './QWidget'; +import { QWidget, QWidgetSignals } from './QWidget'; import addon from '../utils/addon'; import { QAction } from './QAction'; import { QPoint } from '../QtCore/QPoint'; @@ -18,8 +18,8 @@ const { QMenu } = require("@nodegui/nodegui"); const menu = new QMenu(); ``` */ -export class QMenu extends NodeWidget { - constructor(parent?: NodeWidget) { +export class QMenu extends QWidget { + constructor(parent?: QWidget) { let native; if (parent) { native = new addon.QMenu(parent.native); diff --git a/src/lib/QtWidgets/QMenuBar.ts b/src/lib/QtWidgets/QMenuBar.ts index b82305c57..e74e0c779 100644 --- a/src/lib/QtWidgets/QMenuBar.ts +++ b/src/lib/QtWidgets/QMenuBar.ts @@ -1,6 +1,6 @@ import { QMenu } from './QMenu'; import { NativeElement } from '../core/Component'; -import { NodeWidget, QWidgetSignals } from './QWidget'; +import { QWidget, QWidgetSignals } from './QWidget'; import addon from '../utils/addon'; import { checkIfNativeElement } from '../utils/helpers'; import { QAction } from './QAction'; @@ -23,17 +23,17 @@ win.show(); global.win = win; ``` */ -export class QMenuBar extends NodeWidget { +export class QMenuBar extends QWidget { _menus: Set; - constructor(arg?: NodeWidget | NativeElement) { + constructor(arg?: QWidget | NativeElement) { let native; let parent; if (checkIfNativeElement(arg)) { native = arg as NativeElement; } else if (typeof arg === 'object') { native = new addon.QMenuBar(arg.native); - parent = arg as NodeWidget; + parent = arg as QWidget; } else { native = new addon.QMenuBar(); } diff --git a/src/lib/QtWidgets/QMessageBox.ts b/src/lib/QtWidgets/QMessageBox.ts index 4fb4cc5ee..7531842f4 100644 --- a/src/lib/QtWidgets/QMessageBox.ts +++ b/src/lib/QtWidgets/QMessageBox.ts @@ -1,5 +1,5 @@ import addon from '../utils/addon'; -import { NodeWidget } from './QWidget'; +import { QWidget } from './QWidget'; import { NativeRawPointer } from '../core/Component'; import { NodeDialog, QDialogSignals } from './QDialog'; import { QAbstractButton, QAbstractButtonSignals } from './QAbstractButton'; @@ -40,7 +40,7 @@ messageBox.exec(); ``` */ export class QMessageBox extends NodeDialog { - constructor(parent?: NodeWidget) { + constructor(parent?: QWidget) { let native; if (parent) { native = new addon.QMessageBox(parent.native); @@ -86,11 +86,11 @@ export class QMessageBox extends NodeDialog { this.nodeChildren.add(button); } - static about(parent: NodeWidget, title: string, text: string): void { + static about(parent: QWidget, title: string, text: string): void { addon.QMessageBox.about(parent.native, title, text); } - static aboutQt(parent: NodeWidget, title: string): void { + static aboutQt(parent: QWidget, title: string): void { addon.QMessageBox.aboutQt(parent.native, title); } } diff --git a/src/lib/QtWidgets/QPlainTextEdit.ts b/src/lib/QtWidgets/QPlainTextEdit.ts index dd024c846..a620ab5b0 100644 --- a/src/lib/QtWidgets/QPlainTextEdit.ts +++ b/src/lib/QtWidgets/QPlainTextEdit.ts @@ -1,5 +1,5 @@ import addon from '../utils/addon'; -import { NodeWidget } from './QWidget'; +import { QWidget } from './QWidget'; import { NativeElement } from '../core/Component'; import { QAbstractScrollArea, QAbstractScrollAreaSignals } from './QAbstractScrollArea'; import { QTextOptionWrapMode } from '../QtGui/QTextOption'; @@ -16,7 +16,7 @@ export interface QPlainTextEditSignals extends QAbstractScrollAreaSignals { } /** - + > Used to edit and display plain text. * **This class is a JS wrapper around Qt's [QPlainTextEdit class](https://doc.qt.io/qt-5/qplaintextedit.html)** @@ -33,7 +33,7 @@ const plainTextEdit = new QPlainTextEdit(); */ export class QPlainTextEdit extends QAbstractScrollArea { placeholderText?: string; - constructor(parent?: NodeWidget) { + constructor(parent?: QWidget) { let native: NativeElement; if (parent) { native = new addon.QPlainTextEdit(parent.native); diff --git a/src/lib/QtWidgets/QProgressBar.ts b/src/lib/QtWidgets/QProgressBar.ts index 0f60d9b14..c075e28a1 100644 --- a/src/lib/QtWidgets/QProgressBar.ts +++ b/src/lib/QtWidgets/QProgressBar.ts @@ -1,10 +1,10 @@ import addon from '../utils/addon'; -import { NodeWidget, QWidgetSignals } from './QWidget'; +import { QWidget, QWidgetSignals } from './QWidget'; import { NativeElement } from '../core/Component'; import { Orientation, AlignmentFlag } from '../QtEnums'; /** - + > Create and control progress bar widgets. * **This class is a JS wrapper around Qt's [QProgressBar class](https://doc.qt.io/qt-5/qprogressbar.html)** @@ -19,8 +19,8 @@ const { QProgressBar } = require("@nodegui/nodegui"); const progressBar = new QProgressBar(); ``` */ -export class QProgressBar extends NodeWidget { - constructor(parent?: NodeWidget) { +export class QProgressBar extends QWidget { + constructor(parent?: QWidget) { let native: NativeElement; if (parent) { native = new addon.QProgressBar(parent.native); diff --git a/src/lib/QtWidgets/QProgressDialog.ts b/src/lib/QtWidgets/QProgressDialog.ts index 9fd608f49..d21bc5274 100644 --- a/src/lib/QtWidgets/QProgressDialog.ts +++ b/src/lib/QtWidgets/QProgressDialog.ts @@ -1,5 +1,5 @@ import addon from '../utils/addon'; -import { NodeWidget } from './QWidget'; +import { QWidget } from './QWidget'; import { NodeDialog, QDialogSignals } from './QDialog'; /** @@ -20,7 +20,7 @@ const progressDialog = new QProgressDialog(); ``` */ export class QProgressDialog extends NodeDialog { - constructor(parent?: NodeWidget) { + constructor(parent?: QWidget) { let native; if (parent) { native = new addon.QProgressDialog(parent.native); diff --git a/src/lib/QtWidgets/QPushButton.ts b/src/lib/QtWidgets/QPushButton.ts index 8c591e030..dcdf7b724 100644 --- a/src/lib/QtWidgets/QPushButton.ts +++ b/src/lib/QtWidgets/QPushButton.ts @@ -1,5 +1,5 @@ import addon from '../utils/addon'; -import { NodeWidget } from './QWidget'; +import { QWidget } from './QWidget'; import { NativeElement, NativeRawPointer, Component } from '../core/Component'; import { QAbstractButton, QAbstractButtonSignals } from './QAbstractButton'; import { checkIfNativeElement, checkIfNapiExternal } from '../utils/helpers'; @@ -25,7 +25,7 @@ button.setText("Hello"); export class QPushButton extends QAbstractButton { private _menu?: QMenu | null; - constructor(arg?: NodeWidget | NativeRawPointer | NativeElement, disableNativeDeletion = true) { + constructor(arg?: QWidget | NativeRawPointer | NativeElement, disableNativeDeletion = true) { let native; let parent: Component | undefined; if (checkIfNativeElement(arg)) { @@ -33,7 +33,7 @@ export class QPushButton extends QAbstractButton { } else if (checkIfNapiExternal(arg)) { native = new addon.QPushButton(arg, disableNativeDeletion); } else if (arg) { - const parentWidget = arg as NodeWidget; + const parentWidget = arg as QWidget; native = new addon.QPushButton(parentWidget.native); parent = parentWidget; } else { diff --git a/src/lib/QtWidgets/QRadioButton.ts b/src/lib/QtWidgets/QRadioButton.ts index 6813c63ad..a274eac9c 100644 --- a/src/lib/QtWidgets/QRadioButton.ts +++ b/src/lib/QtWidgets/QRadioButton.ts @@ -1,5 +1,5 @@ import addon from '../utils/addon'; -import { NodeWidget } from './QWidget'; +import { QWidget } from './QWidget'; import { NativeElement, NativeRawPointer, Component } from '../core/Component'; import { QAbstractButton, QAbstractButtonSignals } from './QAbstractButton'; import { checkIfNativeElement, checkIfNapiExternal } from '../utils/helpers'; @@ -23,7 +23,7 @@ radioButton.setText("Hello"); */ export class QRadioButton extends QAbstractButton { - constructor(arg?: NodeWidget | NativeRawPointer | NativeElement, disableNativeDeletion = true) { + constructor(arg?: QWidget | NativeRawPointer | NativeElement, disableNativeDeletion = true) { let native; let parent: Component | undefined; if (checkIfNativeElement(arg)) { @@ -31,7 +31,7 @@ export class QRadioButton extends QAbstractButton { } else if (checkIfNapiExternal(arg)) { native = new addon.QRadioButton(arg, disableNativeDeletion); } else if (arg) { - const parentWidget = arg as NodeWidget; + const parentWidget = arg as QWidget; native = new addon.QRadioButton(parentWidget.native); parent = parentWidget; } else { diff --git a/src/lib/QtWidgets/QScrollArea.ts b/src/lib/QtWidgets/QScrollArea.ts index e91d2fdf7..c601bd83f 100644 --- a/src/lib/QtWidgets/QScrollArea.ts +++ b/src/lib/QtWidgets/QScrollArea.ts @@ -1,5 +1,5 @@ import addon from '../utils/addon'; -import { NodeWidget } from './QWidget'; +import { QWidget } from './QWidget'; import { NativeElement } from '../core/Component'; import { QAbstractScrollArea, QAbstractScrollAreaSignals } from './QAbstractScrollArea'; import { AlignmentFlag } from '../QtEnums'; @@ -29,8 +29,8 @@ scrollArea.setWidget(imageLabel); ``` */ export class QScrollArea extends QAbstractScrollArea { - contentWidget?: NodeWidget | null; - constructor(parent?: NodeWidget) { + contentWidget?: QWidget | null; + constructor(parent?: QWidget) { let native: NativeElement; if (parent) { native = new addon.QScrollArea(parent.native); @@ -55,20 +55,20 @@ export class QScrollArea extends QAbstractScrollArea { ensureVisible(x: number, y: number, xmargin = 50, ymargin = 50): void { this.native.ensureVisible(x, y, xmargin, ymargin); } - ensureWidgetVisible(childWidget: NodeWidget, xmargin = 50, ymargin = 50): void { + ensureWidgetVisible(childWidget: QWidget, xmargin = 50, ymargin = 50): void { this.native.ensureWidgetVisible(childWidget.native, xmargin, ymargin); } - setWidget(widget: NodeWidget): void { + setWidget(widget: QWidget): void { this.contentWidget = widget; this.native.setWidget(widget.native); } - widget(): NodeWidget | null { + widget(): QWidget | null { if (this.contentWidget) { return this.contentWidget; } return null; } - takeWidget(): NodeWidget | null { + takeWidget(): QWidget | null { // react:✓ const contentWidget = this.contentWidget; this.contentWidget = null; diff --git a/src/lib/QtWidgets/QScrollBar.ts b/src/lib/QtWidgets/QScrollBar.ts index d8b150503..36083d2f7 100644 --- a/src/lib/QtWidgets/QScrollBar.ts +++ b/src/lib/QtWidgets/QScrollBar.ts @@ -1,5 +1,5 @@ import addon from '../utils/addon'; -import { NodeWidget } from './QWidget'; +import { QWidget } from './QWidget'; import { NativeElement } from '../core/Component'; import { QAbstractSlider, QAbstractSliderSignals } from './QAbstractSlider'; @@ -20,7 +20,7 @@ const scrollbar = new QScrollBar(); ``` */ export class QScrollBar extends QAbstractSlider { - constructor(parent?: NodeWidget) { + constructor(parent?: QWidget) { let native: NativeElement; if (parent) { native = new addon.QScrollBar(parent.native); diff --git a/src/lib/QtWidgets/QShortcut.ts b/src/lib/QtWidgets/QShortcut.ts index 32e306ab0..c1d9581c2 100644 --- a/src/lib/QtWidgets/QShortcut.ts +++ b/src/lib/QtWidgets/QShortcut.ts @@ -1,11 +1,11 @@ import addon from '../utils/addon'; -import { NodeWidget } from './QWidget'; +import { QWidget } from './QWidget'; import { QKeySequence } from '../QtGui/QKeySequence'; import { ShortcutContext } from '../QtEnums'; import { QObject, QObjectSignals } from '../QtCore/QObject'; /** - + > The QShortcut class is used to create keyboard shortcuts. * **This class is a JS wrapper around Qt's [QShortcut class](https://doc.qt.io/qt-5/qshortcut.html)** @@ -29,7 +29,7 @@ global.shortcut = shortcut; ``` */ export class QShortcut extends QObject { - constructor(parent: NodeWidget) { + constructor(parent: QWidget) { super(new addon.QShortcut(parent.native)); } setEnabled(enabled: boolean): void { diff --git a/src/lib/QtWidgets/QSpinBox.ts b/src/lib/QtWidgets/QSpinBox.ts index 87bb300ca..899efa74b 100644 --- a/src/lib/QtWidgets/QSpinBox.ts +++ b/src/lib/QtWidgets/QSpinBox.ts @@ -1,5 +1,5 @@ import addon from '../utils/addon'; -import { NodeWidget } from './QWidget'; +import { QWidget } from './QWidget'; import { QAbstractSpinBox, QAbstractSpinBoxSignals, StepType } from './QAbstractSpinBox'; /** @@ -19,7 +19,7 @@ const spinBox = new QSpinBox(); ``` */ export class QSpinBox extends QAbstractSpinBox { - constructor(parent?: NodeWidget) { + constructor(parent?: QWidget) { let native; if (parent) { native = new addon.QSpinBox(parent.native); diff --git a/src/lib/QtWidgets/QSplitter.ts b/src/lib/QtWidgets/QSplitter.ts index 82dad87c2..e00ea5612 100644 --- a/src/lib/QtWidgets/QSplitter.ts +++ b/src/lib/QtWidgets/QSplitter.ts @@ -1,5 +1,5 @@ import addon from '../utils/addon'; -import { NodeWidget } from './QWidget'; +import { QWidget } from './QWidget'; import { NodeFrame, QFrameSignals } from './QFrame'; import { NativeElement } from '../core/Component'; import { Orientation } from '../QtEnums'; @@ -35,7 +35,7 @@ splitterHorizontal.addWidget(right); */ export class QSplitter extends NodeFrame { - constructor(parent?: NodeWidget) { + constructor(parent?: QWidget) { let native: NativeElement; if (parent) { native = new addon.QSplitter(parent.native); @@ -45,7 +45,7 @@ export class QSplitter extends NodeFrame { super(native); this.setNodeParent(parent); } - addWidget(widget: NodeWidget): void { + addWidget(widget: QWidget): void { this.native.addWidget(widget.native); } childrenCollapsible(): boolean { @@ -54,10 +54,10 @@ export class QSplitter extends NodeFrame { count(): number { return this.native.count(); } - indexOf(widget: NodeWidget): number { + indexOf(widget: QWidget): number { return this.native.indexOf(widget.native); } - insertWidget(index: number, widget: NodeWidget): void { + insertWidget(index: number, widget: QWidget): void { this.native.insertWidget(index, widget.native); } isCollapsible(index: number): boolean { diff --git a/src/lib/QtWidgets/QStackedWidget.ts b/src/lib/QtWidgets/QStackedWidget.ts index 46da1a545..dd7b0a639 100644 --- a/src/lib/QtWidgets/QStackedWidget.ts +++ b/src/lib/QtWidgets/QStackedWidget.ts @@ -1,5 +1,5 @@ import addon from '../utils/addon'; -import { NodeWidget } from './QWidget'; +import { QWidget } from './QWidget'; import { NodeFrame, QFrameSignals } from './QFrame'; /** @@ -44,7 +44,7 @@ win.show(); ``` */ export class QStackedWidget extends NodeFrame { - constructor(parent?: NodeWidget) { + constructor(parent?: QWidget) { let native; if (parent) { native = new addon.QStackedWidget(parent.native); @@ -56,7 +56,7 @@ export class QStackedWidget extends NodeFrame { } // *** Public Function *** - addWidget(widget: NodeWidget): void { + addWidget(widget: QWidget): void { this.native.addWidget(widget.native); this.nodeChildren.add(widget); widget.setFlexNodeSizeControlled(true); @@ -70,7 +70,7 @@ export class QStackedWidget extends NodeFrame { // TODO: QWidget * currentWidget() const // TODO: int indexOf(QWidget *widget) const // TODO: int insertWidget(int index, QWidget *widget) - removeWidget(widget: NodeWidget): void { + removeWidget(widget: QWidget): void { this.native.removeWidget(widget.native); this.nodeChildren.delete(widget); } @@ -80,7 +80,7 @@ export class QStackedWidget extends NodeFrame { setCurrentIndex(index: number): void { this.native.setCurrentIndex(index); } - setCurrentWidget(widget: NodeWidget): void { + setCurrentWidget(widget: QWidget): void { this.native.setCurrentWidget(widget.native); } } diff --git a/src/lib/QtWidgets/QStandardItemModel.ts b/src/lib/QtWidgets/QStandardItemModel.ts index 27b000d80..7928094f9 100644 --- a/src/lib/QtWidgets/QStandardItemModel.ts +++ b/src/lib/QtWidgets/QStandardItemModel.ts @@ -1,5 +1,5 @@ import addon from '../utils/addon'; -import { NodeWidget } from './QWidget'; +import { QWidget } from './QWidget'; import { QObject, QObjectSignals } from '../QtCore/QObject'; import { QStandardItem } from './QStandardItem'; @@ -8,7 +8,7 @@ export interface QStandardItemModelSignals extends QObjectSignals { } export class QStandardItemModel extends QObject { - constructor(parent?: NodeWidget) { + constructor(parent?: QWidget) { let native; if (parent) { native = new addon.QStandardItemModel(parent.native); diff --git a/src/lib/QtWidgets/QStatusBar.ts b/src/lib/QtWidgets/QStatusBar.ts index be36eb713..175b0ff91 100644 --- a/src/lib/QtWidgets/QStatusBar.ts +++ b/src/lib/QtWidgets/QStatusBar.ts @@ -1,5 +1,5 @@ import addon from '../utils/addon'; -import { NodeWidget, QWidgetSignals, QWidget } from './QWidget'; +import { QWidgetSignals, QWidget } from './QWidget'; import { NativeElement } from '../core/Component'; export interface QStatusBarSignals extends QWidgetSignals { @@ -22,11 +22,11 @@ const { QStatusBar } = require("@nodegui/nodegui"); const progressBar = new QStatusBar(); ``` */ -export class QStatusBar extends NodeWidget { +export class QStatusBar extends QWidget { permanentWidgets: Set; widgets: Set; - constructor(parent?: NodeWidget) { + constructor(parent?: QWidget) { let native; if (parent) { native = new addon.QStatusBar(parent.native); diff --git a/src/lib/QtWidgets/QSvgWidget.ts b/src/lib/QtWidgets/QSvgWidget.ts index acf5f258a..b4bb4a8b9 100644 --- a/src/lib/QtWidgets/QSvgWidget.ts +++ b/src/lib/QtWidgets/QSvgWidget.ts @@ -1,9 +1,9 @@ import addon from '../utils/addon'; -import { NodeWidget, QWidgetSignals } from './QWidget'; +import { QWidget, QWidgetSignals } from './QWidget'; import { NativeElement } from '../core/Component'; /** - + > Display SVG files in a widget. * **This class is a JS wrapper around Qt's [QSvgWidget class](https://doc.qt.io/qt-5/qsvgwidget.html)** @@ -26,10 +26,8 @@ fs.readFile("icon.svg", (err, buffer) => { ``` */ -export class QSvgWidget extends NodeWidget { - constructor(); - constructor(parent: NodeWidget); - constructor(parent?: NodeWidget) { +export class QSvgWidget extends QWidget { + constructor(parent?: QWidget) { let native: NativeElement; if (parent) { native = new addon.QSvgWidget(parent.native); diff --git a/src/lib/QtWidgets/QSystemTrayIcon.ts b/src/lib/QtWidgets/QSystemTrayIcon.ts index f9c5cf2ae..9d0d466b4 100644 --- a/src/lib/QtWidgets/QSystemTrayIcon.ts +++ b/src/lib/QtWidgets/QSystemTrayIcon.ts @@ -1,5 +1,5 @@ import addon from '../utils/addon'; -import { NodeWidget } from './QWidget'; +import { QWidget } from './QWidget'; import { QIcon } from '../QtGui/QIcon'; import { QMenu } from './QMenu'; import { QObject, QObjectSignals } from '../QtCore/QObject'; @@ -30,7 +30,7 @@ global.tray = tray; // prevents garbage collection of tray export class QSystemTrayIcon extends QObject { contextMenu?: QMenu; - constructor(parent?: NodeWidget) { + constructor(parent?: QWidget) { let native; if (parent) { native = new addon.QSystemTrayIcon(parent.native); diff --git a/src/lib/QtWidgets/QTabBar.ts b/src/lib/QtWidgets/QTabBar.ts index 797e68c38..944b87c1d 100644 --- a/src/lib/QtWidgets/QTabBar.ts +++ b/src/lib/QtWidgets/QTabBar.ts @@ -1,5 +1,5 @@ import addon from '../utils/addon'; -import { NodeWidget, QWidgetSignals } from './QWidget'; +import { QWidget, QWidgetSignals } from './QWidget'; import { QIcon } from '../QtGui/QIcon'; import { TextElideMode } from '../QtEnums'; import { QSize } from '../QtCore/QSize'; @@ -25,8 +25,8 @@ const tabBar = new QTabBar(); ``` */ -export class QTabBar extends NodeWidget { - constructor(parent?: NodeWidget) { +export class QTabBar extends QWidget { + constructor(parent?: QWidget) { let native; if (parent) { native = new addon.QTabBar(parent.native); @@ -150,7 +150,7 @@ export class QTabBar extends NodeWidget { removeTab(index: number): void { this.native.removeTab(index); } - setTabButton(index: number, position: ButtonPosition, widget: NodeWidget | undefined | null): void { + setTabButton(index: number, position: ButtonPosition, widget: QWidget | undefined | null): void { this.native.setTabButton(index, position, widget == null ? null : widget?.native); } setTabData(index: number, data: QVariant): void { diff --git a/src/lib/QtWidgets/QTabWidget.ts b/src/lib/QtWidgets/QTabWidget.ts index 44ef10d1d..247e0d284 100644 --- a/src/lib/QtWidgets/QTabWidget.ts +++ b/src/lib/QtWidgets/QTabWidget.ts @@ -1,5 +1,5 @@ import addon from '../utils/addon'; -import { NodeWidget, QWidgetSignals } from './QWidget'; +import { QWidget, QWidgetSignals } from './QWidget'; import { NativeElement } from '../core/Component'; import { QIcon } from '../QtGui/QIcon'; import { TabPosition } from '../QtEnums'; @@ -24,10 +24,10 @@ tabWidget.addTab(new QCalendarWidget(), new QIcon(), 'Tab 1'); tabWidget.addTab(new QCalendarWidget(), new QIcon(), 'Tab 2'); ``` */ -export class QTabWidget extends NodeWidget { - tabs: NodeWidget[]; +export class QTabWidget extends QWidget { + tabs: QWidget[]; - constructor(parent?: NodeWidget) { + constructor(parent?: QWidget) { let native: NativeElement; if (parent) { native = new addon.QTabWidget(parent.native); @@ -39,20 +39,20 @@ export class QTabWidget extends NodeWidget { this.tabs = []; } - addTab(page: NodeWidget, icon: QIcon, label: string): number { + addTab(page: QWidget, icon: QIcon, label: string): number { const index = this.native.addTab(page.native, icon.native, label); this.tabs.push(page); page.setFlexNodeSizeControlled(true); return index; } - insertTab(index: number, page: NodeWidget, icon: QIcon, label: string): number { + insertTab(index: number, page: QWidget, icon: QIcon, label: string): number { const newIndex = this.native.insertTab(index, page.native, icon.native, label); this.tabs.splice(index, 0, page); return newIndex; } - indexOf(widget: NodeWidget): number { + indexOf(widget: QWidget): number { return this.native.indexOf(widget.native); } diff --git a/src/lib/QtWidgets/QTableView.ts b/src/lib/QtWidgets/QTableView.ts index 8f80d4da4..b96ecc8b4 100644 --- a/src/lib/QtWidgets/QTableView.ts +++ b/src/lib/QtWidgets/QTableView.ts @@ -1,5 +1,5 @@ import addon from '../utils/addon'; -import { NodeWidget } from './QWidget'; +import { QWidget } from './QWidget'; import { SortOrder, PenStyle } from '../QtEnums'; import { QAbstractItemView, QAbstractItemViewSignals } from './QAbstractItemView'; import { QHeaderView } from './QHeaderView'; @@ -178,7 +178,7 @@ export abstract class NodeTableView extends Q } export class QTableView extends NodeTableView { - constructor(parent?: NodeWidget) { + constructor(parent?: QWidget) { let native; if (parent) { native = new addon.QTableView(parent.native); diff --git a/src/lib/QtWidgets/QTableWidget.ts b/src/lib/QtWidgets/QTableWidget.ts index 546cbac9f..63cf79260 100644 --- a/src/lib/QtWidgets/QTableWidget.ts +++ b/src/lib/QtWidgets/QTableWidget.ts @@ -1,5 +1,5 @@ import addon from '../utils/addon'; -import { NodeWidget, QWidget } from './QWidget'; +import { QWidget } from './QWidget'; import { NativeElement, Component } from '../core/Component'; import { MatchFlag, ScrollHint, SortOrder } from '../QtEnums'; import { QTableWidgetItem } from './QTableWidgetItem'; @@ -39,7 +39,7 @@ win.show(); */ export class QTableWidget extends QAbstractScrollArea { items: Set; - constructor(rows: number, columns: number, parent?: NodeWidget) { + constructor(rows: number, columns: number, parent?: QWidget) { let native; if (parent) { native = new addon.QTableWidget(rows, columns, parent.native); @@ -59,7 +59,7 @@ export class QTableWidget extends QAbstractScrollArea { editItem(item: Component): void { this.native.editItem(item.native); } - setCellWidget(row: number, column: number, widget: NodeWidget): void { + setCellWidget(row: number, column: number, widget: QWidget): void { this.native.setCellWidget(row, column, widget.native); this.items.add(widget); } diff --git a/src/lib/QtWidgets/QTextBrowser.ts b/src/lib/QtWidgets/QTextBrowser.ts index 906156c24..dc71e80e1 100644 --- a/src/lib/QtWidgets/QTextBrowser.ts +++ b/src/lib/QtWidgets/QTextBrowser.ts @@ -1,11 +1,11 @@ import addon from '../utils/addon'; -import { NodeWidget } from './QWidget'; +import { QWidget } from './QWidget'; import { NativeElement } from '../core/Component'; import { QUrl } from '../QtCore/QUrl'; import { NodeTextEdit, QTextEditSignals } from './QTextEdit'; /** - + > Create and control text browser. * **This class is a JS wrapper around Qt's [QTextBrowser class](https://doc.qt.io/qt-5/qtextbrowser.html)** @@ -22,9 +22,7 @@ const textBrowser = new QTextBrowser(); */ export class QTextBrowser extends NodeTextEdit { - constructor(); - constructor(parent: NodeWidget); - constructor(parent?: NodeWidget) { + constructor(parent?: QWidget) { let native: NativeElement; if (parent) { native = new addon.QTextBrowser(parent.native); diff --git a/src/lib/QtWidgets/QTextEdit.ts b/src/lib/QtWidgets/QTextEdit.ts index f7e9d2a20..1b2f1cb72 100644 --- a/src/lib/QtWidgets/QTextEdit.ts +++ b/src/lib/QtWidgets/QTextEdit.ts @@ -1,5 +1,5 @@ import addon from '../utils/addon'; -import { NodeWidget } from './QWidget'; +import { QWidget } from './QWidget'; import { QAbstractScrollArea, QAbstractScrollAreaSignals } from './QAbstractScrollArea'; import { AlignmentFlag, TextInteractionFlag } from '../QtEnums'; import { QFont } from '../QtGui/QFont'; @@ -239,7 +239,7 @@ export enum WrapMode { } export class QTextEdit extends NodeTextEdit { - constructor(parent?: NodeWidget) { + constructor(parent?: QWidget) { let native; if (parent) { native = new addon.QTextEdit(parent.native); diff --git a/src/lib/QtWidgets/QTimeEdit.ts b/src/lib/QtWidgets/QTimeEdit.ts index 7b38d39d3..46500db0f 100644 --- a/src/lib/QtWidgets/QTimeEdit.ts +++ b/src/lib/QtWidgets/QTimeEdit.ts @@ -1,5 +1,5 @@ import addon from '../utils/addon'; -import { NodeWidget } from './QWidget'; +import { QWidget } from './QWidget'; import { NodeDateTimeEdit } from './QDateTimeEdit'; /** @@ -20,7 +20,7 @@ const timeEdit = new QTimeEdit(); ``` */ export class QTimeEdit extends NodeDateTimeEdit { - constructor(parent?: NodeWidget) { + constructor(parent?: QWidget) { let native; if (parent) { native = new addon.QTimeEdit(parent.native); diff --git a/src/lib/QtWidgets/QToolButton.ts b/src/lib/QtWidgets/QToolButton.ts index 3a8cf9729..9fd78bbdd 100644 --- a/src/lib/QtWidgets/QToolButton.ts +++ b/src/lib/QtWidgets/QToolButton.ts @@ -1,5 +1,5 @@ import addon from '../utils/addon'; -import { NodeWidget } from './QWidget'; +import { QWidget } from './QWidget'; import { NativeElement, NativeRawPointer, Component } from '../core/Component'; import { QAbstractButton, QAbstractButtonSignals } from './QAbstractButton'; import { ToolButtonStyle } from '../QtEnums/ToolButtonStyle'; @@ -29,7 +29,7 @@ export class QToolButton extends QAbstractButton { private _defaultAction?: QAction | null; private _menu?: QMenu | null; - constructor(arg?: NodeWidget | NativeRawPointer | NativeElement, disableNativeDeletion = true) { + constructor(arg?: QWidget | NativeRawPointer | NativeElement, disableNativeDeletion = true) { let native; let parent: Component | undefined; if (checkIfNativeElement(arg)) { @@ -37,7 +37,7 @@ export class QToolButton extends QAbstractButton { } else if (checkIfNapiExternal(arg)) { native = new addon.QToolButton(arg, disableNativeDeletion); } else if (arg) { - const parentWidget = arg as NodeWidget; + const parentWidget = arg as QWidget; native = new addon.QToolButton(parentWidget.native); parent = parentWidget; } else { diff --git a/src/lib/QtWidgets/QTreeWidget.ts b/src/lib/QtWidgets/QTreeWidget.ts index 1e60d70eb..27b38a218 100644 --- a/src/lib/QtWidgets/QTreeWidget.ts +++ b/src/lib/QtWidgets/QTreeWidget.ts @@ -1,5 +1,5 @@ import addon from '../utils/addon'; -import { NodeWidget, QWidget } from './QWidget'; +import { QWidget } from './QWidget'; import { NativeElement } from '../core/Component'; import { QAbstractScrollArea, QAbstractScrollAreaSignals } from './QAbstractScrollArea'; import { QTreeWidgetItem } from './QTreeWidgetItem'; @@ -52,7 +52,7 @@ export class QTreeWidget extends QAbstractScrollArea { topLevelItems: Set; itemWidgets: Map; - constructor(parent?: NodeWidget) { + constructor(parent?: QWidget) { let native; if (parent) { native = new addon.QTreeWidget(parent.native); diff --git a/src/lib/QtWidgets/QWidget.ts b/src/lib/QtWidgets/QWidget.ts index 99f776552..2f0039ffb 100644 --- a/src/lib/QtWidgets/QWidget.ts +++ b/src/lib/QtWidgets/QWidget.ts @@ -23,49 +23,51 @@ import { QStyle } from '../QtGui/QStyle'; import { QWindow } from '../QtGui/QWindow'; /** + > Create and control views. -> Abstract class to add functionalities common to all Widgets. +* **This class is a JS wrapper around Qt's [QWidget class](https://doc.qt.io/qt-5/qwidget.html)** -**This class implements all methods, properties of Qt's [QWidget class](https://doc.qt.io/qt-5/qwidget.html) so that it can be inherited by all widgets** +A `QWidget` can be used to encapsulate other widgets and provide structure. It functions similar to a `div` in the web world. -`NodeWidget` is an abstract class and hence no instances of the same should be created. It exists so that we can add similar functionalities to all widget's easily. Additionally it helps in type checking process. If you wish to create a `div` like widget use [QWidget](QWidget.md) instead. - -**NodeWidget is the base class for all widgets.** ### Example ```javascript -const { - NodeWidget, - QPushButton, - QWidget, - QRadioButton -} = require("@nodegui/nodegui"); +const { QWidget } = require("@nodegui/nodegui"); -// showWidget can accept any widget since it expects NodeWidget -const showWidget = (widget: NodeWidget) => { - widget.show(); -}; - -showWidget(new QPushButton()); -showWidget(new QWidget()); -showWidget(new QRadioButton()); +const view = new QWidget(); +view.setObjectName("container"); //Similar to setting `id` on the web +view.setLayout(new FlexLayout()); ``` -All Widgets should extend from NodeWidget -Implement all native QWidget methods here so that all widgets get access to those aswell - */ -export abstract class NodeWidget extends YogaWidget { +export class QWidget extends YogaWidget { _layout?: NodeLayout; - _rawInlineStyle = ''; - type = 'widget'; + _rawInlineStyle: string; + type: string; private _effect?: QGraphicsEffect | null; - constructor(native: NativeElement) { + + constructor(arg?: QWidget | NativeElement) { + let native: NativeElement; + let parent: QWidget = null; + if (checkIfNativeElement(arg)) { + native = arg as NativeElement; + } else if (arg as QWidget) { + parent = arg as QWidget; + native = new addon.QWidget(parent.native); + } else { + native = new addon.QWidget(); + } super(native); + this._rawInlineStyle = ''; + this.type = 'widget'; + + this.setNodeParent(parent); + this.setStyleSheet = memoizeOne(this.setStyleSheet); this.setInlineStyle = memoizeOne(this.setInlineStyle); this.setObjectName = memoizeOne(this.setObjectName); } + get layout(): NodeLayout | undefined { return this._layout; } @@ -659,38 +661,3 @@ export interface QWidgetSignals extends QObjectSignals { windowIconChanged: (iconNative: NativeElement) => void; customContextMenuRequested: (pos: { x: number; y: number }) => void; } - -/** - > Create and control views. - -* **This class is a JS wrapper around Qt's [QWidget class](https://doc.qt.io/qt-5/qwidget.html)** - -A `QWidget` can be used to encapsulate other widgets and provide structure. It functions similar to a `div` in the web world. - - -### Example - -```javascript -const { QWidget } = require("@nodegui/nodegui"); - -const view = new QWidget(); -view.setObjectName("container"); //Similar to setting `id` on the web -view.setLayout(new FlexLayout()); -``` - */ -export class QWidget extends NodeWidget { - constructor(arg?: NodeWidget | NativeElement) { - let native; - let parent; - if (checkIfNativeElement(arg)) { - native = arg as NativeElement; - } else if (arg as NodeWidget) { - parent = arg as NodeWidget; - native = new addon.QWidget(parent.native); - } else { - native = new addon.QWidget(); - } - super(native); - this.setNodeParent(parent); - } -} diff --git a/src/lib/core/FlexLayout.ts b/src/lib/core/FlexLayout.ts index 580221a99..ec643d3fc 100644 --- a/src/lib/core/FlexLayout.ts +++ b/src/lib/core/FlexLayout.ts @@ -1,5 +1,5 @@ import addon from '../utils/addon'; -import { NodeWidget } from '../QtWidgets/QWidget'; +import { QWidget } from '../QtWidgets/QWidget'; import { NodeLayout, QLayoutSignals } from '../QtWidgets/QLayout'; import { FlexNode } from './YogaWidget'; @@ -34,7 +34,7 @@ layout.addWidget(label2); export class FlexLayout extends NodeLayout { protected flexNode?: FlexNode; - constructor(parent?: NodeWidget) { + constructor(parent?: QWidget) { let native; if (parent) { native = new addon.FlexLayout(parent.native); @@ -47,7 +47,7 @@ export class FlexLayout extends NodeLayout { } } - addWidget(childWidget: NodeWidget, childFlexNode?: FlexNode): void { + addWidget(childWidget: QWidget, childFlexNode?: FlexNode): void { const childYogaNode = childFlexNode || childWidget.getFlexNode(); if (this.nodeChildren.has(childWidget)) { this.removeWidget(childWidget, childYogaNode); @@ -57,8 +57,8 @@ export class FlexLayout extends NodeLayout { } insertChildBefore( - childWidget: NodeWidget, - beforeChildWidget: NodeWidget, + childWidget: QWidget, + beforeChildWidget: QWidget, childFlexNode?: FlexNode, beforeChildFlexNode?: FlexNode, ): void { @@ -77,7 +77,7 @@ export class FlexLayout extends NodeLayout { this.native.insertChildBefore(childWidget.native, beforeChildYogaNode, childYogaNode); } - removeWidget(childWidget: NodeWidget, childFlexNode?: FlexNode): void { + removeWidget(childWidget: QWidget, childFlexNode?: FlexNode): void { if (!this.nodeChildren.has(childWidget)) { return; } @@ -91,16 +91,16 @@ export class FlexLayout extends NodeLayout { this.native.setFlexNode(flexNode); } - getChildIndex(childWidget: NodeWidget): number { + getChildIndex(childWidget: QWidget): number { const widgetArr = Array.from(this.nodeChildren); return widgetArr.indexOf(childWidget); } - getNextSibling(childWidget: NodeWidget): NodeWidget | null { + getNextSibling(childWidget: QWidget): QWidget | null { const childIndex = this.getChildIndex(childWidget); const widgetArr = Array.from(this.nodeChildren); if (childIndex !== -1) { - return (widgetArr[childIndex + 1] as NodeWidget) || null; + return (widgetArr[childIndex + 1] as QWidget) || null; } return null; } diff --git a/src/lib/core/Style/StyleSheet.ts b/src/lib/core/Style/StyleSheet.ts index aba56315e..cd9fbb657 100644 --- a/src/lib/core/Style/StyleSheet.ts +++ b/src/lib/core/Style/StyleSheet.ts @@ -1,7 +1,7 @@ import postcss from 'postcss'; import cuid from 'cuid'; import nodeguiAutoPrefixer from 'postcss-nodegui-autoprefixer'; -import { NodeWidget, QWidgetSignals } from '../../QtWidgets/QWidget'; +import { QWidget, QWidgetSignals } from '../../QtWidgets/QWidget'; export class StyleSheet { static create(cssString: string): string { try { @@ -14,7 +14,7 @@ export class StyleSheet { } export function prepareInlineStyleSheet( - widget: NodeWidget, + widget: QWidget, rawStyle: string, ): string { const inlineStyle = StyleSheet.create(rawStyle); From b7476a4ea12063dda3969e65e06dd50d9a15949e Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Fri, 29 Apr 2022 19:40:30 +0200 Subject: [PATCH 05/28] Remove `NodeFrame`, use `QFrame` instead --- src/lib/QtWidgets/QAbstractScrollArea.ts | 4 +- src/lib/QtWidgets/QFrame.ts | 64 ++++++++++++------------ src/lib/QtWidgets/QLabel.ts | 4 +- src/lib/QtWidgets/QSplitter.ts | 4 +- src/lib/QtWidgets/QStackedWidget.ts | 4 +- 5 files changed, 39 insertions(+), 41 deletions(-) diff --git a/src/lib/QtWidgets/QAbstractScrollArea.ts b/src/lib/QtWidgets/QAbstractScrollArea.ts index e1a02471a..7fb63a4ac 100644 --- a/src/lib/QtWidgets/QAbstractScrollArea.ts +++ b/src/lib/QtWidgets/QAbstractScrollArea.ts @@ -1,5 +1,5 @@ import { QWidget } from './QWidget'; -import { NodeFrame, QFrameSignals } from './QFrame'; +import { QFrame, QFrameSignals } from './QFrame'; import { ScrollBarPolicy } from '../QtEnums/ScrollBarPolicy'; import { QSize } from '../QtCore/QSize'; import { QScrollBar } from './QScrollBar'; @@ -17,7 +17,7 @@ import { QScrollBar } from './QScrollBar'; QAbstractScrollArea will list all methods and properties that are common to all scrollable widgets in the NodeGui world. */ -export abstract class QAbstractScrollArea extends NodeFrame { +export abstract class QAbstractScrollArea extends QFrame { viewportWidget?: QWidget; setViewport(widget: QWidget): void { this.viewportWidget = widget; diff --git a/src/lib/QtWidgets/QFrame.ts b/src/lib/QtWidgets/QFrame.ts index a292c2c7f..bac971517 100644 --- a/src/lib/QtWidgets/QFrame.ts +++ b/src/lib/QtWidgets/QFrame.ts @@ -4,7 +4,37 @@ import { NativeElement } from '../core/Component'; import { checkIfNativeElement } from '../utils/helpers'; import { QRect } from '../QtCore/QRect'; -export abstract class NodeFrame extends QWidget { +/** + > Create and control frame. + +* **This class is a JS wrapper around Qt's [QFrame class](https://doc.qt.io/qt-5/qframe.html)** + +The QFrame class is the base class of widgets that can have a frame. It can be used directly for creating simple placeholder frames without any contents. + +### Example + +```javascript +const { QFrame } = require("@nodegui/nodegui"); + +const frame = new QFrame(); +``` + */ +export class QFrame extends QWidget { + constructor(arg?: QWidget | NativeElement) { + let native: NativeElement; + let parent; + if (checkIfNativeElement(arg)) { + native = arg as NativeElement; + } else if (arg as QWidget) { + parent = arg as QWidget; + native = new addon.QFrame(parent.native); + } else { + native = new addon.QFrame(); + } + super(native); + this.setNodeParent(parent); + } + setFrameRect(r: QRect): void { this.setProperty('frameRect', r.native); } @@ -63,35 +93,3 @@ export enum Shape { } export type QFrameSignals = QWidgetSignals; - -/** - > Create and control frame. - -* **This class is a JS wrapper around Qt's [QFrame class](https://doc.qt.io/qt-5/qframe.html)** - -The QFrame class is the base class of widgets that can have a frame. It can be used directly for creating simple placeholder frames without any contents. - -### Example - -```javascript -const { QFrame } = require("@nodegui/nodegui"); - -const frame = new QFrame(); -``` - */ -export class QFrame extends NodeFrame { - constructor(arg?: QWidget | NativeElement) { - let native: NativeElement; - let parent; - if (checkIfNativeElement(arg)) { - native = arg as NativeElement; - } else if (arg as QWidget) { - parent = arg as QWidget; - native = new addon.QFrame(parent.native); - } else { - native = new addon.QFrame(); - } - super(native); - this.setNodeParent(parent); - } -} diff --git a/src/lib/QtWidgets/QLabel.ts b/src/lib/QtWidgets/QLabel.ts index 66f10ff15..b71c10679 100644 --- a/src/lib/QtWidgets/QLabel.ts +++ b/src/lib/QtWidgets/QLabel.ts @@ -1,6 +1,6 @@ import addon from '../utils/addon'; import { QWidget } from './QWidget'; -import { NodeFrame, QFrameSignals } from './QFrame'; +import { QFrame, QFrameSignals } from './QFrame'; import { QPixmap } from '../QtGui/QPixmap'; import { QMovie } from '../QtGui/QMovie'; import { AlignmentFlag } from '../QtEnums/AlignmentFlag'; @@ -26,7 +26,7 @@ label.setText("Hello"); ``` */ -export class QLabel extends NodeFrame { +export class QLabel extends QFrame { private _picture?: QPicture; private _pixmap?: QPixmap; private _movie?: QMovie; diff --git a/src/lib/QtWidgets/QSplitter.ts b/src/lib/QtWidgets/QSplitter.ts index e00ea5612..807813cd5 100644 --- a/src/lib/QtWidgets/QSplitter.ts +++ b/src/lib/QtWidgets/QSplitter.ts @@ -1,6 +1,6 @@ import addon from '../utils/addon'; import { QWidget } from './QWidget'; -import { NodeFrame, QFrameSignals } from './QFrame'; +import { QFrame, QFrameSignals } from './QFrame'; import { NativeElement } from '../core/Component'; import { Orientation } from '../QtEnums'; @@ -34,7 +34,7 @@ splitterHorizontal.addWidget(right); ``` */ -export class QSplitter extends NodeFrame { +export class QSplitter extends QFrame { constructor(parent?: QWidget) { let native: NativeElement; if (parent) { diff --git a/src/lib/QtWidgets/QStackedWidget.ts b/src/lib/QtWidgets/QStackedWidget.ts index dd7b0a639..a0c45831f 100644 --- a/src/lib/QtWidgets/QStackedWidget.ts +++ b/src/lib/QtWidgets/QStackedWidget.ts @@ -1,6 +1,6 @@ import addon from '../utils/addon'; import { QWidget } from './QWidget'; -import { NodeFrame, QFrameSignals } from './QFrame'; +import { QFrame, QFrameSignals } from './QFrame'; /** @@ -43,7 +43,7 @@ win.show(); ``` */ -export class QStackedWidget extends NodeFrame { +export class QStackedWidget extends QFrame { constructor(parent?: QWidget) { let native; if (parent) { From 83e9c096901b1839cef6604d0b0848f507891f00 Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Fri, 29 Apr 2022 19:55:13 +0200 Subject: [PATCH 06/28] Remove `NodeLayout`, use `QLayout` instead --- src/index.ts | 2 +- src/lib/QtWidgets/QBoxLayout.ts | 10 +++++----- src/lib/QtWidgets/QGridLayout.ts | 6 +++--- src/lib/QtWidgets/QLayout.ts | 14 +++++--------- src/lib/QtWidgets/QMainWindow.ts | 6 +++--- src/lib/QtWidgets/QWidget.ts | 10 +++++----- src/lib/core/FlexLayout.ts | 4 ++-- 7 files changed, 24 insertions(+), 28 deletions(-) diff --git a/src/index.ts b/src/index.ts index 0e989d741..1d148bd03 100644 --- a/src/index.ts +++ b/src/index.ts @@ -40,7 +40,7 @@ export { QWindow } from './lib/QtGui/QWindow'; export { WidgetEventTypes } from './lib/core/EventWidget'; // Abstract: export { QWidget, QWidgetSignals } from './lib/QtWidgets/QWidget'; -export { NodeLayout, QLayoutSignals, SizeConstraint } from './lib/QtWidgets/QLayout'; +export { QLayout, QLayoutSignals, SizeConstraint } from './lib/QtWidgets/QLayout'; export { QAbstractScrollArea } from './lib/QtWidgets/QAbstractScrollArea'; export { QAbstractSlider, QAbstractSliderSignals, SliderAction } from './lib/QtWidgets/QAbstractSlider'; export { QAbstractButton, QAbstractButtonSignals } from './lib/QtWidgets/QAbstractButton'; diff --git a/src/lib/QtWidgets/QBoxLayout.ts b/src/lib/QtWidgets/QBoxLayout.ts index daffb431f..5c57c4935 100644 --- a/src/lib/QtWidgets/QBoxLayout.ts +++ b/src/lib/QtWidgets/QBoxLayout.ts @@ -1,6 +1,6 @@ import addon from '../utils/addon'; import { QWidget } from './QWidget'; -import { NodeLayout, QLayoutSignals } from './QLayout'; +import { QLayout, QLayoutSignals } from './QLayout'; import { NativeElement } from '../core/Component'; import { AlignmentFlag, Direction } from '../QtEnums'; @@ -25,8 +25,8 @@ boxLayout.addWidget(new QCalendarWidget()); centralWidget.setLayout(boxLayout); ``` */ -export class QBoxLayout extends NodeLayout { - childLayouts: Set>; +export class QBoxLayout extends QLayout { + childLayouts: Set; constructor(dir: Direction, parent?: QWidget) { let native: NativeElement; if (parent) { @@ -38,7 +38,7 @@ export class QBoxLayout extends NodeLayout { this.setNodeParent(parent); this.childLayouts = new Set(); } - addLayout(layout: NodeLayout, stretch = 0): void { + addLayout(layout: QLayout, stretch = 0): void { this.native.addLayout(layout.native, stretch); this.childLayouts.add(layout); } @@ -62,7 +62,7 @@ export class QBoxLayout extends NodeLayout { direction(): Direction { return this.native.direction(); } - insertLayout(index: number, layout: NodeLayout, stretch = 0): void { + insertLayout(index: number, layout: QLayout, stretch = 0): void { this.native.insertLayout(index, layout.native, stretch); this.childLayouts.add(layout); } diff --git a/src/lib/QtWidgets/QGridLayout.ts b/src/lib/QtWidgets/QGridLayout.ts index d2bbe1fd4..9672d8fe0 100644 --- a/src/lib/QtWidgets/QGridLayout.ts +++ b/src/lib/QtWidgets/QGridLayout.ts @@ -1,6 +1,6 @@ import addon from '../utils/addon'; import { QWidget } from './QWidget'; -import { NodeLayout, QLayoutSignals } from './QLayout'; +import { QLayout, QLayoutSignals } from './QLayout'; import { NativeElement } from '../core/Component'; import { AlignmentFlag } from '../QtEnums'; @@ -29,7 +29,7 @@ layout.addWidget(label2); ``` */ -export class QGridLayout extends NodeLayout { +export class QGridLayout extends QLayout { constructor(parent?: QWidget) { let native: NativeElement; if (parent) { @@ -42,7 +42,7 @@ export class QGridLayout extends NodeLayout { } addLayout( - layout: NodeLayout, + layout: QLayout, row: number, column: number, rowSpan = 1, diff --git a/src/lib/QtWidgets/QLayout.ts b/src/lib/QtWidgets/QLayout.ts index ec0879526..e0c2864b3 100644 --- a/src/lib/QtWidgets/QLayout.ts +++ b/src/lib/QtWidgets/QLayout.ts @@ -9,21 +9,21 @@ import { QObject, QObjectSignals } from '../QtCore/QObject'; **This class implements all methods, properties of Qt's [QLayout class](https://doc.qt.io/qt-5/qlayout.html) so that it can be inherited by all layouts** -`NodeLayout` is an abstract class and hence no instances of the same should be created. It exists so that we can add similar functionalities to all layout's easily. Additionally it helps in typechecking process. +`QLayout` is an abstract class and hence no instances of the same should be created. ### Example ```javascript const { - NodeLayout, + QLayout, FlexLayout, GridLayout, QPushButton, QWidget } = require("@nodegui/nodegui"); -// addChildToLayout can accept any layout since it expects NodeLayout -const addChildToLayout = (layout: NodeLayout, widget: QWidget) => { +// addChildToLayout can accept any layout since it expects QLayout +const addChildToLayout = (layout: QLayout, widget: QWidget) => { layout.addWidget(widget); }; @@ -31,7 +31,7 @@ addChildToLayout(new FlexLayout(), new QPushButton()); addChildToLayout(new GridLayout(), new QWidget()); ``` */ -export abstract class NodeLayout extends QObject { +export abstract class QLayout extends QObject { type = 'layout'; abstract addWidget(childWidget: QWidget, ...args: any[]): void; abstract removeWidget(childWidget: QWidget): void; @@ -67,10 +67,6 @@ export abstract class NodeLayout extends QObject } } -// export class QLayout extends NodeLayout { //Dont need QLayout for now -// native: any; -// } - export enum SizeConstraint { SetDefaultConstraint = 0, SetNoConstraint = 1, diff --git a/src/lib/QtWidgets/QMainWindow.ts b/src/lib/QtWidgets/QMainWindow.ts index f782508c5..bd906c702 100644 --- a/src/lib/QtWidgets/QMainWindow.ts +++ b/src/lib/QtWidgets/QMainWindow.ts @@ -1,6 +1,6 @@ import addon from '../utils/addon'; import { QWidget, QWidgetSignals } from './QWidget'; -import { NodeLayout } from './QLayout'; +import { QLayout } from './QLayout'; import { QMenuBar } from './QMenuBar'; import { QStatusBar } from './QStatusBar'; import { NativeElement } from '../core/Component'; @@ -46,7 +46,7 @@ export class QMainWindow extends QWidget { super(native); this.setNodeParent(parent); - this.setLayout = (parentLayout: NodeLayout): void => { + this.setLayout = (parentLayout: QLayout): void => { if (this.centralWidget) { this.centralWidget.setLayout(parentLayout); } else { @@ -80,7 +80,7 @@ export class QMainWindow extends QWidget { setMenuWidget(menuWidget: QWidget): void { this.native.setMenuWidget(menuWidget.native); } - get layout(): NodeLayout | undefined { + get layout(): QLayout | undefined { if (this.centralWidget) { return this.centralWidget.layout; } diff --git a/src/lib/QtWidgets/QWidget.ts b/src/lib/QtWidgets/QWidget.ts index 2f0039ffb..d514a24c4 100644 --- a/src/lib/QtWidgets/QWidget.ts +++ b/src/lib/QtWidgets/QWidget.ts @@ -1,5 +1,5 @@ import addon from '../utils/addon'; -import { NodeLayout } from './QLayout'; +import { QLayout } from './QLayout'; import { NativeElement } from '../core/Component'; import { FlexLayout } from '../core/FlexLayout'; import { WidgetAttribute, WindowType, ContextMenuPolicy, FocusReason, FocusPolicy } from '../QtEnums'; @@ -41,7 +41,7 @@ view.setLayout(new FlexLayout()); ``` */ export class QWidget extends YogaWidget { - _layout?: NodeLayout; + _layout?: QLayout; _rawInlineStyle: string; type: string; private _effect?: QGraphicsEffect | null; @@ -68,10 +68,10 @@ export class QWidget extends Yo this.setObjectName = memoizeOne(this.setObjectName); } - get layout(): NodeLayout | undefined { + get layout(): QLayout | undefined { return this._layout; } - set layout(l: NodeLayout | undefined) { + set layout(l: QLayout | undefined) { this._layout = l; } // *** Public Functions *** @@ -380,7 +380,7 @@ export class QWidget extends Yo this.native.setStyleSheet(style); } } - setLayout(parentLayout: NodeLayout): void { + setLayout(parentLayout: QLayout): void { const flexLayout = parentLayout as FlexLayout; this.native.setLayout(parentLayout.native); if (flexLayout.setFlexNode) { diff --git a/src/lib/core/FlexLayout.ts b/src/lib/core/FlexLayout.ts index ec643d3fc..2f8d56d57 100644 --- a/src/lib/core/FlexLayout.ts +++ b/src/lib/core/FlexLayout.ts @@ -1,6 +1,6 @@ import addon from '../utils/addon'; import { QWidget } from '../QtWidgets/QWidget'; -import { NodeLayout, QLayoutSignals } from '../QtWidgets/QLayout'; +import { QLayout, QLayoutSignals } from '../QtWidgets/QLayout'; import { FlexNode } from './YogaWidget'; export type FlexLayoutSignals = QLayoutSignals; @@ -31,7 +31,7 @@ layout.addWidget(label); layout.addWidget(label2); ``` */ -export class FlexLayout extends NodeLayout { +export class FlexLayout extends QLayout { protected flexNode?: FlexNode; constructor(parent?: QWidget) { From 165bb820bc3fc5fe5b49d309785ac3b114ca4750 Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Fri, 29 Apr 2022 20:05:21 +0200 Subject: [PATCH 07/28] Remove `NodeDateTimeEdit`, use `QDateTimeEdit` --- src/index.ts | 2 +- src/lib/QtWidgets/QDateEdit.ts | 4 +- src/lib/QtWidgets/QDateTimeEdit.ts | 81 ++++++++++++++++-------------- src/lib/QtWidgets/QTimeEdit.ts | 4 +- 4 files changed, 49 insertions(+), 42 deletions(-) diff --git a/src/index.ts b/src/index.ts index 1d148bd03..01ab996d1 100644 --- a/src/index.ts +++ b/src/index.ts @@ -65,7 +65,7 @@ export { QCalendarWidget, QCalendarWidgetSignals } from './lib/QtWidgets/QCalend export { QCheckBox, QCheckBoxSignals } from './lib/QtWidgets/QCheckBox'; export { QColorDialog, QColorDialogSignals } from './lib/QtWidgets/QColorDialog'; export { QDateEdit } from './lib/QtWidgets/QDateEdit'; -export { QDateTimeEdit, NodeDateTimeEdit, QDateTimeEditSignals } from './lib/QtWidgets/QDateTimeEdit'; +export { QDateTimeEdit, QDateTimeEditSignals } from './lib/QtWidgets/QDateTimeEdit'; export { QLabel, QLabelSignals } from './lib/QtWidgets/QLabel'; export { QLCDNumber, QLCDNumberSignals, Mode, SegmentStyle } from './lib/QtWidgets/QLCDNumber'; export { QDial, QDialSignals } from './lib/QtWidgets/QDial'; diff --git a/src/lib/QtWidgets/QDateEdit.ts b/src/lib/QtWidgets/QDateEdit.ts index faf9b4766..a80e4ce3a 100644 --- a/src/lib/QtWidgets/QDateEdit.ts +++ b/src/lib/QtWidgets/QDateEdit.ts @@ -1,7 +1,7 @@ import addon from '../utils/addon'; import { QWidget } from './QWidget'; import { NativeElement } from '../core/Component'; -import { NodeDateTimeEdit } from './QDateTimeEdit'; +import { QDateTimeEdit } from './QDateTimeEdit'; /** @@ -20,7 +20,7 @@ const dateEdit = new QDateEdit(); // must be implemented ``` */ -export class QDateEdit extends NodeDateTimeEdit { +export class QDateEdit extends QDateTimeEdit { constructor(parent?: QWidget) { let native: NativeElement; if (parent) { diff --git a/src/lib/QtWidgets/QDateTimeEdit.ts b/src/lib/QtWidgets/QDateTimeEdit.ts index c93c40d79..b09d8360f 100644 --- a/src/lib/QtWidgets/QDateTimeEdit.ts +++ b/src/lib/QtWidgets/QDateTimeEdit.ts @@ -6,9 +6,52 @@ import { QDate } from '../QtCore/QDate'; import { QDateTime } from '../QtCore/QDateTime'; import { QTime } from '../QtCore/QTime'; import { TimeSpec } from '../QtEnums'; +import { NativeElement } from '../core/Component'; +import { checkIfNativeElement } from '../utils/helpers'; -export abstract class NodeDateTimeEdit extends QAbstractSpinBox { +/** + +> Creates and controls a widget for editing dates and times with spin box layout. + +* **This class is a JS wrapper around Qt's [QDateTimeEdit class](https://doc.qt.io/qt-5/qdatetimeedit.html)** + +### Example + +```javascript +const { QDateTimeEdit, QDate, QTime } = require("@nodegui/nodegui"); + +const dateTimeEdit = new QDateTimeEdit(); + +let date = new QDate(); +date.setDate(2020, 1, 1); + +let time = new QTime(); +time.setHMS(16, 30, 0); + +dateTimeEdit.setDate(date); +dateTimeEdit.setTime(time); +``` + */ +export class QDateTimeEdit extends QAbstractSpinBox { calendar?: QCalendarWidget; + + constructor(arg?: QWidget | NativeElement) { + let native: NativeElement; + let parent: QWidget = null; + if (checkIfNativeElement(arg)) { + native = arg as NativeElement; + } else if (arg) { + parent = arg as QWidget; + native = new addon.QDateTimeEdit(parent.native); + } else { + native = new addon.QDateTimeEdit(); + } + super(native); + if (parent != null) { + this.setNodeParent(parent); + } + } + setCalendarWidget(calendarWidget: QCalendarWidget): void { this.calendar = calendarWidget; this.native.setCalendarWidget(calendarWidget.native); @@ -61,42 +104,6 @@ export abstract class NodeDateTimeEdit extends QAbstractSpinBox Creates and controls a widget for editing dates and times with spin box layout. - -* **This class is a JS wrapper around Qt's [QDateTimeEdit class](https://doc.qt.io/qt-5/qdatetimeedit.html)** - -### Example - -```javascript -const { QDateTimeEdit, QDate, QTime } = require("@nodegui/nodegui"); - -const dateTimeEdit = new QDateTimeEdit(); - -let date = new QDate(); -date.setDate(2020, 1, 1); - -let time = new QTime(); -time.setHMS(16, 30, 0); - -dateTimeEdit.setDate(date); -dateTimeEdit.setTime(time); -``` - */ -export class QDateTimeEdit extends NodeDateTimeEdit { - constructor(parent?: QWidget) { - let native; - if (parent) { - native = new addon.QDateTimeEdit(parent.native); - } else { - native = new addon.QDateTimeEdit(); - } - super(native); - this.setNodeParent(parent); - } -} - export interface QDateTimeEditSignals extends QAbstractSpinBoxSignals { dateChanged: (date: QDate) => void; dateTimeChanged: (datetime: QDateTime) => void; diff --git a/src/lib/QtWidgets/QTimeEdit.ts b/src/lib/QtWidgets/QTimeEdit.ts index 46500db0f..69b2d3a2e 100644 --- a/src/lib/QtWidgets/QTimeEdit.ts +++ b/src/lib/QtWidgets/QTimeEdit.ts @@ -1,6 +1,6 @@ import addon from '../utils/addon'; import { QWidget } from './QWidget'; -import { NodeDateTimeEdit } from './QDateTimeEdit'; +import { QDateTimeEdit } from './QDateTimeEdit'; /** @@ -19,7 +19,7 @@ const timeEdit = new QTimeEdit(); // must be implemented ``` */ -export class QTimeEdit extends NodeDateTimeEdit { +export class QTimeEdit extends QDateTimeEdit { constructor(parent?: QWidget) { let native; if (parent) { From 23759b1aaa979272ab3d513cdd0217cee74610c1 Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Fri, 29 Apr 2022 20:10:27 +0200 Subject: [PATCH 08/28] Remove `NodeDialog`, use `QDialog` instead --- src/lib/QtWidgets/QColorDialog.ts | 4 +-- src/lib/QtWidgets/QDialog.ts | 52 +++++++++++++--------------- src/lib/QtWidgets/QErrorMessage.ts | 4 +-- src/lib/QtWidgets/QFileDialog.ts | 4 +-- src/lib/QtWidgets/QFontDialog.ts | 4 +-- src/lib/QtWidgets/QInputDialog.ts | 4 +-- src/lib/QtWidgets/QMessageBox.ts | 4 +-- src/lib/QtWidgets/QProgressDialog.ts | 4 +-- 8 files changed, 38 insertions(+), 42 deletions(-) diff --git a/src/lib/QtWidgets/QColorDialog.ts b/src/lib/QtWidgets/QColorDialog.ts index bf7bb9ee1..fcd6941cc 100644 --- a/src/lib/QtWidgets/QColorDialog.ts +++ b/src/lib/QtWidgets/QColorDialog.ts @@ -1,7 +1,7 @@ import addon from '../utils/addon'; import { QWidget } from './QWidget'; import { NativeElement } from '../core/Component'; -import { NodeDialog, QDialogSignals } from './QDialog'; +import { QDialog, QDialogSignals } from './QDialog'; import { QColor } from '../QtGui/QColor'; /** @@ -26,7 +26,7 @@ console.log(color.red(), color.green(), color.blue()); ``` */ -export class QColorDialog extends NodeDialog { +export class QColorDialog extends QDialog { constructor(parent?: QWidget) { let native: NativeElement; if (parent) { diff --git a/src/lib/QtWidgets/QDialog.ts b/src/lib/QtWidgets/QDialog.ts index 9ef4d2eaa..fdf692670 100644 --- a/src/lib/QtWidgets/QDialog.ts +++ b/src/lib/QtWidgets/QDialog.ts @@ -5,9 +5,30 @@ import { checkIfNativeElement } from '../utils/helpers'; import { QWidget, QWidgetSignals } from './QWidget'; import { DialogCode } from '../QtEnums'; -// All Dialogs should extend from NodeDialog -// Implement all native QDialog methods here so that all dialogs get access to those aswell -export abstract class NodeDialog extends QWidget { +/** + +> This is the base class of dialog windows. + +* **This class is a JS wrapper around Qt's [QDialog class](https://doc.qt.io/qt-5/qdialog.html)** + +It is inherited by QFileDialog and QMessageBox (n/a QColorDialog, QErrorMessage, QFontDialog, QInputDialog, QMessageBox, QProgressDialog, and QWizard) + */ +export class QDialog extends QWidget { + constructor(arg?: QDialog | NativeElement) { + let native; + let parent; + if (checkIfNativeElement(arg)) { + native = arg as NativeElement; + } else if (arg as QDialog) { + parent = arg as QDialog; + native = new addon.QDialog(parent.native); + } else { + native = new addon.QDialog(); + } + super(native); + this.setNodeParent(parent); + } + setResult(i: number): void { this.native.setResult(i); } @@ -34,31 +55,6 @@ export abstract class NodeDialog extends QWidget } } -/** - -> This is the base class of dialog windows. - -* **This class is a JS wrapper around Qt's [QDialog class](https://doc.qt.io/qt-5/qdialog.html)** - -It is inherited by QFileDialog and QMessageBox (n/a QColorDialog, QErrorMessage, QFontDialog, QInputDialog, QMessageBox, QProgressDialog, and QWizard) - */ -export class QDialog extends NodeDialog { - constructor(arg?: NodeDialog | NativeElement) { - let native; - let parent; - if (checkIfNativeElement(arg)) { - native = arg as NativeElement; - } else if (arg as NodeDialog) { - parent = arg as NodeDialog; - native = new addon.QDialog(parent.native); - } else { - native = new addon.QDialog(); - } - super(native); - this.setNodeParent(parent); - } -} - export interface QDialogSignals extends QWidgetSignals { accepted: () => void; finished: (result: number) => void; diff --git a/src/lib/QtWidgets/QErrorMessage.ts b/src/lib/QtWidgets/QErrorMessage.ts index 1c2dcbe0e..431a503be 100644 --- a/src/lib/QtWidgets/QErrorMessage.ts +++ b/src/lib/QtWidgets/QErrorMessage.ts @@ -1,7 +1,7 @@ import addon from '../utils/addon'; import { QWidget } from './QWidget'; import { NativeElement } from '../core/Component'; -import { NodeDialog, QDialogSignals } from './QDialog'; +import { QDialog, QDialogSignals } from './QDialog'; /** @@ -20,7 +20,7 @@ const errorMessage = new QErrorMessage(); ``` */ -export class QErrorMessage extends NodeDialog { +export class QErrorMessage extends QDialog { constructor(parent?: QWidget) { let native: NativeElement; if (parent) { diff --git a/src/lib/QtWidgets/QFileDialog.ts b/src/lib/QtWidgets/QFileDialog.ts index cfc77dbf7..0d5243f41 100644 --- a/src/lib/QtWidgets/QFileDialog.ts +++ b/src/lib/QtWidgets/QFileDialog.ts @@ -2,7 +2,7 @@ import addon from '../utils/addon'; import { QWidget } from './QWidget'; import { NativeElement } from '../core/Component'; import { AcceptMode, DialogLabel, FileMode, Option, ViewMode } from '../QtEnums'; -import { NodeDialog, QDialogSignals } from './QDialog'; +import { QDialog, QDialogSignals } from './QDialog'; /** @@ -27,7 +27,7 @@ console.log(selectedFiles); ``` */ -export class QFileDialog extends NodeDialog { +export class QFileDialog extends QDialog { constructor(); constructor(parent: QWidget, caption?: string, directory?: string, filter?: string); constructor(parent?: QWidget, caption = 'Select File', directory = '', filter = '') { diff --git a/src/lib/QtWidgets/QFontDialog.ts b/src/lib/QtWidgets/QFontDialog.ts index 9bc642adf..f8c6bb308 100644 --- a/src/lib/QtWidgets/QFontDialog.ts +++ b/src/lib/QtWidgets/QFontDialog.ts @@ -1,7 +1,7 @@ import addon from '../utils/addon'; import { QWidget } from './QWidget'; import { NativeElement } from '../core/Component'; -import { NodeDialog, QDialogSignals } from './QDialog'; +import { QDialog, QDialogSignals } from './QDialog'; import { QFont } from '../QtGui/QFont'; /** @@ -24,7 +24,7 @@ console.log(font); ``` */ -export class QFontDialog extends NodeDialog { +export class QFontDialog extends QDialog { constructor(parent?: QWidget) { let native: NativeElement; if (parent) { diff --git a/src/lib/QtWidgets/QInputDialog.ts b/src/lib/QtWidgets/QInputDialog.ts index b40620df4..69cbfd3dc 100644 --- a/src/lib/QtWidgets/QInputDialog.ts +++ b/src/lib/QtWidgets/QInputDialog.ts @@ -1,6 +1,6 @@ import addon from '../utils/addon'; import { QWidget } from './QWidget'; -import { NodeDialog, QDialogSignals } from './QDialog'; +import { QDialog, QDialogSignals } from './QDialog'; import { EchoMode } from './QLineEdit'; /** @@ -21,7 +21,7 @@ dialog.exec(); ``` */ -export class QInputDialog extends NodeDialog { +export class QInputDialog extends QDialog { constructor(parent?: QWidget) { let native; if (parent) { diff --git a/src/lib/QtWidgets/QMessageBox.ts b/src/lib/QtWidgets/QMessageBox.ts index 7531842f4..7c08774e3 100644 --- a/src/lib/QtWidgets/QMessageBox.ts +++ b/src/lib/QtWidgets/QMessageBox.ts @@ -1,7 +1,7 @@ import addon from '../utils/addon'; import { QWidget } from './QWidget'; import { NativeRawPointer } from '../core/Component'; -import { NodeDialog, QDialogSignals } from './QDialog'; +import { QDialog, QDialogSignals } from './QDialog'; import { QAbstractButton, QAbstractButtonSignals } from './QAbstractButton'; import { QPushButton } from './QPushButton'; @@ -39,7 +39,7 @@ messageBox.exec(); ``` */ -export class QMessageBox extends NodeDialog { +export class QMessageBox extends QDialog { constructor(parent?: QWidget) { let native; if (parent) { diff --git a/src/lib/QtWidgets/QProgressDialog.ts b/src/lib/QtWidgets/QProgressDialog.ts index d21bc5274..031d82e70 100644 --- a/src/lib/QtWidgets/QProgressDialog.ts +++ b/src/lib/QtWidgets/QProgressDialog.ts @@ -1,6 +1,6 @@ import addon from '../utils/addon'; import { QWidget } from './QWidget'; -import { NodeDialog, QDialogSignals } from './QDialog'; +import { QDialog, QDialogSignals } from './QDialog'; /** @@ -19,7 +19,7 @@ const progressDialog = new QProgressDialog(); ``` */ -export class QProgressDialog extends NodeDialog { +export class QProgressDialog extends QDialog { constructor(parent?: QWidget) { let native; if (parent) { From fda93e9dd524138f94c329068d469c806259293b Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Fri, 29 Apr 2022 20:23:30 +0200 Subject: [PATCH 09/28] Remove `NodeTextEdit`, use `QTextEdit` --- src/lib/QtWidgets/QTextBrowser.ts | 4 ++-- src/lib/QtWidgets/QTextEdit.ts | 32 +++++++++++++++++-------------- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/src/lib/QtWidgets/QTextBrowser.ts b/src/lib/QtWidgets/QTextBrowser.ts index dc71e80e1..ca22adb1a 100644 --- a/src/lib/QtWidgets/QTextBrowser.ts +++ b/src/lib/QtWidgets/QTextBrowser.ts @@ -2,7 +2,7 @@ import addon from '../utils/addon'; import { QWidget } from './QWidget'; import { NativeElement } from '../core/Component'; import { QUrl } from '../QtCore/QUrl'; -import { NodeTextEdit, QTextEditSignals } from './QTextEdit'; +import { QTextEdit, QTextEditSignals } from './QTextEdit'; /** @@ -21,7 +21,7 @@ const textBrowser = new QTextBrowser(); ``` */ -export class QTextBrowser extends NodeTextEdit { +export class QTextBrowser extends QTextEdit { constructor(parent?: QWidget) { let native: NativeElement; if (parent) { diff --git a/src/lib/QtWidgets/QTextEdit.ts b/src/lib/QtWidgets/QTextEdit.ts index 1b2f1cb72..fe1e6e74c 100644 --- a/src/lib/QtWidgets/QTextEdit.ts +++ b/src/lib/QtWidgets/QTextEdit.ts @@ -4,6 +4,8 @@ import { QAbstractScrollArea, QAbstractScrollAreaSignals } from './QAbstractScro import { AlignmentFlag, TextInteractionFlag } from '../QtEnums'; import { QFont } from '../QtGui/QFont'; import { QColor } from '../QtGui/QColor'; +import { checkIfNativeElement } from '../utils/helpers'; +import { NativeElement } from '../core/Component'; /** @@ -22,7 +24,22 @@ const textEdit = new QTextEdit(); ``` */ -export abstract class NodeTextEdit extends QAbstractScrollArea { +export class QTextEdit extends QAbstractScrollArea { + constructor(arg?: QWidget | NativeElement) { + let native: NativeElement; + let parent: QWidget = null; + if (checkIfNativeElement(arg)) { + native = arg as NativeElement; + } else if (arg) { + parent = arg as QWidget; + native = new addon.QTextEdit(parent.native); + } else { + native = new addon.QTextEdit(); + } + super(native); + parent && this.setNodeParent(parent); + } + setAcceptRichText(accept: boolean): void { this.setProperty('acceptRichText', accept); } @@ -238,19 +255,6 @@ export enum WrapMode { WrapAtWordBoundaryOrAnywhere, } -export class QTextEdit extends NodeTextEdit { - constructor(parent?: QWidget) { - let native; - if (parent) { - native = new addon.QTextEdit(parent.native); - } else { - native = new addon.QTextEdit(); - } - super(native); - parent && this.setNodeParent(parent); - } -} - export interface QTextEditSignals extends QAbstractScrollAreaSignals { copyAvailable: (yes: boolean) => void; cursorPositionChanged: () => void; From 10ebd00cde164d1566a1a87dc4919c4fd84d3213 Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Fri, 29 Apr 2022 20:29:29 +0200 Subject: [PATCH 10/28] Remove `NodeListView`, use `QListView` --- src/lib/QtWidgets/QListView.ts | 25 +++++++++++-------------- src/lib/QtWidgets/QListWidget.ts | 4 ++-- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/src/lib/QtWidgets/QListView.ts b/src/lib/QtWidgets/QListView.ts index 618d36848..745d131c7 100644 --- a/src/lib/QtWidgets/QListView.ts +++ b/src/lib/QtWidgets/QListView.ts @@ -20,7 +20,17 @@ const listview = new QListView(); ``` */ -export abstract class NodeListView extends QAbstractItemView { +export class QListView extends QAbstractItemView { + constructor(parent?: QWidget) { + let native: NativeElement; + if (parent) { + native = new addon.QListView(parent.native); + } else { + native = new addon.QListView(); + } + super(native); + parent && this.setNodeParent(parent); + } setBatchSize(batchSize: number): void { this.setProperty('batchSize', batchSize); } @@ -143,17 +153,4 @@ export enum ListViewMode { IconMode, } -export class QListView extends NodeListView { - constructor(parent?: QWidget) { - let native: NativeElement; - if (parent) { - native = new addon.QListView(parent.native); - } else { - native = new addon.QListView(); - } - super(native); - parent && this.setNodeParent(parent); - } -} - export type QListViewSignals = QAbstractItemViewSignals; diff --git a/src/lib/QtWidgets/QListWidget.ts b/src/lib/QtWidgets/QListWidget.ts index 858e299b5..a74b300ef 100644 --- a/src/lib/QtWidgets/QListWidget.ts +++ b/src/lib/QtWidgets/QListWidget.ts @@ -2,7 +2,7 @@ import addon from '../utils/addon'; import { QWidget } from './QWidget'; import { NativeElement, Component } from '../core/Component'; import { QListWidgetItem } from './QListWidgetItem'; -import { NodeListView, QListViewSignals } from './QListView'; +import { QListView, QListViewSignals } from './QListView'; import { QRect } from '../QtCore/QRect'; import { SortOrder, ScrollHint, MatchFlag } from '../QtEnums'; import { QModelIndex } from '../QtCore/QModelIndex'; @@ -32,7 +32,7 @@ for (let i = 0; i < 30; i++) { } ``` */ -export class QListWidget extends NodeListView { +export class QListWidget extends QListView { items: Set; constructor(parent?: QWidget) { From 387555f3c07be4e48db57d239c83e946a585b0cc Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Fri, 29 Apr 2022 20:31:44 +0200 Subject: [PATCH 11/28] Remove `NodeTableView`, use `QTableView` --- src/lib/QtWidgets/QTableView.ts | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/src/lib/QtWidgets/QTableView.ts b/src/lib/QtWidgets/QTableView.ts index b96ecc8b4..1aeab815e 100644 --- a/src/lib/QtWidgets/QTableView.ts +++ b/src/lib/QtWidgets/QTableView.ts @@ -19,7 +19,17 @@ const tableview = new QTableView(); ``` */ -export abstract class NodeTableView extends QAbstractItemView { +export class QTableView extends QAbstractItemView { + constructor(parent?: QWidget) { + let native; + if (parent) { + native = new addon.QTableView(parent.native); + } else { + native = new addon.QTableView(); + } + super(native); + parent && this.setNodeParent(parent); + } // *** Public Functions *** clearSpans(): void { this.native.clearSpans(); @@ -177,17 +187,4 @@ export abstract class NodeTableView extends Q } } -export class QTableView extends NodeTableView { - constructor(parent?: QWidget) { - let native; - if (parent) { - native = new addon.QTableView(parent.native); - } else { - native = new addon.QTableView(); - } - super(native); - parent && this.setNodeParent(parent); - } -} - export type QTableViewSignals = QAbstractItemViewSignals; From 7dcbc325405ee2d570b7c598a2f6b5086c8a8381 Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Fri, 29 Apr 2022 20:35:00 +0200 Subject: [PATCH 12/28] Remove `NodeHeaderView`, use `QHeaderView` --- src/lib/QtWidgets/QHeaderView.ts | 34 +++++++++++++++----------------- 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/src/lib/QtWidgets/QHeaderView.ts b/src/lib/QtWidgets/QHeaderView.ts index 28d7b662f..70f68f803 100644 --- a/src/lib/QtWidgets/QHeaderView.ts +++ b/src/lib/QtWidgets/QHeaderView.ts @@ -11,7 +11,22 @@ import { AlignmentFlag, checkIfNativeElement, Orientation, QPoint, SortOrder } f * **This class is a JS wrapper around Qt's [QHeaderView class](https://doc.qt.io/qt-5/qheaderview.html)** */ -export abstract class NodeHeaderView extends QAbstractItemView { +export class QHeaderView extends QAbstractItemView { + constructor(orientationOrNative: Orientation | NativeElement, parent: QWidget | null = null) { + let native: NativeElement; + if (checkIfNativeElement(orientationOrNative)) { + native = orientationOrNative as NativeElement; + } else { + if (parent != null) { + native = new addon.QHeaderView(orientationOrNative, parent.native); + } else { + native = new addon.QHeaderView(orientationOrNative); + } + } + super(native); + parent && this.setNodeParent(parent); + } + // *** Public Function *** cascadingSectionResizes(): boolean { return this.native.cascadingSectionResizes(); @@ -204,23 +219,6 @@ export abstract class NodeHeaderView extends } } -export class QHeaderView extends NodeHeaderView { - constructor(orientationOrNative: Orientation | NativeElement, parent: QWidget | null = null) { - let native: NativeElement; - if (checkIfNativeElement(orientationOrNative)) { - native = orientationOrNative as NativeElement; - } else { - if (parent != null) { - native = new addon.QHeaderView(orientationOrNative, parent.native); - } else { - native = new addon.QHeaderView(orientationOrNative); - } - } - super(native); - parent && this.setNodeParent(parent); - } -} - export enum QHeaderViewResizeMode { Interactive = 0, Fixed = 2, From 9faf63d5d379ba9755f1e8fc2b544594008fc57e Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Sat, 30 Apr 2022 09:42:18 +0200 Subject: [PATCH 13/28] Rename `QAbstractItemModel.parent()` to `parentModelIndex()` The signature on `QAbstractItemModel.parent()` conflicts with `QObject.parent()`. Maybe in C++ you can get away with that, but in TS it is a huge PITA. --- src/lib/QtCore/QAbstractItemModel.ts | 9 ++++++--- src/lib/QtCore/QAbstractTableModel.ts | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/lib/QtCore/QAbstractItemModel.ts b/src/lib/QtCore/QAbstractItemModel.ts index 9825fa207..d4ce916b7 100644 --- a/src/lib/QtCore/QAbstractItemModel.ts +++ b/src/lib/QtCore/QAbstractItemModel.ts @@ -22,9 +22,9 @@ export class QAbstractItemModel extends QObject { case 'parent': try { - return this.parent(new QModelIndex(args[0])).native; + return this.parentModelIndex(new QModelIndex(args[0])).native; } catch (e) { - console.log(`An exception was thrown while dispatching to method 'parent':`); + console.log(`An exception was thrown while dispatching to method 'parentModelIndex':`); console.log(e); } return new QModelIndex().native; @@ -154,7 +154,10 @@ export class QAbstractItemModel extends QObject { // TODO: bool moveRow(const QModelIndex &sourceParent, int sourceRow, const QModelIndex &destinationParent, int destinationChild) // TODO: virtual bool moveRows(const QModelIndex &sourceParent, int sourceRow, int count, const QModelIndex &destinationParent, int destinationChild) - parent(child: QModelIndex): QModelIndex { + /** + * Note: This corresponds to `QAbstractItemModel::parent(QModelIndex)`. It has been given a different name in TS. + */ + parentModelIndex(child: QModelIndex): QModelIndex { return new QModelIndex(); } diff --git a/src/lib/QtCore/QAbstractTableModel.ts b/src/lib/QtCore/QAbstractTableModel.ts index b44ab5412..a3238e1fc 100644 --- a/src/lib/QtCore/QAbstractTableModel.ts +++ b/src/lib/QtCore/QAbstractTableModel.ts @@ -7,7 +7,7 @@ export class QAbstractTableModel extends QAbstractItemModel { return this.hasIndex(row, column, parent) ? this.createIndex(row, column) : new QModelIndex(); } - parent(child: QModelIndex): QModelIndex { + parentModelIndex(child: QModelIndex): QModelIndex { return new QModelIndex(); } From 1d92cc8f3eb606c66a1c5d00bcc72c1f47f83c0c Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Sat, 30 Apr 2022 19:21:20 +0200 Subject: [PATCH 14/28] Use uint keys inside the C++ wrapper cache --- .../QtGui/QApplication/napplication.hpp | 6 +- .../nodegui/QtWidgets/QWidget/qwidget_macro.h | 2 +- .../nodegui/core/WrapperCache/wrappercache.h | 62 ++++++++++++++----- .../QtGui/QApplication/qapplication_wrap.cpp | 6 +- src/cpp/lib/QtGui/QWindow/qwindow_wrap.cpp | 4 +- src/cpp/lib/test/cachetestqobject_wrap.cpp | 4 +- 6 files changed, 56 insertions(+), 28 deletions(-) diff --git a/src/cpp/include/nodegui/QtGui/QApplication/napplication.hpp b/src/cpp/include/nodegui/QtGui/QApplication/napplication.hpp index 3d051945c..ebbb881b5 100644 --- a/src/cpp/include/nodegui/QtGui/QApplication/napplication.hpp +++ b/src/cpp/include/nodegui/QtGui/QApplication/napplication.hpp @@ -30,7 +30,7 @@ class DLL_EXPORT NApplication : public QApplication, public EventWidget { Napi::Env env = this->emitOnNode.Env(); Napi::HandleScope scope(env); auto instance = - WrapperCache::instance.get(env, screen); + WrapperCache::instance.get(env, screen, false); this->emitOnNode.Call( {Napi::String::New(env, "primaryScreenChanged"), instance}); }); @@ -39,7 +39,7 @@ class DLL_EXPORT NApplication : public QApplication, public EventWidget { Napi::Env env = this->emitOnNode.Env(); Napi::HandleScope scope(env); auto instance = - WrapperCache::instance.get(env, screen); + WrapperCache::instance.get(env, screen, false); this->emitOnNode.Call({Napi::String::New(env, "screenAdded"), instance}); }); @@ -48,7 +48,7 @@ class DLL_EXPORT NApplication : public QApplication, public EventWidget { Napi::Env env = this->emitOnNode.Env(); Napi::HandleScope scope(env); auto instance = - WrapperCache::instance.get(env, screen); + WrapperCache::instance.get(env, screen, false); this->emitOnNode.Call( {Napi::String::New(env, "screenRemoved"), instance}); }); diff --git a/src/cpp/include/nodegui/QtWidgets/QWidget/qwidget_macro.h b/src/cpp/include/nodegui/QtWidgets/QWidget/qwidget_macro.h index c4edc7dcd..c9a0d0355 100644 --- a/src/cpp/include/nodegui/QtWidgets/QWidget/qwidget_macro.h +++ b/src/cpp/include/nodegui/QtWidgets/QWidget/qwidget_macro.h @@ -427,7 +427,7 @@ Napi::Env env = info.Env(); \ QWindow* window = this->instance->windowHandle(); \ if (window) { \ - return WrapperCache::instance.get(env, window); \ + return WrapperCache::instance.get(env, window, false); \ } else { \ return env.Null(); \ } \ diff --git a/src/cpp/include/nodegui/core/WrapperCache/wrappercache.h b/src/cpp/include/nodegui/core/WrapperCache/wrappercache.h index 4c43d33b4..984820bd3 100644 --- a/src/cpp/include/nodegui/core/WrapperCache/wrappercache.h +++ b/src/cpp/include/nodegui/core/WrapperCache/wrappercache.h @@ -6,7 +6,8 @@ #include #include "Extras/Export/export.h" -#include "QtGui/QScreen/qscreen_wrap.h" +#include "Extras/Utils/nutils.h" + struct CachedObject { napi_ref ref; @@ -24,7 +25,7 @@ class DLL_EXPORT WrapperCache : public QObject { Q_OBJECT private: - QMap cache; + QMap cache; public: /** @@ -44,29 +45,53 @@ class DLL_EXPORT WrapperCache : public QObject { * @return The JS wrapper object. */ template - Napi::Object get(Napi::Env env, T* object) { - if (this->cache.contains(object)) { + Napi::Object get(Napi::Env env, T* object, bool isCreatedByNodeGui) { + uint64_t ptrHash = extrautils::hashPointerTo53bit(object); + if (this->cache.contains(ptrHash)) { napi_value result = nullptr; - napi_get_reference_value(env, this->cache[object].ref, &result); - return Napi::Object(env, result); + napi_get_reference_value(env, this->cache[ptrHash].ref, &result); + + napi_valuetype valuetype; + napi_typeof(env, result, &valuetype); + if (valuetype != napi_null) { + return Napi::Object(env, result); + } } Napi::Object wrapper = W::constructor.New({Napi::External::New(env, object)}); - napi_ref ref = nullptr; - napi_create_reference(env, wrapper, 1, &ref); - this->cache[object].env = napi_env(env); - this->cache[object].ref = ref; - - QObject::connect(object, &QObject::destroyed, this, - &WrapperCache::handleDestroyed); + store(env, extrautils::hashPointerTo53bit(object), object, wrapper, isCreatedByNodeGui); return wrapper; } + /** + * Store a mapping from Qt Object to wrapper + * + * @param T - (template argument) The Qt class of the object being cached, + * e.g. `QScreen`. + * @param W - (template argument) The wrapper type which matches the object + * `QScreenWrap`. + * @param env = Napi environment + * @param object - Pointer to the QObject for which a wrapper is required. + * @param wrapper - The wrapper object matching `object`. + */ + void store(Napi::Env env, uint64_t ptrHash, QObject *qobject, Napi::Object wrapper, bool isWeak) { + napi_ref ref = nullptr; + + napi_create_reference(env, wrapper, isWeak ? 0 : 1, &ref); + this->cache[ptrHash].env = napi_env(env); + this->cache[ptrHash].ref = ref; + + QObject::connect(qobject, &QObject::destroyed, this, + &WrapperCache::handleDestroyed); + } + static Napi::Object init(Napi::Env env, Napi::Object exports) { exports.Set("WrapperCache_injectCallback", Napi::Function::New(env)); + // exports.Set("WrapperCache_storeJS", + // Napi::Function::New(env)); return exports; } @@ -81,7 +106,8 @@ class DLL_EXPORT WrapperCache : public QObject { public Q_SLOTS: void handleDestroyed(const QObject* object) { - if (!this->cache.contains(object)) { + uint64_t ptrHash = extrautils::hashPointerTo53bit(object); + if (!this->cache.contains(ptrHash)) { return; } @@ -92,12 +118,14 @@ class DLL_EXPORT WrapperCache : public QObject { Napi::HandleScope scope(env); destroyedCallback.Call( env.Global(), - {Napi::Value::From(env, extrautils::hashPointerTo53bit(object))}); + {Napi::Value::From(env, ptrHash)}); } uint32_t result = 0; - napi_reference_unref(this->cache[object].env, this->cache[object].ref, +// TODO: Grab the wrapper C++ object and null out its ref to the Qt object. + + napi_reference_unref(this->cache[ptrHash].env, this->cache[ptrHash].ref, &result); - this->cache.remove(object); + this->cache.remove(ptrHash); } }; diff --git a/src/cpp/lib/QtGui/QApplication/qapplication_wrap.cpp b/src/cpp/lib/QtGui/QApplication/qapplication_wrap.cpp index 17189e12b..964fcb56c 100644 --- a/src/cpp/lib/QtGui/QApplication/qapplication_wrap.cpp +++ b/src/cpp/lib/QtGui/QApplication/qapplication_wrap.cpp @@ -119,7 +119,7 @@ Napi::Value StaticQApplicationWrapMethods::clipboard( QClipboard* clipboard = QApplication::clipboard(); if (clipboard) { return WrapperCache::instance.get(env, - clipboard); + clipboard, false); } else { return env.Null(); } @@ -163,7 +163,7 @@ Napi::Value StaticQApplicationWrapMethods::primaryScreen( Napi::Env env = info.Env(); auto screen = QApplication::primaryScreen(); if (screen) { - return WrapperCache::instance.get(env, screen); + return WrapperCache::instance.get(env, screen, false); } else { return env.Null(); } @@ -177,7 +177,7 @@ Napi::Value StaticQApplicationWrapMethods::screens( for (int i = 0; i < screens.size(); i++) { QScreen* screen = screens[i]; auto instance = - WrapperCache::instance.get(env, screen); + WrapperCache::instance.get(env, screen, false); jsArray[i] = instance; } return jsArray; diff --git a/src/cpp/lib/QtGui/QWindow/qwindow_wrap.cpp b/src/cpp/lib/QtGui/QWindow/qwindow_wrap.cpp index 00b0d98a7..8412070ff 100644 --- a/src/cpp/lib/QtGui/QWindow/qwindow_wrap.cpp +++ b/src/cpp/lib/QtGui/QWindow/qwindow_wrap.cpp @@ -56,7 +56,7 @@ void QWindowWrap::connectSignalsToEventEmitter() { Napi::Env env = this->emitOnNode.Env(); Napi::HandleScope scope(env); auto instance = - WrapperCache::instance.get(env, screen); + WrapperCache::instance.get(env, screen, false); this->emitOnNode.Call( {Napi::String::New(env, "screenChanged"), instance}); }); @@ -81,7 +81,7 @@ Napi::Value QWindowWrap::screen(const Napi::CallbackInfo& info) { Napi::Env env = info.Env(); QScreen* screen = this->instance->screen(); if (screen) { - return WrapperCache::instance.get(env, screen); + return WrapperCache::instance.get(env, screen, false); } else { return env.Null(); } diff --git a/src/cpp/lib/test/cachetestqobject_wrap.cpp b/src/cpp/lib/test/cachetestqobject_wrap.cpp index 1eaf062f6..9beca174f 100644 --- a/src/cpp/lib/test/cachetestqobject_wrap.cpp +++ b/src/cpp/lib/test/cachetestqobject_wrap.cpp @@ -48,7 +48,7 @@ Napi::Value CacheTestQObjectWrap::foo(const Napi::CallbackInfo& info) { Napi::Env env = info.Env(); CacheTestQObject* foo = this->instance->foo(); return WrapperCache::instance.get( - env, foo); + env, foo, false); } Napi::Value CacheTestQObjectWrap::clearFoo(const Napi::CallbackInfo& info) { @@ -61,5 +61,5 @@ Napi::Value CacheTestQObjectWrap::bar(const Napi::CallbackInfo& info) { Napi::Env env = info.Env(); CacheTestQObject* bar = this->instance->bar(); return WrapperCache::instance.get( - env, bar); + env, bar, false); } From 7bf97ef618ebf4bbe73459b7362d683c49896fdf Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Sat, 30 Apr 2022 20:00:03 +0200 Subject: [PATCH 15/28] Eliminate one template param on `WrapperCache::get()` --- .../include/nodegui/QtGui/QApplication/napplication.hpp | 6 +++--- src/cpp/include/nodegui/QtWidgets/QWidget/qwidget_macro.h | 2 +- src/cpp/include/nodegui/core/WrapperCache/wrappercache.h | 7 +++---- src/cpp/lib/QtGui/QApplication/qapplication_wrap.cpp | 8 ++++---- src/cpp/lib/QtGui/QWindow/qwindow_wrap.cpp | 4 ++-- src/cpp/lib/test/cachetestqobject_wrap.cpp | 8 ++++---- 6 files changed, 17 insertions(+), 18 deletions(-) diff --git a/src/cpp/include/nodegui/QtGui/QApplication/napplication.hpp b/src/cpp/include/nodegui/QtGui/QApplication/napplication.hpp index ebbb881b5..7280d9336 100644 --- a/src/cpp/include/nodegui/QtGui/QApplication/napplication.hpp +++ b/src/cpp/include/nodegui/QtGui/QApplication/napplication.hpp @@ -30,7 +30,7 @@ class DLL_EXPORT NApplication : public QApplication, public EventWidget { Napi::Env env = this->emitOnNode.Env(); Napi::HandleScope scope(env); auto instance = - WrapperCache::instance.get(env, screen, false); + WrapperCache::instance.get(env, screen, &QScreenWrap::constructor, false); this->emitOnNode.Call( {Napi::String::New(env, "primaryScreenChanged"), instance}); }); @@ -39,7 +39,7 @@ class DLL_EXPORT NApplication : public QApplication, public EventWidget { Napi::Env env = this->emitOnNode.Env(); Napi::HandleScope scope(env); auto instance = - WrapperCache::instance.get(env, screen, false); + WrapperCache::instance.get(env, screen, &QScreenWrap::constructor, false); this->emitOnNode.Call({Napi::String::New(env, "screenAdded"), instance}); }); @@ -48,7 +48,7 @@ class DLL_EXPORT NApplication : public QApplication, public EventWidget { Napi::Env env = this->emitOnNode.Env(); Napi::HandleScope scope(env); auto instance = - WrapperCache::instance.get(env, screen, false); + WrapperCache::instance.get(env, screen, &QScreenWrap::constructor, false); this->emitOnNode.Call( {Napi::String::New(env, "screenRemoved"), instance}); }); diff --git a/src/cpp/include/nodegui/QtWidgets/QWidget/qwidget_macro.h b/src/cpp/include/nodegui/QtWidgets/QWidget/qwidget_macro.h index c9a0d0355..4dd0f1c27 100644 --- a/src/cpp/include/nodegui/QtWidgets/QWidget/qwidget_macro.h +++ b/src/cpp/include/nodegui/QtWidgets/QWidget/qwidget_macro.h @@ -427,7 +427,7 @@ Napi::Env env = info.Env(); \ QWindow* window = this->instance->windowHandle(); \ if (window) { \ - return WrapperCache::instance.get(env, window, false); \ + return WrapperCache::instance.get(env, window, &QWindowWrap::constructor, false); \ } else { \ return env.Null(); \ } \ diff --git a/src/cpp/include/nodegui/core/WrapperCache/wrappercache.h b/src/cpp/include/nodegui/core/WrapperCache/wrappercache.h index 984820bd3..2e379d5fb 100644 --- a/src/cpp/include/nodegui/core/WrapperCache/wrappercache.h +++ b/src/cpp/include/nodegui/core/WrapperCache/wrappercache.h @@ -44,8 +44,8 @@ class DLL_EXPORT WrapperCache : public QObject { * @param object - Pointer to the QObject for which a wrapper is required. * @return The JS wrapper object. */ - template - Napi::Object get(Napi::Env env, T* object, bool isCreatedByNodeGui) { + template + Napi::Object get(Napi::Env env, T* object, Napi::FunctionReference* constructorFunc, bool isCreatedByNodeGui) { uint64_t ptrHash = extrautils::hashPointerTo53bit(object); if (this->cache.contains(ptrHash)) { napi_value result = nullptr; @@ -58,8 +58,7 @@ class DLL_EXPORT WrapperCache : public QObject { } } - Napi::Object wrapper = - W::constructor.New({Napi::External::New(env, object)}); + Napi::Object wrapper = constructorFunc->New({Napi::External::New(env, object)}); store(env, extrautils::hashPointerTo53bit(object), object, wrapper, isCreatedByNodeGui); return wrapper; diff --git a/src/cpp/lib/QtGui/QApplication/qapplication_wrap.cpp b/src/cpp/lib/QtGui/QApplication/qapplication_wrap.cpp index 964fcb56c..a17e33367 100644 --- a/src/cpp/lib/QtGui/QApplication/qapplication_wrap.cpp +++ b/src/cpp/lib/QtGui/QApplication/qapplication_wrap.cpp @@ -118,8 +118,8 @@ Napi::Value StaticQApplicationWrapMethods::clipboard( Napi::Env env = info.Env(); QClipboard* clipboard = QApplication::clipboard(); if (clipboard) { - return WrapperCache::instance.get(env, - clipboard, false); + return WrapperCache::instance.get(env, + clipboard, &QClipboardWrap::constructor, false); } else { return env.Null(); } @@ -163,7 +163,7 @@ Napi::Value StaticQApplicationWrapMethods::primaryScreen( Napi::Env env = info.Env(); auto screen = QApplication::primaryScreen(); if (screen) { - return WrapperCache::instance.get(env, screen, false); + return WrapperCache::instance.get(env, screen, &QScreenWrap::constructor, false); } else { return env.Null(); } @@ -177,7 +177,7 @@ Napi::Value StaticQApplicationWrapMethods::screens( for (int i = 0; i < screens.size(); i++) { QScreen* screen = screens[i]; auto instance = - WrapperCache::instance.get(env, screen, false); + WrapperCache::instance.get(env, screen, &QScreenWrap::constructor, false); jsArray[i] = instance; } return jsArray; diff --git a/src/cpp/lib/QtGui/QWindow/qwindow_wrap.cpp b/src/cpp/lib/QtGui/QWindow/qwindow_wrap.cpp index 8412070ff..0058cf299 100644 --- a/src/cpp/lib/QtGui/QWindow/qwindow_wrap.cpp +++ b/src/cpp/lib/QtGui/QWindow/qwindow_wrap.cpp @@ -56,7 +56,7 @@ void QWindowWrap::connectSignalsToEventEmitter() { Napi::Env env = this->emitOnNode.Env(); Napi::HandleScope scope(env); auto instance = - WrapperCache::instance.get(env, screen, false); + WrapperCache::instance.get(env, screen, &QScreenWrap::constructor, false); this->emitOnNode.Call( {Napi::String::New(env, "screenChanged"), instance}); }); @@ -81,7 +81,7 @@ Napi::Value QWindowWrap::screen(const Napi::CallbackInfo& info) { Napi::Env env = info.Env(); QScreen* screen = this->instance->screen(); if (screen) { - return WrapperCache::instance.get(env, screen, false); + return WrapperCache::instance.get(env, screen, &QScreenWrap::constructor, false); } else { return env.Null(); } diff --git a/src/cpp/lib/test/cachetestqobject_wrap.cpp b/src/cpp/lib/test/cachetestqobject_wrap.cpp index 9beca174f..2f2624d51 100644 --- a/src/cpp/lib/test/cachetestqobject_wrap.cpp +++ b/src/cpp/lib/test/cachetestqobject_wrap.cpp @@ -47,8 +47,8 @@ void CacheTestQObjectWrap::connectSignalsToEventEmitter() { Napi::Value CacheTestQObjectWrap::foo(const Napi::CallbackInfo& info) { Napi::Env env = info.Env(); CacheTestQObject* foo = this->instance->foo(); - return WrapperCache::instance.get( - env, foo, false); + return WrapperCache::instance.get( + env, foo, &CacheTestQObjectWrap::constructor, false); } Napi::Value CacheTestQObjectWrap::clearFoo(const Napi::CallbackInfo& info) { @@ -60,6 +60,6 @@ Napi::Value CacheTestQObjectWrap::clearFoo(const Napi::CallbackInfo& info) { Napi::Value CacheTestQObjectWrap::bar(const Napi::CallbackInfo& info) { Napi::Env env = info.Env(); CacheTestQObject* bar = this->instance->bar(); - return WrapperCache::instance.get( - env, bar, false); + return WrapperCache::instance.get( + env, bar, &CacheTestQObjectWrap::constructor, false); } From cbb3f99dfab43f47de435657f865e8ce1b4fa7c6 Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Sun, 1 May 2022 11:08:37 +0200 Subject: [PATCH 16/28] Add `QObject.parent()` and a heap of wrapper management --- .../QAbstractItemModel/nabstractitemmodel.hpp | 4 ++ .../nodegui/QtCore/QObject/qobject_macro.h | 14 ++++- .../nodegui/QtCore/QObject/qobject_wrap.h | 1 + .../nodegui/core/WrapperCache/wrappercache.h | 47 ++++++++++++++- src/cpp/lib/QtCore/QObject/qobject_wrap.cpp | 9 +++ src/lib/QtCore/QObject.ts | 7 +++ src/lib/core/WrapperCache.ts | 59 +++++++++++++++---- src/lib/core/__test__/WrapperCache.test.ts | 16 +++++ tsconfig.json | 2 +- 9 files changed, 145 insertions(+), 14 deletions(-) diff --git a/src/cpp/include/nodegui/QtCore/QAbstractItemModel/nabstractitemmodel.hpp b/src/cpp/include/nodegui/QtCore/QAbstractItemModel/nabstractitemmodel.hpp index cd7c818af..4a79fe8d5 100644 --- a/src/cpp/include/nodegui/QtCore/QAbstractItemModel/nabstractitemmodel.hpp +++ b/src/cpp/include/nodegui/QtCore/QAbstractItemModel/nabstractitemmodel.hpp @@ -35,6 +35,10 @@ class DLL_EXPORT NAbstractItemModel : public QAbstractItemModel, return *newIndex; } + QObject *parent() const { + return nullptr; + } + QModelIndex parent(const QModelIndex& child) const override { Napi::Env env = this->dispatchOnNode.Env(); Napi::HandleScope scope(env); diff --git a/src/cpp/include/nodegui/QtCore/QObject/qobject_macro.h b/src/cpp/include/nodegui/QtCore/QObject/qobject_macro.h index 83880d5b7..47eca9eed 100644 --- a/src/cpp/include/nodegui/QtCore/QObject/qobject_macro.h +++ b/src/cpp/include/nodegui/QtCore/QObject/qobject_macro.h @@ -5,6 +5,8 @@ #include "Extras/Utils/nutils.h" #include "QtCore/QVariant/qvariant_wrap.h" #include "core/Events/eventwidget_macro.h" +#include "core/WrapperCache/wrappercache.h" + /* This macro adds common QObject exported methods @@ -88,6 +90,15 @@ int id = info[0].As().Int32Value(); \ this->instance->killTimer(id); \ return env.Null(); \ + } \ + Napi::Value parent(const Napi::CallbackInfo& info) { \ + Napi::Env env = info.Env(); \ + QObject *parent = this->instance->parent(); \ + if (parent) { \ + return WrapperCache::instance.getWrapper(env, parent); \ + } else { \ + return env.Null(); \ + } \ } // Ideally this macro below should go in @@ -131,7 +142,8 @@ InstanceMethod("dumpObjectInfo", &ComponentWrapName::dumpObjectInfo), \ InstanceMethod("setParent", &ComponentWrapName::setParent), \ InstanceMethod("startTimer", &ComponentWrapName::startTimer), \ - InstanceMethod("killTimer", &ComponentWrapName::killTimer), + InstanceMethod("killTimer", &ComponentWrapName::killTimer), \ + InstanceMethod("parent", &ComponentWrapName::parent), #endif // QOBJECT_WRAPPED_METHODS_EXPORT_DEFINE diff --git a/src/cpp/include/nodegui/QtCore/QObject/qobject_wrap.h b/src/cpp/include/nodegui/QtCore/QObject/qobject_wrap.h index a0129e050..eaf50c5b2 100644 --- a/src/cpp/include/nodegui/QtCore/QObject/qobject_wrap.h +++ b/src/cpp/include/nodegui/QtCore/QObject/qobject_wrap.h @@ -20,5 +20,6 @@ class DLL_EXPORT QObjectWrap : public Napi::ObjectWrap { NObject* getInternalInstance(); // class constructor static Napi::FunctionReference constructor; + static Napi::Object wrapFunc(Napi::Env env, QObject* qobject); // wrapped methods }; diff --git a/src/cpp/include/nodegui/core/WrapperCache/wrappercache.h b/src/cpp/include/nodegui/core/WrapperCache/wrappercache.h index 2e379d5fb..d7d1fb8fd 100644 --- a/src/cpp/include/nodegui/core/WrapperCache/wrappercache.h +++ b/src/cpp/include/nodegui/core/WrapperCache/wrappercache.h @@ -14,6 +14,8 @@ struct CachedObject { napi_env env; }; +typedef Napi::Object (*WrapFunc)(Napi::Env, QObject *); + /** * C++ side cache for wrapper objects. * @@ -26,6 +28,7 @@ class DLL_EXPORT WrapperCache : public QObject { private: QMap cache; + QMap wrapperRegistry; public: /** @@ -64,6 +67,35 @@ class DLL_EXPORT WrapperCache : public QObject { return wrapper; } + void registerWrapper(QString typeName, WrapFunc wrapFunc) { + this->wrapperRegistry[typeName] = wrapFunc; + } + + Napi::Value getWrapper(Napi::Env env, QObject* qobject) { + if (qobject == nullptr) { + return env.Null(); + } + + uint64_t ptrHash = extrautils::hashPointerTo53bit(qobject); + if (this->cache.contains(ptrHash)) { + napi_value result = nullptr; + napi_get_reference_value(env, this->cache[ptrHash].ref, &result); + + napi_valuetype valuetype; + napi_typeof(env, result, &valuetype); + if (valuetype != napi_null) { + return Napi::Object(env, result); + } + } + + // QString className(object->metaObject()->className()); + // if (this->wrapperRegistry.contains(className)) { + // this->wrapperRegistry[className] + // } + + return env.Null(); + } + /** * Store a mapping from Qt Object to wrapper * @@ -89,8 +121,8 @@ class DLL_EXPORT WrapperCache : public QObject { static Napi::Object init(Napi::Env env, Napi::Object exports) { exports.Set("WrapperCache_injectCallback", Napi::Function::New(env)); - // exports.Set("WrapperCache_storeJS", - // Napi::Function::New(env)); + exports.Set("WrapperCache_store", + Napi::Function::New(env)); return exports; } @@ -101,6 +133,17 @@ class DLL_EXPORT WrapperCache : public QObject { return env.Null(); } + static Napi::Value storeJS(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + + Napi::Object objectWrapper = info[0].As(); + QObject* qobject = info[1].As>().Data(); + + uint64_t ptrHash = extrautils::hashPointerTo53bit(qobject); + instance.store(env, ptrHash, qobject, objectWrapper, false); + return env.Null(); + } + static Napi::FunctionReference destroyedCallback; public Q_SLOTS: diff --git a/src/cpp/lib/QtCore/QObject/qobject_wrap.cpp b/src/cpp/lib/QtCore/QObject/qobject_wrap.cpp index bd0ac6401..4c21135e0 100644 --- a/src/cpp/lib/QtCore/QObject/qobject_wrap.cpp +++ b/src/cpp/lib/QtCore/QObject/qobject_wrap.cpp @@ -1,6 +1,7 @@ #include "QtCore/QObject/qobject_wrap.h" #include "Extras/Utils/nutils.h" +#include "core/WrapperCache/wrappercache.h" Napi::FunctionReference QObjectWrap::constructor; @@ -11,6 +12,7 @@ Napi::Object QObjectWrap::init(Napi::Env env, Napi::Object exports) { env, CLASSNAME, {QOBJECT_WRAPPED_METHODS_EXPORT_DEFINE(QObjectWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); + WrapperCache::instance.registerWrapper(QString("NObject"), QObjectWrap::wrapFunc); return exports; } @@ -37,4 +39,11 @@ QObjectWrap::QObjectWrap(const Napi::CallbackInfo& info) .ThrowAsJavaScriptException(); } this->rawData = extrautils::configureQObject(this->getInternalInstance()); + // WrapperCache::instance.store(env, this->getInternalInstance(), this); +} + +Napi::Object QObjectWrap::wrapFunc(Napi::Env env, QObject *qobject) { + // Qtype *exactQObject = dynamic_cast(qobject) + Napi::Object wrapper = QObjectWrap::constructor.New({Napi::External::New(env, qobject)}); + return wrapper; } diff --git a/src/lib/QtCore/QObject.ts b/src/lib/QtCore/QObject.ts index fcd53452b..65d86f4b9 100644 --- a/src/lib/QtCore/QObject.ts +++ b/src/lib/QtCore/QObject.ts @@ -4,6 +4,7 @@ import { checkIfNativeElement } from '../utils/helpers'; import addon from '../utils/addon'; import { QVariant, QVariantType } from './QVariant'; import { TimerType } from '../QtEnums/TimerType'; +import { wrapperCache } from '../core/WrapperCache'; export class QObject extends EventWidget { constructor(nativeElementOrParent?: NativeElement | QObject) { @@ -18,6 +19,9 @@ export class QObject extends Ev native = new addon.QObject(); } super(native); + + wrapperCache.store(this); + this.setNodeParent(parent); } @@ -51,6 +55,9 @@ export class QObject extends Ev this.native.setParent(null); } } + parent(): QObject { + return wrapperCache.getWrapper(this.native.parent()); + } startTimer(intervalMS: number, timerType = TimerType.CoarseTimer): number { return this.native.startTimer(intervalMS, timerType); } diff --git a/src/lib/core/WrapperCache.ts b/src/lib/core/WrapperCache.ts index 13a218d22..ae07fb28b 100644 --- a/src/lib/core/WrapperCache.ts +++ b/src/lib/core/WrapperCache.ts @@ -13,29 +13,68 @@ import { NativeElement } from './Component'; * wrapper automatically and unexpectedly garbage collected. */ export class WrapperCache { - private _cache = new Map(); + private _strongCache = new Map(); + private _weakCache = new Map>(); constructor() { addon.WrapperCache_injectCallback(this._objectDestroyedCallback.bind(this)); } private _objectDestroyedCallback(objectId: number): void { - if (!this._cache.has(objectId)) { - return; + if (this._strongCache.has(objectId)) { + const wrapper = this._strongCache.get(objectId); + wrapper.native = null; + this._strongCache.delete(objectId); + } + + const wrapperRef = this._weakCache.get(objectId); + if (wrapperRef != null) { + const wrapper = wrapperRef.deref(); + if (wrapper != null) { + wrapper.native = null; + this._weakCache.delete(objectId); + } } - const wrapper = this._cache.get(objectId); - wrapper.native = null; - this._cache.delete(objectId); } - get(wrapperConstructor: { new (native: any): T }, native: NativeElement): T { + get(wrapperConstructor: { new (native: any): T }, native: NativeElement): T { const id = native.__id__(); - if (this._cache.has(id)) { - return this._cache.get(id) as T; + if (this._strongCache.has(id)) { + return this._strongCache.get(id) as T; } const wrapper = new wrapperConstructor(native); - this._cache.set(id, wrapper); + this._strongCache.set(id, wrapper); return wrapper; } + + getWrapper(native: any): QObject | null { + if (native == null) { + return null; + } + const id = native.__id__(); + + if (this._strongCache.has(id)) { + return this._strongCache.get(id); + } + + const ref = this._weakCache.get(id); + if (ref != null) { + const wrapper = ref.deref(); + if (wrapper != null) { + return wrapper; + } + } + + return null; // FIXME: Create new wrapper on demand. + } + + store(wrapper: QObject): void { + if (wrapper.native != null) { + const id = wrapper.native.__id__(); + this._weakCache.set(id, new WeakRef(wrapper)); + + addon.WrapperCache_store(wrapper.native, wrapper.native.__external_qobject__()); + } + } } export const wrapperCache = new WrapperCache(); diff --git a/src/lib/core/__test__/WrapperCache.test.ts b/src/lib/core/__test__/WrapperCache.test.ts index fe5cde994..678655c3f 100644 --- a/src/lib/core/__test__/WrapperCache.test.ts +++ b/src/lib/core/__test__/WrapperCache.test.ts @@ -1,3 +1,4 @@ +import { QObject } from '../../QtCore/QObject'; import { QApplication } from '../../QtGui/QApplication'; import { CacheTestQObject } from './CacheTestQObject'; @@ -43,5 +44,20 @@ describe('WrapperCache using CacheTestQObject', () => { expect(foo).not.toEqual(bar); expect(foo.native.__id__()).not.toEqual(bar.native.__id__()); }); + + it('QObject.parent() can be null', () => { + const a = new QObject(); + expect(a.parent()).toBeNull(); + }); + + it('QObject.parent() === QObject.parent()', () => { + const a = new QObject(); + const b = new QObject(a); + expect(a.native.__id__()).toEqual(b.parent().native.__id__()); + expect(a).toEqual(b.parent()); + (a)['magic'] = true; + expect((b.parent())['magic']).toBe(true); + }); + qApp.quit(); }); diff --git a/tsconfig.json b/tsconfig.json index dd79bd9a2..6abc59d20 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "target": "ES2015", + "target": "ES2021", "module": "commonjs", "declaration": true, "sourceMap": false, From 02f901ddf1c531938a47a81c546931ff94bb9d27 Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Sun, 1 May 2022 20:02:02 +0200 Subject: [PATCH 17/28] Add `QObject.delete()` and `QObject.deleteLater()`, and test `QObject` deletion --- .../nodegui/QtCore/QObject/qobject_macro.h | 17 +++++++++++++++-- .../nodegui/core/WrapperCache/wrappercache.h | 4 ++-- src/lib/QtCore/QObject.ts | 6 ++++++ src/lib/core/__test__/WrapperCache.test.ts | 14 ++++++++++++++ 4 files changed, 37 insertions(+), 4 deletions(-) diff --git a/src/cpp/include/nodegui/QtCore/QObject/qobject_macro.h b/src/cpp/include/nodegui/QtCore/QObject/qobject_macro.h index 47eca9eed..13c4859bf 100644 --- a/src/cpp/include/nodegui/QtCore/QObject/qobject_macro.h +++ b/src/cpp/include/nodegui/QtCore/QObject/qobject_macro.h @@ -99,7 +99,18 @@ } else { \ return env.Null(); \ } \ - } + } \ + Napi::Value deleteLater(const Napi::CallbackInfo& info) { \ + Napi::Env env = info.Env(); \ + this->instance->deleteLater(); \ + return env.Null(); \ + } \ + Napi::Value deleteObject(const Napi::CallbackInfo& info) { \ + Napi::Env env = info.Env(); \ + delete static_cast(this->instance); \ + return env.Null(); \ + } \ + // Ideally this macro below should go in // QOBJECT_WRAPPED_METHODS_DECLARATION_WITH_EVENT_SOURCE but some wrappers @@ -143,7 +154,9 @@ InstanceMethod("setParent", &ComponentWrapName::setParent), \ InstanceMethod("startTimer", &ComponentWrapName::startTimer), \ InstanceMethod("killTimer", &ComponentWrapName::killTimer), \ - InstanceMethod("parent", &ComponentWrapName::parent), + InstanceMethod("parent", &ComponentWrapName::parent), \ + InstanceMethod("deleteLater", &ComponentWrapName::deleteLater), \ + InstanceMethod("delete", &ComponentWrapName::deleteObject), #endif // QOBJECT_WRAPPED_METHODS_EXPORT_DEFINE diff --git a/src/cpp/include/nodegui/core/WrapperCache/wrappercache.h b/src/cpp/include/nodegui/core/WrapperCache/wrappercache.h index d7d1fb8fd..7c8037c53 100644 --- a/src/cpp/include/nodegui/core/WrapperCache/wrappercache.h +++ b/src/cpp/include/nodegui/core/WrapperCache/wrappercache.h @@ -147,8 +147,8 @@ class DLL_EXPORT WrapperCache : public QObject { static Napi::FunctionReference destroyedCallback; public Q_SLOTS: - void handleDestroyed(const QObject* object) { - uint64_t ptrHash = extrautils::hashPointerTo53bit(object); + void handleDestroyed(const QObject* qobject) { + uint64_t ptrHash = extrautils::hashPointerTo53bit(qobject); if (!this->cache.contains(ptrHash)) { return; } diff --git a/src/lib/QtCore/QObject.ts b/src/lib/QtCore/QObject.ts index 65d86f4b9..53ae0feff 100644 --- a/src/lib/QtCore/QObject.ts +++ b/src/lib/QtCore/QObject.ts @@ -64,6 +64,12 @@ export class QObject extends Ev killTimer(timerId: number): void { this.native.killTimer(timerId); } + delete(): void { + this.native.delete(); + } + deleteLater(): void { + this.native.deleteLater(); + } } export interface QObjectSignals { diff --git a/src/lib/core/__test__/WrapperCache.test.ts b/src/lib/core/__test__/WrapperCache.test.ts index 678655c3f..4f614b762 100644 --- a/src/lib/core/__test__/WrapperCache.test.ts +++ b/src/lib/core/__test__/WrapperCache.test.ts @@ -59,5 +59,19 @@ describe('WrapperCache using CacheTestQObject', () => { expect((b.parent())['magic']).toBe(true); }); + it('QObject.delete() clears the native field', () => { + const a = new QObject(); + a.delete(); + expect(a.native).toBeNull(); + }); + + it('QObject.delete() clears chains of QObjects and their native field', () => { + const a = new QObject(); + const b = new QObject(a); + a.delete(); + expect(a.native).toBeNull(); + expect(b.native).toBeNull(); + }); + qApp.quit(); }); From bc9bf12e113eb36bbde6b4449065e6bce9895e62 Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Sun, 1 May 2022 20:23:21 +0200 Subject: [PATCH 18/28] Refine the wrapper type registration --- src/cpp/lib/QtCore/QObject/qobject_wrap.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/cpp/lib/QtCore/QObject/qobject_wrap.cpp b/src/cpp/lib/QtCore/QObject/qobject_wrap.cpp index 4c21135e0..1a467a95d 100644 --- a/src/cpp/lib/QtCore/QObject/qobject_wrap.cpp +++ b/src/cpp/lib/QtCore/QObject/qobject_wrap.cpp @@ -12,7 +12,13 @@ Napi::Object QObjectWrap::init(Napi::Env env, Napi::Object exports) { env, CLASSNAME, {QOBJECT_WRAPPED_METHODS_EXPORT_DEFINE(QObjectWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); - WrapperCache::instance.registerWrapper(QString("NObject"), QObjectWrap::wrapFunc); + + WrapperCache::instance.registerWrapper(QString("NObject"), + [](Napi::Env env, QObject *qobject) -> Napi::Object { + QObject *exactQObject = dynamic_cast(qobject); + Napi::Object wrapper = QObjectWrap::constructor.New({Napi::External::New(env, exactQObject)}); + return wrapper; + }); return exports; } @@ -39,11 +45,4 @@ QObjectWrap::QObjectWrap(const Napi::CallbackInfo& info) .ThrowAsJavaScriptException(); } this->rawData = extrautils::configureQObject(this->getInternalInstance()); - // WrapperCache::instance.store(env, this->getInternalInstance(), this); -} - -Napi::Object QObjectWrap::wrapFunc(Napi::Env env, QObject *qobject) { - // Qtype *exactQObject = dynamic_cast(qobject) - Napi::Object wrapper = QObjectWrap::constructor.New({Napi::External::New(env, qobject)}); - return wrapper; } From 880ea7c9986b038ead9ac39a62cd7f76a530457b Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Thu, 5 May 2022 17:10:40 +0200 Subject: [PATCH 19/28] Add `QObject.parent()` and infra for correct subclass wrappers --- .../QAbstractItemModel/nabstractitemmodel.hpp | 4 +- .../nodegui/QtCore/QObject/qobject_macro.h | 33 +++++++-- .../QtGui/QApplication/napplication.hpp | 9 +-- .../nodegui/QtWidgets/QWidget/qwidget_macro.h | 2 +- .../nodegui/core/WrapperCache/wrappercache.h | 74 ++++++++----------- src/cpp/lib/QtCore/QObject/qobject_wrap.cpp | 8 +- .../QtGui/QApplication/qapplication_wrap.cpp | 8 +- .../lib/QtGui/QClipboard/qclipboard_wrap.cpp | 1 + src/cpp/lib/QtGui/QScreen/qscreen_wrap.cpp | 1 + src/cpp/lib/QtGui/QWindow/qwindow_wrap.cpp | 5 +- .../lib/QtWidgets/QWidget/qwidget_wrap.cpp | 1 + src/cpp/lib/test/cachetestqobject_wrap.cpp | 7 +- src/lib/core/WrapperCache.ts | 24 +++++- src/lib/core/__test__/CacheTestQObject.ts | 7 +- src/lib/core/__test__/WrapperCache.test.ts | 11 ++- 15 files changed, 109 insertions(+), 86 deletions(-) diff --git a/src/cpp/include/nodegui/QtCore/QAbstractItemModel/nabstractitemmodel.hpp b/src/cpp/include/nodegui/QtCore/QAbstractItemModel/nabstractitemmodel.hpp index 4a79fe8d5..e5e9d4095 100644 --- a/src/cpp/include/nodegui/QtCore/QAbstractItemModel/nabstractitemmodel.hpp +++ b/src/cpp/include/nodegui/QtCore/QAbstractItemModel/nabstractitemmodel.hpp @@ -35,9 +35,7 @@ class DLL_EXPORT NAbstractItemModel : public QAbstractItemModel, return *newIndex; } - QObject *parent() const { - return nullptr; - } + QObject* parent() const { return nullptr; } QModelIndex parent(const QModelIndex& child) const override { Napi::Env env = this->dispatchOnNode.Env(); diff --git a/src/cpp/include/nodegui/QtCore/QObject/qobject_macro.h b/src/cpp/include/nodegui/QtCore/QObject/qobject_macro.h index 13c4859bf..b77773d48 100644 --- a/src/cpp/include/nodegui/QtCore/QObject/qobject_macro.h +++ b/src/cpp/include/nodegui/QtCore/QObject/qobject_macro.h @@ -8,10 +8,9 @@ #include "core/WrapperCache/wrappercache.h" /* - - This macro adds common QObject exported methods - The exported methods are taken into this macro to avoid writing them in each - and every widget we export. + This macro adds common QObject exported methods + The exported methods are taken into this macro to avoid writing them in each + and every widget we export. */ #ifndef QOBJECT_WRAPPED_METHODS_DECLARATION_WITH_EVENT_SOURCE @@ -22,7 +21,8 @@ Napi::Value __id__(const Napi::CallbackInfo& info) { \ Napi::Env env = info.Env(); \ return Napi::Value::From( \ - env, extrautils::hashPointerTo53bit(this->instance.data())); \ + env, extrautils::hashPointerTo53bit( \ + static_cast(this->instance.data()))); \ } \ Napi::Value inherits(const Napi::CallbackInfo& info) { \ Napi::Env env = info.Env(); \ @@ -93,7 +93,7 @@ } \ Napi::Value parent(const Napi::CallbackInfo& info) { \ Napi::Env env = info.Env(); \ - QObject *parent = this->instance->parent(); \ + QObject* parent = this->instance->parent(); \ if (parent) { \ return WrapperCache::instance.getWrapper(env, parent); \ } else { \ @@ -109,8 +109,7 @@ Napi::Env env = info.Env(); \ delete static_cast(this->instance); \ return env.Null(); \ - } \ - + } // Ideally this macro below should go in // QOBJECT_WRAPPED_METHODS_DECLARATION_WITH_EVENT_SOURCE but some wrappers @@ -176,4 +175,22 @@ #define QOBJECT_SIGNALS QOBJECT_SIGNALS_ON_TARGET(this) #endif // QOBJECT_SIGNALS +/* + Macro to register a function to wrap QObject pointers of a + given subclass to wrapper instances. First parameter is the + plain name of the QObject subclass (no quotes), seconds is the + name of the wrapper class. + */ +#ifndef QOBJECT_REGISTER_WRAPPER +#define QOBJECT_REGISTER_WRAPPER(qobjectType, ComponentWrapName) \ + WrapperCache::instance.registerWrapper( \ + QString(#qobjectType), \ + [](Napi::Env env, QObject* qobject) -> Napi::Object { \ + qobjectType* exactQObject = dynamic_cast(qobject); \ + Napi::Object wrapper = ComponentWrapName::constructor.New( \ + {Napi::External::New(env, exactQObject)}); \ + return wrapper; \ + }); +#endif // QOBJECT_REGISTER_WRAPPER + #include "QtCore/QObject/qobject_wrap.h" diff --git a/src/cpp/include/nodegui/QtGui/QApplication/napplication.hpp b/src/cpp/include/nodegui/QtGui/QApplication/napplication.hpp index 7280d9336..4e58fd592 100644 --- a/src/cpp/include/nodegui/QtGui/QApplication/napplication.hpp +++ b/src/cpp/include/nodegui/QtGui/QApplication/napplication.hpp @@ -29,8 +29,7 @@ class DLL_EXPORT NApplication : public QApplication, public EventWidget { this, &QGuiApplication::primaryScreenChanged, [=](QScreen* screen) { Napi::Env env = this->emitOnNode.Env(); Napi::HandleScope scope(env); - auto instance = - WrapperCache::instance.get(env, screen, &QScreenWrap::constructor, false); + auto instance = WrapperCache::instance.getWrapper(env, screen, true); this->emitOnNode.Call( {Napi::String::New(env, "primaryScreenChanged"), instance}); }); @@ -38,8 +37,7 @@ class DLL_EXPORT NApplication : public QApplication, public EventWidget { QObject::connect(this, &QGuiApplication::screenAdded, [=](QScreen* screen) { Napi::Env env = this->emitOnNode.Env(); Napi::HandleScope scope(env); - auto instance = - WrapperCache::instance.get(env, screen, &QScreenWrap::constructor, false); + auto instance = WrapperCache::instance.getWrapper(env, screen, true); this->emitOnNode.Call({Napi::String::New(env, "screenAdded"), instance}); }); @@ -47,8 +45,7 @@ class DLL_EXPORT NApplication : public QApplication, public EventWidget { this, &QGuiApplication::screenRemoved, [=](QScreen* screen) { Napi::Env env = this->emitOnNode.Env(); Napi::HandleScope scope(env); - auto instance = - WrapperCache::instance.get(env, screen, &QScreenWrap::constructor, false); + auto instance = WrapperCache::instance.getWrapper(env, screen, true); this->emitOnNode.Call( {Napi::String::New(env, "screenRemoved"), instance}); }); diff --git a/src/cpp/include/nodegui/QtWidgets/QWidget/qwidget_macro.h b/src/cpp/include/nodegui/QtWidgets/QWidget/qwidget_macro.h index 4dd0f1c27..93e313677 100644 --- a/src/cpp/include/nodegui/QtWidgets/QWidget/qwidget_macro.h +++ b/src/cpp/include/nodegui/QtWidgets/QWidget/qwidget_macro.h @@ -427,7 +427,7 @@ Napi::Env env = info.Env(); \ QWindow* window = this->instance->windowHandle(); \ if (window) { \ - return WrapperCache::instance.get(env, window, &QWindowWrap::constructor, false); \ + return WrapperCache::instance.getWrapper(env, window, true); \ } else { \ return env.Null(); \ } \ diff --git a/src/cpp/include/nodegui/core/WrapperCache/wrappercache.h b/src/cpp/include/nodegui/core/WrapperCache/wrappercache.h index 7c8037c53..b633c8890 100644 --- a/src/cpp/include/nodegui/core/WrapperCache/wrappercache.h +++ b/src/cpp/include/nodegui/core/WrapperCache/wrappercache.h @@ -2,19 +2,19 @@ #include +#include #include #include #include "Extras/Export/export.h" #include "Extras/Utils/nutils.h" - struct CachedObject { napi_ref ref; napi_env env; }; -typedef Napi::Object (*WrapFunc)(Napi::Env, QObject *); +typedef Napi::Object (*WrapFunc)(Napi::Env, QObject*); /** * C++ side cache for wrapper objects. @@ -37,41 +37,28 @@ class DLL_EXPORT WrapperCache : public QObject { static WrapperCache instance; /** - * Get a wrapper for a given Qt object. + * Register a function to wrap certain instances of a `QObject` subclass. * - * @param T - (template argument) The Qt class of the object being cached, - * e.g. `QScreen`. - * @param W - (template argument) The wrapper type which matches the object - * `QScreenWrap`. - * @param env = Napi environment - * @param object - Pointer to the QObject for which a wrapper is required. - * @return The JS wrapper object. + * @param typeName - The name of the `QObject` subclass this wrapper function + * applies to. + * @param wrapFunc - Function to wrap `QObject` instances. */ - template - Napi::Object get(Napi::Env env, T* object, Napi::FunctionReference* constructorFunc, bool isCreatedByNodeGui) { - uint64_t ptrHash = extrautils::hashPointerTo53bit(object); - if (this->cache.contains(ptrHash)) { - napi_value result = nullptr; - napi_get_reference_value(env, this->cache[ptrHash].ref, &result); - - napi_valuetype valuetype; - napi_typeof(env, result, &valuetype); - if (valuetype != napi_null) { - return Napi::Object(env, result); - } - } - - Napi::Object wrapper = constructorFunc->New({Napi::External::New(env, object)}); - - store(env, extrautils::hashPointerTo53bit(object), object, wrapper, isCreatedByNodeGui); - return wrapper; - } - void registerWrapper(QString typeName, WrapFunc wrapFunc) { this->wrapperRegistry[typeName] = wrapFunc; } - Napi::Value getWrapper(Napi::Env env, QObject* qobject) { + /** + * Get a wrapper for a QObject + * + * @param env - Napi environment + * @param qobject - The QObject or subclass instance to wrap + * @param keepAlive - Set this to true if the wrapper object should be kept + * alive until the underlying QObject is destroyed regardless of whether + * the JS side holding a reference to it or not. (Defaults to false). + * @return Napi object wrapping the object + */ + Napi::Value getWrapper(Napi::Env env, QObject* qobject, + bool keepAlive = false) { if (qobject == nullptr) { return env.Null(); } @@ -88,10 +75,15 @@ class DLL_EXPORT WrapperCache : public QObject { } } - // QString className(object->metaObject()->className()); - // if (this->wrapperRegistry.contains(className)) { - // this->wrapperRegistry[className] - // } + QString className(qobject->metaObject()->className()); + if (this->wrapperRegistry.contains(className)) { + Napi::Object wrapper = this->wrapperRegistry[className](env, qobject); + store(env, ptrHash, qobject, wrapper, !keepAlive); + return wrapper; + } else { + qDebug() << "NodeGui: Unable to find wrapper for instance of class " + << className << ".\n\n"; + } return env.Null(); } @@ -107,7 +99,8 @@ class DLL_EXPORT WrapperCache : public QObject { * @param object - Pointer to the QObject for which a wrapper is required. * @param wrapper - The wrapper object matching `object`. */ - void store(Napi::Env env, uint64_t ptrHash, QObject *qobject, Napi::Object wrapper, bool isWeak) { + void store(Napi::Env env, uint64_t ptrHash, QObject* qobject, + Napi::Object wrapper, bool isWeak) { napi_ref ref = nullptr; napi_create_reference(env, wrapper, isWeak ? 0 : 1, &ref); @@ -121,8 +114,7 @@ class DLL_EXPORT WrapperCache : public QObject { static Napi::Object init(Napi::Env env, Napi::Object exports) { exports.Set("WrapperCache_injectCallback", Napi::Function::New(env)); - exports.Set("WrapperCache_store", - Napi::Function::New(env)); + exports.Set("WrapperCache_store", Napi::Function::New(env)); return exports; } @@ -158,14 +150,10 @@ class DLL_EXPORT WrapperCache : public QObject { if (destroyedCallback) { Napi::Env env = destroyedCallback.Env(); Napi::HandleScope scope(env); - destroyedCallback.Call( - env.Global(), - {Napi::Value::From(env, ptrHash)}); + destroyedCallback.Call(env.Global(), {Napi::Value::From(env, ptrHash)}); } uint32_t result = 0; -// TODO: Grab the wrapper C++ object and null out its ref to the Qt object. - napi_reference_unref(this->cache[ptrHash].env, this->cache[ptrHash].ref, &result); this->cache.remove(ptrHash); diff --git a/src/cpp/lib/QtCore/QObject/qobject_wrap.cpp b/src/cpp/lib/QtCore/QObject/qobject_wrap.cpp index 1a467a95d..61aff178f 100644 --- a/src/cpp/lib/QtCore/QObject/qobject_wrap.cpp +++ b/src/cpp/lib/QtCore/QObject/qobject_wrap.cpp @@ -12,13 +12,7 @@ Napi::Object QObjectWrap::init(Napi::Env env, Napi::Object exports) { env, CLASSNAME, {QOBJECT_WRAPPED_METHODS_EXPORT_DEFINE(QObjectWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); - - WrapperCache::instance.registerWrapper(QString("NObject"), - [](Napi::Env env, QObject *qobject) -> Napi::Object { - QObject *exactQObject = dynamic_cast(qobject); - Napi::Object wrapper = QObjectWrap::constructor.New({Napi::External::New(env, exactQObject)}); - return wrapper; - }); + QOBJECT_REGISTER_WRAPPER(NObject, QObjectWrap); return exports; } diff --git a/src/cpp/lib/QtGui/QApplication/qapplication_wrap.cpp b/src/cpp/lib/QtGui/QApplication/qapplication_wrap.cpp index a17e33367..32739150b 100644 --- a/src/cpp/lib/QtGui/QApplication/qapplication_wrap.cpp +++ b/src/cpp/lib/QtGui/QApplication/qapplication_wrap.cpp @@ -118,8 +118,7 @@ Napi::Value StaticQApplicationWrapMethods::clipboard( Napi::Env env = info.Env(); QClipboard* clipboard = QApplication::clipboard(); if (clipboard) { - return WrapperCache::instance.get(env, - clipboard, &QClipboardWrap::constructor, false); + return WrapperCache::instance.getWrapper(env, clipboard, true); } else { return env.Null(); } @@ -163,7 +162,7 @@ Napi::Value StaticQApplicationWrapMethods::primaryScreen( Napi::Env env = info.Env(); auto screen = QApplication::primaryScreen(); if (screen) { - return WrapperCache::instance.get(env, screen, &QScreenWrap::constructor, false); + return WrapperCache::instance.getWrapper(env, screen, true); } else { return env.Null(); } @@ -176,8 +175,7 @@ Napi::Value StaticQApplicationWrapMethods::screens( Napi::Array jsArray = Napi::Array::New(env, screens.size()); for (int i = 0; i < screens.size(); i++) { QScreen* screen = screens[i]; - auto instance = - WrapperCache::instance.get(env, screen, &QScreenWrap::constructor, false); + auto instance = WrapperCache::instance.getWrapper(env, screen, true); jsArray[i] = instance; } return jsArray; diff --git a/src/cpp/lib/QtGui/QClipboard/qclipboard_wrap.cpp b/src/cpp/lib/QtGui/QClipboard/qclipboard_wrap.cpp index 68d00e6d1..0eca693d9 100644 --- a/src/cpp/lib/QtGui/QClipboard/qclipboard_wrap.cpp +++ b/src/cpp/lib/QtGui/QClipboard/qclipboard_wrap.cpp @@ -19,6 +19,7 @@ Napi::Object QClipboardWrap::init(Napi::Env env, Napi::Object exports) { QOBJECT_WRAPPED_METHODS_EXPORT_DEFINE(QClipboardWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); + QOBJECT_REGISTER_WRAPPER(QClipboard, QClipboardWrap); return exports; } diff --git a/src/cpp/lib/QtGui/QScreen/qscreen_wrap.cpp b/src/cpp/lib/QtGui/QScreen/qscreen_wrap.cpp index 24ef717b7..f3a8064e4 100644 --- a/src/cpp/lib/QtGui/QScreen/qscreen_wrap.cpp +++ b/src/cpp/lib/QtGui/QScreen/qscreen_wrap.cpp @@ -16,6 +16,7 @@ Napi::Object QScreenWrap::init(Napi::Env env, Napi::Object exports) { QOBJECT_WRAPPED_METHODS_EXPORT_DEFINE(QScreenWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); + QOBJECT_REGISTER_WRAPPER(QScreen, QScreenWrap); return exports; } diff --git a/src/cpp/lib/QtGui/QWindow/qwindow_wrap.cpp b/src/cpp/lib/QtGui/QWindow/qwindow_wrap.cpp index 0058cf299..78fdc4333 100644 --- a/src/cpp/lib/QtGui/QWindow/qwindow_wrap.cpp +++ b/src/cpp/lib/QtGui/QWindow/qwindow_wrap.cpp @@ -55,8 +55,7 @@ void QWindowWrap::connectSignalsToEventEmitter() { this->instance.data(), &QWindow::screenChanged, [=](QScreen* screen) { Napi::Env env = this->emitOnNode.Env(); Napi::HandleScope scope(env); - auto instance = - WrapperCache::instance.get(env, screen, &QScreenWrap::constructor, false); + auto instance = WrapperCache::instance.getWrapper(env, screen, true); this->emitOnNode.Call( {Napi::String::New(env, "screenChanged"), instance}); }); @@ -81,7 +80,7 @@ Napi::Value QWindowWrap::screen(const Napi::CallbackInfo& info) { Napi::Env env = info.Env(); QScreen* screen = this->instance->screen(); if (screen) { - return WrapperCache::instance.get(env, screen, &QScreenWrap::constructor, false); + return WrapperCache::instance.getWrapper(env, screen, true); } else { return env.Null(); } diff --git a/src/cpp/lib/QtWidgets/QWidget/qwidget_wrap.cpp b/src/cpp/lib/QtWidgets/QWidget/qwidget_wrap.cpp index 4079a0b12..3d0976535 100644 --- a/src/cpp/lib/QtWidgets/QWidget/qwidget_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QWidget/qwidget_wrap.cpp @@ -12,6 +12,7 @@ Napi::Object QWidgetWrap::init(Napi::Env env, Napi::Object exports) { env, CLASSNAME, {QWIDGET_WRAPPED_METHODS_EXPORT_DEFINE(QWidgetWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); + QOBJECT_REGISTER_WRAPPER(NWidget, QWidgetWrap); return exports; } diff --git a/src/cpp/lib/test/cachetestqobject_wrap.cpp b/src/cpp/lib/test/cachetestqobject_wrap.cpp index 2f2624d51..ccb040fe9 100644 --- a/src/cpp/lib/test/cachetestqobject_wrap.cpp +++ b/src/cpp/lib/test/cachetestqobject_wrap.cpp @@ -16,6 +16,7 @@ Napi::Object CacheTestQObjectWrap::init(Napi::Env env, Napi::Object exports) { QOBJECT_WRAPPED_METHODS_EXPORT_DEFINE(CacheTestQObjectWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); + QOBJECT_REGISTER_WRAPPER(CacheTestQObject, CacheTestQObjectWrap); return exports; } @@ -47,8 +48,7 @@ void CacheTestQObjectWrap::connectSignalsToEventEmitter() { Napi::Value CacheTestQObjectWrap::foo(const Napi::CallbackInfo& info) { Napi::Env env = info.Env(); CacheTestQObject* foo = this->instance->foo(); - return WrapperCache::instance.get( - env, foo, &CacheTestQObjectWrap::constructor, false); + return WrapperCache::instance.getWrapper(env, foo); } Napi::Value CacheTestQObjectWrap::clearFoo(const Napi::CallbackInfo& info) { @@ -60,6 +60,5 @@ Napi::Value CacheTestQObjectWrap::clearFoo(const Napi::CallbackInfo& info) { Napi::Value CacheTestQObjectWrap::bar(const Napi::CallbackInfo& info) { Napi::Env env = info.Env(); CacheTestQObject* bar = this->instance->bar(); - return WrapperCache::instance.get( - env, bar, &CacheTestQObjectWrap::constructor, false); + return WrapperCache::instance.getWrapper(env, bar); } diff --git a/src/lib/core/WrapperCache.ts b/src/lib/core/WrapperCache.ts index ae07fb28b..61e036cfa 100644 --- a/src/lib/core/WrapperCache.ts +++ b/src/lib/core/WrapperCache.ts @@ -1,3 +1,4 @@ +import { QObject } from '../QtCore/QObject'; import addon from '../utils/addon'; import { NativeElement } from './Component'; @@ -15,11 +16,17 @@ import { NativeElement } from './Component'; export class WrapperCache { private _strongCache = new Map(); private _weakCache = new Map>(); + private _wrapperRegistry = new Map(); constructor() { addon.WrapperCache_injectCallback(this._objectDestroyedCallback.bind(this)); } + _flush(): void { + this._strongCache = new Map(); + this._weakCache = new Map>(); + } + private _objectDestroyedCallback(objectId: number): void { if (this._strongCache.has(objectId)) { const wrapper = this._strongCache.get(objectId); @@ -47,12 +54,13 @@ export class WrapperCache { return wrapper; } + // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types getWrapper(native: any): QObject | null { if (native == null) { return null; } - const id = native.__id__(); + const id = native.__id__(); if (this._strongCache.has(id)) { return this._strongCache.get(id); } @@ -65,7 +73,19 @@ export class WrapperCache { } } - return null; // FIXME: Create new wrapper on demand. + if (this._wrapperRegistry.has(native.wrapperType)) { + const wrapper = new (this._wrapperRegistry.get(native.wrapperType))(native); + this.store(wrapper); + return wrapper; + } else { + console.log(`NodeGui: Unable to find JS wrapper for type '${native.wrapperType}'.`); + } + + return null; + } + + registerWrapper(qobjectClassName: string, wrapperConstructor: { new (native: any): QObject }): void { + this._wrapperRegistry.set(qobjectClassName, wrapperConstructor); } store(wrapper: QObject): void { diff --git a/src/lib/core/__test__/CacheTestQObject.ts b/src/lib/core/__test__/CacheTestQObject.ts index b3235bfa8..3ee23ea0e 100644 --- a/src/lib/core/__test__/CacheTestQObject.ts +++ b/src/lib/core/__test__/CacheTestQObject.ts @@ -6,7 +6,7 @@ import { wrapperCache } from '../../core/WrapperCache'; export class CacheTestQObject extends QObject { constructor(arg?: NativeElement) { let native; - if (native == null) { + if (arg == null) { native = new addon.CacheTestQObject(); } else { native = arg; @@ -16,7 +16,7 @@ export class CacheTestQObject extends QObject { } foo(): CacheTestQObject { - return wrapperCache.get(CacheTestQObject, this.native.foo()); + return wrapperCache.getWrapper(this.native.foo()) as CacheTestQObject; } clearFoo(): void { @@ -24,6 +24,7 @@ export class CacheTestQObject extends QObject { } bar(): CacheTestQObject { - return wrapperCache.get(CacheTestQObject, this.native.bar()); + return wrapperCache.getWrapper(this.native.bar()) as CacheTestQObject; } } +wrapperCache.registerWrapper('CacheTestQObjectWrap', CacheTestQObject); diff --git a/src/lib/core/__test__/WrapperCache.test.ts b/src/lib/core/__test__/WrapperCache.test.ts index 4f614b762..ddae7f3cf 100644 --- a/src/lib/core/__test__/WrapperCache.test.ts +++ b/src/lib/core/__test__/WrapperCache.test.ts @@ -1,12 +1,14 @@ import { QObject } from '../../QtCore/QObject'; import { QApplication } from '../../QtGui/QApplication'; import { CacheTestQObject } from './CacheTestQObject'; +import { wrapperCache } from '../WrapperCache'; describe('WrapperCache using CacheTestQObject', () => { const qApp = QApplication.instance(); qApp.setQuitOnLastWindowClosed(true); it('Cached foo', () => { + wrapperCache._flush(); const a = new CacheTestQObject(); expect(a).not.toBeNull(); @@ -14,11 +16,12 @@ describe('WrapperCache using CacheTestQObject', () => { expect(foo).not.toBeNull(); const foo2 = a.foo(); - expect(foo).toBe(foo2); expect(foo.native.__id__()).toBe(foo2.native.__id__()); + expect(foo).toBe(foo2); }); it('clearFoo() and wrapper expiration', () => { + wrapperCache._flush(); const a = new CacheTestQObject(); const foo = a.foo(); a.clearFoo(); @@ -26,6 +29,7 @@ describe('WrapperCache using CacheTestQObject', () => { }); it('clearFoo() and new wrapper', () => { + wrapperCache._flush(); const a = new CacheTestQObject(); const foo = a.foo(); const fooId = foo.native.__id__(); @@ -38,6 +42,7 @@ describe('WrapperCache using CacheTestQObject', () => { }); it('Cached foo and bar', () => { + wrapperCache._flush(); const a = new CacheTestQObject(); const foo = a.foo(); const bar = a.bar(); @@ -46,11 +51,13 @@ describe('WrapperCache using CacheTestQObject', () => { }); it('QObject.parent() can be null', () => { + wrapperCache._flush(); const a = new QObject(); expect(a.parent()).toBeNull(); }); it('QObject.parent() === QObject.parent()', () => { + wrapperCache._flush(); const a = new QObject(); const b = new QObject(a); expect(a.native.__id__()).toEqual(b.parent().native.__id__()); @@ -60,12 +67,14 @@ describe('WrapperCache using CacheTestQObject', () => { }); it('QObject.delete() clears the native field', () => { + wrapperCache._flush(); const a = new QObject(); a.delete(); expect(a.native).toBeNull(); }); it('QObject.delete() clears chains of QObjects and their native field', () => { + wrapperCache._flush(); const a = new QObject(); const b = new QObject(a); a.delete(); From f3d7d73acc35c6cbe0b4383a4ca51a6ea1890e37 Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Thu, 5 May 2022 19:25:01 +0200 Subject: [PATCH 20/28] Add `QObject.children()` --- .../include/nodegui/QtCore/QObject/qobject_macro.h | 13 ++++++++++++- src/lib/QtCore/QObject.ts | 3 +++ src/lib/core/__test__/WrapperCache.test.ts | 11 +++++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/cpp/include/nodegui/QtCore/QObject/qobject_macro.h b/src/cpp/include/nodegui/QtCore/QObject/qobject_macro.h index b77773d48..8b745f0f3 100644 --- a/src/cpp/include/nodegui/QtCore/QObject/qobject_macro.h +++ b/src/cpp/include/nodegui/QtCore/QObject/qobject_macro.h @@ -109,6 +109,16 @@ Napi::Env env = info.Env(); \ delete static_cast(this->instance); \ return env.Null(); \ + } \ + Napi::Value children(const Napi::CallbackInfo& info) { \ + Napi::Env env = info.Env(); \ + QObjectList children = this->instance->children(); \ + Napi::Array resultArrayNapi = Napi::Array::New(env, children.size()); \ + for (int i = 0; i < children.size(); i++) { \ + resultArrayNapi[i] = \ + WrapperCache::instance.getWrapper(env, children[i]); \ + } \ + return resultArrayNapi; \ } // Ideally this macro below should go in @@ -155,7 +165,8 @@ InstanceMethod("killTimer", &ComponentWrapName::killTimer), \ InstanceMethod("parent", &ComponentWrapName::parent), \ InstanceMethod("deleteLater", &ComponentWrapName::deleteLater), \ - InstanceMethod("delete", &ComponentWrapName::deleteObject), + InstanceMethod("delete", &ComponentWrapName::deleteObject), \ + InstanceMethod("children", &ComponentWrapName::children), #endif // QOBJECT_WRAPPED_METHODS_EXPORT_DEFINE diff --git a/src/lib/QtCore/QObject.ts b/src/lib/QtCore/QObject.ts index 53ae0feff..b3b4ad450 100644 --- a/src/lib/QtCore/QObject.ts +++ b/src/lib/QtCore/QObject.ts @@ -70,6 +70,9 @@ export class QObject extends Ev deleteLater(): void { this.native.deleteLater(); } + children(): QObject[] { + return this.native.children().map((kid: any) => wrapperCache.getWrapper(kid)); + } } export interface QObjectSignals { diff --git a/src/lib/core/__test__/WrapperCache.test.ts b/src/lib/core/__test__/WrapperCache.test.ts index ddae7f3cf..342d3f859 100644 --- a/src/lib/core/__test__/WrapperCache.test.ts +++ b/src/lib/core/__test__/WrapperCache.test.ts @@ -82,5 +82,16 @@ describe('WrapperCache using CacheTestQObject', () => { expect(b.native).toBeNull(); }); + it('Object.children()', () => { + wrapperCache._flush(); + const parent = new QObject(); + const kid1 = new QObject(parent); + const kid2 = new QObject(parent); + const allKids = parent.children(); + expect(allKids.length).toBe(2); + expect(allKids[0]).toEqual(kid1); + expect(allKids[1]).toEqual(kid2); + }); + qApp.quit(); }); From 6aa3f00fa3fa1b50ec418377494adb226c2f23ef Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Sat, 7 May 2022 09:57:23 +0200 Subject: [PATCH 21/28] Massive C++ wrapper update --- src/cpp/include/nodegui/Extras/Utils/nutils.h | 3 +- .../qitemselectionmodel_wrap.h | 1 - .../nodegui/QtCore/QMimeData/qmimedata_wrap.h | 6 +- .../nodegui/QtCore/QObject/qobject_wrap.h | 4 +- .../include/nodegui/QtGui/QDrag/qdrag_wrap.h | 4 +- .../qabstractitemview_macro.h | 4 +- .../qabstractscrollarea_macro.h | 4 +- .../nodegui/QtWidgets/QAction/qaction_wrap.h | 5 +- .../QtWidgets/QBoxLayout/qboxlayout_wrap.h | 4 +- .../QButtonGroup/qbuttongroup_wrap.h | 4 +- .../QCalendarWidget/qcalendarwidget_wrap.h | 4 +- .../QtWidgets/QCheckBox/qcheckbox_wrap.h | 5 +- .../QColorDialog/qcolordialog_wrap.h | 4 +- .../QtWidgets/QComboBox/qcombobox_wrap.h | 4 +- .../QtWidgets/QDateEdit/qdateedit_wrap.h | 4 +- .../QDateTimeEdit/qdatetimeedit_wrap.h | 4 +- .../nodegui/QtWidgets/QDial/qdial_wrap.h | 4 +- .../nodegui/QtWidgets/QDialog/qdialog_wrap.h | 4 +- .../QDoubleSpinBox/qdoublespinbox_wrap.h | 4 +- .../QErrorMessage/qerrormessage_wrap.h | 4 +- .../QtWidgets/QFileDialog/qfiledialog_wrap.h | 4 +- .../QtWidgets/QFontDialog/qfontdialog_wrap.h | 4 +- .../nodegui/QtWidgets/QFrame/qframe_wrap.h | 4 +- .../qgraphicsblureffect_wrap.h | 5 +- .../qgraphicsdropshadoweffect_wrap.h | 4 +- .../QtWidgets/QGridLayout/qgridlayout_wrap.h | 4 +- .../QtWidgets/QGroupBox/qgroupbox_wrap.h | 4 +- .../QtWidgets/QHeaderView/qheaderview_wrap.h | 1 - .../QInputDialog/qinputdialog_wrap.h | 4 +- .../QtWidgets/QLCDNumber/qlcdnumber_wrap.h | 4 +- .../nodegui/QtWidgets/QLabel/qlabel_wrap.h | 4 +- .../nodegui/QtWidgets/QLayout/qlayout_wrap.h | 6 +- .../QtWidgets/QLineEdit/qlineedit_wrap.h | 4 +- .../QtWidgets/QListView/qlistview_wrap.h | 5 +- .../QtWidgets/QListWidget/qlistwidget_wrap.h | 4 +- .../QtWidgets/QMainWindow/qmainwindow_wrap.h | 4 +- .../include/nodegui/QtWidgets/QMenu/nmenu.hpp | 6 +- .../nodegui/QtWidgets/QMenu/qmenu_wrap.h | 4 +- .../QtWidgets/QMenuBar/qmenubar_wrap.h | 4 +- .../QtWidgets/QMessageBox/qmessagebox_wrap.h | 4 +- .../QPlainTextEdit/qplaintextedit_wrap.h | 4 +- .../QProgressBar/qprogressbar_wrap.h | 4 +- .../QProgressDialog/qprogressdialog_wrap.h | 4 +- .../QtWidgets/QPushButton/qpushbutton_wrap.h | 5 +- .../QRadioButton/qradiobutton_wrap.h | 5 +- .../QtWidgets/QScrollArea/qscrollarea_wrap.h | 6 +- .../QtWidgets/QScrollBar/qscrollbar_wrap.h | 4 +- .../QtWidgets/QShortcut/qshortcut_wrap.h | 4 +- .../nodegui/QtWidgets/QSlider/qslider_wrap.h | 4 +- .../QtWidgets/QSpinBox/qspinbox_wrap.h | 4 +- .../QtWidgets/QSplitter/qsplitter_wrap.h | 4 +- .../QStackedWidget/qstackedwidget_wrap.h | 4 +- .../qstandarditemmodel_wrap.h | 4 +- .../QtWidgets/QStatusBar/qstatusbar_wrap.h | 4 +- .../QtWidgets/QSvgWidget/qsvgwidget_wrap.h | 4 +- .../QSystemTrayIcon/qsystemtrayicon_wrap.h | 4 +- .../nodegui/QtWidgets/QTabBar/qtabbar_wrap.h | 5 +- .../QtWidgets/QTabWidget/qtabwidget_wrap.h | 4 +- .../QtWidgets/QTableView/qtableview_macro.h | 6 +- .../QtWidgets/QTableView/qtableview_wrap.h | 5 +- .../QTableWidget/qtablewidget_wrap.h | 4 +- .../QTextBrowser/qtextbrowser_wrap.h | 4 +- .../QtWidgets/QTextEdit/qtextedit_wrap.h | 4 +- .../QtWidgets/QTimeEdit/qtimeedit_wrap.h | 4 +- .../QtWidgets/QToolButton/ntoolbutton.hpp | 6 +- .../QtWidgets/QToolButton/qtoolbutton_wrap.h | 5 +- .../QtWidgets/QTreeWidget/qtreewidget_wrap.h | 4 +- .../nodegui/QtWidgets/QWidget/qwidget_wrap.h | 4 +- .../nodegui/core/WrapperCache/wrappercache.h | 34 +++++-- src/cpp/lib/Extras/Utils/nutils.cpp | 11 ++- .../qabstractitemmodel_wrap.cpp | 17 +++- .../qitemselectionmodel_wrap.cpp | 28 ++++-- .../lib/QtCore/QMimeData/qmimedata_wrap.cpp | 41 +++------ src/cpp/lib/QtCore/QObject/qobject_wrap.cpp | 13 +-- .../QtGui/QApplication/qapplication_wrap.cpp | 8 +- src/cpp/lib/QtGui/QDrag/qdrag_wrap.cpp | 26 ++++-- src/cpp/lib/QtGui/QMovie/qmovie_wrap.cpp | 28 +++--- src/cpp/lib/QtGui/QScreen/qscreen_wrap.cpp | 2 +- src/cpp/lib/QtGui/QStyle/qstyle_wrap.cpp | 3 +- src/cpp/lib/QtGui/QWindow/qwindow_wrap.cpp | 4 +- .../lib/QtWidgets/QAction/qaction_wrap.cpp | 46 +++++----- .../QtWidgets/QBoxLayout/qboxlayout_wrap.cpp | 22 +++-- .../QButtonGroup/qbuttongroup_wrap.cpp | 29 +++--- .../QCalendarWidget/qcalendarwidget_wrap.cpp | 36 +++++--- .../QtWidgets/QCheckBox/qcheckbox_wrap.cpp | 42 ++++----- .../QColorDialog/qcolordialog_wrap.cpp | 34 ++++--- .../QtWidgets/QComboBox/qcombobox_wrap.cpp | 33 ++++--- .../QtWidgets/QDateEdit/qdateedit_wrap.cpp | 31 ++++--- .../QDateTimeEdit/qdatetimeedit_wrap.cpp | 33 ++++--- src/cpp/lib/QtWidgets/QDial/qdial_wrap.cpp | 32 ++++--- .../lib/QtWidgets/QDialog/qdialog_wrap.cpp | 28 +++--- .../QDoubleSpinBox/qdoublespinbox_wrap.cpp | 34 ++++--- .../QErrorMessage/qerrormessage_wrap.cpp | 34 ++++--- .../QFileDialog/qfiledialog_wrap.cpp | 17 ++-- .../QFontDialog/qfontdialog_wrap.cpp | 33 ++++--- src/cpp/lib/QtWidgets/QFrame/qframe_wrap.cpp | 31 ++++--- .../qgraphicsblureffect_wrap.cpp | 30 +++++-- .../qgraphicsdropshadoweffect_wrap.cpp | 33 +++++-- .../QGridLayout/qgridlayout_wrap.cpp | 28 ++++-- .../QtWidgets/QGroupBox/qgroupbox_wrap.cpp | 31 ++++--- .../QHeaderView/qheaderview_wrap.cpp | 18 ++-- .../QInputDialog/qinputdialog_wrap.cpp | 34 ++++--- .../QtWidgets/QLCDNumber/qlcdnumber_wrap.cpp | 32 ++++--- src/cpp/lib/QtWidgets/QLabel/qlabel_wrap.cpp | 37 +++++--- .../lib/QtWidgets/QLayout/qlayout_wrap.cpp | 19 +++- .../QtWidgets/QLineEdit/qlineedit_wrap.cpp | 31 ++++--- .../QtWidgets/QListView/qlistview_wrap.cpp | 44 +++++----- .../QListWidget/qlistwidget_wrap.cpp | 32 ++++--- .../QListWidgetItem/qlistwidgetitem_wrap.cpp | 12 +-- .../QMainWindow/qmainwindow_wrap.cpp | 30 ++++--- src/cpp/lib/QtWidgets/QMenu/qmenu_wrap.cpp | 31 ++++--- .../lib/QtWidgets/QMenuBar/qmenubar_wrap.cpp | 22 +++-- .../QMessageBox/qmessagebox_wrap.cpp | 33 ++++--- .../QPlainTextEdit/qplaintextedit_wrap.cpp | 34 ++++--- .../QProgressBar/qprogressbar_wrap.cpp | 33 ++++--- .../QProgressDialog/qprogressdialog_wrap.cpp | 34 ++++--- .../QPushButton/qpushbutton_wrap.cpp | 44 +++++----- .../QRadioButton/qradiobutton_wrap.cpp | 41 +++++---- .../QScrollArea/qscrollarea_wrap.cpp | 88 +++++++++++-------- .../QtWidgets/QScrollBar/qscrollbar_wrap.cpp | 33 ++++--- .../QtWidgets/QShortcut/qshortcut_wrap.cpp | 26 ++++-- .../lib/QtWidgets/QSlider/qslider_wrap.cpp | 32 ++++--- .../lib/QtWidgets/QSpinBox/qspinbox_wrap.cpp | 31 ++++--- .../QtWidgets/QSplitter/qsplitter_wrap.cpp | 31 ++++--- .../QStackedWidget/qstackedwidget_wrap.cpp | 35 +++++--- .../QStandardItem/qstandarditem_wrap.cpp | 11 +-- .../qstandarditemmodel_wrap.cpp | 30 ++++--- .../QtWidgets/QStatusBar/qstatusbar_wrap.cpp | 34 ++++--- .../QtWidgets/QSvgWidget/qsvgwidget_wrap.cpp | 32 ++++--- .../QSystemTrayIcon/qsystemtrayicon_wrap.cpp | 30 ++++--- .../lib/QtWidgets/QTabBar/qtabbar_wrap.cpp | 43 ++++----- .../QtWidgets/QTabWidget/qtabwidget_wrap.cpp | 34 ++++--- .../QtWidgets/QTableView/qtableview_wrap.cpp | 44 +++++----- .../QTableWidget/qtablewidget_wrap.cpp | 51 ++++++----- .../qtablewidgetitem_wrap.cpp | 9 +- .../QTextBrowser/qtextbrowser_wrap.cpp | 33 ++++--- .../QtWidgets/QTextEdit/qtextedit_wrap.cpp | 31 ++++--- .../QtWidgets/QTimeEdit/qtimeedit_wrap.cpp | 31 ++++--- .../QToolButton/qtoolbutton_wrap.cpp | 43 +++++---- .../QTreeWidget/qtreewidget_wrap.cpp | 32 ++++--- .../lib/QtWidgets/QWidget/qwidget_wrap.cpp | 25 +++--- src/cpp/main.cpp | 6 +- src/lib/QtCore/QObject.ts | 2 - src/lib/QtWidgets/QAbstractScrollArea.ts | 8 +- src/lib/QtWidgets/QAction.ts | 11 ++- src/lib/QtWidgets/QBoxLayout.ts | 23 +++-- src/lib/QtWidgets/QButtonGroup.ts | 15 ++-- src/lib/QtWidgets/QCalendarWidget.ts | 11 ++- src/lib/QtWidgets/QCheckBox.ts | 13 ++- src/lib/QtWidgets/QColorDialog.ts | 1 - src/lib/QtWidgets/QComboBox.ts | 1 - src/lib/QtWidgets/QDateEdit.ts | 1 - src/lib/QtWidgets/QDateTimeEdit.ts | 6 +- src/lib/QtWidgets/QDial.ts | 1 - src/lib/QtWidgets/QDialog.ts | 1 - src/lib/QtWidgets/QDoubleSpinBox.ts | 1 - src/lib/QtWidgets/QErrorMessage.ts | 1 - src/lib/QtWidgets/QFileDialog.ts | 1 - src/lib/QtWidgets/QFontDialog.ts | 1 - src/lib/QtWidgets/QFrame.ts | 1 - src/lib/QtWidgets/QGridLayout.ts | 3 - src/lib/QtWidgets/QGroupBox.ts | 1 - src/lib/QtWidgets/QHeaderView.ts | 1 - src/lib/QtWidgets/QInputDialog.ts | 1 - src/lib/QtWidgets/QLCDNumber.ts | 1 - src/lib/QtWidgets/QLabel.ts | 1 - src/lib/QtWidgets/QLineEdit.ts | 1 - src/lib/QtWidgets/QListView.ts | 9 +- src/lib/QtWidgets/QListWidget.ts | 1 - src/lib/QtWidgets/QMainWindow.ts | 8 +- src/lib/QtWidgets/QMenu.ts | 1 - src/lib/QtWidgets/QMenuBar.ts | 3 - src/lib/QtWidgets/QMessageBox.ts | 3 - src/lib/QtWidgets/QPlainTextEdit.ts | 1 - src/lib/QtWidgets/QProgressBar.ts | 1 - src/lib/QtWidgets/QProgressDialog.ts | 1 - src/lib/QtWidgets/QPushButton.ts | 5 +- src/lib/QtWidgets/QRadioButton.ts | 5 +- src/lib/QtWidgets/QScrollArea.ts | 18 +--- src/lib/QtWidgets/QScrollBar.ts | 1 - src/lib/QtWidgets/QSlider.ts | 1 - src/lib/QtWidgets/QSpinBox.ts | 1 - src/lib/QtWidgets/QSplitter.ts | 1 - src/lib/QtWidgets/QStackedWidget.ts | 3 - src/lib/QtWidgets/QStandardItemModel.ts | 1 - src/lib/QtWidgets/QStatusBar.ts | 1 - src/lib/QtWidgets/QSvgWidget.ts | 1 - src/lib/QtWidgets/QTabBar.ts | 1 - src/lib/QtWidgets/QTabWidget.ts | 1 - src/lib/QtWidgets/QTableView.ts | 1 - src/lib/QtWidgets/QTableWidget.ts | 1 - src/lib/QtWidgets/QTextBrowser.ts | 1 - src/lib/QtWidgets/QTextEdit.ts | 1 - src/lib/QtWidgets/QTimeEdit.ts | 1 - src/lib/QtWidgets/QToolButton.ts | 5 +- src/lib/QtWidgets/QTreeWidget.ts | 1 - src/lib/QtWidgets/QTreeWidgetItem.ts | 7 +- src/lib/QtWidgets/QWidget.ts | 34 +++---- src/lib/core/Component.ts | 9 -- src/lib/core/FlexLayout.ts | 21 +---- src/lib/core/__test__/CacheTestQObject.ts | 1 - src/lib/utils/helpers.ts | 2 +- 202 files changed, 1564 insertions(+), 1191 deletions(-) diff --git a/src/cpp/include/nodegui/Extras/Utils/nutils.h b/src/cpp/include/nodegui/Extras/Utils/nutils.h index 5142443ba..e7b54d11e 100644 --- a/src/cpp/include/nodegui/Extras/Utils/nutils.h +++ b/src/cpp/include/nodegui/Extras/Utils/nutils.h @@ -13,8 +13,7 @@ namespace extrautils { DLL_EXPORT QVariant* convertToQVariant(Napi::Env& env, Napi::Value& value); DLL_EXPORT bool isNapiValueInt(Napi::Env& env, Napi::Value& num); DLL_EXPORT std::string getNapiObjectClassName(Napi::Object& object); -DLL_EXPORT void* configureQWidget(QWidget* widget, YGNodeRef node, - bool isLeafNode = false); +DLL_EXPORT void* configureQWidget(QWidget* widget, bool isLeafNode = false); DLL_EXPORT void* configureQObject(QObject* object); DLL_EXPORT void* configureComponent(void* component); DLL_EXPORT uint64_t hashPointerTo53bit(const void* input); diff --git a/src/cpp/include/nodegui/QtCore/QItemSelectionModel/qitemselectionmodel_wrap.h b/src/cpp/include/nodegui/QtCore/QItemSelectionModel/qitemselectionmodel_wrap.h index 3f4ac5101..3bf7883ae 100644 --- a/src/cpp/include/nodegui/QtCore/QItemSelectionModel/qitemselectionmodel_wrap.h +++ b/src/cpp/include/nodegui/QtCore/QItemSelectionModel/qitemselectionmodel_wrap.h @@ -14,7 +14,6 @@ class DLL_EXPORT QItemSelectionModelWrap private: QPointer instance; - bool disableDeletion; public: static Napi::Object init(Napi::Env env, Napi::Object exports); diff --git a/src/cpp/include/nodegui/QtCore/QMimeData/qmimedata_wrap.h b/src/cpp/include/nodegui/QtCore/QMimeData/qmimedata_wrap.h index e87b1d718..ca42191e0 100644 --- a/src/cpp/include/nodegui/QtCore/QMimeData/qmimedata_wrap.h +++ b/src/cpp/include/nodegui/QtCore/QMimeData/qmimedata_wrap.h @@ -5,13 +5,13 @@ #include #include "Extras/Export/export.h" -#include "core/Component/component_macro.h" +#include "QtCore/QObject/qobject_macro.h" class DLL_EXPORT QMimeDataWrap : public Napi::ObjectWrap { - COMPONENT_WRAPPED_METHODS_DECLARATION + QOBJECT_WRAPPED_METHODS_DECLARATION private: - std::unique_ptr instance; + QPointer instance; public: static Napi::Object init(Napi::Env env, Napi::Object exports); diff --git a/src/cpp/include/nodegui/QtCore/QObject/qobject_wrap.h b/src/cpp/include/nodegui/QtCore/QObject/qobject_wrap.h index eaf50c5b2..0aca30b2e 100644 --- a/src/cpp/include/nodegui/QtCore/QObject/qobject_wrap.h +++ b/src/cpp/include/nodegui/QtCore/QObject/qobject_wrap.h @@ -11,13 +11,13 @@ class DLL_EXPORT QObjectWrap : public Napi::ObjectWrap { QOBJECT_WRAPPED_METHODS_DECLARATION private: - QPointer instance; + QPointer instance; public: static Napi::Object init(Napi::Env env, Napi::Object exports); QObjectWrap(const Napi::CallbackInfo& info); ~QObjectWrap(); - NObject* getInternalInstance(); + QObject* getInternalInstance(); // class constructor static Napi::FunctionReference constructor; static Napi::Object wrapFunc(Napi::Env env, QObject* qobject); diff --git a/src/cpp/include/nodegui/QtGui/QDrag/qdrag_wrap.h b/src/cpp/include/nodegui/QtGui/QDrag/qdrag_wrap.h index da688bd08..39d17f2ae 100644 --- a/src/cpp/include/nodegui/QtGui/QDrag/qdrag_wrap.h +++ b/src/cpp/include/nodegui/QtGui/QDrag/qdrag_wrap.h @@ -22,13 +22,13 @@ class DLL_EXPORT QDragWrap : public Napi::ObjectWrap { // except that it is automatically cleared when the referenced object is // destroyed (unlike normal C++ pointers, which become "dangling pointers" in // such cases). T must be a subclass of QObject. - QPointer instance; + QPointer instance; public: static Napi::Object init(Napi::Env env, Napi::Object exports); QDragWrap(const Napi::CallbackInfo& info); ~QDragWrap(); - NDrag* getInternalInstance(); + QDrag* getInternalInstance(); // class constructor static Napi::FunctionReference constructor; diff --git a/src/cpp/include/nodegui/QtWidgets/QAbstractItemView/qabstractitemview_macro.h b/src/cpp/include/nodegui/QtWidgets/QAbstractItemView/qabstractitemview_macro.h index 64d71e353..9e6781716 100644 --- a/src/cpp/include/nodegui/QtWidgets/QAbstractItemView/qabstractitemview_macro.h +++ b/src/cpp/include/nodegui/QtWidgets/QAbstractItemView/qabstractitemview_macro.h @@ -145,9 +145,7 @@ Napi::Value selectionModel(const Napi::CallbackInfo& info) { \ Napi::Env env = info.Env(); \ QItemSelectionModel* model = this->instance->selectionModel(); \ - auto modelExt = Napi::External::New(env, model); \ - auto instance = QItemSelectionModelWrap::constructor.New({modelExt}); \ - return instance; \ + return WrapperCache::instance.getWrapper(env, model); \ } \ Napi::Value isPersistentEditorOpen(const Napi::CallbackInfo& info) { \ Napi::Env env = info.Env(); \ diff --git a/src/cpp/include/nodegui/QtWidgets/QAbstractScrollArea/qabstractscrollarea_macro.h b/src/cpp/include/nodegui/QtWidgets/QAbstractScrollArea/qabstractscrollarea_macro.h index 9bf5d3309..9bb8a13e8 100644 --- a/src/cpp/include/nodegui/QtWidgets/QAbstractScrollArea/qabstractscrollarea_macro.h +++ b/src/cpp/include/nodegui/QtWidgets/QAbstractScrollArea/qabstractscrollarea_macro.h @@ -58,9 +58,7 @@ Napi::Value viewport(const Napi::CallbackInfo& info) { \ Napi::Env env = info.Env(); \ QWidget* viewPort = this->instance->viewport(); \ - NWidget* nviewPort = reinterpret_cast(viewPort); \ - auto instance = QWidgetWrap::constructor.New( \ - {Napi::External::New(env, nviewPort)}); \ + auto instance = WrapperCache::instance.getWrapper(env, viewPort); \ return instance; \ } diff --git a/src/cpp/include/nodegui/QtWidgets/QAction/qaction_wrap.h b/src/cpp/include/nodegui/QtWidgets/QAction/qaction_wrap.h index d4d118b77..d0b382a11 100644 --- a/src/cpp/include/nodegui/QtWidgets/QAction/qaction_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QAction/qaction_wrap.h @@ -11,14 +11,13 @@ class DLL_EXPORT QActionWrap : public Napi::ObjectWrap { QOBJECT_WRAPPED_METHODS_DECLARATION private: - QPointer instance; - bool disableDeletion; + QPointer instance; public: static Napi::Object init(Napi::Env env, Napi::Object exports); QActionWrap(const Napi::CallbackInfo& info); ~QActionWrap(); - NAction* getInternalInstance(); + QAction* getInternalInstance(); // class constructor static Napi::FunctionReference constructor; // wrapped methods diff --git a/src/cpp/include/nodegui/QtWidgets/QBoxLayout/qboxlayout_wrap.h b/src/cpp/include/nodegui/QtWidgets/QBoxLayout/qboxlayout_wrap.h index 09a6646f7..290b02108 100644 --- a/src/cpp/include/nodegui/QtWidgets/QBoxLayout/qboxlayout_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QBoxLayout/qboxlayout_wrap.h @@ -12,13 +12,13 @@ class DLL_EXPORT QBoxLayoutWrap : public Napi::ObjectWrap { QLAYOUT_WRAPPED_METHODS_DECLARATION private: - QPointer instance; + QPointer instance; public: static Napi::Object init(Napi::Env env, Napi::Object exports); QBoxLayoutWrap(const Napi::CallbackInfo& info); ~QBoxLayoutWrap(); - NBoxLayout* getInternalInstance(); + QBoxLayout* getInternalInstance(); // class constructor static Napi::FunctionReference constructor; // wrapped methods diff --git a/src/cpp/include/nodegui/QtWidgets/QButtonGroup/qbuttongroup_wrap.h b/src/cpp/include/nodegui/QtWidgets/QButtonGroup/qbuttongroup_wrap.h index 1f79b7722..5100dff6e 100644 --- a/src/cpp/include/nodegui/QtWidgets/QButtonGroup/qbuttongroup_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QButtonGroup/qbuttongroup_wrap.h @@ -9,13 +9,13 @@ #include "nbuttongroup.hpp" class DLL_EXPORT QButtonGroupWrap : public Napi::ObjectWrap { private: - QPointer instance; + QPointer instance; public: static Napi::Object init(Napi::Env env, Napi::Object exports); QButtonGroupWrap(const Napi::CallbackInfo& info); ~QButtonGroupWrap(); - NButtonGroup* getInternalInstance(); + QButtonGroup* getInternalInstance(); // class constructor static Napi::FunctionReference constructor; // wrapped methods diff --git a/src/cpp/include/nodegui/QtWidgets/QCalendarWidget/qcalendarwidget_wrap.h b/src/cpp/include/nodegui/QtWidgets/QCalendarWidget/qcalendarwidget_wrap.h index 30cdd66cd..cf005eaac 100644 --- a/src/cpp/include/nodegui/QtWidgets/QCalendarWidget/qcalendarwidget_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QCalendarWidget/qcalendarwidget_wrap.h @@ -11,13 +11,13 @@ class DLL_EXPORT QCalendarWidgetWrap : public Napi::ObjectWrap { private: - QPointer instance; + QPointer instance; public: static Napi::Object init(Napi::Env env, Napi::Object exports); QCalendarWidgetWrap(const Napi::CallbackInfo &info); ~QCalendarWidgetWrap(); - NCalendarWidget *getInternalInstance(); + QCalendarWidget *getInternalInstance(); // class constructor static Napi::FunctionReference constructor; // wrapped methods diff --git a/src/cpp/include/nodegui/QtWidgets/QCheckBox/qcheckbox_wrap.h b/src/cpp/include/nodegui/QtWidgets/QCheckBox/qcheckbox_wrap.h index 67809fe2d..b15ae5f3a 100644 --- a/src/cpp/include/nodegui/QtWidgets/QCheckBox/qcheckbox_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QCheckBox/qcheckbox_wrap.h @@ -12,14 +12,13 @@ class DLL_EXPORT QCheckBoxWrap : public Napi::ObjectWrap { QABSTRACTBUTTON_WRAPPED_METHODS_DECLARATION private: - QPointer instance; - bool disableDeletion; + QPointer instance; public: static Napi::Object init(Napi::Env env, Napi::Object exports); QCheckBoxWrap(const Napi::CallbackInfo& info); ~QCheckBoxWrap(); - NCheckBox* getInternalInstance(); + QCheckBox* getInternalInstance(); // class constructor static Napi::FunctionReference constructor; // wrapped methods diff --git a/src/cpp/include/nodegui/QtWidgets/QColorDialog/qcolordialog_wrap.h b/src/cpp/include/nodegui/QtWidgets/QColorDialog/qcolordialog_wrap.h index 25a6479c4..968e5cca3 100644 --- a/src/cpp/include/nodegui/QtWidgets/QColorDialog/qcolordialog_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QColorDialog/qcolordialog_wrap.h @@ -11,13 +11,13 @@ class DLL_EXPORT QColorDialogWrap : public Napi::ObjectWrap { QDIALOG_WRAPPED_METHODS_DECLARATION private: - QPointer instance; + QPointer instance; public: static Napi::Object init(Napi::Env env, Napi::Object exports); QColorDialogWrap(const Napi::CallbackInfo& info); ~QColorDialogWrap(); - NColorDialog* getInternalInstance(); + QColorDialog* getInternalInstance(); // class constructor static Napi::FunctionReference constructor; // wrapped methods diff --git a/src/cpp/include/nodegui/QtWidgets/QComboBox/qcombobox_wrap.h b/src/cpp/include/nodegui/QtWidgets/QComboBox/qcombobox_wrap.h index c739d5046..e5ed8407a 100644 --- a/src/cpp/include/nodegui/QtWidgets/QComboBox/qcombobox_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QComboBox/qcombobox_wrap.h @@ -11,13 +11,13 @@ class DLL_EXPORT QComboBoxWrap : public Napi::ObjectWrap { QWIDGET_WRAPPED_METHODS_DECLARATION private: - QPointer instance; + QPointer instance; public: static Napi::Object init(Napi::Env env, Napi::Object exports); QComboBoxWrap(const Napi::CallbackInfo& info); ~QComboBoxWrap(); - NComboBox* getInternalInstance(); + QComboBox* getInternalInstance(); // class constructor static Napi::FunctionReference constructor; // wrapped methods diff --git a/src/cpp/include/nodegui/QtWidgets/QDateEdit/qdateedit_wrap.h b/src/cpp/include/nodegui/QtWidgets/QDateEdit/qdateedit_wrap.h index 37d09271e..9498d049f 100644 --- a/src/cpp/include/nodegui/QtWidgets/QDateEdit/qdateedit_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QDateEdit/qdateedit_wrap.h @@ -11,13 +11,13 @@ class DLL_EXPORT QDateEditWrap : public Napi::ObjectWrap { QDATETIMEEDIT_WRAPPED_METHODS_DECLARATION private: - QPointer instance; + QPointer instance; public: static Napi::Object init(Napi::Env env, Napi::Object exports); QDateEditWrap(const Napi::CallbackInfo &info); ~QDateEditWrap(); - NDateEdit *getInternalInstance(); + QDateEdit *getInternalInstance(); // class constructor static Napi::FunctionReference constructor; // wrapped methods diff --git a/src/cpp/include/nodegui/QtWidgets/QDateTimeEdit/qdatetimeedit_wrap.h b/src/cpp/include/nodegui/QtWidgets/QDateTimeEdit/qdatetimeedit_wrap.h index 7f6ffcc83..c994acdf7 100644 --- a/src/cpp/include/nodegui/QtWidgets/QDateTimeEdit/qdatetimeedit_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QDateTimeEdit/qdatetimeedit_wrap.h @@ -12,13 +12,13 @@ class DLL_EXPORT QDateTimeEditWrap : public Napi::ObjectWrap { QDATETIMEEDIT_WRAPPED_METHODS_DECLARATION private: - QPointer instance; + QPointer instance; public: static Napi::Object init(Napi::Env env, Napi::Object exports); QDateTimeEditWrap(const Napi::CallbackInfo &info); ~QDateTimeEditWrap(); - NDateTimeEdit *getInternalInstance(); + QDateTimeEdit *getInternalInstance(); // class constructor static Napi::FunctionReference constructor; // wrapped methods diff --git a/src/cpp/include/nodegui/QtWidgets/QDial/qdial_wrap.h b/src/cpp/include/nodegui/QtWidgets/QDial/qdial_wrap.h index f6fa9c4e6..d7e010fb2 100644 --- a/src/cpp/include/nodegui/QtWidgets/QDial/qdial_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QDial/qdial_wrap.h @@ -12,13 +12,13 @@ class DLL_EXPORT QDialWrap : public Napi::ObjectWrap { QABSTRACTSLIDER_WRAPPED_METHODS_DECLARATION private: - QPointer instance; + QPointer instance; public: static Napi::Object init(Napi::Env env, Napi::Object exports); QDialWrap(const Napi::CallbackInfo& info); ~QDialWrap(); - NDial* getInternalInstance(); + QDial* getInternalInstance(); // class constructor static Napi::FunctionReference constructor; // wrapped methods diff --git a/src/cpp/include/nodegui/QtWidgets/QDialog/qdialog_wrap.h b/src/cpp/include/nodegui/QtWidgets/QDialog/qdialog_wrap.h index 374ed1d96..5a144e8df 100644 --- a/src/cpp/include/nodegui/QtWidgets/QDialog/qdialog_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QDialog/qdialog_wrap.h @@ -11,13 +11,13 @@ class DLL_EXPORT QDialogWrap : public Napi::ObjectWrap { QDIALOG_WRAPPED_METHODS_DECLARATION private: - QPointer instance; + QPointer instance; public: static Napi::Object init(Napi::Env env, Napi::Object exports); QDialogWrap(const Napi::CallbackInfo& info); ~QDialogWrap(); - NDialog* getInternalInstance(); + QDialog* getInternalInstance(); // class constructor static Napi::FunctionReference constructor; // wrapped methods diff --git a/src/cpp/include/nodegui/QtWidgets/QDoubleSpinBox/qdoublespinbox_wrap.h b/src/cpp/include/nodegui/QtWidgets/QDoubleSpinBox/qdoublespinbox_wrap.h index 435aa3a2d..6d358bec3 100644 --- a/src/cpp/include/nodegui/QtWidgets/QDoubleSpinBox/qdoublespinbox_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QDoubleSpinBox/qdoublespinbox_wrap.h @@ -12,13 +12,13 @@ class DLL_EXPORT QDoubleSpinBoxWrap : public Napi::ObjectWrap { QABSTRACTSPINBOX_WRAPPED_METHODS_DECLARATION private: - QPointer instance; + QPointer instance; public: static Napi::Object init(Napi::Env env, Napi::Object exports); QDoubleSpinBoxWrap(const Napi::CallbackInfo& info); ~QDoubleSpinBoxWrap(); - NDoubleSpinBox* getInternalInstance(); + QDoubleSpinBox* getInternalInstance(); // class constructor static Napi::FunctionReference constructor; // wrapped methods diff --git a/src/cpp/include/nodegui/QtWidgets/QErrorMessage/qerrormessage_wrap.h b/src/cpp/include/nodegui/QtWidgets/QErrorMessage/qerrormessage_wrap.h index c9fa3981c..a5d984e47 100644 --- a/src/cpp/include/nodegui/QtWidgets/QErrorMessage/qerrormessage_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QErrorMessage/qerrormessage_wrap.h @@ -12,13 +12,13 @@ class DLL_EXPORT QErrorMessageWrap : public Napi::ObjectWrap { QDIALOG_WRAPPED_METHODS_DECLARATION private: - QPointer instance; + QPointer instance; public: static Napi::Object init(Napi::Env env, Napi::Object exports); QErrorMessageWrap(const Napi::CallbackInfo& info); ~QErrorMessageWrap(); - NErrorMessage* getInternalInstance(); + QErrorMessage* getInternalInstance(); // class constructor static Napi::FunctionReference constructor; // wrapped methods diff --git a/src/cpp/include/nodegui/QtWidgets/QFileDialog/qfiledialog_wrap.h b/src/cpp/include/nodegui/QtWidgets/QFileDialog/qfiledialog_wrap.h index 85ad21697..9f90ef19a 100644 --- a/src/cpp/include/nodegui/QtWidgets/QFileDialog/qfiledialog_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QFileDialog/qfiledialog_wrap.h @@ -11,13 +11,13 @@ class DLL_EXPORT QFileDialogWrap : public Napi::ObjectWrap { QDIALOG_WRAPPED_METHODS_DECLARATION private: - QPointer instance; + QPointer instance; public: static Napi::Object init(Napi::Env env, Napi::Object exports); QFileDialogWrap(const Napi::CallbackInfo& info); ~QFileDialogWrap(); - NFileDialog* getInternalInstance(); + QFileDialog* getInternalInstance(); // class constructor static Napi::FunctionReference constructor; // wrapped methods diff --git a/src/cpp/include/nodegui/QtWidgets/QFontDialog/qfontdialog_wrap.h b/src/cpp/include/nodegui/QtWidgets/QFontDialog/qfontdialog_wrap.h index d6282f27f..c08b8e1ab 100644 --- a/src/cpp/include/nodegui/QtWidgets/QFontDialog/qfontdialog_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QFontDialog/qfontdialog_wrap.h @@ -11,13 +11,13 @@ class DLL_EXPORT QFontDialogWrap : public Napi::ObjectWrap { QDIALOG_WRAPPED_METHODS_DECLARATION private: - QPointer instance; + QPointer instance; public: static Napi::Object init(Napi::Env env, Napi::Object exports); QFontDialogWrap(const Napi::CallbackInfo& info); ~QFontDialogWrap(); - NFontDialog* getInternalInstance(); + QFontDialog* getInternalInstance(); // class constructor static Napi::FunctionReference constructor; // wrapped methods diff --git a/src/cpp/include/nodegui/QtWidgets/QFrame/qframe_wrap.h b/src/cpp/include/nodegui/QtWidgets/QFrame/qframe_wrap.h index cdf8a05ae..c0b705d2d 100644 --- a/src/cpp/include/nodegui/QtWidgets/QFrame/qframe_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QFrame/qframe_wrap.h @@ -11,13 +11,13 @@ class DLL_EXPORT QFrameWrap : public Napi::ObjectWrap { QFRAME_WRAPPED_METHODS_DECLARATION private: - QPointer instance; + QPointer instance; public: static Napi::Object init(Napi::Env env, Napi::Object exports); QFrameWrap(const Napi::CallbackInfo& info); ~QFrameWrap(); - NFrame* getInternalInstance(); + QFrame* getInternalInstance(); // class constructor static Napi::FunctionReference constructor; // wrapped methods diff --git a/src/cpp/include/nodegui/QtWidgets/QGraphicsBlurEffect/qgraphicsblureffect_wrap.h b/src/cpp/include/nodegui/QtWidgets/QGraphicsBlurEffect/qgraphicsblureffect_wrap.h index 483526296..8062ef33c 100644 --- a/src/cpp/include/nodegui/QtWidgets/QGraphicsBlurEffect/qgraphicsblureffect_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QGraphicsBlurEffect/qgraphicsblureffect_wrap.h @@ -5,6 +5,7 @@ #include #include "Extras/Export/export.h" +#include "Extras/Utils/nutils.h" #include "QtWidgets/QGraphicsEffect/qgraphicseffect_macro.h" #include "ngraphicsblureffect.hpp" @@ -12,13 +13,13 @@ class DLL_EXPORT QGraphicsBlurEffectWrap : public Napi::ObjectWrap { QGRAPHICSEFFECT_WRAPPED_METHODS_DECLARATION private: - QPointer instance; + QPointer instance; public: static Napi::Object init(Napi::Env env, Napi::Object exports); QGraphicsBlurEffectWrap(const Napi::CallbackInfo& info); ~QGraphicsBlurEffectWrap(); - NGraphicsBlurEffect* getInternalInstance(); + QGraphicsBlurEffect* getInternalInstance(); // class constructor static Napi::FunctionReference constructor; // wrapped methods diff --git a/src/cpp/include/nodegui/QtWidgets/QGraphicsDropShadowEffect/qgraphicsdropshadoweffect_wrap.h b/src/cpp/include/nodegui/QtWidgets/QGraphicsDropShadowEffect/qgraphicsdropshadoweffect_wrap.h index 0eee0eaee..d6e3a3050 100644 --- a/src/cpp/include/nodegui/QtWidgets/QGraphicsDropShadowEffect/qgraphicsdropshadoweffect_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QGraphicsDropShadowEffect/qgraphicsdropshadoweffect_wrap.h @@ -12,13 +12,13 @@ class DLL_EXPORT QGraphicsDropShadowEffectWrap : public Napi::ObjectWrap { QGRAPHICSEFFECT_WRAPPED_METHODS_DECLARATION private: - QPointer instance; + QPointer instance; public: static Napi::Object init(Napi::Env env, Napi::Object exports); QGraphicsDropShadowEffectWrap(const Napi::CallbackInfo& info); ~QGraphicsDropShadowEffectWrap(); - NGraphicsDropShadowEffect* getInternalInstance(); + QGraphicsDropShadowEffect* getInternalInstance(); // class constructor static Napi::FunctionReference constructor; // wrapped methods diff --git a/src/cpp/include/nodegui/QtWidgets/QGridLayout/qgridlayout_wrap.h b/src/cpp/include/nodegui/QtWidgets/QGridLayout/qgridlayout_wrap.h index 7d6df8112..d4e8f4cc6 100644 --- a/src/cpp/include/nodegui/QtWidgets/QGridLayout/qgridlayout_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QGridLayout/qgridlayout_wrap.h @@ -12,13 +12,13 @@ class DLL_EXPORT QGridLayoutWrap : public Napi::ObjectWrap { QLAYOUT_WRAPPED_METHODS_DECLARATION private: - QPointer instance; + QPointer instance; public: static Napi::Object init(Napi::Env env, Napi::Object exports); QGridLayoutWrap(const Napi::CallbackInfo& info); ~QGridLayoutWrap(); - NGridLayout* getInternalInstance(); + QGridLayout* getInternalInstance(); // class constructor static Napi::FunctionReference constructor; // wrapped methods diff --git a/src/cpp/include/nodegui/QtWidgets/QGroupBox/qgroupbox_wrap.h b/src/cpp/include/nodegui/QtWidgets/QGroupBox/qgroupbox_wrap.h index e0aaffff2..a2521b9a1 100644 --- a/src/cpp/include/nodegui/QtWidgets/QGroupBox/qgroupbox_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QGroupBox/qgroupbox_wrap.h @@ -11,13 +11,13 @@ class DLL_EXPORT QGroupBoxWrap : public Napi::ObjectWrap { QWIDGET_WRAPPED_METHODS_DECLARATION private: - QPointer instance; + QPointer instance; public: static Napi::Object init(Napi::Env env, Napi::Object exports); QGroupBoxWrap(const Napi::CallbackInfo& info); ~QGroupBoxWrap(); - NGroupBox* getInternalInstance(); + QGroupBox* getInternalInstance(); // class constructor static Napi::FunctionReference constructor; // wrapped methods diff --git a/src/cpp/include/nodegui/QtWidgets/QHeaderView/qheaderview_wrap.h b/src/cpp/include/nodegui/QtWidgets/QHeaderView/qheaderview_wrap.h index 2f21eaf24..f6b9281cf 100644 --- a/src/cpp/include/nodegui/QtWidgets/QHeaderView/qheaderview_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QHeaderView/qheaderview_wrap.h @@ -45,7 +45,6 @@ class DLL_EXPORT QHeaderViewWrap : public Napi::ObjectWrap { private: QPointer instance; - bool disableDeletion; public: static Napi::Object init(Napi::Env env, Napi::Object exports); diff --git a/src/cpp/include/nodegui/QtWidgets/QInputDialog/qinputdialog_wrap.h b/src/cpp/include/nodegui/QtWidgets/QInputDialog/qinputdialog_wrap.h index 71079fea5..20787251d 100644 --- a/src/cpp/include/nodegui/QtWidgets/QInputDialog/qinputdialog_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QInputDialog/qinputdialog_wrap.h @@ -11,13 +11,13 @@ class DLL_EXPORT QInputDialogWrap : public Napi::ObjectWrap { QDIALOG_WRAPPED_METHODS_DECLARATION private: - QPointer instance; + QPointer instance; public: static Napi::Object init(Napi::Env env, Napi::Object exports); QInputDialogWrap(const Napi::CallbackInfo& info); ~QInputDialogWrap(); - NInputDialog* getInternalInstance(); + QInputDialog* getInternalInstance(); // class constructor static Napi::FunctionReference constructor; // members diff --git a/src/cpp/include/nodegui/QtWidgets/QLCDNumber/qlcdnumber_wrap.h b/src/cpp/include/nodegui/QtWidgets/QLCDNumber/qlcdnumber_wrap.h index 218e2a1bb..0fb12240c 100644 --- a/src/cpp/include/nodegui/QtWidgets/QLCDNumber/qlcdnumber_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QLCDNumber/qlcdnumber_wrap.h @@ -11,13 +11,13 @@ class DLL_EXPORT QLCDNumberWrap : public Napi::ObjectWrap { QWIDGET_WRAPPED_METHODS_DECLARATION private: - QPointer instance; + QPointer instance; public: static Napi::Object init(Napi::Env env, Napi::Object exports); QLCDNumberWrap(const Napi::CallbackInfo& info); ~QLCDNumberWrap(); - NLCDNumber* getInternalInstance(); + QLCDNumber* getInternalInstance(); // class constructor static Napi::FunctionReference constructor; // wrapped methods diff --git a/src/cpp/include/nodegui/QtWidgets/QLabel/qlabel_wrap.h b/src/cpp/include/nodegui/QtWidgets/QLabel/qlabel_wrap.h index 5d4e1d89a..c7e6529c5 100644 --- a/src/cpp/include/nodegui/QtWidgets/QLabel/qlabel_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QLabel/qlabel_wrap.h @@ -12,13 +12,13 @@ class DLL_EXPORT QLabelWrap : public Napi::ObjectWrap { QFRAME_WRAPPED_METHODS_DECLARATION private: - QPointer instance; + QPointer instance; public: static Napi::Object init(Napi::Env env, Napi::Object exports); QLabelWrap(const Napi::CallbackInfo& info); ~QLabelWrap(); - NLabel* getInternalInstance(); + QLabel* getInternalInstance(); // class constructor static Napi::FunctionReference constructor; // wrapped methods diff --git a/src/cpp/include/nodegui/QtWidgets/QLayout/qlayout_wrap.h b/src/cpp/include/nodegui/QtWidgets/QLayout/qlayout_wrap.h index 3d3e06de0..dffbb21df 100644 --- a/src/cpp/include/nodegui/QtWidgets/QLayout/qlayout_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QLayout/qlayout_wrap.h @@ -13,13 +13,13 @@ class DLL_EXPORT QLayoutWrap : public Napi::ObjectWrap { QLAYOUT_WRAPPED_METHODS_DECLARATION private: - QPointer instance; + QPointer instance; public: - static void init(Napi::Env env); + static void init(Napi::Env env, Napi::Object exports); QLayoutWrap(const Napi::CallbackInfo& info); ~QLayoutWrap(); - NLayout* getInternalInstance(); + QLayout* getInternalInstance(); // class constructor static Napi::FunctionReference constructor; // wrapped methods diff --git a/src/cpp/include/nodegui/QtWidgets/QLineEdit/qlineedit_wrap.h b/src/cpp/include/nodegui/QtWidgets/QLineEdit/qlineedit_wrap.h index d95e141bf..1d7e43189 100644 --- a/src/cpp/include/nodegui/QtWidgets/QLineEdit/qlineedit_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QLineEdit/qlineedit_wrap.h @@ -11,13 +11,13 @@ class DLL_EXPORT QLineEditWrap : public Napi::ObjectWrap { QWIDGET_WRAPPED_METHODS_DECLARATION private: - QPointer instance; + QPointer instance; public: static Napi::Object init(Napi::Env env, Napi::Object exports); QLineEditWrap(const Napi::CallbackInfo& info); ~QLineEditWrap(); - NLineEdit* getInternalInstance(); + QLineEdit* getInternalInstance(); // class constructor static Napi::FunctionReference constructor; // wrapped methods diff --git a/src/cpp/include/nodegui/QtWidgets/QListView/qlistview_wrap.h b/src/cpp/include/nodegui/QtWidgets/QListView/qlistview_wrap.h index ba0d07f58..6b3e5df27 100644 --- a/src/cpp/include/nodegui/QtWidgets/QListView/qlistview_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QListView/qlistview_wrap.h @@ -11,14 +11,13 @@ class DLL_EXPORT QListViewWrap : public Napi::ObjectWrap { QLISTVIEW_WRAPPED_METHODS_DECLARATION private: - QPointer instance; - bool disableDeletion; + QPointer instance; public: static Napi::Object init(Napi::Env env, Napi::Object exports); QListViewWrap(const Napi::CallbackInfo& info); ~QListViewWrap(); - NListView* getInternalInstance(); + QListView* getInternalInstance(); // class constructor static Napi::FunctionReference constructor; // wrapped methods diff --git a/src/cpp/include/nodegui/QtWidgets/QListWidget/qlistwidget_wrap.h b/src/cpp/include/nodegui/QtWidgets/QListWidget/qlistwidget_wrap.h index 2dd7fe50e..684ded35e 100644 --- a/src/cpp/include/nodegui/QtWidgets/QListWidget/qlistwidget_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QListWidget/qlistwidget_wrap.h @@ -12,13 +12,13 @@ class DLL_EXPORT QListWidgetWrap : public Napi::ObjectWrap { QLISTVIEW_WRAPPED_METHODS_DECLARATION private: - QPointer instance; + QPointer instance; public: static Napi::Object init(Napi::Env env, Napi::Object exports); QListWidgetWrap(const Napi::CallbackInfo& info); ~QListWidgetWrap(); - NListWidget* getInternalInstance(); + QListWidget* getInternalInstance(); // class constructor static Napi::FunctionReference constructor; // wrapped methods diff --git a/src/cpp/include/nodegui/QtWidgets/QMainWindow/qmainwindow_wrap.h b/src/cpp/include/nodegui/QtWidgets/QMainWindow/qmainwindow_wrap.h index 056c707f9..2fbdb6eee 100644 --- a/src/cpp/include/nodegui/QtWidgets/QMainWindow/qmainwindow_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QMainWindow/qmainwindow_wrap.h @@ -12,13 +12,13 @@ class DLL_EXPORT QMainWindowWrap : public Napi::ObjectWrap { QWIDGET_WRAPPED_METHODS_DECLARATION private: - QPointer instance; + QPointer instance; public: static Napi::Object init(Napi::Env env, Napi::Object exports); QMainWindowWrap(const Napi::CallbackInfo& info); ~QMainWindowWrap(); - NMainWindow* getInternalInstance(); + QMainWindow* getInternalInstance(); // class constructor static Napi::FunctionReference constructor; // wrapped methods diff --git a/src/cpp/include/nodegui/QtWidgets/QMenu/nmenu.hpp b/src/cpp/include/nodegui/QtWidgets/QMenu/nmenu.hpp index 0e70aa4df..6fca47757 100644 --- a/src/cpp/include/nodegui/QtWidgets/QMenu/nmenu.hpp +++ b/src/cpp/include/nodegui/QtWidgets/QMenu/nmenu.hpp @@ -17,10 +17,8 @@ class DLL_EXPORT NMenu : public QMenu, public NodeWidget { QObject::connect(this, &QMenu::triggered, [=](QAction* action) { Napi::Env env = this->emitOnNode.Env(); Napi::HandleScope scope(env); - auto actionInstance = QActionWrap::constructor.New( - {Napi::External::New(env, action)}); - this->emitOnNode.Call( - {Napi::String::New(env, "triggered"), actionInstance}); + auto instance = WrapperCache::instance.getWrapper(env, action); + this->emitOnNode.Call({Napi::String::New(env, "triggered"), instance}); }); } }; diff --git a/src/cpp/include/nodegui/QtWidgets/QMenu/qmenu_wrap.h b/src/cpp/include/nodegui/QtWidgets/QMenu/qmenu_wrap.h index f45b158f5..88b599d68 100644 --- a/src/cpp/include/nodegui/QtWidgets/QMenu/qmenu_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QMenu/qmenu_wrap.h @@ -10,13 +10,13 @@ class DLL_EXPORT QMenuWrap : public Napi::ObjectWrap { QWIDGET_WRAPPED_METHODS_DECLARATION private: - QPointer instance; + QPointer instance; public: static Napi::Object init(Napi::Env env, Napi::Object exports); QMenuWrap(const Napi::CallbackInfo& info); ~QMenuWrap(); - NMenu* getInternalInstance(); + QMenu* getInternalInstance(); static Napi::FunctionReference constructor; // wrapped methods Napi::Value clear(const Napi::CallbackInfo& info); diff --git a/src/cpp/include/nodegui/QtWidgets/QMenuBar/qmenubar_wrap.h b/src/cpp/include/nodegui/QtWidgets/QMenuBar/qmenubar_wrap.h index dd04274ab..6ec6722e8 100644 --- a/src/cpp/include/nodegui/QtWidgets/QMenuBar/qmenubar_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QMenuBar/qmenubar_wrap.h @@ -10,13 +10,13 @@ class DLL_EXPORT QMenuBarWrap : public Napi::ObjectWrap { QWIDGET_WRAPPED_METHODS_DECLARATION private: - QPointer instance; + QPointer instance; public: static Napi::Object init(Napi::Env env, Napi::Object exports); QMenuBarWrap(const Napi::CallbackInfo& info); ~QMenuBarWrap(); - NMenuBar* getInternalInstance(); + QMenuBar* getInternalInstance(); static Napi::FunctionReference constructor; // wrapped methods Napi::Value addMenu(const Napi::CallbackInfo& info); diff --git a/src/cpp/include/nodegui/QtWidgets/QMessageBox/qmessagebox_wrap.h b/src/cpp/include/nodegui/QtWidgets/QMessageBox/qmessagebox_wrap.h index c21c7e883..6e7fc49c4 100644 --- a/src/cpp/include/nodegui/QtWidgets/QMessageBox/qmessagebox_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QMessageBox/qmessagebox_wrap.h @@ -11,13 +11,13 @@ class DLL_EXPORT QMessageBoxWrap : public Napi::ObjectWrap { QDIALOG_WRAPPED_METHODS_DECLARATION private: - QPointer instance; + QPointer instance; public: static Napi::Object init(Napi::Env env, Napi::Object exports); QMessageBoxWrap(const Napi::CallbackInfo& info); ~QMessageBoxWrap(); - NMessageBox* getInternalInstance(); + QMessageBox* getInternalInstance(); // class constructor static Napi::FunctionReference constructor; // wrapped methods diff --git a/src/cpp/include/nodegui/QtWidgets/QPlainTextEdit/qplaintextedit_wrap.h b/src/cpp/include/nodegui/QtWidgets/QPlainTextEdit/qplaintextedit_wrap.h index b3627711c..b8d55b151 100644 --- a/src/cpp/include/nodegui/QtWidgets/QPlainTextEdit/qplaintextedit_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QPlainTextEdit/qplaintextedit_wrap.h @@ -13,13 +13,13 @@ class DLL_EXPORT QPlainTextEditWrap : public Napi::ObjectWrap { QABSTRACTSCROLLAREA_WRAPPED_METHODS_DECLARATION private: - QPointer instance; + QPointer instance; public: static Napi::Object init(Napi::Env env, Napi::Object exports); QPlainTextEditWrap(const Napi::CallbackInfo &info); ~QPlainTextEditWrap(); - NPlainTextEdit *getInternalInstance(); + QPlainTextEdit *getInternalInstance(); // class constructor static Napi::FunctionReference constructor; // wrapped methods diff --git a/src/cpp/include/nodegui/QtWidgets/QProgressBar/qprogressbar_wrap.h b/src/cpp/include/nodegui/QtWidgets/QProgressBar/qprogressbar_wrap.h index e19f97171..43316e46d 100644 --- a/src/cpp/include/nodegui/QtWidgets/QProgressBar/qprogressbar_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QProgressBar/qprogressbar_wrap.h @@ -11,13 +11,13 @@ class DLL_EXPORT QProgressBarWrap : public Napi::ObjectWrap { QWIDGET_WRAPPED_METHODS_DECLARATION private: - QPointer instance; + QPointer instance; public: static Napi::Object init(Napi::Env env, Napi::Object exports); QProgressBarWrap(const Napi::CallbackInfo& info); ~QProgressBarWrap(); - NProgressBar* getInternalInstance(); + QProgressBar* getInternalInstance(); // class constructor static Napi::FunctionReference constructor; // wrapped methods diff --git a/src/cpp/include/nodegui/QtWidgets/QProgressDialog/qprogressdialog_wrap.h b/src/cpp/include/nodegui/QtWidgets/QProgressDialog/qprogressdialog_wrap.h index ca2e88153..73bcdcf9f 100644 --- a/src/cpp/include/nodegui/QtWidgets/QProgressDialog/qprogressdialog_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QProgressDialog/qprogressdialog_wrap.h @@ -12,13 +12,13 @@ class DLL_EXPORT QProgressDialogWrap : public Napi::ObjectWrap { QDIALOG_WRAPPED_METHODS_DECLARATION private: - QPointer instance; + QPointer instance; public: static Napi::Object init(Napi::Env env, Napi::Object exports); QProgressDialogWrap(const Napi::CallbackInfo& info); ~QProgressDialogWrap(); - NProgressDialog* getInternalInstance(); + QProgressDialog* getInternalInstance(); // class constructor static Napi::FunctionReference constructor; // wrapped methods diff --git a/src/cpp/include/nodegui/QtWidgets/QPushButton/qpushbutton_wrap.h b/src/cpp/include/nodegui/QtWidgets/QPushButton/qpushbutton_wrap.h index 92f4bd660..824bfabd9 100644 --- a/src/cpp/include/nodegui/QtWidgets/QPushButton/qpushbutton_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QPushButton/qpushbutton_wrap.h @@ -12,14 +12,13 @@ class DLL_EXPORT QPushButtonWrap : public Napi::ObjectWrap { QABSTRACTBUTTON_WRAPPED_METHODS_DECLARATION private: - QPointer instance; - bool disableDeletion; + QPointer instance; public: static Napi::Object init(Napi::Env env, Napi::Object exports); QPushButtonWrap(const Napi::CallbackInfo& info); ~QPushButtonWrap(); - NPushButton* getInternalInstance(); + QPushButton* getInternalInstance(); // class constructor static Napi::FunctionReference constructor; // wrapped methods diff --git a/src/cpp/include/nodegui/QtWidgets/QRadioButton/qradiobutton_wrap.h b/src/cpp/include/nodegui/QtWidgets/QRadioButton/qradiobutton_wrap.h index bd2fc0be0..d8dd3fc32 100644 --- a/src/cpp/include/nodegui/QtWidgets/QRadioButton/qradiobutton_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QRadioButton/qradiobutton_wrap.h @@ -13,14 +13,13 @@ class DLL_EXPORT QRadioButtonWrap : public Napi::ObjectWrap { QABSTRACTBUTTON_WRAPPED_METHODS_DECLARATION private: - QPointer instance; - bool disableDeletion; + QPointer instance; public: static Napi::Object init(Napi::Env env, Napi::Object exports); QRadioButtonWrap(const Napi::CallbackInfo& info); ~QRadioButtonWrap(); - NRadioButton* getInternalInstance(); + QRadioButton* getInternalInstance(); // class constructor static Napi::FunctionReference constructor; // wrapped methods diff --git a/src/cpp/include/nodegui/QtWidgets/QScrollArea/qscrollarea_wrap.h b/src/cpp/include/nodegui/QtWidgets/QScrollArea/qscrollarea_wrap.h index 2e6862503..3bca82c79 100644 --- a/src/cpp/include/nodegui/QtWidgets/QScrollArea/qscrollarea_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QScrollArea/qscrollarea_wrap.h @@ -11,20 +11,20 @@ class DLL_EXPORT QScrollAreaWrap : public Napi::ObjectWrap { QABSTRACTSCROLLAREA_WRAPPED_METHODS_DECLARATION private: - QPointer instance; - YGNodeRef scrollNode; + QPointer instance; public: static Napi::Object init(Napi::Env env, Napi::Object exports); QScrollAreaWrap(const Napi::CallbackInfo& info); ~QScrollAreaWrap(); - NScrollArea* getInternalInstance(); + QScrollArea* getInternalInstance(); // class constructor static Napi::FunctionReference constructor; // wrapped methods Napi::Value ensureVisible(const Napi::CallbackInfo& info); Napi::Value ensureWidgetVisible(const Napi::CallbackInfo& info); Napi::Value setWidget(const Napi::CallbackInfo& info); + Napi::Value widget(const Napi::CallbackInfo& info); Napi::Value takeWidget(const Napi::CallbackInfo& info); Napi::Value setViewportMargins(const Napi::CallbackInfo& info); Napi::Value viewportMargins(const Napi::CallbackInfo& info); diff --git a/src/cpp/include/nodegui/QtWidgets/QScrollBar/qscrollbar_wrap.h b/src/cpp/include/nodegui/QtWidgets/QScrollBar/qscrollbar_wrap.h index ffd8c9a1c..434356ca0 100644 --- a/src/cpp/include/nodegui/QtWidgets/QScrollBar/qscrollbar_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QScrollBar/qscrollbar_wrap.h @@ -12,13 +12,13 @@ class DLL_EXPORT QScrollBarWrap : public Napi::ObjectWrap { QABSTRACTSLIDER_WRAPPED_METHODS_DECLARATION private: - QPointer instance; + QPointer instance; public: static Napi::Object init(Napi::Env env, Napi::Object exports); QScrollBarWrap(const Napi::CallbackInfo& info); ~QScrollBarWrap(); - NScrollBar* getInternalInstance(); + QScrollBar* getInternalInstance(); // class constructor static Napi::FunctionReference constructor; // wrapped methods diff --git a/src/cpp/include/nodegui/QtWidgets/QShortcut/qshortcut_wrap.h b/src/cpp/include/nodegui/QtWidgets/QShortcut/qshortcut_wrap.h index 052f962dc..1c7bf5667 100644 --- a/src/cpp/include/nodegui/QtWidgets/QShortcut/qshortcut_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QShortcut/qshortcut_wrap.h @@ -11,13 +11,13 @@ class DLL_EXPORT QShortcutWrap : public Napi::ObjectWrap { QOBJECT_WRAPPED_METHODS_DECLARATION private: - QPointer instance; + QPointer instance; public: static Napi::Object init(Napi::Env env, Napi::Object exports); QShortcutWrap(const Napi::CallbackInfo& info); ~QShortcutWrap(); - NShortcut* getInternalInstance(); + QShortcut* getInternalInstance(); // class constructor static Napi::FunctionReference constructor; // wrapped methods diff --git a/src/cpp/include/nodegui/QtWidgets/QSlider/qslider_wrap.h b/src/cpp/include/nodegui/QtWidgets/QSlider/qslider_wrap.h index 653ec702c..7bd811ee7 100644 --- a/src/cpp/include/nodegui/QtWidgets/QSlider/qslider_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QSlider/qslider_wrap.h @@ -12,13 +12,13 @@ class DLL_EXPORT QSliderWrap : public Napi::ObjectWrap { QABSTRACTSLIDER_WRAPPED_METHODS_DECLARATION private: - QPointer instance; + QPointer instance; public: static Napi::Object init(Napi::Env env, Napi::Object exports); QSliderWrap(const Napi::CallbackInfo& info); ~QSliderWrap(); - NSlider* getInternalInstance(); + QSlider* getInternalInstance(); // class constructor static Napi::FunctionReference constructor; // wrapped methods diff --git a/src/cpp/include/nodegui/QtWidgets/QSpinBox/qspinbox_wrap.h b/src/cpp/include/nodegui/QtWidgets/QSpinBox/qspinbox_wrap.h index e26389542..ca1cb169f 100644 --- a/src/cpp/include/nodegui/QtWidgets/QSpinBox/qspinbox_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QSpinBox/qspinbox_wrap.h @@ -11,13 +11,13 @@ class DLL_EXPORT QSpinBoxWrap : public Napi::ObjectWrap { QABSTRACTSPINBOX_WRAPPED_METHODS_DECLARATION private: - QPointer instance; + QPointer instance; public: static Napi::Object init(Napi::Env env, Napi::Object exports); QSpinBoxWrap(const Napi::CallbackInfo &info); ~QSpinBoxWrap(); - NSpinBox *getInternalInstance(); + QSpinBox *getInternalInstance(); // class constructor static Napi::FunctionReference constructor; // wrapped methods diff --git a/src/cpp/include/nodegui/QtWidgets/QSplitter/qsplitter_wrap.h b/src/cpp/include/nodegui/QtWidgets/QSplitter/qsplitter_wrap.h index bae681e0a..aac552267 100644 --- a/src/cpp/include/nodegui/QtWidgets/QSplitter/qsplitter_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QSplitter/qsplitter_wrap.h @@ -11,13 +11,13 @@ class DLL_EXPORT QSplitterWrap : public Napi::ObjectWrap { QFRAME_WRAPPED_METHODS_DECLARATION private: - QPointer instance; + QPointer instance; public: static Napi::Object init(Napi::Env env, Napi::Object exports); QSplitterWrap(const Napi::CallbackInfo& info); ~QSplitterWrap(); - NSplitter* getInternalInstance(); + QSplitter* getInternalInstance(); // class constructor static Napi::FunctionReference constructor; // wrapped methods diff --git a/src/cpp/include/nodegui/QtWidgets/QStackedWidget/qstackedwidget_wrap.h b/src/cpp/include/nodegui/QtWidgets/QStackedWidget/qstackedwidget_wrap.h index e29fed9d6..acfba76db 100644 --- a/src/cpp/include/nodegui/QtWidgets/QStackedWidget/qstackedwidget_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QStackedWidget/qstackedwidget_wrap.h @@ -12,13 +12,13 @@ class DLL_EXPORT QStackedWidgetWrap : public Napi::ObjectWrap { QFRAME_WRAPPED_METHODS_DECLARATION private: - QPointer instance; + QPointer instance; public: static Napi::Object init(Napi::Env env, Napi::Object exports); QStackedWidgetWrap(const Napi::CallbackInfo &info); ~QStackedWidgetWrap(); - NStackedWidget *getInternalInstance(); + QStackedWidget *getInternalInstance(); // class constructor static Napi::FunctionReference constructor; // wrapped methods diff --git a/src/cpp/include/nodegui/QtWidgets/QStandardItemModel/qstandarditemmodel_wrap.h b/src/cpp/include/nodegui/QtWidgets/QStandardItemModel/qstandarditemmodel_wrap.h index f4bbc5508..4a979896e 100644 --- a/src/cpp/include/nodegui/QtWidgets/QStandardItemModel/qstandarditemmodel_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QStandardItemModel/qstandarditemmodel_wrap.h @@ -10,13 +10,13 @@ class DLL_EXPORT QStandardItemModelWrap : public Napi::ObjectWrap { private: - QPointer instance; + QPointer instance; public: static Napi::Object init(Napi::Env env, Napi::Object exports); QStandardItemModelWrap(const Napi::CallbackInfo& info); ~QStandardItemModelWrap(); - NStandardItemModel* getInternalInstance(); + QStandardItemModel* getInternalInstance(); // class constructor static Napi::FunctionReference constructor; // wrapped methods diff --git a/src/cpp/include/nodegui/QtWidgets/QStatusBar/qstatusbar_wrap.h b/src/cpp/include/nodegui/QtWidgets/QStatusBar/qstatusbar_wrap.h index eaa6a774e..f02414cbc 100644 --- a/src/cpp/include/nodegui/QtWidgets/QStatusBar/qstatusbar_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QStatusBar/qstatusbar_wrap.h @@ -12,7 +12,7 @@ class DLL_EXPORT QStatusBarWrap : public Napi::ObjectWrap { QWIDGET_WRAPPED_METHODS_DECLARATION private: - QPointer instance; + QPointer instance; public: static Napi::Object init(Napi::Env env, Napi::Object exports); @@ -22,7 +22,7 @@ class DLL_EXPORT QStatusBarWrap : public Napi::ObjectWrap { QStatusBarWrap(const Napi::CallbackInfo &info); ~QStatusBarWrap(); - NStatusBar *getInternalInstance(); + QStatusBar *getInternalInstance(); // Wrapped methods Napi::Value addPermanentWidget(const Napi::CallbackInfo &info); diff --git a/src/cpp/include/nodegui/QtWidgets/QSvgWidget/qsvgwidget_wrap.h b/src/cpp/include/nodegui/QtWidgets/QSvgWidget/qsvgwidget_wrap.h index ebe731ae6..3897a1e2c 100644 --- a/src/cpp/include/nodegui/QtWidgets/QSvgWidget/qsvgwidget_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QSvgWidget/qsvgwidget_wrap.h @@ -11,13 +11,13 @@ class DLL_EXPORT QSvgWidgetWrap : public Napi::ObjectWrap { QWIDGET_WRAPPED_METHODS_DECLARATION private: - QPointer instance; + QPointer instance; public: static Napi::Object init(Napi::Env env, Napi::Object exports); QSvgWidgetWrap(const Napi::CallbackInfo& info); ~QSvgWidgetWrap(); - NSvgWidget* getInternalInstance(); + QSvgWidget* getInternalInstance(); // class constructor static Napi::FunctionReference constructor; // wrapped methods diff --git a/src/cpp/include/nodegui/QtWidgets/QSystemTrayIcon/qsystemtrayicon_wrap.h b/src/cpp/include/nodegui/QtWidgets/QSystemTrayIcon/qsystemtrayicon_wrap.h index 1fcdf9695..2549b928c 100644 --- a/src/cpp/include/nodegui/QtWidgets/QSystemTrayIcon/qsystemtrayicon_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QSystemTrayIcon/qsystemtrayicon_wrap.h @@ -12,13 +12,13 @@ class DLL_EXPORT QSystemTrayIconWrap : public Napi::ObjectWrap { QOBJECT_WRAPPED_METHODS_DECLARATION private: - QPointer instance; + QPointer instance; public: static Napi::Object init(Napi::Env env, Napi::Object exports); QSystemTrayIconWrap(const Napi::CallbackInfo& info); ~QSystemTrayIconWrap(); - NSystemTrayIcon* getInternalInstance(); + QSystemTrayIcon* getInternalInstance(); // class constructor static Napi::FunctionReference constructor; // wrapped methods diff --git a/src/cpp/include/nodegui/QtWidgets/QTabBar/qtabbar_wrap.h b/src/cpp/include/nodegui/QtWidgets/QTabBar/qtabbar_wrap.h index ff7bfcbf2..2c338e25d 100644 --- a/src/cpp/include/nodegui/QtWidgets/QTabBar/qtabbar_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QTabBar/qtabbar_wrap.h @@ -11,14 +11,13 @@ class DLL_EXPORT QTabBarWrap : public Napi::ObjectWrap { QWIDGET_WRAPPED_METHODS_DECLARATION private: - QPointer instance; - bool disableDeletion; + QPointer instance; public: static Napi::Object init(Napi::Env env, Napi::Object exports); QTabBarWrap(const Napi::CallbackInfo& info); ~QTabBarWrap(); - NTabBar* getInternalInstance(); + QTabBar* getInternalInstance(); // class constructor static Napi::FunctionReference constructor; // wrapped methods diff --git a/src/cpp/include/nodegui/QtWidgets/QTabWidget/qtabwidget_wrap.h b/src/cpp/include/nodegui/QtWidgets/QTabWidget/qtabwidget_wrap.h index b25b23550..f2ef97a9a 100644 --- a/src/cpp/include/nodegui/QtWidgets/QTabWidget/qtabwidget_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QTabWidget/qtabwidget_wrap.h @@ -11,13 +11,13 @@ class DLL_EXPORT QTabWidgetWrap : public Napi::ObjectWrap { QWIDGET_WRAPPED_METHODS_DECLARATION private: - QPointer instance; + QPointer instance; public: static Napi::Object init(Napi::Env env, Napi::Object exports); QTabWidgetWrap(const Napi::CallbackInfo &info); ~QTabWidgetWrap(); - NTabWidget *getInternalInstance(); + QTabWidget *getInternalInstance(); // class constructor static Napi::FunctionReference constructor; // wrapped methods diff --git a/src/cpp/include/nodegui/QtWidgets/QTableView/qtableview_macro.h b/src/cpp/include/nodegui/QtWidgets/QTableView/qtableview_macro.h index 70457e143..f5fd1a8be 100644 --- a/src/cpp/include/nodegui/QtWidgets/QTableView/qtableview_macro.h +++ b/src/cpp/include/nodegui/QtWidgets/QTableView/qtableview_macro.h @@ -181,15 +181,13 @@ Napi::Value horizontalHeader(const Napi::CallbackInfo& info) { \ Napi::Env env = info.Env(); \ auto header = this->instance->horizontalHeader(); \ - auto instance = QHeaderViewWrap::constructor.New( \ - {Napi::External::New(env, header)}); \ + auto instance = WrapperCache::instance.getWrapper(env, header); \ return instance; \ } \ Napi::Value verticalHeader(const Napi::CallbackInfo& info) { \ Napi::Env env = info.Env(); \ auto header = this->instance->verticalHeader(); \ - auto instance = QHeaderViewWrap::constructor.New( \ - {Napi::External::New(env, header)}); \ + auto instance = WrapperCache::instance.getWrapper(env, header); \ return instance; \ } diff --git a/src/cpp/include/nodegui/QtWidgets/QTableView/qtableview_wrap.h b/src/cpp/include/nodegui/QtWidgets/QTableView/qtableview_wrap.h index 8d98a44bf..cef62d924 100644 --- a/src/cpp/include/nodegui/QtWidgets/QTableView/qtableview_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QTableView/qtableview_wrap.h @@ -11,14 +11,13 @@ class DLL_EXPORT QTableViewWrap : public Napi::ObjectWrap { QTABLEVIEW_WRAPPED_METHODS_DECLARATION private: - QPointer instance; - bool disableDeletion; + QPointer instance; public: static Napi::Object init(Napi::Env env, Napi::Object exports); QTableViewWrap(const Napi::CallbackInfo& info); ~QTableViewWrap(); - NTableView* getInternalInstance(); + QTableView* getInternalInstance(); // class constructor static Napi::FunctionReference constructor; // wrapped methods diff --git a/src/cpp/include/nodegui/QtWidgets/QTableWidget/qtablewidget_wrap.h b/src/cpp/include/nodegui/QtWidgets/QTableWidget/qtablewidget_wrap.h index 833fcd233..724e28c67 100644 --- a/src/cpp/include/nodegui/QtWidgets/QTableWidget/qtablewidget_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QTableWidget/qtablewidget_wrap.h @@ -11,13 +11,13 @@ class DLL_EXPORT QTableWidgetWrap : public Napi::ObjectWrap { QABSTRACTSCROLLAREA_WRAPPED_METHODS_DECLARATION private: - QPointer instance; + QPointer instance; public: static Napi::Object init(Napi::Env env, Napi::Object exports); QTableWidgetWrap(const Napi::CallbackInfo& info); ~QTableWidgetWrap(); - NTableWidget* getInternalInstance(); + QTableWidget* getInternalInstance(); // class constructor static Napi::FunctionReference constructor; // wrapped methods diff --git a/src/cpp/include/nodegui/QtWidgets/QTextBrowser/qtextbrowser_wrap.h b/src/cpp/include/nodegui/QtWidgets/QTextBrowser/qtextbrowser_wrap.h index e72eabddf..33ad4494e 100644 --- a/src/cpp/include/nodegui/QtWidgets/QTextBrowser/qtextbrowser_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QTextBrowser/qtextbrowser_wrap.h @@ -11,13 +11,13 @@ class DLL_EXPORT QTextBrowserWrap : public Napi::ObjectWrap { QTEXTEDIT_WRAPPED_METHODS_DECLARATION private: - QPointer instance; + QPointer instance; public: static Napi::Object init(Napi::Env env, Napi::Object exports); QTextBrowserWrap(const Napi::CallbackInfo& info); ~QTextBrowserWrap(); - NTextBrowser* getInternalInstance(); + QTextBrowser* getInternalInstance(); // class constructor static Napi::FunctionReference constructor; // wrapped methods diff --git a/src/cpp/include/nodegui/QtWidgets/QTextEdit/qtextedit_wrap.h b/src/cpp/include/nodegui/QtWidgets/QTextEdit/qtextedit_wrap.h index a6173e4f6..68d4981a6 100644 --- a/src/cpp/include/nodegui/QtWidgets/QTextEdit/qtextedit_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QTextEdit/qtextedit_wrap.h @@ -11,13 +11,13 @@ class DLL_EXPORT QTextEditWrap : public Napi::ObjectWrap { QTEXTEDIT_WRAPPED_METHODS_DECLARATION private: - QPointer instance; + QPointer instance; public: static Napi::Object init(Napi::Env env, Napi::Object exports); QTextEditWrap(const Napi::CallbackInfo& info); ~QTextEditWrap(); - NTextEdit* getInternalInstance(); + QTextEdit* getInternalInstance(); // class constructor static Napi::FunctionReference constructor; // wrapped methods diff --git a/src/cpp/include/nodegui/QtWidgets/QTimeEdit/qtimeedit_wrap.h b/src/cpp/include/nodegui/QtWidgets/QTimeEdit/qtimeedit_wrap.h index fe322e4d4..a4761ba40 100644 --- a/src/cpp/include/nodegui/QtWidgets/QTimeEdit/qtimeedit_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QTimeEdit/qtimeedit_wrap.h @@ -12,13 +12,13 @@ class DLL_EXPORT QTimeEditWrap : public Napi::ObjectWrap { QDATETIMEEDIT_WRAPPED_METHODS_DECLARATION private: - QPointer instance; + QPointer instance; public: static Napi::Object init(Napi::Env env, Napi::Object exports); QTimeEditWrap(const Napi::CallbackInfo &info); ~QTimeEditWrap(); - NTimeEdit *getInternalInstance(); + QTimeEdit *getInternalInstance(); // class constructor static Napi::FunctionReference constructor; // wrapped methods diff --git a/src/cpp/include/nodegui/QtWidgets/QToolButton/ntoolbutton.hpp b/src/cpp/include/nodegui/QtWidgets/QToolButton/ntoolbutton.hpp index 45c0a94d0..bc966959d 100644 --- a/src/cpp/include/nodegui/QtWidgets/QToolButton/ntoolbutton.hpp +++ b/src/cpp/include/nodegui/QtWidgets/QToolButton/ntoolbutton.hpp @@ -21,11 +21,7 @@ class DLL_EXPORT NToolButton : public QToolButton, public NodeWidget { QObject::connect(this, &QToolButton::triggered, [=](QAction* action) { Napi::Env env = this->emitOnNode.Env(); Napi::HandleScope scope(env); - - // disable deletion of the native instance for these by passing true - auto instance = QActionWrap::constructor.New( - {Napi::External::New(env, action), - Napi::Boolean::New(env, true)}); + auto instance = WrapperCache::instance.getWrapper(env, action); this->emitOnNode.Call({Napi::String::New(env, "triggered"), instance}); }); } diff --git a/src/cpp/include/nodegui/QtWidgets/QToolButton/qtoolbutton_wrap.h b/src/cpp/include/nodegui/QtWidgets/QToolButton/qtoolbutton_wrap.h index fe3f765e7..94223291c 100644 --- a/src/cpp/include/nodegui/QtWidgets/QToolButton/qtoolbutton_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QToolButton/qtoolbutton_wrap.h @@ -12,14 +12,13 @@ class DLL_EXPORT QToolButtonWrap : public Napi::ObjectWrap { QABSTRACTBUTTON_WRAPPED_METHODS_DECLARATION private: - QPointer instance; - bool disableDeletion; + QPointer instance; public: static Napi::Object init(Napi::Env env, Napi::Object exports); QToolButtonWrap(const Napi::CallbackInfo& info); ~QToolButtonWrap(); - NToolButton* getInternalInstance(); + QToolButton* getInternalInstance(); // class constructor static Napi::FunctionReference constructor; // wrapped methods diff --git a/src/cpp/include/nodegui/QtWidgets/QTreeWidget/qtreewidget_wrap.h b/src/cpp/include/nodegui/QtWidgets/QTreeWidget/qtreewidget_wrap.h index a94b9214f..d654813de 100644 --- a/src/cpp/include/nodegui/QtWidgets/QTreeWidget/qtreewidget_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QTreeWidget/qtreewidget_wrap.h @@ -11,7 +11,7 @@ class DLL_EXPORT QTreeWidgetWrap : public Napi::ObjectWrap { QWIDGET_WRAPPED_METHODS_DECLARATION private: - QPointer instance; + QPointer instance; public: static Napi::Object init(Napi::Env env, Napi::Object exports); @@ -20,7 +20,7 @@ class DLL_EXPORT QTreeWidgetWrap : public Napi::ObjectWrap { ~QTreeWidgetWrap(); - NTreeWidget *getInternalInstance(); + QTreeWidget *getInternalInstance(); // class constructor static Napi::FunctionReference constructor; diff --git a/src/cpp/include/nodegui/QtWidgets/QWidget/qwidget_wrap.h b/src/cpp/include/nodegui/QtWidgets/QWidget/qwidget_wrap.h index 0befba43a..fee82900b 100644 --- a/src/cpp/include/nodegui/QtWidgets/QWidget/qwidget_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QWidget/qwidget_wrap.h @@ -27,13 +27,13 @@ class DLL_EXPORT NodeWidgetWrap : public Napi::ObjectWrap { class DLL_EXPORT QWidgetWrap : public Napi::ObjectWrap { QWIDGET_WRAPPED_METHODS_DECLARATION private: - QPointer instance; + QPointer instance; public: static Napi::Object init(Napi::Env env, Napi::Object exports); QWidgetWrap(const Napi::CallbackInfo& info); ~QWidgetWrap(); - NWidget* getInternalInstance(); + QWidget* getInternalInstance(); // class constructor static Napi::FunctionReference constructor; // wrapped methods diff --git a/src/cpp/include/nodegui/core/WrapperCache/wrappercache.h b/src/cpp/include/nodegui/core/WrapperCache/wrappercache.h index b633c8890..013d16a5b 100644 --- a/src/cpp/include/nodegui/core/WrapperCache/wrappercache.h +++ b/src/cpp/include/nodegui/core/WrapperCache/wrappercache.h @@ -4,6 +4,7 @@ #include #include +#include #include #include "Extras/Export/export.h" @@ -75,16 +76,33 @@ class DLL_EXPORT WrapperCache : public QObject { } } - QString className(qobject->metaObject()->className()); - if (this->wrapperRegistry.contains(className)) { - Napi::Object wrapper = this->wrapperRegistry[className](env, qobject); - store(env, ptrHash, qobject, wrapper, !keepAlive); - return wrapper; - } else { - qDebug() << "NodeGui: Unable to find wrapper for instance of class " - << className << ".\n\n"; + // Might have to climb up the class hierarchy looking for a wrapper type we + // support. This makes us immune to internal Qt subclasses, i.e. + // `QWidgetWindow` when `QWindow` was expected. + const QMetaObject* meta = qobject->metaObject(); + while (meta != nullptr) { + QString className(meta->className()); + if (this->wrapperRegistry.contains(className)) { + Napi::Object wrapper = this->wrapperRegistry[className](env, qobject); + store(env, ptrHash, qobject, wrapper, !keepAlive); + return wrapper; + } + meta = meta->superClass(); } + QMapIterator i(this->wrapperRegistry); + QString allQWrapperNames; + while (i.hasNext()) { + i.next(); + allQWrapperNames.append(i.key()); + allQWrapperNames.append(", "); + } + + qDebug() << "NodeGui: Unable to find wrapper for instance of C++ class " + << qobject->metaObject()->className() + << ". (The following C++ classes are recognized: " + << allQWrapperNames << ")"; + return env.Null(); } diff --git a/src/cpp/lib/Extras/Utils/nutils.cpp b/src/cpp/lib/Extras/Utils/nutils.cpp index b52d86f83..ed4990072 100644 --- a/src/cpp/lib/Extras/Utils/nutils.cpp +++ b/src/cpp/lib/Extras/Utils/nutils.cpp @@ -7,6 +7,7 @@ #include "core/Component/component_wrap.h" #include "core/FlexLayout/flexutils.h" +#include "core/YogaWidget/yogawidget.h" bool extrautils::isNapiValueInt(Napi::Env& env, Napi::Value& num) { return env.Global() @@ -101,12 +102,16 @@ QVariant* extrautils::convertToQVariant(Napi::Env& env, Napi::Value& value) { } void* extrautils::configureComponent(void* component) { return component; } + void* extrautils::configureQObject(QObject* object) { return configureComponent(object); } -void* extrautils::configureQWidget(QWidget* widget, YGNodeRef node, - bool isLeafNode) { - flexutils::configureFlexNode(widget, node, isLeafNode); + +void* extrautils::configureQWidget(QWidget* widget, bool isLeafNode) { + YogaWidget* yogaWidget = dynamic_cast(widget); + if (yogaWidget) { + flexutils::configureFlexNode(widget, yogaWidget->getFlexNode(), isLeafNode); + } return configureQObject(widget); } diff --git a/src/cpp/lib/QtCore/QAbstractItemModel/qabstractitemmodel_wrap.cpp b/src/cpp/lib/QtCore/QAbstractItemModel/qabstractitemmodel_wrap.cpp index b0aa9f2ea..ed6360671 100644 --- a/src/cpp/lib/QtCore/QAbstractItemModel/qabstractitemmodel_wrap.cpp +++ b/src/cpp/lib/QtCore/QAbstractItemModel/qabstractitemmodel_wrap.cpp @@ -45,6 +45,7 @@ Napi::Object QAbstractItemModelWrap::init(Napi::Env env, Napi::Object exports) { QOBJECT_WRAPPED_METHODS_EXPORT_DEFINE(QAbstractItemModelWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); + QOBJECT_REGISTER_WRAPPER(NAbstractItemModel, QAbstractItemModelWrap); return exports; } @@ -58,7 +59,21 @@ QAbstractItemModelWrap::~QAbstractItemModelWrap() { QAbstractItemModelWrap::QAbstractItemModelWrap(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); - this->instance = new NAbstractItemModel(); + size_t argCount = info.Length(); + if (argCount == 0) { + // --- Construct a new instance + this->instance = new NAbstractItemModel(); + } else if (argCount == 1) { + if (info[0].IsExternal()) { + // --- Wrap a given C++ instance + this->instance = info[0].As>().Data(); + } + } else { + Napi::TypeError::New(env, + "NodeGui: QAbstractItemModelWrap: Wrong number of " + "arguments to constructor") + .ThrowAsJavaScriptException(); + } } Napi::Value QAbstractItemModelWrap::initNodeDispatcher( diff --git a/src/cpp/lib/QtCore/QItemSelectionModel/qitemselectionmodel_wrap.cpp b/src/cpp/lib/QtCore/QItemSelectionModel/qitemselectionmodel_wrap.cpp index f6ea1f900..e5df598ec 100644 --- a/src/cpp/lib/QtCore/QItemSelectionModel/qitemselectionmodel_wrap.cpp +++ b/src/cpp/lib/QtCore/QItemSelectionModel/qitemselectionmodel_wrap.cpp @@ -38,6 +38,7 @@ Napi::Object QItemSelectionModelWrap::init(Napi::Env env, QOBJECT_WRAPPED_METHODS_EXPORT_DEFINE(QItemSelectionModelWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); + QOBJECT_REGISTER_WRAPPER(QItemSelectionModel, QItemSelectionModelWrap); return exports; } @@ -46,20 +47,33 @@ QItemSelectionModel* QItemSelectionModelWrap::getInternalInstance() { } QItemSelectionModelWrap::~QItemSelectionModelWrap() { - if (!this->disableDeletion) { - extrautils::safeDelete(this->instance); - } + extrautils::safeDelete(this->instance); } QItemSelectionModelWrap::QItemSelectionModelWrap(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); - if (info.Length() == 0) { + size_t argCount = info.Length(); + if (argCount == 0) { + // --- Construct a new instance this->instance = new NItemSelectionModel(); - this->disableDeletion = false; + } else if (argCount == 1) { + if (info[0].IsExternal()) { + // --- Wrap a given C++ instance + this->instance = info[0].As>().Data(); + } else { + // --- Construct a new instance and pass a parent + // Napi::Object parentObject = info[0].As(); + // QObjectWrap* parentObjectWrap = + // Napi::ObjectWrap::Unwrap(parentObject); + // this->instance = new + // NItemSelectionModel(parentObjectWrap->getInternalInstance()); + } } else { - this->instance = info[0].As>().Data(); - this->disableDeletion = true; + Napi::TypeError::New(env, + "NodeGui: QItemSelectionModelWrap: Wrong number of " + "arguments to constructor") + .ThrowAsJavaScriptException(); } } Napi::Value QItemSelectionModelWrap::columnIntersectsSelection( diff --git a/src/cpp/lib/QtCore/QMimeData/qmimedata_wrap.cpp b/src/cpp/lib/QtCore/QMimeData/qmimedata_wrap.cpp index c0ba24c27..6476be13e 100644 --- a/src/cpp/lib/QtCore/QMimeData/qmimedata_wrap.cpp +++ b/src/cpp/lib/QtCore/QMimeData/qmimedata_wrap.cpp @@ -10,7 +10,6 @@ Napi::Object QMimeDataWrap::init(Napi::Env env, Napi::Object exports) { char CLASSNAME[] = "QMimeData"; Napi::Function func = DefineClass(env, CLASSNAME, - {InstanceMethod("clear", &QMimeDataWrap::clear), InstanceMethod("hasColor", &QMimeDataWrap::hasColor), InstanceMethod("hasHtml", &QMimeDataWrap::hasHtml), @@ -25,43 +24,31 @@ Napi::Object QMimeDataWrap::init(Napi::Env env, Napi::Object exports) { InstanceMethod("setUrls", &QMimeDataWrap::setUrls), InstanceMethod("text", &QMimeDataWrap::text), InstanceMethod("urls", &QMimeDataWrap::urls), - - COMPONENT_WRAPPED_METHODS_EXPORT_DEFINE(QMimeDataWrap)}); + QOBJECT_WRAPPED_METHODS_EXPORT_DEFINE(QMimeDataWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); + QOBJECT_REGISTER_WRAPPER(QMimeData, QMimeDataWrap); return exports; } -QMimeData* QMimeDataWrap::getInternalInstance() { return this->instance.get(); } +QMimeData* QMimeDataWrap::getInternalInstance() { return this->instance; } -QMimeDataWrap::~QMimeDataWrap() { this->instance.reset(); } +QMimeDataWrap::~QMimeDataWrap() { extrautils::safeDelete(this->instance); } QMimeDataWrap::QMimeDataWrap(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); - if (info.Length() == 1) { - Napi::External eventObject = - info[0].As>(); - this->instance = std::make_unique(); - // Copy data to our instance - QMimeData* mimeReference = eventObject.Data(); - this->cloneFromMimeData(mimeReference); - // foreach(QString format, mimeReference->formats()) - // { - // // Retrieving data - // QByteArray data = mimeReference->data(format); - // // Checking for custom MIME types - // if(format.startsWith("application/x-qt")) - // { - // // Retrieving true format name - // int indexBegin = format.indexOf('"') + 1; - // int indexEnd = format.indexOf('"', indexBegin); - // format = format.mid(indexBegin, indexEnd - indexBegin); - // } - // this->instance->setData(format, data); - // } + size_t argCount = info.Length(); + if (argCount == 0) { + // --- Construct a new instance + this->instance = new QMimeData(); + } else if (argCount == 1 && info[0].IsExternal()) { + // --- Wrap a given C++ instance + this->instance = info[0].As>().Data(); } else { - this->instance = std::make_unique(); + Napi::TypeError::New( + env, "NodeGui: QMimeDataWrap: Wrong number of arguments to constructor") + .ThrowAsJavaScriptException(); } this->rawData = extrautils::configureComponent(this->getInternalInstance()); } diff --git a/src/cpp/lib/QtCore/QObject/qobject_wrap.cpp b/src/cpp/lib/QtCore/QObject/qobject_wrap.cpp index 61aff178f..c138abedb 100644 --- a/src/cpp/lib/QtCore/QObject/qobject_wrap.cpp +++ b/src/cpp/lib/QtCore/QObject/qobject_wrap.cpp @@ -12,30 +12,31 @@ Napi::Object QObjectWrap::init(Napi::Env env, Napi::Object exports) { env, CLASSNAME, {QOBJECT_WRAPPED_METHODS_EXPORT_DEFINE(QObjectWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); - QOBJECT_REGISTER_WRAPPER(NObject, QObjectWrap); + QOBJECT_REGISTER_WRAPPER(QObject, QObjectWrap); return exports; } -NObject* QObjectWrap::getInternalInstance() { return this->instance; } +QObject* QObjectWrap::getInternalInstance() { return this->instance; } QObjectWrap::~QObjectWrap() { extrautils::safeDelete(this->instance); } QObjectWrap::QObjectWrap(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); - if (info.Length() == 1) { + size_t argCount = info.Length(); + if (argCount == 1) { if (info[0].IsExternal()) { - this->instance = info[0].As>().Data(); + this->instance = info[0].As>().Data(); } else { Napi::Object parentObject = info[0].As(); QObjectWrap* parentWidgetWrap = Napi::ObjectWrap::Unwrap(parentObject); this->instance = new NObject(parentWidgetWrap->getInternalInstance()); } - } else if (info.Length() == 0) { + } else if (argCount == 0) { this->instance = new NObject(); } else { - Napi::TypeError::New(env, "Wrong number of arguments") + Napi::TypeError::New(env, "NodeGui: QObjectWrap: Wrong number of arguments") .ThrowAsJavaScriptException(); } this->rawData = extrautils::configureQObject(this->getInternalInstance()); diff --git a/src/cpp/lib/QtGui/QApplication/qapplication_wrap.cpp b/src/cpp/lib/QtGui/QApplication/qapplication_wrap.cpp index 32739150b..112b34c86 100644 --- a/src/cpp/lib/QtGui/QApplication/qapplication_wrap.cpp +++ b/src/cpp/lib/QtGui/QApplication/qapplication_wrap.cpp @@ -41,13 +41,15 @@ Napi::Object QApplicationWrap::init(Napi::Env env, Napi::Object exports) { QApplicationWrap::QApplicationWrap(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); - if (info.Length() == 1) { + size_t argCount = info.Length(); + if (argCount == 1) { this->instance = info[0].As>().Data(); - } else if (info.Length() == 0) { + } else if (argCount == 0) { this->instance = new NApplication(qode::qode_argc, qode::qode_argv); this->_wasManuallyCreated = true; } else { - Napi::TypeError::New(env, "Wrong number of arguments") + Napi::TypeError::New(env, + "NodeGui: QApplicationWrap: Wrong number of arguments") .ThrowAsJavaScriptException(); } this->rawData = extrautils::configureComponent(this->getInternalInstance()); diff --git a/src/cpp/lib/QtGui/QDrag/qdrag_wrap.cpp b/src/cpp/lib/QtGui/QDrag/qdrag_wrap.cpp index be3319195..0e80de3cc 100644 --- a/src/cpp/lib/QtGui/QDrag/qdrag_wrap.cpp +++ b/src/cpp/lib/QtGui/QDrag/qdrag_wrap.cpp @@ -32,21 +32,33 @@ Napi::Object QDragWrap::init(Napi::Env env, Napi::Object exports) { COMPONENT_WRAPPED_METHODS_EXPORT_DEFINE(QDragWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); + QOBJECT_REGISTER_WRAPPER(QDrag, QDragWrap); return exports; } -NDrag* QDragWrap::getInternalInstance() { return this->instance; } +QDrag* QDragWrap::getInternalInstance() { return this->instance; } QDragWrap::QDragWrap(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); - if (info.Length() == 1) { - Napi::Object wrap0_0 = info[0].As(); - QObjectWrap* wrap0_1 = Napi::ObjectWrap::Unwrap(wrap0_0); - QObject* dragSource = wrap0_1->getInternalInstance(); - this->instance = new NDrag(dragSource); + size_t argCount = info.Length(); + if (argCount == 0) { + // --- Construct a new instance + this->instance = new NDrag(nullptr); + } else if (argCount == 1) { + if (info[0].IsExternal()) { + // --- Wrap a given C++ instance + this->instance = info[0].As>().Data(); + } else { + // --- Construct a new instance and pass a parent + Napi::Object sourceObject = info[0].As(); + QObjectWrap* sourceObjectWrap = + Napi::ObjectWrap::Unwrap(sourceObject); + this->instance = new NDrag(sourceObjectWrap->getInternalInstance()); + } } else { - Napi::TypeError::New(env, "Wrong number of arguments") + Napi::TypeError::New( + env, "NodeGui: QDragWrap: Wrong number of arguments to constructor") .ThrowAsJavaScriptException(); } this->rawData = extrautils::configureComponent(this->getInternalInstance()); diff --git a/src/cpp/lib/QtGui/QMovie/qmovie_wrap.cpp b/src/cpp/lib/QtGui/QMovie/qmovie_wrap.cpp index 5985af2ef..88ba4ce69 100644 --- a/src/cpp/lib/QtGui/QMovie/qmovie_wrap.cpp +++ b/src/cpp/lib/QtGui/QMovie/qmovie_wrap.cpp @@ -42,21 +42,27 @@ QMovieWrap::~QMovieWrap() { extrautils::safeDelete(this->instance); } QMovieWrap::QMovieWrap(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); - if (info.Length() == 1) { - if (info[0].IsExternal()) { - this->instance = new NMovie(info[0].As>().Data()); - } else { - Napi::Object parentObject = info[0].As(); - QMovieWrap* parentWidgetWrap = - Napi::ObjectWrap::Unwrap(parentObject); - this->instance = new NMovie(parentWidgetWrap->getInternalInstance()); - } - } else if (info.Length() == 0) { + size_t argCount = info.Length(); + if (argCount == 0) { + // --- Construct a new instance this->instance = new NMovie(); + } else if (argCount == 1) { + if (info[0].IsExternal()) { + // --- Wrap a given C++ instance + this->instance = info[0].As>().Data(); + } else { + // --- Construct a new instance and pass a parent + Napi::Object parentObject = info[0].As(); + QObjectWrap* parentObjectWrap = + Napi::ObjectWrap::Unwrap(parentObject); + this->instance = new NMovie(parentObjectWrap->getInternalInstance()); + } } else { - Napi::TypeError::New(env, "Wrong number of arguments") + Napi::TypeError::New( + env, "NodeGui: QMovieWrap: Wrong number of arguments to constructor") .ThrowAsJavaScriptException(); } + QOBJECT_REGISTER_WRAPPER(QMovie, QMovieWrap); this->bufferDevice = QSharedPointer(new QBuffer); this->rawData = extrautils::configureQObject(this->getInternalInstance()); } diff --git a/src/cpp/lib/QtGui/QScreen/qscreen_wrap.cpp b/src/cpp/lib/QtGui/QScreen/qscreen_wrap.cpp index f3a8064e4..871182da7 100644 --- a/src/cpp/lib/QtGui/QScreen/qscreen_wrap.cpp +++ b/src/cpp/lib/QtGui/QScreen/qscreen_wrap.cpp @@ -26,7 +26,7 @@ QScreenWrap::QScreenWrap(const Napi::CallbackInfo& info) if (info[0].IsExternal()) { this->instance = info[0].As>().Data(); } else { - Napi::TypeError::New(env, "Incorrect initialization of QScreenWrap") + Napi::TypeError::New(env, "NodeGui: QScreenWrap: Incorrect initialization") .ThrowAsJavaScriptException(); } this->rawData = extrautils::configureComponent(this->getInternalInstance()); diff --git a/src/cpp/lib/QtGui/QStyle/qstyle_wrap.cpp b/src/cpp/lib/QtGui/QStyle/qstyle_wrap.cpp index 99efe1e1e..4ab3c4295 100644 --- a/src/cpp/lib/QtGui/QStyle/qstyle_wrap.cpp +++ b/src/cpp/lib/QtGui/QStyle/qstyle_wrap.cpp @@ -25,7 +25,8 @@ QStyleWrap::QStyleWrap(const Napi::CallbackInfo& info) if (info[0].IsExternal()) { this->instance = info[0].As>().Data(); } else { - Napi::TypeError::New(env, "Incorrect initialization of QStyleWrap") + Napi::TypeError::New( + env, "NodeGui: QStyleWrap: Incorrect initialization of QStyleWrap") .ThrowAsJavaScriptException(); } this->rawData = extrautils::configureComponent(this->getInternalInstance()); diff --git a/src/cpp/lib/QtGui/QWindow/qwindow_wrap.cpp b/src/cpp/lib/QtGui/QWindow/qwindow_wrap.cpp index 78fdc4333..fee76f489 100644 --- a/src/cpp/lib/QtGui/QWindow/qwindow_wrap.cpp +++ b/src/cpp/lib/QtGui/QWindow/qwindow_wrap.cpp @@ -25,6 +25,7 @@ Napi::Object QWindowWrap::init(Napi::Env env, Napi::Object exports) { QOBJECT_WRAPPED_METHODS_EXPORT_DEFINE(QWindowWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); + QOBJECT_REGISTER_WRAPPER(QWindow, QWindowWrap); return exports; } @@ -36,7 +37,8 @@ QWindowWrap::QWindowWrap(const Napi::CallbackInfo& info) if (info.Length() == 1 && info[0].IsExternal()) { this->instance = info[0].As>().Data(); } else { - Napi::TypeError::New(env, "Wrong number of arguments to QWindow.") + Napi::TypeError::New(env, + "NodeGui: QWindowWrap: Bad arguments to constructor.") .ThrowAsJavaScriptException(); } this->rawData = extrautils::configureQObject(this->getInternalInstance()); diff --git a/src/cpp/lib/QtWidgets/QAction/qaction_wrap.cpp b/src/cpp/lib/QtWidgets/QAction/qaction_wrap.cpp index cc75c009f..7f6e2f462 100644 --- a/src/cpp/lib/QtWidgets/QAction/qaction_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QAction/qaction_wrap.cpp @@ -34,44 +34,40 @@ Napi::Object QActionWrap::init(Napi::Env env, Napi::Object exports) { QOBJECT_WRAPPED_METHODS_EXPORT_DEFINE(QActionWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); + QOBJECT_REGISTER_WRAPPER(QAction, QActionWrap); return exports; } -NAction* QActionWrap::getInternalInstance() { return this->instance; } +QAction* QActionWrap::getInternalInstance() { return this->instance; } QActionWrap::QActionWrap(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); - - this->disableDeletion = false; - if (info.Length() > 0 && info[0].IsExternal()) { - // --- if external --- - this->instance = info[0].As>().Data(); - if (info.Length() == 2) { - this->disableDeletion = info[1].As().Value(); + size_t argCount = info.Length(); + if (argCount == 0) { + // --- Construct a new instance + this->instance = new NAction(); + } else if (argCount == 1) { + if (info[0].IsExternal()) { + // --- Wrap a given C++ instance + this->instance = info[0].As>().Data(); + } else { + // --- Construct a new instance and pass a parent + Napi::Object parentObject = info[0].As(); + QObjectWrap* parentObjectWrap = + Napi::ObjectWrap::Unwrap(parentObject); + this->instance = new NAction(parentObjectWrap->getInternalInstance()); } } else { - // --- regular cases --- - if (info.Length() == 1) { - Napi::Object parentObject = info[0].As(); - NodeWidgetWrap* parentWidgetWrap = - Napi::ObjectWrap::Unwrap(parentObject); - this->instance = new NAction(parentWidgetWrap->getInternalInstance()); - } else if (info.Length() == 0) { - this->instance = new NAction(); - } else { - Napi::TypeError::New(env, "Wrong number of arguments") - .ThrowAsJavaScriptException(); - } + Napi::TypeError::New( + env, "NodeGui: QActionWrap: Wrong number of arguments to constructor") + .ThrowAsJavaScriptException(); } + this->rawData = extrautils::configureQObject(this->getInternalInstance()); } -QActionWrap::~QActionWrap() { - if (!this->disableDeletion) { - extrautils::safeDelete(this->instance); - } -} +QActionWrap::~QActionWrap() { extrautils::safeDelete(this->instance); } Napi::Value QActionWrap::setText(const Napi::CallbackInfo& info) { Napi::Env env = info.Env(); diff --git a/src/cpp/lib/QtWidgets/QBoxLayout/qboxlayout_wrap.cpp b/src/cpp/lib/QtWidgets/QBoxLayout/qboxlayout_wrap.cpp index 28e53f058..a42745ff2 100644 --- a/src/cpp/lib/QtWidgets/QBoxLayout/qboxlayout_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QBoxLayout/qboxlayout_wrap.cpp @@ -27,16 +27,19 @@ Napi::Object QBoxLayoutWrap::init(Napi::Env env, Napi::Object exports) { QLAYOUT_WRAPPED_METHODS_EXPORT_DEFINE(QBoxLayoutWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); + QOBJECT_REGISTER_WRAPPER(QBoxLayout, QBoxLayoutWrap); return exports; } -NBoxLayout* QBoxLayoutWrap::getInternalInstance() { return this->instance; } +QBoxLayout* QBoxLayoutWrap::getInternalInstance() { return this->instance; } + QBoxLayoutWrap::~QBoxLayoutWrap() { extrautils::safeDelete(this->instance); } QBoxLayoutWrap::QBoxLayoutWrap(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); - if (info.Length() == 2) { + size_t argCount = info.Length(); + if (argCount == 2) { QBoxLayout::Direction dir = static_cast( info[0].As().Int32Value()); Napi::Object parentObject = info[1].As(); @@ -44,12 +47,17 @@ QBoxLayoutWrap::QBoxLayoutWrap(const Napi::CallbackInfo& info) Napi::ObjectWrap::Unwrap(parentObject); this->instance = new NBoxLayout(dir, parentWidgetWrap->getInternalInstance()); - } else if (info.Length() == 1) { - QBoxLayout::Direction dir = static_cast( - info[0].As().Int32Value()); - this->instance = new NBoxLayout(dir); + } else if (argCount == 1) { + if (info[0].IsExternal()) { + // --- Wrap a given C++ instance + this->instance = info[0].As>().Data(); + } else { + QBoxLayout::Direction dir = static_cast( + info[0].As().Int32Value()); + this->instance = new NBoxLayout(dir); + } } else { - Napi::TypeError::New(env, "Wrong number of arguments") + Napi::TypeError::New(env, "QBoxLayoutWrap: Wrong number of arguments") .ThrowAsJavaScriptException(); } this->rawData = extrautils::configureQObject(this->getInternalInstance()); diff --git a/src/cpp/lib/QtWidgets/QButtonGroup/qbuttongroup_wrap.cpp b/src/cpp/lib/QtWidgets/QButtonGroup/qbuttongroup_wrap.cpp index 143c41f62..1da2efaea 100644 --- a/src/cpp/lib/QtWidgets/QButtonGroup/qbuttongroup_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QButtonGroup/qbuttongroup_wrap.cpp @@ -27,25 +27,34 @@ Napi::Object QButtonGroupWrap::init(Napi::Env env, Napi::Object exports) { QOBJECT_WRAPPED_METHODS_EXPORT_DEFINE(QButtonGroupWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); + QOBJECT_REGISTER_WRAPPER(QButtonGroup, QButtonGroupWrap); return exports; } -NButtonGroup* QButtonGroupWrap::getInternalInstance() { return this->instance; } +QButtonGroup* QButtonGroupWrap::getInternalInstance() { return this->instance; } QButtonGroupWrap::QButtonGroupWrap(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); - if (info.Length() == 1) { - Napi::Object parentObject = info[0].As(); - NodeWidgetWrap* parentWidgetWrap = - Napi::ObjectWrap::Unwrap(parentObject); - this->instance = new NButtonGroup( - parentWidgetWrap - ->getInternalInstance()); // this sets the parent to current widget - } else if (info.Length() == 0) { + size_t argCount = info.Length(); + if (argCount == 0) { + // --- Construct a new instance this->instance = new NButtonGroup(); + } else if (argCount == 1) { + if (info[0].IsExternal()) { + // --- Wrap a given C++ instance + this->instance = info[0].As>().Data(); + } else { + Napi::Object parentObject = info[0].As(); + NodeWidgetWrap* parentWidgetWrap = + Napi::ObjectWrap::Unwrap(parentObject); + this->instance = + new NButtonGroup(parentWidgetWrap->getInternalInstance()); + } } else { - Napi::TypeError::New(env, "Wrong number of arguments") + Napi::TypeError::New( + env, + "NodeGui: QButtonGroupWrap: Wrong number of arguments to constructor") .ThrowAsJavaScriptException(); } this->rawData = extrautils::configureQObject(this->getInternalInstance()); diff --git a/src/cpp/lib/QtWidgets/QCalendarWidget/qcalendarwidget_wrap.cpp b/src/cpp/lib/QtWidgets/QCalendarWidget/qcalendarwidget_wrap.cpp index 99de9374b..0506189ea 100644 --- a/src/cpp/lib/QtWidgets/QCalendarWidget/qcalendarwidget_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QCalendarWidget/qcalendarwidget_wrap.cpp @@ -28,10 +28,11 @@ Napi::Object QCalendarWidgetWrap::init(Napi::Env env, Napi::Object exports) { QWIDGET_WRAPPED_METHODS_EXPORT_DEFINE(QCalendarWidgetWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); + QOBJECT_REGISTER_WRAPPER(QCalendarWidget, QCalendarWidgetWrap); return exports; } -NCalendarWidget *QCalendarWidgetWrap::getInternalInstance() { +QCalendarWidget *QCalendarWidgetWrap::getInternalInstance() { return this->instance; } @@ -42,22 +43,31 @@ QCalendarWidgetWrap::~QCalendarWidgetWrap() { QCalendarWidgetWrap::QCalendarWidgetWrap(const Napi::CallbackInfo &info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); - if (info.Length() == 1) { - Napi::Object parentObject = info[0].As(); - NodeWidgetWrap *parentWidgetWrap = - Napi::ObjectWrap::Unwrap(parentObject); - this->instance = new NCalendarWidget( - parentWidgetWrap - ->getInternalInstance()); // this sets the parent to current widget - } else if (info.Length() == 0) { + size_t argCount = info.Length(); + if (argCount == 0) { + // --- Construct a new instance this->instance = new NCalendarWidget(); + } else if (argCount == 1) { + if (info[0].IsExternal()) { + // --- Wrap a given C++ instance + this->instance = info[0].As>().Data(); + } else { + // --- Construct a new instance and pass a parent + Napi::Object parentObject = info[0].As(); + NodeWidgetWrap *parentWidgetWrap = + Napi::ObjectWrap::Unwrap(parentObject); + this->instance = + new NCalendarWidget(parentWidgetWrap->getInternalInstance()); + } } else { - Napi::TypeError::New(env, "Wrong number of arguments") + Napi::TypeError::New(env, + "NodeGui: QCalendarWidgetWrap: Wrong number of " + "arguments to constructor") .ThrowAsJavaScriptException(); } - this->rawData = extrautils::configureQWidget( - this->getInternalInstance(), this->getInternalInstance()->getFlexNode(), - true); + + this->rawData = + extrautils::configureQWidget(this->getInternalInstance(), true); } Napi::Value QCalendarWidgetWrap::monthShown(const Napi::CallbackInfo &info) { diff --git a/src/cpp/lib/QtWidgets/QCheckBox/qcheckbox_wrap.cpp b/src/cpp/lib/QtWidgets/QCheckBox/qcheckbox_wrap.cpp index d4297db49..87d5c5879 100644 --- a/src/cpp/lib/QtWidgets/QCheckBox/qcheckbox_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QCheckBox/qcheckbox_wrap.cpp @@ -17,44 +17,40 @@ Napi::Object QCheckBoxWrap::init(Napi::Env env, Napi::Object exports) { QABSTRACTBUTTON_WRAPPED_METHODS_EXPORT_DEFINE(QCheckBoxWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); + QOBJECT_REGISTER_WRAPPER(QCheckBox, QCheckBoxWrap); return exports; } -NCheckBox* QCheckBoxWrap::getInternalInstance() { return this->instance; } +QCheckBox* QCheckBoxWrap::getInternalInstance() { return this->instance; } QCheckBoxWrap::QCheckBoxWrap(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); - this->disableDeletion = false; - if (info.Length() > 0 && info[0].IsExternal()) { - // --- if external --- - this->instance = info[0].As>().Data(); - if (info.Length() == 2) { - this->disableDeletion = info[1].As().Value(); - } - } else { - if (info.Length() == 1) { + size_t argCount = info.Length(); + if (argCount == 0) { + // --- Construct a new instance + this->instance = new NCheckBox(); + } else if (argCount == 1) { + if (info[0].IsExternal()) { + // --- Wrap a given C++ instance + this->instance = info[0].As>().Data(); + } else { + // --- Construct a new instance and pass a parent Napi::Object parentObject = info[0].As(); NodeWidgetWrap* parentWidgetWrap = Napi::ObjectWrap::Unwrap(parentObject); this->instance = new NCheckBox(parentWidgetWrap->getInternalInstance()); - } else if (info.Length() == 0) { - this->instance = new NCheckBox(); - } else { - Napi::TypeError::New(env, "Wrong number of arguments") - .ThrowAsJavaScriptException(); } + } else { + Napi::TypeError::New( + env, "NodeGui: QCheckBoxWrap: Wrong number of arguments to constructor") + .ThrowAsJavaScriptException(); } - this->rawData = extrautils::configureQWidget( - this->getInternalInstance(), this->getInternalInstance()->getFlexNode(), - true); + this->rawData = + extrautils::configureQWidget(this->getInternalInstance(), true); } -QCheckBoxWrap::~QCheckBoxWrap() { - if (!this->disableDeletion) { - extrautils::safeDelete(this->instance); - } -} +QCheckBoxWrap::~QCheckBoxWrap() { extrautils::safeDelete(this->instance); } Napi::Value QCheckBoxWrap::checkState(const Napi::CallbackInfo& info) { Napi::Env env = info.Env(); diff --git a/src/cpp/lib/QtWidgets/QColorDialog/qcolordialog_wrap.cpp b/src/cpp/lib/QtWidgets/QColorDialog/qcolordialog_wrap.cpp index b41c3440f..5fb1e1ad3 100644 --- a/src/cpp/lib/QtWidgets/QColorDialog/qcolordialog_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QColorDialog/qcolordialog_wrap.cpp @@ -27,10 +27,11 @@ Napi::Object QColorDialogWrap::init(Napi::Env env, Napi::Object exports) { QDIALOG_WRAPPED_METHODS_EXPORT_DEFINE(QColorDialogWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); + QOBJECT_REGISTER_WRAPPER(QColorDialog, QColorDialogWrap); return exports; } -NColorDialog* QColorDialogWrap::getInternalInstance() { return this->instance; } +QColorDialog* QColorDialogWrap::getInternalInstance() { return this->instance; } QColorDialogWrap::~QColorDialogWrap() { extrautils::safeDelete(this->instance); @@ -39,21 +40,30 @@ QColorDialogWrap::~QColorDialogWrap() { QColorDialogWrap::QColorDialogWrap(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); - if (info.Length() == 1) { - Napi::Object parentObject = info[0].As(); - NodeWidgetWrap* parentWidgetWrap = - Napi::ObjectWrap::Unwrap(parentObject); - QWidget* parent = parentWidgetWrap->getInternalInstance(); - this->instance = new NColorDialog(parent); - } else if (info.Length() == 0) { + size_t argCount = info.Length(); + if (argCount == 0) { + // --- Construct a new instance this->instance = new NColorDialog(); + } else if (argCount == 1) { + if (info[0].IsExternal()) { + // --- Wrap a given C++ instance + this->instance = info[0].As>().Data(); + } else { + // --- Construct a new instance and pass a parent + Napi::Object parentObject = info[0].As(); + NodeWidgetWrap* parentWidgetWrap = + Napi::ObjectWrap::Unwrap(parentObject); + this->instance = + new NColorDialog(parentWidgetWrap->getInternalInstance()); + } } else { - Napi::TypeError::New(env, "Wrong number of arguments") + Napi::TypeError::New( + env, + "NodeGui: QColorDialogWrap: Wrong number of arguments to constructor") .ThrowAsJavaScriptException(); } - this->rawData = extrautils::configureQWidget( - this->getInternalInstance(), this->getInternalInstance()->getFlexNode(), - false); + this->rawData = + extrautils::configureQWidget(this->getInternalInstance(), false); } Napi::Value QColorDialogWrap::selectedColor(const Napi::CallbackInfo& info) { diff --git a/src/cpp/lib/QtWidgets/QComboBox/qcombobox_wrap.cpp b/src/cpp/lib/QtWidgets/QComboBox/qcombobox_wrap.cpp index 714e7402e..6af18286f 100644 --- a/src/cpp/lib/QtWidgets/QComboBox/qcombobox_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QComboBox/qcombobox_wrap.cpp @@ -66,30 +66,39 @@ Napi::Object QComboBoxWrap::init(Napi::Env env, Napi::Object exports) { QWIDGET_WRAPPED_METHODS_EXPORT_DEFINE(QComboBoxWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); + QOBJECT_REGISTER_WRAPPER(QComboBox, QComboBoxWrap); return exports; } -NComboBox* QComboBoxWrap::getInternalInstance() { return this->instance; } +QComboBox* QComboBoxWrap::getInternalInstance() { return this->instance; } + QComboBoxWrap::~QComboBoxWrap() { extrautils::safeDelete(this->instance); } QComboBoxWrap::QComboBoxWrap(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); - if (info.Length() == 1) { - Napi::Object parentObject = info[0].As(); - NodeWidgetWrap* parentWidgetWrap = - Napi::ObjectWrap::Unwrap(parentObject); - - this->instance = new NComboBox(parentWidgetWrap->getInternalInstance()); - } else if (info.Length() == 0) { + size_t argCount = info.Length(); + if (argCount == 0) { + // --- Construct a new instance this->instance = new NComboBox(); + } else if (argCount == 1) { + if (info[0].IsExternal()) { + // --- Wrap a given C++ instance + this->instance = info[0].As>().Data(); + } else { + // --- Construct a new instance and pass a parent + Napi::Object parentObject = info[0].As(); + NodeWidgetWrap* parentWidgetWrap = + Napi::ObjectWrap::Unwrap(parentObject); + this->instance = new NComboBox(parentWidgetWrap->getInternalInstance()); + } } else { - Napi::TypeError::New(env, "Wrong number of arguments") + Napi::TypeError::New( + env, "NodeGui: QComboBoxWrap: Wrong number of arguments to constructor") .ThrowAsJavaScriptException(); } - this->rawData = extrautils::configureQWidget( - this->getInternalInstance(), this->getInternalInstance()->getFlexNode(), - true); + this->rawData = + extrautils::configureQWidget(this->getInternalInstance(), true); } Napi::Value QComboBoxWrap::addItem(const Napi::CallbackInfo& info) { diff --git a/src/cpp/lib/QtWidgets/QDateEdit/qdateedit_wrap.cpp b/src/cpp/lib/QtWidgets/QDateEdit/qdateedit_wrap.cpp index 93ea2fa5b..7bcd6edd2 100644 --- a/src/cpp/lib/QtWidgets/QDateEdit/qdateedit_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QDateEdit/qdateedit_wrap.cpp @@ -12,28 +12,37 @@ Napi::Object QDateEditWrap::init(Napi::Env env, Napi::Object exports) { {QDATETIMEEDIT_WRAPPED_METHODS_EXPORT_DEFINE(QDateEditWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); + QOBJECT_REGISTER_WRAPPER(QDateEdit, QDateEditWrap); return exports; } -NDateEdit* QDateEditWrap::getInternalInstance() { return this->instance; } +QDateEdit* QDateEditWrap::getInternalInstance() { return this->instance; } QDateEditWrap::QDateEditWrap(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); - if (info.Length() == 1) { - Napi::Object parentObject = info[0].As(); - NodeWidgetWrap* parentWidgetWrap = - Napi::ObjectWrap::Unwrap(parentObject); - this->instance = new NDateEdit(parentWidgetWrap->getInternalInstance()); - } else if (info.Length() == 0) { + size_t argCount = info.Length(); + if (argCount == 0) { + // --- Construct a new instance this->instance = new NDateEdit(); + } else if (argCount == 1) { + if (info[0].IsExternal()) { + // --- Wrap a given C++ instance + this->instance = info[0].As>().Data(); + } else { + // --- Construct a new instance and pass a parent + Napi::Object parentObject = info[0].As(); + NodeWidgetWrap* parentWidgetWrap = + Napi::ObjectWrap::Unwrap(parentObject); + this->instance = new NDateEdit(parentWidgetWrap->getInternalInstance()); + } } else { - Napi::TypeError::New(env, "Wrong number of arguments") + Napi::TypeError::New( + env, "NodeGui: QDateEditWrap: Wrong number of arguments to constructor") .ThrowAsJavaScriptException(); } - this->rawData = extrautils::configureQWidget( - this->getInternalInstance(), this->getInternalInstance()->getFlexNode(), - true); + this->rawData = + extrautils::configureQWidget(this->getInternalInstance(), true); } QDateEditWrap::~QDateEditWrap() { extrautils::safeDelete(this->instance); } diff --git a/src/cpp/lib/QtWidgets/QDateTimeEdit/qdatetimeedit_wrap.cpp b/src/cpp/lib/QtWidgets/QDateTimeEdit/qdatetimeedit_wrap.cpp index 776e8bc2c..0082be0a7 100644 --- a/src/cpp/lib/QtWidgets/QDateTimeEdit/qdatetimeedit_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QDateTimeEdit/qdatetimeedit_wrap.cpp @@ -12,30 +12,41 @@ Napi::Object QDateTimeEditWrap::init(Napi::Env env, Napi::Object exports) { {QDATETIMEEDIT_WRAPPED_METHODS_EXPORT_DEFINE(QDateTimeEditWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); + QOBJECT_REGISTER_WRAPPER(QDateTimeEdit, QDateTimeEditWrap); return exports; } -NDateTimeEdit* QDateTimeEditWrap::getInternalInstance() { +QDateTimeEdit* QDateTimeEditWrap::getInternalInstance() { return this->instance; } QDateTimeEditWrap::QDateTimeEditWrap(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); - if (info.Length() == 1) { - Napi::Object parentObject = info[0].As(); - NodeWidgetWrap* parentWidgetWrap = - Napi::ObjectWrap::Unwrap(parentObject); - this->instance = new NDateTimeEdit(parentWidgetWrap->getInternalInstance()); - } else if (info.Length() == 0) { + size_t argCount = info.Length(); + if (argCount == 0) { + // --- Construct a new instance this->instance = new NDateTimeEdit(); + } else if (argCount == 1) { + if (info[0].IsExternal()) { + // --- Wrap a given C++ instance + this->instance = info[0].As>().Data(); + } else { + // --- Construct a new instance and pass a parent + Napi::Object parentObject = info[0].As(); + NodeWidgetWrap* parentWidgetWrap = + Napi::ObjectWrap::Unwrap(parentObject); + this->instance = + new NDateTimeEdit(parentWidgetWrap->getInternalInstance()); + } } else { - Napi::TypeError::New(env, "Wrong number of arguments") + Napi::TypeError::New( + env, + "NodeGui: QDateTimeEditWrap: Wrong number of arguments to constructor") .ThrowAsJavaScriptException(); } - this->rawData = extrautils::configureQWidget( - this->getInternalInstance(), this->getInternalInstance()->getFlexNode(), - true); + this->rawData = + extrautils::configureQWidget(this->getInternalInstance(), true); } QDateTimeEditWrap::~QDateTimeEditWrap() { diff --git a/src/cpp/lib/QtWidgets/QDial/qdial_wrap.cpp b/src/cpp/lib/QtWidgets/QDial/qdial_wrap.cpp index be8b1c696..8c4ff98bc 100644 --- a/src/cpp/lib/QtWidgets/QDial/qdial_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QDial/qdial_wrap.cpp @@ -16,29 +16,37 @@ Napi::Object QDialWrap::init(Napi::Env env, Napi::Object exports) { {QABSTRACTSLIDER_WRAPPED_METHODS_EXPORT_DEFINE(QDialWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); + QOBJECT_REGISTER_WRAPPER(QDial, QDialWrap); return exports; } -NDial* QDialWrap::getInternalInstance() { return this->instance; } +QDial* QDialWrap::getInternalInstance() { return this->instance; } QDialWrap::QDialWrap(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); - if (info.Length() == 1) { - Napi::Object parentObject = info[0].As(); - NodeWidgetWrap* parentWidgetWrap = - Napi::ObjectWrap::Unwrap(parentObject); - this->instance = new NDial(parentWidgetWrap->getInternalInstance()); - } else if (info.Length() == 0) { + size_t argCount = info.Length(); + if (argCount == 0) { + // --- Construct a new instance this->instance = new NDial(); + } else if (argCount == 1) { + if (info[0].IsExternal()) { + // --- Wrap a given C++ instance + this->instance = info[0].As>().Data(); + } else { + // --- Construct a new instance and pass a parent + Napi::Object parentObject = info[0].As(); + NodeWidgetWrap* parentWidgetWrap = + Napi::ObjectWrap::Unwrap(parentObject); + this->instance = new NDial(parentWidgetWrap->getInternalInstance()); + } } else { - Napi::TypeError::New(env, "Wrong number of arguments") + Napi::TypeError::New( + env, "NodeGui: QDialWrap: Wrong number of arguments to constructor") .ThrowAsJavaScriptException(); } - - this->rawData = extrautils::configureQWidget( - this->getInternalInstance(), this->getInternalInstance()->getFlexNode(), - true); + this->rawData = + extrautils::configureQWidget(this->getInternalInstance(), true); } QDialWrap::~QDialWrap() { extrautils::safeDelete(this->instance); } diff --git a/src/cpp/lib/QtWidgets/QDialog/qdialog_wrap.cpp b/src/cpp/lib/QtWidgets/QDialog/qdialog_wrap.cpp index 0fa9bc0c0..a9faa1e2c 100644 --- a/src/cpp/lib/QtWidgets/QDialog/qdialog_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QDialog/qdialog_wrap.cpp @@ -11,33 +11,37 @@ Napi::Object QDialogWrap::init(Napi::Env env, Napi::Object exports) { env, CLASSNAME, {QDIALOG_WRAPPED_METHODS_EXPORT_DEFINE(QDialogWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); + QOBJECT_REGISTER_WRAPPER(QDialog, QDialogWrap); return exports; } -NDialog *QDialogWrap::getInternalInstance() { return this->instance; } +QDialog *QDialogWrap::getInternalInstance() { return this->instance; } QDialogWrap::~QDialogWrap() { extrautils::safeDelete(this->instance); } QDialogWrap::QDialogWrap(const Napi::CallbackInfo &info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); - if (info.Length() == 1) { + size_t argCount = info.Length(); + if (argCount == 0) { + // --- Construct a new instance + this->instance = new NDialog(); + } else if (argCount == 1) { if (info[0].IsExternal()) { - this->instance = - new NDialog(info[0].As>().Data()); + // --- Wrap a given C++ instance + this->instance = info[0].As>().Data(); } else { + // --- Construct a new instance and pass a parent Napi::Object parentObject = info[0].As(); - QDialogWrap *parentWidgetWrap = - Napi::ObjectWrap::Unwrap(parentObject); + NodeWidgetWrap *parentWidgetWrap = + Napi::ObjectWrap::Unwrap(parentObject); this->instance = new NDialog(parentWidgetWrap->getInternalInstance()); } - } else if (info.Length() == 0) { - this->instance = new NDialog(); } else { - Napi::TypeError::New(env, "Wrong number of arguments") + Napi::TypeError::New( + env, "NodeGui: QDialogWrap: Wrong number of arguments to constructor") .ThrowAsJavaScriptException(); } - this->rawData = extrautils::configureQWidget( - this->getInternalInstance(), this->getInternalInstance()->getFlexNode(), - false); + this->rawData = + extrautils::configureQWidget(this->getInternalInstance(), false); } diff --git a/src/cpp/lib/QtWidgets/QDoubleSpinBox/qdoublespinbox_wrap.cpp b/src/cpp/lib/QtWidgets/QDoubleSpinBox/qdoublespinbox_wrap.cpp index 55a6157c4..b3ab1d073 100644 --- a/src/cpp/lib/QtWidgets/QDoubleSpinBox/qdoublespinbox_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QDoubleSpinBox/qdoublespinbox_wrap.cpp @@ -16,31 +16,41 @@ Napi::Object QDoubleSpinBoxWrap::init(Napi::Env env, Napi::Object exports) { QABSTRACTSPINBOX_WRAPPED_METHODS_EXPORT_DEFINE(QDoubleSpinBoxWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); + QOBJECT_REGISTER_WRAPPER(QDoubleSpinBox, QDoubleSpinBoxWrap); return exports; } -NDoubleSpinBox* QDoubleSpinBoxWrap::getInternalInstance() { +QDoubleSpinBox* QDoubleSpinBoxWrap::getInternalInstance() { return this->instance; } QDoubleSpinBoxWrap::QDoubleSpinBoxWrap(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); - if (info.Length() == 1) { - Napi::Object parentObject = info[0].As(); - NodeWidgetWrap* parentWidgetWrap = - Napi::ObjectWrap::Unwrap(parentObject); - this->instance = - new NDoubleSpinBox(parentWidgetWrap->getInternalInstance()); - } else if (info.Length() == 0) { + size_t argCount = info.Length(); + if (argCount == 0) { + // --- Construct a new instance this->instance = new NDoubleSpinBox(); + } else if (argCount == 1) { + if (info[0].IsExternal()) { + // --- Wrap a given C++ instance + this->instance = info[0].As>().Data(); + } else { + // --- Construct a new instance and pass a parent + Napi::Object parentObject = info[0].As(); + NodeWidgetWrap* parentWidgetWrap = + Napi::ObjectWrap::Unwrap(parentObject); + this->instance = + new NDoubleSpinBox(parentWidgetWrap->getInternalInstance()); + } } else { - Napi::TypeError::New(env, "Wrong number of arguments") + Napi::TypeError::New( + env, + "NodeGui: QDoubleSpinBoxWrap: Wrong number of arguments to constructor") .ThrowAsJavaScriptException(); } - this->rawData = extrautils::configureQWidget( - this->getInternalInstance(), this->getInternalInstance()->getFlexNode(), - true); + this->rawData = + extrautils::configureQWidget(this->getInternalInstance(), true); } QDoubleSpinBoxWrap::~QDoubleSpinBoxWrap() { diff --git a/src/cpp/lib/QtWidgets/QErrorMessage/qerrormessage_wrap.cpp b/src/cpp/lib/QtWidgets/QErrorMessage/qerrormessage_wrap.cpp index 9cbb30cf7..a23f4551b 100644 --- a/src/cpp/lib/QtWidgets/QErrorMessage/qerrormessage_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QErrorMessage/qerrormessage_wrap.cpp @@ -16,10 +16,11 @@ Napi::Object QErrorMessageWrap::init(Napi::Env env, Napi::Object exports) { QDIALOG_WRAPPED_METHODS_EXPORT_DEFINE(QErrorMessageWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); + QOBJECT_REGISTER_WRAPPER(QErrorMessage, QErrorMessageWrap); return exports; } -NErrorMessage* QErrorMessageWrap::getInternalInstance() { +QErrorMessage* QErrorMessageWrap::getInternalInstance() { return this->instance; } @@ -30,21 +31,30 @@ QErrorMessageWrap::~QErrorMessageWrap() { QErrorMessageWrap::QErrorMessageWrap(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); - if (info.Length() == 1) { - Napi::Object parentObject = info[0].As(); - NodeWidgetWrap* parentWidgetWrap = - Napi::ObjectWrap::Unwrap(parentObject); - QWidget* parent = parentWidgetWrap->getInternalInstance(); - this->instance = new NErrorMessage(parent); - } else if (info.Length() == 0) { + size_t argCount = info.Length(); + if (argCount == 0) { + // --- Construct a new instance this->instance = new NErrorMessage(); + } else if (argCount == 1) { + if (info[0].IsExternal()) { + // --- Wrap a given C++ instance + this->instance = info[0].As>().Data(); + } else { + // --- Construct a new instance and pass a parent + Napi::Object parentObject = info[0].As(); + NodeWidgetWrap* parentWidgetWrap = + Napi::ObjectWrap::Unwrap(parentObject); + this->instance = + new NErrorMessage(parentWidgetWrap->getInternalInstance()); + } } else { - Napi::TypeError::New(env, "Wrong number of arguments") + Napi::TypeError::New( + env, + "NodeGui: QErrorMessageWrap: Wrong number of arguments to constructor") .ThrowAsJavaScriptException(); } - this->rawData = extrautils::configureQWidget( - this->getInternalInstance(), this->getInternalInstance()->getFlexNode(), - false); + this->rawData = + extrautils::configureQWidget(this->getInternalInstance(), false); } Napi::Value QErrorMessageWrap::showMessage(const Napi::CallbackInfo& info) { diff --git a/src/cpp/lib/QtWidgets/QFileDialog/qfiledialog_wrap.cpp b/src/cpp/lib/QtWidgets/QFileDialog/qfiledialog_wrap.cpp index c3766f534..f3e38d31a 100644 --- a/src/cpp/lib/QtWidgets/QFileDialog/qfiledialog_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QFileDialog/qfiledialog_wrap.cpp @@ -24,16 +24,19 @@ Napi::Object QFileDialogWrap::init(Napi::Env env, Napi::Object exports) { QDIALOG_WRAPPED_METHODS_EXPORT_DEFINE(QFileDialogWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); + QOBJECT_REGISTER_WRAPPER(QFileDialog, QFileDialogWrap); return exports; } -NFileDialog* QFileDialogWrap::getInternalInstance() { return this->instance; } +QFileDialog* QFileDialogWrap::getInternalInstance() { return this->instance; } + QFileDialogWrap::~QFileDialogWrap() { extrautils::safeDelete(this->instance); } QFileDialogWrap::QFileDialogWrap(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); - if (info.Length() == 4) { + size_t argCount = info.Length(); + if (argCount == 4) { Napi::Object parentObject = info[0].As(); NodeWidgetWrap* parentWidgetWrap = Napi::ObjectWrap::Unwrap(parentObject); @@ -45,15 +48,15 @@ QFileDialogWrap::QFileDialogWrap(const Napi::CallbackInfo& info) QString filter = QString::fromUtf8(info[3].As().Utf8Value().c_str()); this->instance = new NFileDialog(parent, caption, directory, filter); - } else if (info.Length() == 0) { + } else if (argCount == 0) { this->instance = new NFileDialog(); } else { - Napi::TypeError::New(env, "Wrong number of arguments") + Napi::TypeError::New(env, + "NodeGui: QFileDialogWrap: Wrong number of arguments") .ThrowAsJavaScriptException(); } - this->rawData = extrautils::configureQWidget( - this->getInternalInstance(), this->getInternalInstance()->getFlexNode(), - false); + this->rawData = + extrautils::configureQWidget(this->getInternalInstance(), false); } Napi::Value QFileDialogWrap::supportedSchemes(const Napi::CallbackInfo& info) { diff --git a/src/cpp/lib/QtWidgets/QFontDialog/qfontdialog_wrap.cpp b/src/cpp/lib/QtWidgets/QFontDialog/qfontdialog_wrap.cpp index 5194c9f15..bec840ae8 100644 --- a/src/cpp/lib/QtWidgets/QFontDialog/qfontdialog_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QFontDialog/qfontdialog_wrap.cpp @@ -18,31 +18,40 @@ Napi::Object QFontDialogWrap::init(Napi::Env env, Napi::Object exports) { QDIALOG_WRAPPED_METHODS_EXPORT_DEFINE(QFontDialogWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); + QOBJECT_REGISTER_WRAPPER(QFontDialog, QFontDialogWrap); return exports; } -NFontDialog* QFontDialogWrap::getInternalInstance() { return this->instance; } +QFontDialog* QFontDialogWrap::getInternalInstance() { return this->instance; } QFontDialogWrap::~QFontDialogWrap() { extrautils::safeDelete(this->instance); } QFontDialogWrap::QFontDialogWrap(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); - if (info.Length() == 1) { - Napi::Object parentObject = info[0].As(); - NodeWidgetWrap* parentWidgetWrap = - Napi::ObjectWrap::Unwrap(parentObject); - QWidget* parent = parentWidgetWrap->getInternalInstance(); - this->instance = new NFontDialog(parent); - } else if (info.Length() == 0) { + size_t argCount = info.Length(); + if (argCount == 0) { + // --- Construct a new instance this->instance = new NFontDialog(); + } else if (argCount == 1) { + if (info[0].IsExternal()) { + // --- Wrap a given C++ instance + this->instance = info[0].As>().Data(); + } else { + // --- Construct a new instance and pass a parent + Napi::Object parentObject = info[0].As(); + NodeWidgetWrap* parentWidgetWrap = + Napi::ObjectWrap::Unwrap(parentObject); + this->instance = new NFontDialog(parentWidgetWrap->getInternalInstance()); + } } else { - Napi::TypeError::New(env, "Wrong number of arguments") + Napi::TypeError::New( + env, + "NodeGui: QFontDialogWrap: Wrong number of arguments to constructor") .ThrowAsJavaScriptException(); } - this->rawData = extrautils::configureQWidget( - this->getInternalInstance(), this->getInternalInstance()->getFlexNode(), - false); + this->rawData = + extrautils::configureQWidget(this->getInternalInstance(), false); } Napi::Value QFontDialogWrap::selectedFont(const Napi::CallbackInfo& info) { diff --git a/src/cpp/lib/QtWidgets/QFrame/qframe_wrap.cpp b/src/cpp/lib/QtWidgets/QFrame/qframe_wrap.cpp index cb337b2a1..c32441204 100644 --- a/src/cpp/lib/QtWidgets/QFrame/qframe_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QFrame/qframe_wrap.cpp @@ -11,28 +11,37 @@ Napi::Object QFrameWrap::init(Napi::Env env, Napi::Object exports) { env, CLASSNAME, {QFRAME_WRAPPED_METHODS_EXPORT_DEFINE(QFrameWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); + QOBJECT_REGISTER_WRAPPER(QFrame, QFrameWrap); return exports; } -NFrame* QFrameWrap::getInternalInstance() { return this->instance; } +QFrame* QFrameWrap::getInternalInstance() { return this->instance; } QFrameWrap::~QFrameWrap() { extrautils::safeDelete(this->instance); } QFrameWrap::QFrameWrap(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); - if (info.Length() == 1) { - Napi::Object parentObject = info[0].As(); - NodeWidgetWrap* parentWidgetWrap = - Napi::ObjectWrap::Unwrap(parentObject); - this->instance = new NFrame(parentWidgetWrap->getInternalInstance()); - } else if (info.Length() == 0) { + size_t argCount = info.Length(); + if (argCount == 0) { + // --- Construct a new instance this->instance = new NFrame(); + } else if (argCount == 1) { + if (info[0].IsExternal()) { + // --- Wrap a given C++ instance + this->instance = info[0].As>().Data(); + } else { + // --- Construct a new instance and pass a parent + Napi::Object parentObject = info[0].As(); + NodeWidgetWrap* parentWidgetWrap = + Napi::ObjectWrap::Unwrap(parentObject); + this->instance = new NFrame(parentWidgetWrap->getInternalInstance()); + } } else { - Napi::TypeError::New(env, "Wrong number of arguments") + Napi::TypeError::New( + env, "NodeGui: QFrameWrap: Wrong number of arguments to constructor") .ThrowAsJavaScriptException(); } - this->rawData = extrautils::configureQWidget( - this->getInternalInstance(), this->getInternalInstance()->getFlexNode(), - false); + this->rawData = + extrautils::configureQWidget(this->getInternalInstance(), false); } diff --git a/src/cpp/lib/QtWidgets/QGraphicsBlurEffect/qgraphicsblureffect_wrap.cpp b/src/cpp/lib/QtWidgets/QGraphicsBlurEffect/qgraphicsblureffect_wrap.cpp index 0786be2a5..12d8e719a 100644 --- a/src/cpp/lib/QtWidgets/QGraphicsBlurEffect/qgraphicsblureffect_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QGraphicsBlurEffect/qgraphicsblureffect_wrap.cpp @@ -2,6 +2,7 @@ #include "Extras/Utils/nutils.h" #include "QtCore/QObject/qobject_wrap.h" +#include "QtWidgets/QWidget/qwidget_wrap.h" Napi::FunctionReference QGraphicsBlurEffectWrap::constructor; @@ -14,10 +15,11 @@ Napi::Object QGraphicsBlurEffectWrap::init(Napi::Env env, {QGRAPHICSEFFECT_WRAPPED_METHODS_EXPORT_DEFINE(QGraphicsBlurEffectWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); + QOBJECT_REGISTER_WRAPPER(QGraphicsBlurEffect, QGraphicsBlurEffectWrap); return exports; } -NGraphicsBlurEffect* QGraphicsBlurEffectWrap::getInternalInstance() { +QGraphicsBlurEffect* QGraphicsBlurEffectWrap::getInternalInstance() { return this->instance; } @@ -28,16 +30,26 @@ QGraphicsBlurEffectWrap::~QGraphicsBlurEffectWrap() { QGraphicsBlurEffectWrap::QGraphicsBlurEffectWrap(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); - if (info.Length() == 1) { - Napi::Object parentObject = info[0].As(); - QObjectWrap* parentObjectWrap = - Napi::ObjectWrap::Unwrap(parentObject); - this->instance = - new NGraphicsBlurEffect(parentObjectWrap->getInternalInstance()); - } else if (info.Length() == 0) { + size_t argCount = info.Length(); + if (argCount == 0) { + // --- Construct a new instance this->instance = new NGraphicsBlurEffect(); + } else if (argCount == 1) { + if (info[0].IsExternal()) { + // --- Wrap a given C++ instance + this->instance = info[0].As>().Data(); + } else { + // --- Construct a new instance and pass a parent + Napi::Object parentObject = info[0].As(); + NodeWidgetWrap* parentWidgetWrap = + Napi::ObjectWrap::Unwrap(parentObject); + this->instance = + new NGraphicsBlurEffect(parentWidgetWrap->getInternalInstance()); + } } else { - Napi::TypeError::New(env, "Wrong number of arguments") + Napi::TypeError::New(env, + "NodeGui: QGraphicsBlurEffectWrap: Wrong number of " + "arguments to constructor") .ThrowAsJavaScriptException(); } this->rawData = extrautils::configureQObject(this->getInternalInstance()); diff --git a/src/cpp/lib/QtWidgets/QGraphicsDropShadowEffect/qgraphicsdropshadoweffect_wrap.cpp b/src/cpp/lib/QtWidgets/QGraphicsDropShadowEffect/qgraphicsdropshadoweffect_wrap.cpp index 51e3bd093..b7e9ebb0c 100644 --- a/src/cpp/lib/QtWidgets/QGraphicsDropShadowEffect/qgraphicsdropshadoweffect_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QGraphicsDropShadowEffect/qgraphicsdropshadoweffect_wrap.cpp @@ -2,6 +2,7 @@ #include "Extras/Utils/nutils.h" #include "QtCore/QObject/qobject_wrap.h" +#include "QtWidgets/QWidget/qwidget_wrap.h" Napi::FunctionReference QGraphicsDropShadowEffectWrap::constructor; @@ -15,10 +16,12 @@ Napi::Object QGraphicsDropShadowEffectWrap::init(Napi::Env env, QGraphicsDropShadowEffectWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); + QOBJECT_REGISTER_WRAPPER(QGraphicsDropShadowEffect, + QGraphicsDropShadowEffectWrap); return exports; } -NGraphicsDropShadowEffect* +QGraphicsDropShadowEffect* QGraphicsDropShadowEffectWrap::getInternalInstance() { return this->instance; } @@ -31,16 +34,28 @@ QGraphicsDropShadowEffectWrap::QGraphicsDropShadowEffectWrap( const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); - if (info.Length() == 1) { - Napi::Object parentObject = info[0].As(); - QObjectWrap* parentObjectWrap = - Napi::ObjectWrap::Unwrap(parentObject); - this->instance = - new NGraphicsDropShadowEffect(parentObjectWrap->getInternalInstance()); - } else if (info.Length() == 0) { + size_t argCount = info.Length(); + if (argCount == 0) { + // --- Construct a new instance this->instance = new NGraphicsDropShadowEffect(); + } else if (argCount == 1) { + if (info[0].IsExternal()) { + // --- Wrap a given C++ instance + this->instance = + info[0].As>().Data(); + } else { + // --- Construct a new instance and pass a parent + Napi::Object parentObject = info[0].As(); + NodeWidgetWrap* parentWidgetWrap = + Napi::ObjectWrap::Unwrap(parentObject); + this->instance = new NGraphicsDropShadowEffect( + parentWidgetWrap->getInternalInstance()); + } } else { - Napi::TypeError::New(env, "Wrong number of arguments") + Napi::TypeError::New( + env, + "NodeGui: QGraphicsDropShadowEffectWrap: Wrong number of " + "arguments to constructor") .ThrowAsJavaScriptException(); } this->rawData = extrautils::configureQObject(this->getInternalInstance()); diff --git a/src/cpp/lib/QtWidgets/QGridLayout/qgridlayout_wrap.cpp b/src/cpp/lib/QtWidgets/QGridLayout/qgridlayout_wrap.cpp index de09979fc..7786f61d3 100644 --- a/src/cpp/lib/QtWidgets/QGridLayout/qgridlayout_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QGridLayout/qgridlayout_wrap.cpp @@ -35,24 +35,36 @@ Napi::Object QGridLayoutWrap::init(Napi::Env env, Napi::Object exports) { QLAYOUT_WRAPPED_METHODS_EXPORT_DEFINE(QGridLayoutWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); + QOBJECT_REGISTER_WRAPPER(QGridLayout, QGridLayoutWrap); return exports; } -NGridLayout* QGridLayoutWrap::getInternalInstance() { return this->instance; } +QGridLayout* QGridLayoutWrap::getInternalInstance() { return this->instance; } + QGridLayoutWrap::~QGridLayoutWrap() { extrautils::safeDelete(this->instance); } QGridLayoutWrap::QGridLayoutWrap(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); - if (info.Length() == 1) { - Napi::Object parentObject = info[0].As(); - NodeWidgetWrap* parentWidgetWrap = - Napi::ObjectWrap::Unwrap(parentObject); - this->instance = new NGridLayout(parentWidgetWrap->getInternalInstance()); - } else if (info.Length() == 0) { + size_t argCount = info.Length(); + if (argCount == 0) { + // --- Construct a new instance this->instance = new NGridLayout(); + } else if (argCount == 1) { + if (info[0].IsExternal()) { + // --- Wrap a given C++ instance + this->instance = info[0].As>().Data(); + } else { + // --- Construct a new instance and pass a parent + Napi::Object parentObject = info[0].As(); + NodeWidgetWrap* parentWidgetWrap = + Napi::ObjectWrap::Unwrap(parentObject); + this->instance = new NGridLayout(parentWidgetWrap->getInternalInstance()); + } } else { - Napi::TypeError::New(env, "Wrong number of arguments") + Napi::TypeError::New( + env, + "NodeGui: QGridLayoutWrap: Wrong number of arguments to constructor") .ThrowAsJavaScriptException(); } this->rawData = extrautils::configureQObject(this->getInternalInstance()); diff --git a/src/cpp/lib/QtWidgets/QGroupBox/qgroupbox_wrap.cpp b/src/cpp/lib/QtWidgets/QGroupBox/qgroupbox_wrap.cpp index 2b90ed7ba..34bd58850 100644 --- a/src/cpp/lib/QtWidgets/QGroupBox/qgroupbox_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QGroupBox/qgroupbox_wrap.cpp @@ -13,29 +13,38 @@ Napi::Object QGroupBoxWrap::init(Napi::Env env, Napi::Object exports) { Napi::Function func = DefineClass( env, CLASSNAME, {QWIDGET_WRAPPED_METHODS_EXPORT_DEFINE(QGroupBoxWrap)}); constructor = Napi::Persistent(func); + QOBJECT_REGISTER_WRAPPER(QGroupBox, QGroupBoxWrap); exports.Set(CLASSNAME, func); return exports; } -NGroupBox* QGroupBoxWrap::getInternalInstance() { return this->instance; } +QGroupBox* QGroupBoxWrap::getInternalInstance() { return this->instance; } QGroupBoxWrap::QGroupBoxWrap(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); - if (info.Length() == 1) { - Napi::Object parentObject = info[0].As(); - NodeWidgetWrap* parentWidgetWrap = - Napi::ObjectWrap::Unwrap(parentObject); - this->instance = new NGroupBox(parentWidgetWrap->getInternalInstance()); - } else if (info.Length() == 0) { + size_t argCount = info.Length(); + if (argCount == 0) { + // --- Construct a new instance this->instance = new NGroupBox(); + } else if (argCount == 1) { + if (info[0].IsExternal()) { + // --- Wrap a given C++ instance + this->instance = info[0].As>().Data(); + } else { + // --- Construct a new instance and pass a parent + Napi::Object parentObject = info[0].As(); + NodeWidgetWrap* parentWidgetWrap = + Napi::ObjectWrap::Unwrap(parentObject); + this->instance = new NGroupBox(parentWidgetWrap->getInternalInstance()); + } } else { - Napi::TypeError::New(env, "Wrong number of arguments") + Napi::TypeError::New( + env, "NodeGui: QGroupBoxWrap: Wrong number of arguments to constructor") .ThrowAsJavaScriptException(); } - this->rawData = extrautils::configureQWidget( - this->getInternalInstance(), this->getInternalInstance()->getFlexNode(), - false); + this->rawData = + extrautils::configureQWidget(this->getInternalInstance(), false); } QGroupBoxWrap::~QGroupBoxWrap() { extrautils::safeDelete(this->instance); } diff --git a/src/cpp/lib/QtWidgets/QHeaderView/qheaderview_wrap.cpp b/src/cpp/lib/QtWidgets/QHeaderView/qheaderview_wrap.cpp index 3bc9ef2d9..d9333fd05 100644 --- a/src/cpp/lib/QtWidgets/QHeaderView/qheaderview_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QHeaderView/qheaderview_wrap.cpp @@ -111,27 +111,21 @@ Napi::Object QHeaderViewWrap::init(Napi::Env env, Napi::Object exports) { }); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); + QOBJECT_REGISTER_WRAPPER(QHeaderView, QHeaderViewWrap); return exports; } QHeaderView* QHeaderViewWrap::getInternalInstance() { return this->instance; } -QHeaderViewWrap::~QHeaderViewWrap() { - if (!this->disableDeletion) { - extrautils::safeDelete(this->instance); - } -} +QHeaderViewWrap::~QHeaderViewWrap() { extrautils::safeDelete(this->instance); } QHeaderViewWrap::QHeaderViewWrap(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); - size_t len = info.Length(); - - this->disableDeletion = false; - if (len == 1) { + size_t argCount = info.Length(); + if (argCount == 1) { if (info[0].IsExternal()) { this->instance = info[0].As>().Data(); - this->disableDeletion = true; } else { int orientation = info[0].As().Int32Value(); this->instance = @@ -152,8 +146,8 @@ QHeaderViewWrap::QHeaderViewWrap(const Napi::CallbackInfo& info) this->rawData = nullptr; FlexItem* item = dynamic_cast(this->getInternalInstance()); if (item) { - this->rawData = extrautils::configureQWidget(this->getInternalInstance(), - item->getFlexNode(), false); + this->rawData = + extrautils::configureQWidget(this->getInternalInstance(), false); } } diff --git a/src/cpp/lib/QtWidgets/QInputDialog/qinputdialog_wrap.cpp b/src/cpp/lib/QtWidgets/QInputDialog/qinputdialog_wrap.cpp index cdeec107d..0cc838c6d 100644 --- a/src/cpp/lib/QtWidgets/QInputDialog/qinputdialog_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QInputDialog/qinputdialog_wrap.cpp @@ -56,10 +56,12 @@ Napi::Object QInputDialogWrap::init(Napi::Env env, Napi::Object exports) { QDIALOG_WRAPPED_METHODS_EXPORT_DEFINE(QInputDialogWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); + QOBJECT_REGISTER_WRAPPER(QInputDialog, QInputDialogWrap); return exports; } -NInputDialog* QInputDialogWrap::getInternalInstance() { return this->instance; } +QInputDialog* QInputDialogWrap::getInternalInstance() { return this->instance; } + QInputDialogWrap::~QInputDialogWrap() { extrautils::safeDelete(this->instance); } @@ -67,20 +69,30 @@ QInputDialogWrap::~QInputDialogWrap() { QInputDialogWrap::QInputDialogWrap(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); - if (info.Length() == 1) { - Napi::Object parentObject = info[0].As(); - NodeWidgetWrap* parentWidgetWrap = - Napi::ObjectWrap::Unwrap(parentObject); - this->instance = new NInputDialog(parentWidgetWrap->getInternalInstance()); - } else if (info.Length() == 0) { + size_t argCount = info.Length(); + if (argCount == 0) { + // --- Construct a new instance this->instance = new NInputDialog(); + } else if (argCount == 1) { + if (info[0].IsExternal()) { + // --- Wrap a given C++ instance + this->instance = info[0].As>().Data(); + } else { + // --- Construct a new instance and pass a parent + Napi::Object parentObject = info[0].As(); + NodeWidgetWrap* parentWidgetWrap = + Napi::ObjectWrap::Unwrap(parentObject); + this->instance = + new NInputDialog(parentWidgetWrap->getInternalInstance()); + } } else { - Napi::TypeError::New(env, "Wrong number of arguments") + Napi::TypeError::New( + env, + "NodeGui: QInputDialogWrap: Wrong number of arguments to constructor") .ThrowAsJavaScriptException(); } - this->rawData = extrautils::configureQWidget( - this->getInternalInstance(), this->getInternalInstance()->getFlexNode(), - false); + this->rawData = + extrautils::configureQWidget(this->getInternalInstance(), false); } Napi::Value QInputDialogWrap::setCancelButtonText( diff --git a/src/cpp/lib/QtWidgets/QLCDNumber/qlcdnumber_wrap.cpp b/src/cpp/lib/QtWidgets/QLCDNumber/qlcdnumber_wrap.cpp index 33241d646..99f790cf5 100644 --- a/src/cpp/lib/QtWidgets/QLCDNumber/qlcdnumber_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QLCDNumber/qlcdnumber_wrap.cpp @@ -20,31 +20,41 @@ Napi::Object QLCDNumberWrap::init(Napi::Env env, Napi::Object exports) { InstanceMethod("setOctMode", &QLCDNumberWrap::setOctMode), QWIDGET_WRAPPED_METHODS_EXPORT_DEFINE(QLCDNumberWrap)}); constructor = Napi::Persistent(func); + QOBJECT_REGISTER_WRAPPER(QLCDNumber, QLCDNumberWrap); exports.Set(CLASSNAME, func); return exports; } -NLCDNumber* QLCDNumberWrap::getInternalInstance() { return this->instance; } +QLCDNumber* QLCDNumberWrap::getInternalInstance() { return this->instance; } QLCDNumberWrap::~QLCDNumberWrap() { extrautils::safeDelete(this->instance); } QLCDNumberWrap::QLCDNumberWrap(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); - if (info.Length() == 1) { - Napi::Object parentObject = info[0].As(); - NodeWidgetWrap* parentWidgetWrap = - Napi::ObjectWrap::Unwrap(parentObject); - this->instance = new NLCDNumber(parentWidgetWrap->getInternalInstance()); - } else if (info.Length() == 0) { + size_t argCount = info.Length(); + if (argCount == 0) { + // --- Construct a new instance this->instance = new NLCDNumber(); + } else if (argCount == 1) { + if (info[0].IsExternal()) { + // --- Wrap a given C++ instance + this->instance = info[0].As>().Data(); + } else { + // --- Construct a new instance and pass a parent + Napi::Object parentObject = info[0].As(); + NodeWidgetWrap* parentWidgetWrap = + Napi::ObjectWrap::Unwrap(parentObject); + this->instance = new NLCDNumber(parentWidgetWrap->getInternalInstance()); + } } else { - Napi::TypeError::New(env, "Wrong number of arguments") + Napi::TypeError::New( + env, + "NodeGui: QLCDNumberWrap: Wrong number of arguments to constructor") .ThrowAsJavaScriptException(); } - this->rawData = extrautils::configureQWidget( - this->getInternalInstance(), this->getInternalInstance()->getFlexNode(), - true); + this->rawData = + extrautils::configureQWidget(this->getInternalInstance(), true); } Napi::Value QLCDNumberWrap::checkOverflow(const Napi::CallbackInfo& info) { diff --git a/src/cpp/lib/QtWidgets/QLabel/qlabel_wrap.cpp b/src/cpp/lib/QtWidgets/QLabel/qlabel_wrap.cpp index 59f614084..65b4298b3 100644 --- a/src/cpp/lib/QtWidgets/QLabel/qlabel_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QLabel/qlabel_wrap.cpp @@ -27,31 +27,46 @@ Napi::Object QLabelWrap::init(Napi::Env env, Napi::Object exports) { QFRAME_WRAPPED_METHODS_EXPORT_DEFINE(QLabelWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); + QOBJECT_REGISTER_WRAPPER(QLabel, QLabelWrap); return exports; } -NLabel* QLabelWrap::getInternalInstance() { return this->instance; } +QLabel* QLabelWrap::getInternalInstance() { return this->instance; } QLabelWrap::~QLabelWrap() { extrautils::safeDelete(this->instance); } QLabelWrap::QLabelWrap(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); - if (info.Length() == 1) { - Napi::Object parentObject = info[0].As(); - NodeWidgetWrap* parentWidgetWrap = - Napi::ObjectWrap::Unwrap(parentObject); - this->instance = new NLabel(parentWidgetWrap->getInternalInstance()); - } else if (info.Length() == 0) { + size_t argCount = info.Length(); + if (argCount == 0) { + // --- Construct a new instance this->instance = new NLabel(); + } else if (argCount == 1) { + if (info[0].IsExternal()) { + // --- Wrap a given C++ instance + this->instance = info[0].As>().Data(); + } else { + // --- Construct a new instance and pass a parent + Napi::Object parentObject = info[0].As(); + NodeWidgetWrap* parentWidgetWrap = + Napi::ObjectWrap::Unwrap(parentObject); + this->instance = new NLabel(parentWidgetWrap->getInternalInstance()); + } } else { - Napi::TypeError::New(env, "Wrong number of arguments") + Napi::TypeError::New( + env, "NodeGui: QLabelWrap: Wrong number of arguments to constructor") .ThrowAsJavaScriptException(); } - auto flexNode = this->getInternalInstance()->getFlexNode(); - YGNodeSetNodeType(flexNode, YGNodeType::YGNodeTypeText); + + YogaWidget* yogaWidget = + dynamic_cast(this->getInternalInstance()); + if (yogaWidget) { + auto flexNode = yogaWidget->getFlexNode(); + YGNodeSetNodeType(flexNode, YGNodeType::YGNodeTypeText); + } this->rawData = - extrautils::configureQWidget(this->getInternalInstance(), flexNode, true); + extrautils::configureQWidget(this->getInternalInstance(), true); } Napi::Value QLabelWrap::setSelection(const Napi::CallbackInfo& info) { diff --git a/src/cpp/lib/QtWidgets/QLayout/qlayout_wrap.cpp b/src/cpp/lib/QtWidgets/QLayout/qlayout_wrap.cpp index 8d616e135..97f35af4e 100644 --- a/src/cpp/lib/QtWidgets/QLayout/qlayout_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QLayout/qlayout_wrap.cpp @@ -3,16 +3,29 @@ #include "Extras/Utils/nutils.h" Napi::FunctionReference QLayoutWrap::constructor; -void QLayoutWrap::init(Napi::Env env) { +void QLayoutWrap::init(Napi::Env env, Napi::Object exports) { char CLASSNAME[] = "QLayout"; Napi::Function func = DefineClass( env, CLASSNAME, {QLAYOUT_WRAPPED_METHODS_EXPORT_DEFINE(QLayoutWrap)}); constructor = Napi::Persistent(func); + exports.Set(CLASSNAME, func); + QOBJECT_REGISTER_WRAPPER(QLayout, QLayoutWrap); } -NLayout* QLayoutWrap::getInternalInstance() { return this->instance; } +QLayout* QLayoutWrap::getInternalInstance() { return this->instance; } QLayoutWrap::QLayoutWrap(const Napi::CallbackInfo& info) - : Napi::ObjectWrap(info) {} + : Napi::ObjectWrap(info) { + Napi::Env env = info.Env(); + size_t argCount = info.Length(); + if (argCount == 1 && info[0].IsExternal()) { + // --- Wrap a given C++ instance + this->instance = info[0].As>().Data(); + } else { + Napi::TypeError::New(env, "NodeGui: QLayoutWrap: Wrong number of arguments") + .ThrowAsJavaScriptException(); + } + this->rawData = extrautils::configureQObject(this->getInternalInstance()); +} QLayoutWrap::~QLayoutWrap() { extrautils::safeDelete(this->instance); } diff --git a/src/cpp/lib/QtWidgets/QLineEdit/qlineedit_wrap.cpp b/src/cpp/lib/QtWidgets/QLineEdit/qlineedit_wrap.cpp index 4581a5f6b..56eb00382 100644 --- a/src/cpp/lib/QtWidgets/QLineEdit/qlineedit_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QLineEdit/qlineedit_wrap.cpp @@ -40,28 +40,37 @@ Napi::Object QLineEditWrap::init(Napi::Env env, Napi::Object exports) { QWIDGET_WRAPPED_METHODS_EXPORT_DEFINE(QLineEditWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); + QOBJECT_REGISTER_WRAPPER(QLineEdit, QLineEditWrap); return exports; } -NLineEdit* QLineEditWrap::getInternalInstance() { return this->instance; } +QLineEdit* QLineEditWrap::getInternalInstance() { return this->instance; } QLineEditWrap::QLineEditWrap(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); - if (info.Length() == 1) { - Napi::Object parentObject = info[0].As(); - NodeWidgetWrap* parentWidgetWrap = - Napi::ObjectWrap::Unwrap(parentObject); - this->instance = new NLineEdit(parentWidgetWrap->getInternalInstance()); - } else if (info.Length() == 0) { + size_t argCount = info.Length(); + if (argCount == 0) { + // --- Construct a new instance this->instance = new NLineEdit(); + } else if (argCount == 1) { + if (info[0].IsExternal()) { + // --- Wrap a given C++ instance + this->instance = info[0].As>().Data(); + } else { + // --- Construct a new instance and pass a parent + Napi::Object parentObject = info[0].As(); + NodeWidgetWrap* parentWidgetWrap = + Napi::ObjectWrap::Unwrap(parentObject); + this->instance = new NLineEdit(parentWidgetWrap->getInternalInstance()); + } } else { - Napi::TypeError::New(env, "Wrong number of arguments") + Napi::TypeError::New( + env, "NodeGui: QLineEditWrap: Wrong number of arguments to constructor") .ThrowAsJavaScriptException(); } - this->rawData = extrautils::configureQWidget( - this->getInternalInstance(), this->getInternalInstance()->getFlexNode(), - true); + this->rawData = + extrautils::configureQWidget(this->getInternalInstance(), true); } QLineEditWrap::~QLineEditWrap() { extrautils::safeDelete(this->instance); } diff --git a/src/cpp/lib/QtWidgets/QListView/qlistview_wrap.cpp b/src/cpp/lib/QtWidgets/QListView/qlistview_wrap.cpp index c253f28ae..cedc6f575 100644 --- a/src/cpp/lib/QtWidgets/QListView/qlistview_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QListView/qlistview_wrap.cpp @@ -11,42 +11,38 @@ Napi::Object QListViewWrap::init(Napi::Env env, Napi::Object exports) { env, CLASSNAME, {QLISTVIEW_WRAPPED_METHODS_EXPORT_DEFINE(QListViewWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); + QOBJECT_REGISTER_WRAPPER(QListView, QListViewWrap); return exports; } -NListView* QListViewWrap::getInternalInstance() { return this->instance; } +QListView* QListViewWrap::getInternalInstance() { return this->instance; } -QListViewWrap::~QListViewWrap() { - if (!this->disableDeletion) { - extrautils::safeDelete(this->instance); - } -} +QListViewWrap::~QListViewWrap() { extrautils::safeDelete(this->instance); } QListViewWrap::QListViewWrap(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); - this->disableDeletion = false; - if (info.Length() > 0 && info[0].IsExternal()) { - // --- if external --- - this->instance = info[0].As>().Data(); - if (info.Length() == 2) { - this->disableDeletion = info[1].As().Value(); - } - } else { - // --- regular cases --- - if (info.Length() == 1) { + + size_t argCount = info.Length(); + if (argCount == 0) { + // --- Construct a new instance + this->instance = new NListView(); + } else if (argCount == 1) { + if (info[0].IsExternal()) { + // --- Wrap a given C++ instance + this->instance = info[0].As>().Data(); + } else { + // --- Construct a new instance and pass a parent Napi::Object parentObject = info[0].As(); NodeWidgetWrap* parentWidgetWrap = Napi::ObjectWrap::Unwrap(parentObject); this->instance = new NListView(parentWidgetWrap->getInternalInstance()); - } else if (info.Length() == 0) { - this->instance = new NListView(); - } else { - Napi::TypeError::New(env, "Wrong number of arguments") - .ThrowAsJavaScriptException(); } + } else { + Napi::TypeError::New( + env, "NodeGui: QListViewWrap: Wrong number of arguments to constructor") + .ThrowAsJavaScriptException(); } - this->rawData = extrautils::configureQWidget( - this->getInternalInstance(), this->getInternalInstance()->getFlexNode(), - true); + this->rawData = + extrautils::configureQWidget(this->getInternalInstance(), true); } diff --git a/src/cpp/lib/QtWidgets/QListWidget/qlistwidget_wrap.cpp b/src/cpp/lib/QtWidgets/QListWidget/qlistwidget_wrap.cpp index dbed200be..b2a003c7c 100644 --- a/src/cpp/lib/QtWidgets/QListWidget/qlistwidget_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QListWidget/qlistwidget_wrap.cpp @@ -41,30 +41,40 @@ Napi::Object QListWidgetWrap::init(Napi::Env env, Napi::Object exports) { QLISTVIEW_WRAPPED_METHODS_EXPORT_DEFINE(QListWidgetWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); + QOBJECT_REGISTER_WRAPPER(QListWidget, QListWidgetWrap); return exports; } -NListWidget* QListWidgetWrap::getInternalInstance() { return this->instance; } +QListWidget* QListWidgetWrap::getInternalInstance() { return this->instance; } QListWidgetWrap::~QListWidgetWrap() { extrautils::safeDelete(this->instance); } QListWidgetWrap::QListWidgetWrap(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); - if (info.Length() == 1) { - Napi::Object parentObject = info[0].As(); - NodeWidgetWrap* parentWidgetWrap = - Napi::ObjectWrap::Unwrap(parentObject); - this->instance = new NListWidget(parentWidgetWrap->getInternalInstance()); - } else if (info.Length() == 0) { + size_t argCount = info.Length(); + if (argCount == 0) { + // --- Construct a new instance this->instance = new NListWidget(); + } else if (argCount == 1) { + if (info[0].IsExternal()) { + // --- Wrap a given C++ instance + this->instance = info[0].As>().Data(); + } else { + // --- Construct a new instance and pass a parent + Napi::Object parentObject = info[0].As(); + NodeWidgetWrap* parentWidgetWrap = + Napi::ObjectWrap::Unwrap(parentObject); + this->instance = new NListWidget(parentWidgetWrap->getInternalInstance()); + } } else { - Napi::TypeError::New(env, "Wrong number of arguments") + Napi::TypeError::New( + env, + "NodeGui: QListWidgetWrap: Wrong number of arguments to constructor") .ThrowAsJavaScriptException(); } - this->rawData = extrautils::configureQWidget( - this->getInternalInstance(), this->getInternalInstance()->getFlexNode(), - true); + this->rawData = + extrautils::configureQWidget(this->getInternalInstance(), true); } Napi::Value QListWidgetWrap::addItem(const Napi::CallbackInfo& info) { diff --git a/src/cpp/lib/QtWidgets/QListWidgetItem/qlistwidgetitem_wrap.cpp b/src/cpp/lib/QtWidgets/QListWidgetItem/qlistwidgetitem_wrap.cpp index cb8299258..27038fb68 100644 --- a/src/cpp/lib/QtWidgets/QListWidgetItem/qlistwidgetitem_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QListWidgetItem/qlistwidgetitem_wrap.cpp @@ -67,22 +67,24 @@ QListWidgetItemWrap::QListWidgetItemWrap(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); this->disableDeletion = false; - if (info.Length() > 0 && info[0].IsExternal()) { + size_t argCount = info.Length(); + if (argCount > 0 && info[0].IsExternal()) { // --- if external --- this->instance = info[0].As>().Data(); - if (info.Length() == 2) { + if (argCount == 2) { this->disableDeletion = info[1].As().Value(); } } else { // --- regular cases --- - if (info.Length() == 1) { + if (argCount == 1) { QString text = QString::fromUtf8(info[0].As().Utf8Value().c_str()); this->instance = new QListWidgetItem(text); - } else if (info.Length() == 0) { + } else if (argCount == 0) { this->instance = new QListWidgetItem(); } else { - Napi::TypeError::New(env, "Wrong number of arguments") + Napi::TypeError::New( + env, "NodeGui: QListWidgetItemWrap: Wrong number of arguments") .ThrowAsJavaScriptException(); } } diff --git a/src/cpp/lib/QtWidgets/QMainWindow/qmainwindow_wrap.cpp b/src/cpp/lib/QtWidgets/QMainWindow/qmainwindow_wrap.cpp index 677507be7..a5639273a 100644 --- a/src/cpp/lib/QtWidgets/QMainWindow/qmainwindow_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QMainWindow/qmainwindow_wrap.cpp @@ -27,29 +27,39 @@ Napi::Object QMainWindowWrap::init(Napi::Env env, Napi::Object exports) { }); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); + QOBJECT_REGISTER_WRAPPER(QMainWindow, QMainWindowWrap); return exports; } -NMainWindow* QMainWindowWrap::getInternalInstance() { return this->instance; } +QMainWindow* QMainWindowWrap::getInternalInstance() { return this->instance; } QMainWindowWrap::~QMainWindowWrap() { extrautils::safeDelete(this->instance); } QMainWindowWrap::QMainWindowWrap(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); - if (info.Length() == 1) { - Napi::Object parentObject = info[0].As(); - NodeWidgetWrap* parentWidgetWrap = - Napi::ObjectWrap::Unwrap(parentObject); - this->instance = new NMainWindow(parentWidgetWrap->getInternalInstance()); - } else if (info.Length() == 0) { + + size_t argCount = info.Length(); + if (argCount == 0) { + // --- Construct a new instance this->instance = new NMainWindow(); + } else if (argCount == 1) { + if (info[0].IsExternal()) { + // --- Wrap a given C++ instance + this->instance = info[0].As>().Data(); + } else { + Napi::Object parentObject = info[0].As(); + NodeWidgetWrap* parentWidgetWrap = + Napi::ObjectWrap::Unwrap(parentObject); + this->instance = new NMainWindow(parentWidgetWrap->getInternalInstance()); + } } else { - Napi::TypeError::New(env, "Wrong number of arguments") + Napi::TypeError::New( + env, + "NodeGui: QMainWindowWrap: Wrong number of arguments to constructor") .ThrowAsJavaScriptException(); } - this->rawData = extrautils::configureQWidget( - this->getInternalInstance(), this->getInternalInstance()->getFlexNode()); + this->rawData = extrautils::configureQWidget(this->getInternalInstance()); } Napi::Value QMainWindowWrap::setCentralWidget(const Napi::CallbackInfo& info) { diff --git a/src/cpp/lib/QtWidgets/QMenu/qmenu_wrap.cpp b/src/cpp/lib/QtWidgets/QMenu/qmenu_wrap.cpp index 50964ef3b..a68dfa044 100644 --- a/src/cpp/lib/QtWidgets/QMenu/qmenu_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QMenu/qmenu_wrap.cpp @@ -23,28 +23,37 @@ Napi::Object QMenuWrap::init(Napi::Env env, Napi::Object exports) { QWIDGET_WRAPPED_METHODS_EXPORT_DEFINE(QMenuWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); + QOBJECT_REGISTER_WRAPPER(QMenu, QMenuWrap); return exports; } -NMenu* QMenuWrap::getInternalInstance() { return this->instance; } +QMenu* QMenuWrap::getInternalInstance() { return this->instance; } QMenuWrap::QMenuWrap(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); - if (info.Length() == 1) { - Napi::Object parentObject = info[0].As(); - NodeWidgetWrap* parentWidgetWrap = - Napi::ObjectWrap::Unwrap(parentObject); - this->instance = new NMenu(parentWidgetWrap->getInternalInstance()); - } else if (info.Length() == 0) { + size_t argCount = info.Length(); + if (argCount == 0) { + // --- Construct a new instance this->instance = new NMenu(); + } else if (argCount == 1) { + if (info[0].IsExternal()) { + // --- Wrap a given C++ instance + this->instance = info[0].As>().Data(); + } else { + // --- Construct a new instance and pass a parent + Napi::Object parentObject = info[0].As(); + NodeWidgetWrap* parentWidgetWrap = + Napi::ObjectWrap::Unwrap(parentObject); + this->instance = new NMenu(parentWidgetWrap->getInternalInstance()); + } } else { - Napi::TypeError::New(env, "Wrong number of arguments") + Napi::TypeError::New( + env, "NodeGui: QMenuWrap: Wrong number of arguments to constructor") .ThrowAsJavaScriptException(); } - this->rawData = extrautils::configureQWidget( - this->getInternalInstance(), this->getInternalInstance()->getFlexNode(), - true); + this->rawData = + extrautils::configureQWidget(this->getInternalInstance(), true); } QMenuWrap::~QMenuWrap() { extrautils::safeDelete(this->instance); } diff --git a/src/cpp/lib/QtWidgets/QMenuBar/qmenubar_wrap.cpp b/src/cpp/lib/QtWidgets/QMenuBar/qmenubar_wrap.cpp index 7b5b557cf..e063c3632 100644 --- a/src/cpp/lib/QtWidgets/QMenuBar/qmenubar_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QMenuBar/qmenubar_wrap.cpp @@ -21,32 +21,36 @@ Napi::Object QMenuBarWrap::init(Napi::Env env, Napi::Object exports) { QWIDGET_WRAPPED_METHODS_EXPORT_DEFINE(QMenuBarWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); + QOBJECT_REGISTER_WRAPPER(QMenuBar, QMenuBarWrap); return exports; } -NMenuBar* QMenuBarWrap::getInternalInstance() { return this->instance; } +QMenuBar* QMenuBarWrap::getInternalInstance() { return this->instance; } QMenuBarWrap::QMenuBarWrap(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); - if (info.Length() == 1) { + size_t argCount = info.Length(); + if (argCount == 0) { + // --- Construct a new instance + this->instance = new NMenuBar(); + } else if (argCount == 1) { if (info[0].IsExternal()) { - this->instance = - new NMenuBar(info[0].As>().Data()); + // --- Wrap a given C++ instance + this->instance = info[0].As>().Data(); } else { + // --- Construct a new instance and pass a parent Napi::Object parentObject = info[0].As(); NodeWidgetWrap* parentWidgetWrap = Napi::ObjectWrap::Unwrap(parentObject); this->instance = new NMenuBar(parentWidgetWrap->getInternalInstance()); } - } else if (info.Length() == 0) { - this->instance = new NMenuBar(); } else { - Napi::TypeError::New(env, "Wrong number of arguments") + Napi::TypeError::New( + env, "NodeGui: QMenuBarWrap: Wrong number of arguments to constructor") .ThrowAsJavaScriptException(); } - this->rawData = extrautils::configureQWidget( - this->getInternalInstance(), this->getInternalInstance()->getFlexNode()); + this->rawData = extrautils::configureQWidget(this->getInternalInstance()); } QMenuBarWrap::~QMenuBarWrap() { extrautils::safeDelete(this->instance); } diff --git a/src/cpp/lib/QtWidgets/QMessageBox/qmessagebox_wrap.cpp b/src/cpp/lib/QtWidgets/QMessageBox/qmessagebox_wrap.cpp index 2eba06311..edb3c3bcc 100644 --- a/src/cpp/lib/QtWidgets/QMessageBox/qmessagebox_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QMessageBox/qmessagebox_wrap.cpp @@ -23,30 +23,41 @@ Napi::Object QMessageBoxWrap::init(Napi::Env env, Napi::Object exports) { QDIALOG_WRAPPED_METHODS_EXPORT_DEFINE(QMessageBoxWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); + QOBJECT_REGISTER_WRAPPER(QMessageBox, QMessageBoxWrap); return exports; } -NMessageBox* QMessageBoxWrap::getInternalInstance() { return this->instance; } +QMessageBox* QMessageBoxWrap::getInternalInstance() { return this->instance; } + QMessageBoxWrap::~QMessageBoxWrap() { extrautils::safeDelete(this->instance); } QMessageBoxWrap::QMessageBoxWrap(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); - if (info.Length() == 1) { - Napi::Object parentObject = info[0].As(); - NodeWidgetWrap* parentWidgetWrap = - Napi::ObjectWrap::Unwrap(parentObject); - this->instance = new NMessageBox(parentWidgetWrap->getInternalInstance()); - } else if (info.Length() == 0) { + size_t argCount = info.Length(); + if (argCount == 0) { + // --- Construct a new instance this->instance = new NMessageBox(); + } else if (argCount == 1) { + if (info[0].IsExternal()) { + // --- Wrap a given C++ instance + this->instance = info[0].As>().Data(); + } else { + // --- Construct a new instance and pass a parent + Napi::Object parentObject = info[0].As(); + NodeWidgetWrap* parentWidgetWrap = + Napi::ObjectWrap::Unwrap(parentObject); + this->instance = new NMessageBox(parentWidgetWrap->getInternalInstance()); + } } else { - Napi::TypeError::New(env, "Wrong number of arguments") + Napi::TypeError::New( + env, + "NodeGui: QMessageBoxWrap: Wrong number of arguments to constructor") .ThrowAsJavaScriptException(); } this->instance->setStandardButtons(QMessageBox::NoButton); - this->rawData = extrautils::configureQWidget( - this->getInternalInstance(), this->getInternalInstance()->getFlexNode(), - false); + this->rawData = + extrautils::configureQWidget(this->getInternalInstance(), false); } Napi::Value QMessageBoxWrap::setDefaultButton(const Napi::CallbackInfo& info) { diff --git a/src/cpp/lib/QtWidgets/QPlainTextEdit/qplaintextedit_wrap.cpp b/src/cpp/lib/QtWidgets/QPlainTextEdit/qplaintextedit_wrap.cpp index 944d068f4..bd6cd6c5d 100644 --- a/src/cpp/lib/QtWidgets/QPlainTextEdit/qplaintextedit_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QPlainTextEdit/qplaintextedit_wrap.cpp @@ -27,31 +27,41 @@ Napi::Object QPlainTextEditWrap::init(Napi::Env env, Napi::Object exports) { QABSTRACTSCROLLAREA_WRAPPED_METHODS_EXPORT_DEFINE(QPlainTextEditWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); + QOBJECT_REGISTER_WRAPPER(QPlainTextEdit, QPlainTextEditWrap); return exports; } -NPlainTextEdit *QPlainTextEditWrap::getInternalInstance() { +QPlainTextEdit *QPlainTextEditWrap::getInternalInstance() { return this->instance; } QPlainTextEditWrap::QPlainTextEditWrap(const Napi::CallbackInfo &info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); - if (info.Length() == 1) { - Napi::Object parentObject = info[0].As(); - NodeWidgetWrap *parentWidgetWrap = - Napi::ObjectWrap::Unwrap(parentObject); - this->instance = - new NPlainTextEdit(parentWidgetWrap->getInternalInstance()); - } else if (info.Length() == 0) { + size_t argCount = info.Length(); + if (argCount == 0) { + // --- Construct a new instance this->instance = new NPlainTextEdit(); + } else if (argCount == 1) { + if (info[0].IsExternal()) { + // --- Wrap a given C++ instance + this->instance = info[0].As>().Data(); + } else { + // --- Construct a new instance and pass a parent + Napi::Object parentObject = info[0].As(); + NodeWidgetWrap *parentWidgetWrap = + Napi::ObjectWrap::Unwrap(parentObject); + this->instance = + new NPlainTextEdit(parentWidgetWrap->getInternalInstance()); + } } else { - Napi::TypeError::New(env, "Wrong number of arguments") + Napi::TypeError::New( + env, + "NodeGui: QPlainTextEditWrap: Wrong number of arguments to constructor") .ThrowAsJavaScriptException(); } - this->rawData = extrautils::configureQWidget( - this->getInternalInstance(), this->getInternalInstance()->getFlexNode(), - true); + this->rawData = + extrautils::configureQWidget(this->getInternalInstance(), true); } QPlainTextEditWrap::~QPlainTextEditWrap() { diff --git a/src/cpp/lib/QtWidgets/QProgressBar/qprogressbar_wrap.cpp b/src/cpp/lib/QtWidgets/QProgressBar/qprogressbar_wrap.cpp index 5e514d31c..f7cf93c4a 100644 --- a/src/cpp/lib/QtWidgets/QProgressBar/qprogressbar_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QProgressBar/qprogressbar_wrap.cpp @@ -18,10 +18,11 @@ Napi::Object QProgressBarWrap::init(Napi::Env env, Napi::Object exports) { QWIDGET_WRAPPED_METHODS_EXPORT_DEFINE(QProgressBarWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); + QOBJECT_REGISTER_WRAPPER(QProgressBar, QProgressBarWrap); return exports; } -NProgressBar* QProgressBarWrap::getInternalInstance() { return this->instance; } +QProgressBar* QProgressBarWrap::getInternalInstance() { return this->instance; } QProgressBarWrap::~QProgressBarWrap() { extrautils::safeDelete(this->instance); @@ -30,20 +31,30 @@ QProgressBarWrap::~QProgressBarWrap() { QProgressBarWrap::QProgressBarWrap(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); - if (info.Length() == 1) { - Napi::Object parentObject = info[0].As(); - NodeWidgetWrap* parentWidgetWrap = - Napi::ObjectWrap::Unwrap(parentObject); - this->instance = new NProgressBar(parentWidgetWrap->getInternalInstance()); - } else if (info.Length() == 0) { + size_t argCount = info.Length(); + if (argCount == 0) { + // --- Construct a new instance this->instance = new NProgressBar(); + } else if (argCount == 1) { + if (info[0].IsExternal()) { + // --- Wrap a given C++ instance + this->instance = info[0].As>().Data(); + } else { + // --- Construct a new instance and pass a parent + Napi::Object parentObject = info[0].As(); + NodeWidgetWrap* parentWidgetWrap = + Napi::ObjectWrap::Unwrap(parentObject); + this->instance = + new NProgressBar(parentWidgetWrap->getInternalInstance()); + } } else { - Napi::TypeError::New(env, "Wrong number of arguments") + Napi::TypeError::New( + env, + "NodeGui: QProgressBarWrap: Wrong number of arguments to constructor") .ThrowAsJavaScriptException(); } - this->rawData = extrautils::configureQWidget( - this->getInternalInstance(), this->getInternalInstance()->getFlexNode(), - true); + this->rawData = + extrautils::configureQWidget(this->getInternalInstance(), true); } Napi::Value QProgressBarWrap::resetFormat(const Napi::CallbackInfo& info) { diff --git a/src/cpp/lib/QtWidgets/QProgressDialog/qprogressdialog_wrap.cpp b/src/cpp/lib/QtWidgets/QProgressDialog/qprogressdialog_wrap.cpp index b3442dbf3..d3e82faa9 100644 --- a/src/cpp/lib/QtWidgets/QProgressDialog/qprogressdialog_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QProgressDialog/qprogressdialog_wrap.cpp @@ -20,10 +20,11 @@ Napi::Object QProgressDialogWrap::init(Napi::Env env, Napi::Object exports) { QDIALOG_WRAPPED_METHODS_EXPORT_DEFINE(QProgressDialogWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); + QOBJECT_REGISTER_WRAPPER(QProgressDialog, QProgressDialogWrap); return exports; } -NProgressDialog* QProgressDialogWrap::getInternalInstance() { +QProgressDialog* QProgressDialogWrap::getInternalInstance() { return this->instance; } @@ -34,21 +35,30 @@ QProgressDialogWrap::~QProgressDialogWrap() { QProgressDialogWrap::QProgressDialogWrap(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); - if (info.Length() == 1) { - Napi::Object parentObject = info[0].As(); - NodeWidgetWrap* parentWidgetWrap = - Napi::ObjectWrap::Unwrap(parentObject); - QWidget* parent = parentWidgetWrap->getInternalInstance(); - this->instance = new NProgressDialog(parent); - } else if (info.Length() == 0) { + size_t argCount = info.Length(); + if (argCount == 0) { + // --- Construct a new instance this->instance = new NProgressDialog(); + } else if (argCount == 1) { + if (info[0].IsExternal()) { + // --- Wrap a given C++ instance + this->instance = info[0].As>().Data(); + } else { + // --- Construct a new instance and pass a parent + Napi::Object parentObject = info[0].As(); + NodeWidgetWrap* parentWidgetWrap = + Napi::ObjectWrap::Unwrap(parentObject); + this->instance = + new NProgressDialog(parentWidgetWrap->getInternalInstance()); + } } else { - Napi::TypeError::New(env, "Wrong number of arguments") + Napi::TypeError::New(env, + "NodeGui: QProgressDialogWrap: Wrong number of " + "arguments to constructor") .ThrowAsJavaScriptException(); } - this->rawData = extrautils::configureQWidget( - this->getInternalInstance(), this->getInternalInstance()->getFlexNode(), - false); + this->rawData = + extrautils::configureQWidget(this->getInternalInstance(), false); } Napi::Value QProgressDialogWrap::cancel(const Napi::CallbackInfo& info) { diff --git a/src/cpp/lib/QtWidgets/QPushButton/qpushbutton_wrap.cpp b/src/cpp/lib/QtWidgets/QPushButton/qpushbutton_wrap.cpp index 88b9d32c8..916714ce1 100644 --- a/src/cpp/lib/QtWidgets/QPushButton/qpushbutton_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QPushButton/qpushbutton_wrap.cpp @@ -16,44 +16,40 @@ Napi::Object QPushButtonWrap::init(Napi::Env env, Napi::Object exports) { QABSTRACTBUTTON_WRAPPED_METHODS_EXPORT_DEFINE(QPushButtonWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); + QOBJECT_REGISTER_WRAPPER(QPushButton, QPushButtonWrap); return exports; } -NPushButton* QPushButtonWrap::getInternalInstance() { return this->instance; } +QPushButton* QPushButtonWrap::getInternalInstance() { return this->instance; } -QPushButtonWrap::~QPushButtonWrap() { - if (!this->disableDeletion) { - extrautils::safeDelete(this->instance); - } -} +QPushButtonWrap::~QPushButtonWrap() { extrautils::safeDelete(this->instance); } QPushButtonWrap::QPushButtonWrap(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); - this->disableDeletion = false; - if (info.Length() > 0 && info[0].IsExternal()) { - // --- if external --- - this->instance = info[0].As>().Data(); - if (info.Length() == 2) { - this->disableDeletion = info[1].As().Value(); - } - } else { - if (info.Length() == 1) { + size_t argCount = info.Length(); + if (argCount == 0) { + // --- Construct a new instance + this->instance = new NPushButton(); + } else if (argCount == 1) { + if (info[0].IsExternal()) { + // --- Wrap a given C++ instance + this->instance = info[0].As>().Data(); + } else { + // --- Construct a new instance and pass a parent Napi::Object parentObject = info[0].As(); NodeWidgetWrap* parentWidgetWrap = Napi::ObjectWrap::Unwrap(parentObject); this->instance = new NPushButton(parentWidgetWrap->getInternalInstance()); - } else if (info.Length() == 0) { - this->instance = new NPushButton(); - } else { - Napi::TypeError::New(env, "Wrong number of arguments") - .ThrowAsJavaScriptException(); } + } else { + Napi::TypeError::New( + env, + "NodeGui: QPushButtonWrap: Wrong number of arguments to constructor") + .ThrowAsJavaScriptException(); } - - this->rawData = extrautils::configureQWidget( - this->getInternalInstance(), this->getInternalInstance()->getFlexNode(), - true); + this->rawData = + extrautils::configureQWidget(this->getInternalInstance(), true); } Napi::Value QPushButtonWrap::setMenu(const Napi::CallbackInfo& info) { diff --git a/src/cpp/lib/QtWidgets/QRadioButton/qradiobutton_wrap.cpp b/src/cpp/lib/QtWidgets/QRadioButton/qradiobutton_wrap.cpp index 22cf2f72c..0e6ea18c5 100644 --- a/src/cpp/lib/QtWidgets/QRadioButton/qradiobutton_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QRadioButton/qradiobutton_wrap.cpp @@ -16,42 +16,41 @@ Napi::Object QRadioButtonWrap::init(Napi::Env env, Napi::Object exports) { {QABSTRACTBUTTON_WRAPPED_METHODS_EXPORT_DEFINE(QRadioButtonWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); + QOBJECT_REGISTER_WRAPPER(QRadioButton, QRadioButtonWrap); return exports; } -NRadioButton* QRadioButtonWrap::getInternalInstance() { return this->instance; } +QRadioButton* QRadioButtonWrap::getInternalInstance() { return this->instance; } QRadioButtonWrap::QRadioButtonWrap(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); - this->disableDeletion = false; - if (info.Length() > 0 && info[0].IsExternal()) { - // --- if external --- - this->instance = info[0].As>().Data(); - if (info.Length() == 2) { - this->disableDeletion = info[1].As().Value(); - } - } else { - if (info.Length() == 1) { + size_t argCount = info.Length(); + if (argCount == 0) { + // --- Construct a new instance + this->instance = new NRadioButton(); + } else if (argCount == 1) { + if (info[0].IsExternal()) { + // --- Wrap a given C++ instance + this->instance = info[0].As>().Data(); + } else { + // --- Construct a new instance and pass a parent Napi::Object parentObject = info[0].As(); NodeWidgetWrap* parentWidgetWrap = Napi::ObjectWrap::Unwrap(parentObject); this->instance = new NRadioButton(parentWidgetWrap->getInternalInstance()); - } else if (info.Length() == 0) { - this->instance = new NRadioButton(); - } else { - Napi::TypeError::New(env, "Wrong number of arguments") - .ThrowAsJavaScriptException(); } + } else { + Napi::TypeError::New( + env, + "NodeGui: QRadioButtonWrap: Wrong number of arguments to constructor") + .ThrowAsJavaScriptException(); } - this->rawData = extrautils::configureQWidget( - this->getInternalInstance(), this->getInternalInstance()->getFlexNode(), - true); + this->rawData = + extrautils::configureQWidget(this->getInternalInstance(), true); } QRadioButtonWrap::~QRadioButtonWrap() { - if (!this->disableDeletion) { - extrautils::safeDelete(this->instance); - } + extrautils::safeDelete(this->instance); } diff --git a/src/cpp/lib/QtWidgets/QScrollArea/qscrollarea_wrap.cpp b/src/cpp/lib/QtWidgets/QScrollArea/qscrollarea_wrap.cpp index 1ea746c5b..934f3ef1d 100644 --- a/src/cpp/lib/QtWidgets/QScrollArea/qscrollarea_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QScrollArea/qscrollarea_wrap.cpp @@ -14,6 +14,7 @@ Napi::Object QScrollAreaWrap::init(Napi::Env env, Napi::Object exports) { InstanceMethod("ensureWidgetVisible", &QScrollAreaWrap::ensureWidgetVisible), InstanceMethod("setWidget", &QScrollAreaWrap::setWidget), + InstanceMethod("widget", &QScrollAreaWrap::widget), InstanceMethod("takeWidget", &QScrollAreaWrap::takeWidget), InstanceMethod("setViewportMargins", &QScrollAreaWrap::setViewportMargins), @@ -21,38 +22,41 @@ Napi::Object QScrollAreaWrap::init(Napi::Env env, Napi::Object exports) { QABSTRACTSCROLLAREA_WRAPPED_METHODS_EXPORT_DEFINE(QScrollAreaWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); + QOBJECT_REGISTER_WRAPPER(QScrollArea, QScrollAreaWrap); return exports; } -NScrollArea* QScrollAreaWrap::getInternalInstance() { return this->instance; } +QScrollArea* QScrollAreaWrap::getInternalInstance() { return this->instance; } -QScrollAreaWrap::~QScrollAreaWrap() { - extrautils::safeDelete(this->instance); - YGNodeFree(this->scrollNode); -} +QScrollAreaWrap::~QScrollAreaWrap() { extrautils::safeDelete(this->instance); } QScrollAreaWrap::QScrollAreaWrap(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); - if (info.Length() == 1) { - Napi::Object parentObject = info[0].As(); - NodeWidgetWrap* parentWidgetWrap = - Napi::ObjectWrap::Unwrap(parentObject); - this->instance = new NScrollArea(parentWidgetWrap->getInternalInstance()); - } else if (info.Length() == 0) { + size_t argCount = info.Length(); + if (argCount == 0) { + // --- Construct a new instance this->instance = new NScrollArea(); + } else if (argCount == 1) { + if (info[0].IsExternal()) { + // --- Wrap a given C++ instance + this->instance = info[0].As>().Data(); + } else { + // --- Construct a new instance and pass a parent + Napi::Object parentObject = info[0].As(); + NodeWidgetWrap* parentWidgetWrap = + Napi::ObjectWrap::Unwrap(parentObject); + this->instance = new NScrollArea(parentWidgetWrap->getInternalInstance()); + } } else { - Napi::TypeError::New(env, "Wrong number of arguments") + Napi::TypeError::New( + env, + "NodeGui: QScrollAreaWrap: Wrong number of arguments to constructor") .ThrowAsJavaScriptException(); } - this->scrollNode = YGNodeNew(); - YGConfigSetUseWebDefaults(this->scrollNode->getConfig(), true); - FlexNodeContext* scrollNodeCtx = new FlexNodeContext(this->instance); - YGNodeSetContext(this->scrollNode, scrollNodeCtx); - this->rawData = extrautils::configureQWidget( - this->getInternalInstance(), this->getInternalInstance()->getFlexNode(), - false); + this->rawData = + extrautils::configureQWidget(this->getInternalInstance(), false); } Napi::Value QScrollAreaWrap::ensureVisible(const Napi::CallbackInfo& info) { @@ -87,18 +91,31 @@ Napi::Value QScrollAreaWrap::setWidget(const Napi::CallbackInfo& info) { return env.Null(); } +Napi::Value QScrollAreaWrap::widget(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + QObject* widget = this->instance->widget(); + if (widget) { + return WrapperCache::instance.getWrapper(env, widget); + } else { + return env.Null(); + } +} + Napi::Value QScrollAreaWrap::takeWidget(const Napi::CallbackInfo& info) { Napi::Env env = info.Env(); - this->instance->takeWidget(); - // We will not return the value here since we are doing it in js side anyway - return env.Null(); + QObject* widget = this->instance->takeWidget(); + if (widget) { + return WrapperCache::instance.getWrapper(env, widget); + } else { + return env.Null(); + } } Napi::Value QScrollAreaWrap::setViewportMargins( const Napi::CallbackInfo& info) { Napi::Env env = info.Env(); - NScrollArea* nScrollArea = qobject_cast(this->instance); - if (nScrollArea != nullptr) { + NScrollArea* nScrollArea = dynamic_cast(this->instance.data()); + if (nScrollArea) { int left = info[0].As().Int32Value(); int top = info[1].As().Int32Value(); int right = info[2].As().Int32Value(); @@ -110,17 +127,16 @@ Napi::Value QScrollAreaWrap::setViewportMargins( Napi::Value QScrollAreaWrap::viewportMargins(const Napi::CallbackInfo& info) { Napi::Env env = info.Env(); - NScrollArea* nScrollArea = qobject_cast(this->instance); - - QMargins margins; - if (nScrollArea != nullptr) { - margins = nScrollArea->viewportMargins(); + NScrollArea* nScrollArea = dynamic_cast(this->instance.data()); + if (nScrollArea) { + QMargins margins = nScrollArea->viewportMargins(); + Napi::Array resultNapi = Napi::Array::New(env, 4); + resultNapi[uint32_t(0)] = Napi::Number::From(env, margins.left()); + resultNapi[1] = Napi::Value::From(env, margins.top()); + resultNapi[2] = Napi::Value::From(env, margins.right()); + resultNapi[3] = Napi::Value::From(env, margins.bottom()); + return resultNapi; + } else { + return env.Null(); } - - Napi::Array resultNapi = Napi::Array::New(env, 4); - resultNapi[uint32_t(0)] = Napi::Number::From(env, margins.left()); - resultNapi[1] = Napi::Value::From(env, margins.top()); - resultNapi[2] = Napi::Value::From(env, margins.right()); - resultNapi[3] = Napi::Value::From(env, margins.bottom()); - return resultNapi; } diff --git a/src/cpp/lib/QtWidgets/QScrollBar/qscrollbar_wrap.cpp b/src/cpp/lib/QtWidgets/QScrollBar/qscrollbar_wrap.cpp index 75ad57ae7..df4f6d530 100644 --- a/src/cpp/lib/QtWidgets/QScrollBar/qscrollbar_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QScrollBar/qscrollbar_wrap.cpp @@ -15,29 +15,38 @@ Napi::Object QScrollBarWrap::init(Napi::Env env, Napi::Object exports) { {QABSTRACTSLIDER_WRAPPED_METHODS_EXPORT_DEFINE(QScrollBarWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); + QOBJECT_REGISTER_WRAPPER(QScrollBar, QScrollBarWrap); return exports; } -NScrollBar* QScrollBarWrap::getInternalInstance() { return this->instance; } +QScrollBar* QScrollBarWrap::getInternalInstance() { return this->instance; } QScrollBarWrap::QScrollBarWrap(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); - if (info.Length() == 1) { - Napi::Object parentObject = info[0].As(); - NodeWidgetWrap* parentWidgetWrap = - Napi::ObjectWrap::Unwrap(parentObject); - this->instance = new NScrollBar(parentWidgetWrap->getInternalInstance()); - } else if (info.Length() == 0) { + size_t argCount = info.Length(); + if (argCount == 0) { + // --- Construct a new instance this->instance = new NScrollBar(); + } else if (argCount == 1) { + if (info[0].IsExternal()) { + // --- Wrap a given C++ instance + this->instance = info[0].As>().Data(); + } else { + // --- Construct a new instance and pass a parent + Napi::Object parentObject = info[0].As(); + NodeWidgetWrap* parentWidgetWrap = + Napi::ObjectWrap::Unwrap(parentObject); + this->instance = new NScrollBar(parentWidgetWrap->getInternalInstance()); + } } else { - Napi::TypeError::New(env, "Wrong number of arguments") + Napi::TypeError::New( + env, + "NodeGui: QScrollBarWrap: Wrong number of arguments to constructor") .ThrowAsJavaScriptException(); } - - this->rawData = extrautils::configureQWidget( - this->getInternalInstance(), this->getInternalInstance()->getFlexNode(), - true); + this->rawData = + extrautils::configureQWidget(this->getInternalInstance(), true); } QScrollBarWrap::~QScrollBarWrap() { extrautils::safeDelete(this->instance); } diff --git a/src/cpp/lib/QtWidgets/QShortcut/qshortcut_wrap.cpp b/src/cpp/lib/QtWidgets/QShortcut/qshortcut_wrap.cpp index f7bd8c582..ae8235f71 100644 --- a/src/cpp/lib/QtWidgets/QShortcut/qshortcut_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QShortcut/qshortcut_wrap.cpp @@ -21,21 +21,33 @@ Napi::Object QShortcutWrap::init(Napi::Env env, Napi::Object exports) { QOBJECT_WRAPPED_METHODS_EXPORT_DEFINE(QShortcutWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); + QOBJECT_REGISTER_WRAPPER(QShortcut, QShortcutWrap); return exports; } -NShortcut* QShortcutWrap::getInternalInstance() { return this->instance; } +QShortcut* QShortcutWrap::getInternalInstance() { return this->instance; } QShortcutWrap::QShortcutWrap(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); - if (info.Length() == 1) { - Napi::Object parentObject = info[0].As(); - NodeWidgetWrap* parentWidgetWrap = - Napi::ObjectWrap::Unwrap(parentObject); - this->instance = new NShortcut(parentWidgetWrap->getInternalInstance()); + size_t argCount = info.Length(); + + // Note: QShortcut object always need a parent or instance to wrap + + if (argCount == 1) { + if (info[0].IsExternal()) { + // --- Wrap a given C++ instance + this->instance = info[0].As>().Data(); + } else { + // --- Construct a new instance and pass a parent + Napi::Object parentObject = info[0].As(); + NodeWidgetWrap* parentWidgetWrap = + Napi::ObjectWrap::Unwrap(parentObject); + this->instance = new NShortcut(parentWidgetWrap->getInternalInstance()); + } } else { - Napi::TypeError::New(env, "Wrong number of arguments") + Napi::TypeError::New( + env, "NodeGui: QShortcutWrap: Wrong number of arguments to constructor") .ThrowAsJavaScriptException(); } this->rawData = extrautils::configureQObject(this->getInternalInstance()); diff --git a/src/cpp/lib/QtWidgets/QSlider/qslider_wrap.cpp b/src/cpp/lib/QtWidgets/QSlider/qslider_wrap.cpp index 4b1aecea7..51bdbf5a2 100644 --- a/src/cpp/lib/QtWidgets/QSlider/qslider_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QSlider/qslider_wrap.cpp @@ -15,29 +15,37 @@ Napi::Object QSliderWrap::init(Napi::Env env, Napi::Object exports) { {QABSTRACTSLIDER_WRAPPED_METHODS_EXPORT_DEFINE(QSliderWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); + QOBJECT_REGISTER_WRAPPER(QSlider, QSliderWrap); return exports; } -NSlider* QSliderWrap::getInternalInstance() { return this->instance; } +QSlider* QSliderWrap::getInternalInstance() { return this->instance; } QSliderWrap::QSliderWrap(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); - if (info.Length() == 1) { - Napi::Object parentObject = info[0].As(); - NodeWidgetWrap* parentWidgetWrap = - Napi::ObjectWrap::Unwrap(parentObject); - this->instance = new NSlider(parentWidgetWrap->getInternalInstance()); - } else if (info.Length() == 0) { + size_t argCount = info.Length(); + if (argCount == 0) { + // --- Construct a new instance this->instance = new NSlider(); + } else if (argCount == 1) { + if (info[0].IsExternal()) { + // --- Wrap a given C++ instance + this->instance = info[0].As>().Data(); + } else { + // --- Construct a new instance and pass a parent + Napi::Object parentObject = info[0].As(); + NodeWidgetWrap* parentWidgetWrap = + Napi::ObjectWrap::Unwrap(parentObject); + this->instance = new NSlider(parentWidgetWrap->getInternalInstance()); + } } else { - Napi::TypeError::New(env, "Wrong number of arguments") + Napi::TypeError::New( + env, "NodeGui: QSliderWrap: Wrong number of arguments to constructor") .ThrowAsJavaScriptException(); } - - this->rawData = extrautils::configureQWidget( - this->getInternalInstance(), this->getInternalInstance()->getFlexNode(), - true); + this->rawData = + extrautils::configureQWidget(this->getInternalInstance(), true); } QSliderWrap::~QSliderWrap() { extrautils::safeDelete(this->instance); } diff --git a/src/cpp/lib/QtWidgets/QSpinBox/qspinbox_wrap.cpp b/src/cpp/lib/QtWidgets/QSpinBox/qspinbox_wrap.cpp index dc081a7d6..677fb0d04 100644 --- a/src/cpp/lib/QtWidgets/QSpinBox/qspinbox_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QSpinBox/qspinbox_wrap.cpp @@ -15,28 +15,37 @@ Napi::Object QSpinBoxWrap::init(Napi::Env env, Napi::Object exports) { QABSTRACTSPINBOX_WRAPPED_METHODS_EXPORT_DEFINE(QSpinBoxWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); + QOBJECT_REGISTER_WRAPPER(QSpinBox, QSpinBoxWrap); return exports; } -NSpinBox* QSpinBoxWrap::getInternalInstance() { return this->instance; } +QSpinBox* QSpinBoxWrap::getInternalInstance() { return this->instance; } QSpinBoxWrap::QSpinBoxWrap(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); - if (info.Length() == 1) { - Napi::Object parentObject = info[0].As(); - NodeWidgetWrap* parentWidgetWrap = - Napi::ObjectWrap::Unwrap(parentObject); - this->instance = new NSpinBox(parentWidgetWrap->getInternalInstance()); - } else if (info.Length() == 0) { + size_t argCount = info.Length(); + if (argCount == 0) { + // --- Construct a new instance this->instance = new NSpinBox(); + } else if (argCount == 1) { + if (info[0].IsExternal()) { + // --- Wrap a given C++ instance + this->instance = info[0].As>().Data(); + } else { + // --- Construct a new instance and pass a parent + Napi::Object parentObject = info[0].As(); + NodeWidgetWrap* parentWidgetWrap = + Napi::ObjectWrap::Unwrap(parentObject); + this->instance = new NSpinBox(parentWidgetWrap->getInternalInstance()); + } } else { - Napi::TypeError::New(env, "Wrong number of arguments") + Napi::TypeError::New( + env, "NodeGui: QSpinBoxWrap: Wrong number of arguments to constructor") .ThrowAsJavaScriptException(); } - this->rawData = extrautils::configureQWidget( - this->getInternalInstance(), this->getInternalInstance()->getFlexNode(), - true); + this->rawData = + extrautils::configureQWidget(this->getInternalInstance(), true); } QSpinBoxWrap::~QSpinBoxWrap() { extrautils::safeDelete(this->instance); } diff --git a/src/cpp/lib/QtWidgets/QSplitter/qsplitter_wrap.cpp b/src/cpp/lib/QtWidgets/QSplitter/qsplitter_wrap.cpp index c70a5f090..08aa13aeb 100644 --- a/src/cpp/lib/QtWidgets/QSplitter/qsplitter_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QSplitter/qsplitter_wrap.cpp @@ -22,30 +22,39 @@ Napi::Object QSplitterWrap::init(Napi::Env env, Napi::Object exports) { QFRAME_WRAPPED_METHODS_EXPORT_DEFINE(QSplitterWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); + QOBJECT_REGISTER_WRAPPER(QSplitter, QSplitterWrap); return exports; } -NSplitter* QSplitterWrap::getInternalInstance() { return this->instance; } +QSplitter* QSplitterWrap::getInternalInstance() { return this->instance; } QSplitterWrap::~QSplitterWrap() { extrautils::safeDelete(this->instance); } QSplitterWrap::QSplitterWrap(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); - if (info.Length() == 1) { - Napi::Object parentObject = info[0].As(); - NodeWidgetWrap* parentWidgetWrap = - Napi::ObjectWrap::Unwrap(parentObject); - this->instance = new NSplitter(parentWidgetWrap->getInternalInstance()); - } else if (info.Length() == 0) { + size_t argCount = info.Length(); + if (argCount == 0) { + // --- Construct a new instance this->instance = new NSplitter(); + } else if (argCount == 1) { + if (info[0].IsExternal()) { + // --- Wrap a given C++ instance + this->instance = info[0].As>().Data(); + } else { + // --- Construct a new instance and pass a parent + Napi::Object parentObject = info[0].As(); + NodeWidgetWrap* parentWidgetWrap = + Napi::ObjectWrap::Unwrap(parentObject); + this->instance = new NSplitter(parentWidgetWrap->getInternalInstance()); + } } else { - Napi::TypeError::New(env, "Wrong number of arguments") + Napi::TypeError::New( + env, "NodeGui: QSplitterWrap: Wrong number of arguments to constructor") .ThrowAsJavaScriptException(); } - this->rawData = extrautils::configureQWidget( - this->getInternalInstance(), this->getInternalInstance()->getFlexNode(), - false); + this->rawData = + extrautils::configureQWidget(this->getInternalInstance(), false); } Napi::Value QSplitterWrap::addWidget(const Napi::CallbackInfo& info) { diff --git a/src/cpp/lib/QtWidgets/QStackedWidget/qstackedwidget_wrap.cpp b/src/cpp/lib/QtWidgets/QStackedWidget/qstackedwidget_wrap.cpp index 8fe1f0f49..a7d6e5c00 100644 --- a/src/cpp/lib/QtWidgets/QStackedWidget/qstackedwidget_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QStackedWidget/qstackedwidget_wrap.cpp @@ -21,10 +21,11 @@ Napi::Object QStackedWidgetWrap::init(Napi::Env env, Napi::Object exports) { QFRAME_WRAPPED_METHODS_EXPORT_DEFINE(QStackedWidgetWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); + QOBJECT_REGISTER_WRAPPER(QStackedWidget, QStackedWidgetWrap); return exports; } -NStackedWidget* QStackedWidgetWrap::getInternalInstance() { +QStackedWidget* QStackedWidgetWrap::getInternalInstance() { return this->instance; } @@ -35,22 +36,30 @@ QStackedWidgetWrap::~QStackedWidgetWrap() { QStackedWidgetWrap::QStackedWidgetWrap(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); - if (info.Length() == 1) { - Napi::Object parentObject = info[0].As(); - NodeWidgetWrap* parentWidgetWrap = - Napi::ObjectWrap::Unwrap(parentObject); - this->instance = new NStackedWidget( - parentWidgetWrap - ->getInternalInstance()); // this sets the parent to current widget - } else if (info.Length() == 0) { + size_t argCount = info.Length(); + if (argCount == 0) { + // --- Construct a new instance this->instance = new NStackedWidget(); + } else if (argCount == 1) { + if (info[0].IsExternal()) { + // --- Wrap a given C++ instance + this->instance = info[0].As>().Data(); + } else { + // --- Construct a new instance and pass a parent + Napi::Object parentObject = info[0].As(); + NodeWidgetWrap* parentWidgetWrap = + Napi::ObjectWrap::Unwrap(parentObject); + this->instance = + new NStackedWidget(parentWidgetWrap->getInternalInstance()); + } } else { - Napi::TypeError::New(env, "Wrong number of arguments") + Napi::TypeError::New( + env, + "NodeGui: QStackedWidgetWrap: Wrong number of arguments to constructor") .ThrowAsJavaScriptException(); } - this->rawData = extrautils::configureQWidget( - this->getInternalInstance(), this->getInternalInstance()->getFlexNode(), - true); + this->rawData = + extrautils::configureQWidget(this->getInternalInstance(), true); } Napi::Value QStackedWidgetWrap::addWidget(const Napi::CallbackInfo& info) { diff --git a/src/cpp/lib/QtWidgets/QStandardItem/qstandarditem_wrap.cpp b/src/cpp/lib/QtWidgets/QStandardItem/qstandarditem_wrap.cpp index ec2af7a2f..761d71176 100644 --- a/src/cpp/lib/QtWidgets/QStandardItem/qstandarditem_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QStandardItem/qstandarditem_wrap.cpp @@ -37,20 +37,21 @@ QStandardItemWrap::QStandardItemWrap(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); this->disableDeletion = false; - if (info.Length() > 0 && info[0].IsExternal()) { + size_t argCount = info.Length(); + if (argCount > 0 && info[0].IsExternal()) { this->instance = info[0].As>().Data(); - if (info.Length() == 2) { + if (argCount == 2) { this->disableDeletion = info[1].As().Value(); } } else { - if (info.Length() == 1) { + if (argCount == 1) { QString text = QString::fromUtf8(info[0].As().Utf8Value().c_str()); this->instance = new QStandardItem(text); - } else if (info.Length() == 0) { + } else if (argCount == 0) { this->instance = new QStandardItem(); } else { - Napi::TypeError::New(env, "Wrong number of arguments") + Napi::TypeError::New(env, "QStandardItemWrap: Wrong number of arguments") .ThrowAsJavaScriptException(); } } diff --git a/src/cpp/lib/QtWidgets/QStandardItemModel/qstandarditemmodel_wrap.cpp b/src/cpp/lib/QtWidgets/QStandardItemModel/qstandarditemmodel_wrap.cpp index 5454aeea4..d0a5844c0 100644 --- a/src/cpp/lib/QtWidgets/QStandardItemModel/qstandarditemmodel_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QStandardItemModel/qstandarditemmodel_wrap.cpp @@ -22,27 +22,37 @@ Napi::Object QStandardItemModelWrap::init(Napi::Env env, Napi::Object exports) { QOBJECT_WRAPPED_METHODS_EXPORT_DEFINE(QStandardItemModelWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); + QOBJECT_REGISTER_WRAPPER(QStandardItemModel, QStandardItemModelWrap); return exports; } -NStandardItemModel* QStandardItemModelWrap::getInternalInstance() { +QStandardItemModel* QStandardItemModelWrap::getInternalInstance() { return this->instance; } QStandardItemModelWrap::QStandardItemModelWrap(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); - if (info.Length() == 1) { - Napi::Object parentObject = info[0].As(); - NodeWidgetWrap* parentWidgetWrap = - Napi::ObjectWrap::Unwrap(parentObject); - this->instance = new NStandardItemModel( - parentWidgetWrap - ->getInternalInstance()); // this sets the parent to current widget - } else if (info.Length() == 0) { + size_t argCount = info.Length(); + if (argCount == 0) { + // --- Construct a new instance this->instance = new NStandardItemModel(); + } else if (argCount == 1) { + if (info[0].IsExternal()) { + // --- Wrap a given C++ instance + this->instance = info[0].As>().Data(); + } else { + // --- Construct a new instance and pass a parent + Napi::Object parentObject = info[0].As(); + NodeWidgetWrap* parentWidgetWrap = + Napi::ObjectWrap::Unwrap(parentObject); + this->instance = + new NStandardItemModel(parentWidgetWrap->getInternalInstance()); + } } else { - Napi::TypeError::New(env, "Wrong number of arguments") + Napi::TypeError::New(env, + "NodeGui: QStandardItemModelWrap: Wrong number of " + "arguments to constructor") .ThrowAsJavaScriptException(); } this->rawData = extrautils::configureQObject(this->getInternalInstance()); diff --git a/src/cpp/lib/QtWidgets/QStatusBar/qstatusbar_wrap.cpp b/src/cpp/lib/QtWidgets/QStatusBar/qstatusbar_wrap.cpp index 06965262f..935811104 100644 --- a/src/cpp/lib/QtWidgets/QStatusBar/qstatusbar_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QStatusBar/qstatusbar_wrap.cpp @@ -28,10 +28,11 @@ Napi::Object QStatusBarWrap::init(Napi::Env env, Napi::Object exports) { QWIDGET_WRAPPED_METHODS_EXPORT_DEFINE(QStatusBarWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); + QOBJECT_REGISTER_WRAPPER(QStatusBar, QStatusBarWrap); return exports; } -NStatusBar *QStatusBarWrap::getInternalInstance() { return this->instance; } +QStatusBar *QStatusBarWrap::getInternalInstance() { return this->instance; } Napi::Value QStatusBarWrap::fromQStatusBar(Napi::Env env, QStatusBar *statusBar) { @@ -50,22 +51,29 @@ QStatusBarWrap::~QStatusBarWrap() { extrautils::safeDelete(this->instance); } QStatusBarWrap::QStatusBarWrap(const Napi::CallbackInfo &info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); - if (info.Length() == 1) { - Napi::Object parentObject = info[0].As(); - NodeWidgetWrap *parentWidgetWrap = - Napi::ObjectWrap::Unwrap(parentObject); - - this->instance = new NStatusBar(parentWidgetWrap->getInternalInstance()); - } else if (info.Length() == 0) { + size_t argCount = info.Length(); + if (argCount == 0) { + // --- Construct a new instance this->instance = new NStatusBar(); + } else if (argCount == 1) { + if (info[0].IsExternal()) { + // --- Wrap a given C++ instance + this->instance = info[0].As>().Data(); + } else { + // --- Construct a new instance and pass a parent + Napi::Object parentObject = info[0].As(); + NodeWidgetWrap *parentWidgetWrap = + Napi::ObjectWrap::Unwrap(parentObject); + this->instance = new NStatusBar(parentWidgetWrap->getInternalInstance()); + } } else { - Napi::TypeError::New(env, "Wrong number of arguments") + Napi::TypeError::New( + env, + "NodeGui: QStatusBarWrap: Wrong number of arguments to constructor") .ThrowAsJavaScriptException(); } - - this->rawData = extrautils::configureQWidget( - this->getInternalInstance(), this->getInternalInstance()->getFlexNode(), - true); + this->rawData = + extrautils::configureQWidget(this->getInternalInstance(), true); } Napi::Value QStatusBarWrap::addPermanentWidget(const Napi::CallbackInfo &info) { diff --git a/src/cpp/lib/QtWidgets/QSvgWidget/qsvgwidget_wrap.cpp b/src/cpp/lib/QtWidgets/QSvgWidget/qsvgwidget_wrap.cpp index 52ca63adb..86539a9fa 100644 --- a/src/cpp/lib/QtWidgets/QSvgWidget/qsvgwidget_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QSvgWidget/qsvgwidget_wrap.cpp @@ -16,30 +16,40 @@ Napi::Object QSvgWidgetWrap::init(Napi::Env env, Napi::Object exports) { QWIDGET_WRAPPED_METHODS_EXPORT_DEFINE(QSvgWidgetWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); + QOBJECT_REGISTER_WRAPPER(QSvgWidget, QSvgWidgetWrap); return exports; } -NSvgWidget* QSvgWidgetWrap::getInternalInstance() { return this->instance; } +QSvgWidget* QSvgWidgetWrap::getInternalInstance() { return this->instance; } QSvgWidgetWrap::~QSvgWidgetWrap() { extrautils::safeDelete(this->instance); } QSvgWidgetWrap::QSvgWidgetWrap(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); - if (info.Length() == 1) { - Napi::Object parentObject = info[0].As(); - NodeWidgetWrap* parentWidgetWrap = - Napi::ObjectWrap::Unwrap(parentObject); - this->instance = new NSvgWidget(parentWidgetWrap->getInternalInstance()); - } else if (info.Length() == 0) { + size_t argCount = info.Length(); + if (argCount == 0) { + // --- Construct a new instance this->instance = new NSvgWidget(); + } else if (argCount == 1) { + if (info[0].IsExternal()) { + // --- Wrap a given C++ instance + this->instance = info[0].As>().Data(); + } else { + // --- Construct a new instance and pass a parent + Napi::Object parentObject = info[0].As(); + NodeWidgetWrap* parentWidgetWrap = + Napi::ObjectWrap::Unwrap(parentObject); + this->instance = new NSvgWidget(parentWidgetWrap->getInternalInstance()); + } } else { - Napi::TypeError::New(env, "Wrong number of arguments") + Napi::TypeError::New( + env, + "NodeGui: QSvgWidgetWrap: Wrong number of arguments to constructor") .ThrowAsJavaScriptException(); } - this->rawData = extrautils::configureQWidget( - this->getInternalInstance(), this->getInternalInstance()->getFlexNode(), - true); + this->rawData = + extrautils::configureQWidget(this->getInternalInstance(), true); } Napi::Value QSvgWidgetWrap::load(const Napi::CallbackInfo& info) { diff --git a/src/cpp/lib/QtWidgets/QSystemTrayIcon/qsystemtrayicon_wrap.cpp b/src/cpp/lib/QtWidgets/QSystemTrayIcon/qsystemtrayicon_wrap.cpp index 59d28d255..1f3ab8ff2 100644 --- a/src/cpp/lib/QtWidgets/QSystemTrayIcon/qsystemtrayicon_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QSystemTrayIcon/qsystemtrayicon_wrap.cpp @@ -25,27 +25,37 @@ Napi::Object QSystemTrayIconWrap::init(Napi::Env env, Napi::Object exports) { QOBJECT_WRAPPED_METHODS_EXPORT_DEFINE(QSystemTrayIconWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); + QOBJECT_REGISTER_WRAPPER(QSystemTrayIcon, QSystemTrayIconWrap); return exports; } -NSystemTrayIcon* QSystemTrayIconWrap::getInternalInstance() { +QSystemTrayIcon* QSystemTrayIconWrap::getInternalInstance() { return this->instance; } QSystemTrayIconWrap::QSystemTrayIconWrap(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); - if (info.Length() == 1) { - Napi::Object parentObject = info[0].As(); - NodeWidgetWrap* parentWidgetWrap = - Napi::ObjectWrap::Unwrap(parentObject); - this->instance = new NSystemTrayIcon( - parentWidgetWrap - ->getInternalInstance()); // this sets the parent to current widget - } else if (info.Length() == 0) { + size_t argCount = info.Length(); + if (argCount == 0) { + // --- Construct a new instance this->instance = new NSystemTrayIcon(); + } else if (argCount == 1) { + if (info[0].IsExternal()) { + // --- Wrap a given C++ instance + this->instance = info[0].As>().Data(); + } else { + // --- Construct a new instance and pass a parent + Napi::Object parentObject = info[0].As(); + NodeWidgetWrap* parentWidgetWrap = + Napi::ObjectWrap::Unwrap(parentObject); + this->instance = + new NSystemTrayIcon(parentWidgetWrap->getInternalInstance()); + } } else { - Napi::TypeError::New(env, "Wrong number of arguments") + Napi::TypeError::New(env, + "NodeGui: QSystemTrayIconWrap: Wrong number of " + "arguments to constructor") .ThrowAsJavaScriptException(); } this->rawData = extrautils::configureQObject(this->getInternalInstance()); diff --git a/src/cpp/lib/QtWidgets/QTabBar/qtabbar_wrap.cpp b/src/cpp/lib/QtWidgets/QTabBar/qtabbar_wrap.cpp index e1f28d7a3..3cc804f30 100644 --- a/src/cpp/lib/QtWidgets/QTabBar/qtabbar_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QTabBar/qtabbar_wrap.cpp @@ -43,44 +43,39 @@ Napi::Object QTabBarWrap::init(Napi::Env env, Napi::Object exports) { QWIDGET_WRAPPED_METHODS_EXPORT_DEFINE(QTabBarWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); + QOBJECT_REGISTER_WRAPPER(QTabBar, QTabBarWrap); return exports; } -NTabBar* QTabBarWrap::getInternalInstance() { return this->instance; } +QTabBar* QTabBarWrap::getInternalInstance() { return this->instance; } -QTabBarWrap::~QTabBarWrap() { - if (!this->disableDeletion) { - extrautils::safeDelete(this->instance); - } -} +QTabBarWrap::~QTabBarWrap() { extrautils::safeDelete(this->instance); } QTabBarWrap::QTabBarWrap(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); - this->disableDeletion = false; - if (info.Length() > 0 && info[0].IsExternal()) { - // --- if external --- - this->instance = info[0].As>().Data(); - if (info.Length() == 2) { - this->disableDeletion = info[1].As().Value(); - } - } else { - // --- regular cases --- - if (info.Length() == 1) { + size_t argCount = info.Length(); + if (argCount == 0) { + // --- Construct a new instance + this->instance = new NTabBar(); + } else if (argCount == 1) { + if (info[0].IsExternal()) { + // --- Wrap a given C++ instance + this->instance = info[0].As>().Data(); + } else { + // --- Construct a new instance and pass a parent Napi::Object parentObject = info[0].As(); NodeWidgetWrap* parentWidgetWrap = Napi::ObjectWrap::Unwrap(parentObject); this->instance = new NTabBar(parentWidgetWrap->getInternalInstance()); - } else if (info.Length() == 0) { - this->instance = new NTabBar(); - } else { - Napi::TypeError::New(env, "Wrong number of arguments") - .ThrowAsJavaScriptException(); } + } else { + Napi::TypeError::New( + env, "NodeGui: QTabBarWrap: Wrong number of arguments to constructor") + .ThrowAsJavaScriptException(); } - this->rawData = extrautils::configureQWidget( - this->getInternalInstance(), this->getInternalInstance()->getFlexNode(), - true); + this->rawData = + extrautils::configureQWidget(this->getInternalInstance(), true); } Napi::Value QTabBarWrap::setAccessibleTabName(const Napi::CallbackInfo& info) { diff --git a/src/cpp/lib/QtWidgets/QTabWidget/qtabwidget_wrap.cpp b/src/cpp/lib/QtWidgets/QTabWidget/qtabwidget_wrap.cpp index 88f97df25..fa873bd85 100644 --- a/src/cpp/lib/QtWidgets/QTabWidget/qtabwidget_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QTabWidget/qtabwidget_wrap.cpp @@ -26,32 +26,40 @@ Napi::Object QTabWidgetWrap::init(Napi::Env env, Napi::Object exports) { QWIDGET_WRAPPED_METHODS_EXPORT_DEFINE(QTabWidgetWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); + QOBJECT_REGISTER_WRAPPER(QTabWidget, QTabWidgetWrap); return exports; } -NTabWidget* QTabWidgetWrap::getInternalInstance() { return this->instance; } +QTabWidget* QTabWidgetWrap::getInternalInstance() { return this->instance; } QTabWidgetWrap::~QTabWidgetWrap() { extrautils::safeDelete(this->instance); } QTabWidgetWrap::QTabWidgetWrap(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); - if (info.Length() == 1) { - Napi::Object parentObject = info[0].As(); - NodeWidgetWrap* parentWidgetWrap = - Napi::ObjectWrap::Unwrap(parentObject); - this->instance = new NTabWidget( - parentWidgetWrap - ->getInternalInstance()); // this sets the parent to current widget - } else if (info.Length() == 0) { + size_t argCount = info.Length(); + if (argCount == 0) { + // --- Construct a new instance this->instance = new NTabWidget(); + } else if (argCount == 1) { + if (info[0].IsExternal()) { + // --- Wrap a given C++ instance + this->instance = info[0].As>().Data(); + } else { + // --- Construct a new instance and pass a parent + Napi::Object parentObject = info[0].As(); + NodeWidgetWrap* parentWidgetWrap = + Napi::ObjectWrap::Unwrap(parentObject); + this->instance = new NTabWidget(parentWidgetWrap->getInternalInstance()); + } } else { - Napi::TypeError::New(env, "Wrong number of arguments") + Napi::TypeError::New( + env, + "NodeGui: QTabWidgetWrap: Wrong number of arguments to constructor") .ThrowAsJavaScriptException(); } - this->rawData = extrautils::configureQWidget( - this->getInternalInstance(), this->getInternalInstance()->getFlexNode(), - true); + this->rawData = + extrautils::configureQWidget(this->getInternalInstance(), true); } Napi::Value QTabWidgetWrap::addTab(const Napi::CallbackInfo& info) { diff --git a/src/cpp/lib/QtWidgets/QTableView/qtableview_wrap.cpp b/src/cpp/lib/QtWidgets/QTableView/qtableview_wrap.cpp index 2fe5dfc6d..debf4c6ea 100644 --- a/src/cpp/lib/QtWidgets/QTableView/qtableview_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QTableView/qtableview_wrap.cpp @@ -12,42 +12,38 @@ Napi::Object QTableViewWrap::init(Napi::Env env, Napi::Object exports) { {QTABLEVIEW_WRAPPED_METHODS_EXPORT_DEFINE(QTableViewWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); + QOBJECT_REGISTER_WRAPPER(QTableView, QTableViewWrap); return exports; } -NTableView* QTableViewWrap::getInternalInstance() { return this->instance; } +QTableView* QTableViewWrap::getInternalInstance() { return this->instance; } -QTableViewWrap::~QTableViewWrap() { - if (!this->disableDeletion) { - extrautils::safeDelete(this->instance); - } -} +QTableViewWrap::~QTableViewWrap() { extrautils::safeDelete(this->instance); } QTableViewWrap::QTableViewWrap(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); - this->disableDeletion = false; - if (info.Length() > 0 && info[0].IsExternal()) { - // --- if external --- - this->instance = info[0].As>().Data(); - if (info.Length() == 2) { - this->disableDeletion = info[1].As().Value(); - } - } else { - // --- regular cases --- - if (info.Length() == 1) { + size_t argCount = info.Length(); + if (argCount == 0) { + // --- Construct a new instance + this->instance = new NTableView(); + } else if (argCount == 1) { + if (info[0].IsExternal()) { + // --- Wrap a given C++ instance + this->instance = info[0].As>().Data(); + } else { + // --- Construct a new instance and pass a parent Napi::Object parentObject = info[0].As(); NodeWidgetWrap* parentWidgetWrap = Napi::ObjectWrap::Unwrap(parentObject); this->instance = new NTableView(parentWidgetWrap->getInternalInstance()); - } else if (info.Length() == 0) { - this->instance = new NTableView(); - } else { - Napi::TypeError::New(env, "Wrong number of arguments") - .ThrowAsJavaScriptException(); } + } else { + Napi::TypeError::New( + env, + "NodeGui: QTableViewWrap: Wrong number of arguments to constructor") + .ThrowAsJavaScriptException(); } - this->rawData = extrautils::configureQWidget( - this->getInternalInstance(), this->getInternalInstance()->getFlexNode(), - false); + this->rawData = + extrautils::configureQWidget(this->getInternalInstance(), false); } diff --git a/src/cpp/lib/QtWidgets/QTableWidget/qtablewidget_wrap.cpp b/src/cpp/lib/QtWidgets/QTableWidget/qtablewidget_wrap.cpp index 090089512..3320a5823 100644 --- a/src/cpp/lib/QtWidgets/QTableWidget/qtablewidget_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QTableWidget/qtablewidget_wrap.cpp @@ -86,10 +86,12 @@ Napi::Object QTableWidgetWrap::init(Napi::Env env, Napi::Object exports) { QABSTRACTSCROLLAREA_WRAPPED_METHODS_EXPORT_DEFINE(QTableWidgetWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); + QOBJECT_REGISTER_WRAPPER(QTableWidget, QTableWidgetWrap); return exports; } -NTableWidget* QTableWidgetWrap::getInternalInstance() { return this->instance; } +QTableWidget* QTableWidgetWrap::getInternalInstance() { return this->instance; } + QTableWidgetWrap::~QTableWidgetWrap() { extrautils::safeDelete(this->instance); } @@ -97,34 +99,43 @@ QTableWidgetWrap::~QTableWidgetWrap() { QTableWidgetWrap::QTableWidgetWrap(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); - if (info.Length() == 2 || info.Length() == 3) { - int rows = info[0].As().Int32Value(); - int columns = info[1].As().Int32Value(); - if (info.Length() == 3) { - Napi::Object parentObject = info[2].As(); + size_t argCount = info.Length(); + if (argCount == 0) { + // --- Construct a new instance + this->instance = new NTableWidget(); + } else if (argCount == 1) { + if (info[0].IsExternal()) { + // --- Wrap a given C++ instance + this->instance = info[0].As>().Data(); + } else { + // --- Construct a new instance and pass a parent + Napi::Object parentObject = info[0].As(); NodeWidgetWrap* parentWidgetWrap = Napi::ObjectWrap::Unwrap(parentObject); - this->instance = new NTableWidget( - rows, columns, parentWidgetWrap->getInternalInstance()); - } else { - this->instance = new NTableWidget(rows, columns); + this->instance = + new NTableWidget(parentWidgetWrap->getInternalInstance()); } - - } else if (info.Length() == 1) { - Napi::Object parentObject = info[0].As(); + } else if (argCount == 2) { + int rows = info[0].As().Int32Value(); + int columns = info[1].As().Int32Value(); + this->instance = new NTableWidget(rows, columns); + } else if (argCount == 3) { + int rows = info[0].As().Int32Value(); + int columns = info[1].As().Int32Value(); + Napi::Object parentObject = info[2].As(); NodeWidgetWrap* parentWidgetWrap = Napi::ObjectWrap::Unwrap(parentObject); - this->instance = new NTableWidget(parentWidgetWrap->getInternalInstance()); - } else if (info.Length() == 0) { - this->instance = new NTableWidget(); + this->instance = new NTableWidget(rows, columns, + parentWidgetWrap->getInternalInstance()); } else { - Napi::TypeError::New(env, "Wrong number of arguments") + Napi::TypeError::New( + env, + "NodeGui: QTableWidgetWrap: Wrong number of arguments to constructor") .ThrowAsJavaScriptException(); } - this->rawData = extrautils::configureQWidget( - this->getInternalInstance(), this->getInternalInstance()->getFlexNode(), - false); + this->rawData = + extrautils::configureQWidget(this->getInternalInstance(), false); } Napi::Value QTableWidgetWrap::selectedRanges(const Napi::CallbackInfo& info) { diff --git a/src/cpp/lib/QtWidgets/QTableWidgetItem/qtablewidgetitem_wrap.cpp b/src/cpp/lib/QtWidgets/QTableWidgetItem/qtablewidgetitem_wrap.cpp index b8f75a4cd..626602d9b 100644 --- a/src/cpp/lib/QtWidgets/QTableWidgetItem/qtablewidgetitem_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QTableWidgetItem/qtablewidgetitem_wrap.cpp @@ -65,19 +65,20 @@ QTableWidgetItemWrap::~QTableWidgetItemWrap() { QTableWidgetItemWrap::QTableWidgetItemWrap(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); + size_t argCount = info.Length(); this->disableDeletion = false; - if (info.Length() > 0 && info[0].IsExternal()) { + if (argCount > 0 && info[0].IsExternal()) { // --- if external --- this->instance = info[0].As>().Data(); - if (info.Length() == 2) { + if (argCount == 2) { this->disableDeletion = info[1].As().Value(); } } else { - if (info.Length() == 1) { + if (argCount == 1) { QString text = QString::fromUtf8(info[0].As().Utf8Value().c_str()); this->instance = new QTableWidgetItem(text); - } else if (info.Length() == 0) { + } else if (argCount == 0) { this->instance = new QTableWidgetItem(); } else { Napi::TypeError::New(env, diff --git a/src/cpp/lib/QtWidgets/QTextBrowser/qtextbrowser_wrap.cpp b/src/cpp/lib/QtWidgets/QTextBrowser/qtextbrowser_wrap.cpp index cccc02e7e..cd0e4cd9d 100644 --- a/src/cpp/lib/QtWidgets/QTextBrowser/qtextbrowser_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QTextBrowser/qtextbrowser_wrap.cpp @@ -30,28 +30,39 @@ Napi::Object QTextBrowserWrap::init(Napi::Env env, Napi::Object exports) { QTEXTEDIT_WRAPPED_METHODS_EXPORT_DEFINE(QTextBrowserWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); + QOBJECT_REGISTER_WRAPPER(QTextBrowser, QTextBrowserWrap); return exports; } -NTextBrowser* QTextBrowserWrap::getInternalInstance() { return this->instance; } +QTextBrowser* QTextBrowserWrap::getInternalInstance() { return this->instance; } QTextBrowserWrap::QTextBrowserWrap(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); - if (info.Length() == 1) { - Napi::Object parentObject = info[0].As(); - NodeWidgetWrap* parentWidgetWrap = - Napi::ObjectWrap::Unwrap(parentObject); - this->instance = new NTextBrowser(parentWidgetWrap->getInternalInstance()); - } else if (info.Length() == 0) { + size_t argCount = info.Length(); + if (argCount == 0) { + // --- Construct a new instance this->instance = new NTextBrowser(); + } else if (argCount == 1) { + if (info[0].IsExternal()) { + // --- Wrap a given C++ instance + this->instance = info[0].As>().Data(); + } else { + // --- Construct a new instance and pass a parent + Napi::Object parentObject = info[0].As(); + NodeWidgetWrap* parentWidgetWrap = + Napi::ObjectWrap::Unwrap(parentObject); + this->instance = + new NTextBrowser(parentWidgetWrap->getInternalInstance()); + } } else { - Napi::TypeError::New(env, "Wrong number of arguments") + Napi::TypeError::New( + env, + "NodeGui: QTextBrowserWrap: Wrong number of arguments to constructor") .ThrowAsJavaScriptException(); } - this->rawData = extrautils::configureQWidget( - this->getInternalInstance(), this->getInternalInstance()->getFlexNode(), - true); + this->rawData = + extrautils::configureQWidget(this->getInternalInstance(), true); } QTextBrowserWrap::~QTextBrowserWrap() { diff --git a/src/cpp/lib/QtWidgets/QTextEdit/qtextedit_wrap.cpp b/src/cpp/lib/QtWidgets/QTextEdit/qtextedit_wrap.cpp index 9f7c00595..e0ae6c127 100644 --- a/src/cpp/lib/QtWidgets/QTextEdit/qtextedit_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QTextEdit/qtextedit_wrap.cpp @@ -14,28 +14,37 @@ Napi::Object QTextEditWrap::init(Napi::Env env, Napi::Object exports) { env, CLASSNAME, {QTEXTEDIT_WRAPPED_METHODS_EXPORT_DEFINE(QTextEditWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); + QOBJECT_REGISTER_WRAPPER(QTextEdit, QTextEditWrap); return exports; } -NTextEdit* QTextEditWrap::getInternalInstance() { return this->instance; } +QTextEdit* QTextEditWrap::getInternalInstance() { return this->instance; } QTextEditWrap::QTextEditWrap(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); - if (info.Length() == 1) { - Napi::Object parentObject = info[0].As(); - NodeWidgetWrap* parentWidgetWrap = - Napi::ObjectWrap::Unwrap(parentObject); - this->instance = new NTextEdit(parentWidgetWrap->getInternalInstance()); - } else if (info.Length() == 0) { + size_t argCount = info.Length(); + if (argCount == 0) { + // --- Construct a new instance this->instance = new NTextEdit(); + } else if (argCount == 1) { + if (info[0].IsExternal()) { + // --- Wrap a given C++ instance + this->instance = info[0].As>().Data(); + } else { + // --- Construct a new instance and pass a parent + Napi::Object parentObject = info[0].As(); + NodeWidgetWrap* parentWidgetWrap = + Napi::ObjectWrap::Unwrap(parentObject); + this->instance = new NTextEdit(parentWidgetWrap->getInternalInstance()); + } } else { - Napi::TypeError::New(env, "Wrong number of arguments") + Napi::TypeError::New( + env, "NodeGui: QTextEditWrap: Wrong number of arguments to constructor") .ThrowAsJavaScriptException(); } - this->rawData = extrautils::configureQWidget( - this->getInternalInstance(), this->getInternalInstance()->getFlexNode(), - true); + this->rawData = + extrautils::configureQWidget(this->getInternalInstance(), true); } QTextEditWrap::~QTextEditWrap() { extrautils::safeDelete(this->instance); } diff --git a/src/cpp/lib/QtWidgets/QTimeEdit/qtimeedit_wrap.cpp b/src/cpp/lib/QtWidgets/QTimeEdit/qtimeedit_wrap.cpp index b65ca8046..aad63c731 100644 --- a/src/cpp/lib/QtWidgets/QTimeEdit/qtimeedit_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QTimeEdit/qtimeedit_wrap.cpp @@ -12,28 +12,37 @@ Napi::Object QTimeEditWrap::init(Napi::Env env, Napi::Object exports) { {QDATETIMEEDIT_WRAPPED_METHODS_EXPORT_DEFINE(QTimeEditWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); + QOBJECT_REGISTER_WRAPPER(QTimeEdit, QTimeEditWrap); return exports; } -NTimeEdit* QTimeEditWrap::getInternalInstance() { return this->instance; } +QTimeEdit* QTimeEditWrap::getInternalInstance() { return this->instance; } QTimeEditWrap::QTimeEditWrap(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); - if (info.Length() == 1) { - Napi::Object parentObject = info[0].As(); - NodeWidgetWrap* parentWidgetWrap = - Napi::ObjectWrap::Unwrap(parentObject); - this->instance = new NTimeEdit(parentWidgetWrap->getInternalInstance()); - } else if (info.Length() == 0) { + size_t argCount = info.Length(); + if (argCount == 0) { + // --- Construct a new instance this->instance = new NTimeEdit(); + } else if (argCount == 1) { + if (info[0].IsExternal()) { + // --- Wrap a given C++ instance + this->instance = info[0].As>().Data(); + } else { + // --- Construct a new instance and pass a parent + Napi::Object parentObject = info[0].As(); + NodeWidgetWrap* parentWidgetWrap = + Napi::ObjectWrap::Unwrap(parentObject); + this->instance = new NTimeEdit(parentWidgetWrap->getInternalInstance()); + } } else { - Napi::TypeError::New(env, "Wrong number of arguments") + Napi::TypeError::New( + env, "NodeGui: QTimeEditWrap: Wrong number of arguments to constructor") .ThrowAsJavaScriptException(); } - this->rawData = extrautils::configureQWidget( - this->getInternalInstance(), this->getInternalInstance()->getFlexNode(), - true); + this->rawData = + extrautils::configureQWidget(this->getInternalInstance(), true); } QTimeEditWrap::~QTimeEditWrap() { extrautils::safeDelete(this->instance); } diff --git a/src/cpp/lib/QtWidgets/QToolButton/qtoolbutton_wrap.cpp b/src/cpp/lib/QtWidgets/QToolButton/qtoolbutton_wrap.cpp index e763fbf72..d809aa9d1 100644 --- a/src/cpp/lib/QtWidgets/QToolButton/qtoolbutton_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QToolButton/qtoolbutton_wrap.cpp @@ -18,43 +18,40 @@ Napi::Object QToolButtonWrap::init(Napi::Env env, Napi::Object exports) { QABSTRACTBUTTON_WRAPPED_METHODS_EXPORT_DEFINE(QToolButtonWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); + QOBJECT_REGISTER_WRAPPER(QToolButton, QToolButtonWrap); return exports; } -NToolButton* QToolButtonWrap::getInternalInstance() { return this->instance; } +QToolButton* QToolButtonWrap::getInternalInstance() { return this->instance; } -QToolButtonWrap::~QToolButtonWrap() { - if (!this->disableDeletion) { - extrautils::safeDelete(this->instance); - } -} +QToolButtonWrap::~QToolButtonWrap() { extrautils::safeDelete(this->instance); } QToolButtonWrap::QToolButtonWrap(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); - this->disableDeletion = false; - if (info.Length() > 0 && info[0].IsExternal()) { - // --- if external --- - this->instance = info[0].As>().Data(); - if (info.Length() == 2) { - this->disableDeletion = info[1].As().Value(); - } - } else { - if (info.Length() == 1) { + size_t argCount = info.Length(); + if (argCount == 0) { + // --- Construct a new instance + this->instance = new NToolButton(); + } else if (argCount == 1) { + if (info[0].IsExternal()) { + // --- Wrap a given C++ instance + this->instance = info[0].As>().Data(); + } else { + // --- Construct a new instance and pass a parent Napi::Object parentObject = info[0].As(); NodeWidgetWrap* parentWidgetWrap = Napi::ObjectWrap::Unwrap(parentObject); this->instance = new NToolButton(parentWidgetWrap->getInternalInstance()); - } else if (info.Length() == 0) { - this->instance = new NToolButton(); - } else { - Napi::TypeError::New(env, "Wrong number of arguments") - .ThrowAsJavaScriptException(); } + } else { + Napi::TypeError::New( + env, + "NodeGui: QToolButtonWrap: Wrong number of arguments to constructor") + .ThrowAsJavaScriptException(); } - this->rawData = extrautils::configureQWidget( - this->getInternalInstance(), this->getInternalInstance()->getFlexNode(), - true); + this->rawData = + extrautils::configureQWidget(this->getInternalInstance(), true); } Napi::Value QToolButtonWrap::setMenu(const Napi::CallbackInfo& info) { diff --git a/src/cpp/lib/QtWidgets/QTreeWidget/qtreewidget_wrap.cpp b/src/cpp/lib/QtWidgets/QTreeWidget/qtreewidget_wrap.cpp index 618ee9740..19884ed7c 100644 --- a/src/cpp/lib/QtWidgets/QTreeWidget/qtreewidget_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QTreeWidget/qtreewidget_wrap.cpp @@ -32,28 +32,38 @@ Napi::Object QTreeWidgetWrap::init(Napi::Env env, Napi::Object exports) { QWIDGET_WRAPPED_METHODS_EXPORT_DEFINE(QTreeWidgetWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); + QOBJECT_REGISTER_WRAPPER(QTreeWidget, QTreeWidgetWrap); return exports; } -NTreeWidget* QTreeWidgetWrap::getInternalInstance() { return this->instance; } +QTreeWidget* QTreeWidgetWrap::getInternalInstance() { return this->instance; } QTreeWidgetWrap::QTreeWidgetWrap(const Napi::CallbackInfo& info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); - if (info.Length() == 1) { - Napi::Object parentObject = info[0].As(); - NodeWidgetWrap* parentWidgetWrap = - Napi::ObjectWrap::Unwrap(parentObject); - this->instance = new NTreeWidget(parentWidgetWrap->getInternalInstance()); - } else if (info.Length() == 0) { + size_t argCount = info.Length(); + if (argCount == 0) { + // --- Construct a new instance this->instance = new NTreeWidget(); + } else if (argCount == 1) { + if (info[0].IsExternal()) { + // --- Wrap a given C++ instance + this->instance = info[0].As>().Data(); + } else { + // --- Construct a new instance and pass a parent + Napi::Object parentObject = info[0].As(); + NodeWidgetWrap* parentWidgetWrap = + Napi::ObjectWrap::Unwrap(parentObject); + this->instance = new NTreeWidget(parentWidgetWrap->getInternalInstance()); + } } else { - Napi::TypeError::New(env, "Wrong number of arguments") + Napi::TypeError::New( + env, + "NodeGui: QTreeWidgetWrap: Wrong number of arguments to constructor") .ThrowAsJavaScriptException(); } - this->rawData = extrautils::configureQWidget( - this->getInternalInstance(), this->getInternalInstance()->getFlexNode(), - true); + this->rawData = + extrautils::configureQWidget(this->getInternalInstance(), true); } QTreeWidgetWrap::~QTreeWidgetWrap() { extrautils::safeDelete(this->instance); } diff --git a/src/cpp/lib/QtWidgets/QWidget/qwidget_wrap.cpp b/src/cpp/lib/QtWidgets/QWidget/qwidget_wrap.cpp index 3d0976535..272a5db35 100644 --- a/src/cpp/lib/QtWidgets/QWidget/qwidget_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QWidget/qwidget_wrap.cpp @@ -12,34 +12,37 @@ Napi::Object QWidgetWrap::init(Napi::Env env, Napi::Object exports) { env, CLASSNAME, {QWIDGET_WRAPPED_METHODS_EXPORT_DEFINE(QWidgetWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); - QOBJECT_REGISTER_WRAPPER(NWidget, QWidgetWrap); + QOBJECT_REGISTER_WRAPPER(QWidget, QWidgetWrap); return exports; } -NWidget *QWidgetWrap::getInternalInstance() { return this->instance; } +QWidget *QWidgetWrap::getInternalInstance() { return this->instance; } QWidgetWrap::~QWidgetWrap() { extrautils::safeDelete(this->instance); } QWidgetWrap::QWidgetWrap(const Napi::CallbackInfo &info) : Napi::ObjectWrap(info) { Napi::Env env = info.Env(); - if (info.Length() == 1) { + size_t argCount = info.Length(); + if (argCount == 0) { + // --- Construct a new instance + this->instance = new NWidget(); + } else if (argCount == 1) { if (info[0].IsExternal()) { - this->instance = - new NWidget(info[0].As>().Data()); + // --- Wrap a given C++ instance + this->instance = info[0].As>().Data(); } else { + // --- Construct a new instance and pass a parent Napi::Object parentObject = info[0].As(); NodeWidgetWrap *parentWidgetWrap = Napi::ObjectWrap::Unwrap(parentObject); this->instance = new NWidget(parentWidgetWrap->getInternalInstance()); } - } else if (info.Length() == 0) { - this->instance = new NWidget(); } else { - Napi::TypeError::New(env, "Wrong number of arguments") + Napi::TypeError::New( + env, "NodeGui: QWidgetWrap: Wrong number of arguments to constructor") .ThrowAsJavaScriptException(); } - this->rawData = extrautils::configureQWidget( - this->getInternalInstance(), this->getInternalInstance()->getFlexNode(), - false); + this->rawData = + extrautils::configureQWidget(this->getInternalInstance(), false); } diff --git a/src/cpp/main.cpp b/src/cpp/main.cpp index 90b135276..39609727a 100644 --- a/src/cpp/main.cpp +++ b/src/cpp/main.cpp @@ -122,16 +122,14 @@ #include "test/cachetestqobject_wrap.h" // These cant be instantiated in JS Side -void InitPrivateHelpers(Napi::Env env) { - qodeIntegration::integrate(); - QLayoutWrap::init(env); // Abstact class wrapper for pointing to any layout -} +void InitPrivateHelpers(Napi::Env env) { qodeIntegration::integrate(); } Napi::Object Main(Napi::Env env, Napi::Object exports) { InitPrivateHelpers(env); NUtilsWrap::init(env, exports); WrapperCache::init(env, exports); QApplicationWrap::init(env, exports); + QLayoutWrap::init(env, exports); QDateWrap::init(env, exports); QDateTimeWrap::init(env, exports); QMimeDataWrap::init(env, exports); diff --git a/src/lib/QtCore/QObject.ts b/src/lib/QtCore/QObject.ts index b3b4ad450..34899473f 100644 --- a/src/lib/QtCore/QObject.ts +++ b/src/lib/QtCore/QObject.ts @@ -21,8 +21,6 @@ export class QObject extends Ev super(native); wrapperCache.store(this); - - this.setNodeParent(parent); } inherits(className: string): boolean { diff --git a/src/lib/QtWidgets/QAbstractScrollArea.ts b/src/lib/QtWidgets/QAbstractScrollArea.ts index 7fb63a4ac..5e786404b 100644 --- a/src/lib/QtWidgets/QAbstractScrollArea.ts +++ b/src/lib/QtWidgets/QAbstractScrollArea.ts @@ -3,6 +3,7 @@ import { QFrame, QFrameSignals } from './QFrame'; import { ScrollBarPolicy } from '../QtEnums/ScrollBarPolicy'; import { QSize } from '../QtCore/QSize'; import { QScrollBar } from './QScrollBar'; +import { wrapperCache } from '../core/WrapperCache'; /** @@ -18,16 +19,11 @@ QAbstractScrollArea will list all methods and properties that are common to all */ export abstract class QAbstractScrollArea extends QFrame { - viewportWidget?: QWidget; setViewport(widget: QWidget): void { - this.viewportWidget = widget; this.native.setViewport(widget.native); } viewport(): QWidget { - if (!this.viewportWidget) { - this.viewportWidget = new QWidget(this.native.viewport()); - } - return this.viewportWidget; + return wrapperCache.getWrapper(this.native.viewport()) as QWidget; } maximumViewportSize(): QSize { return this.native.maximumViewportSize(); diff --git a/src/lib/QtWidgets/QAction.ts b/src/lib/QtWidgets/QAction.ts index d79e8ef90..096cc3ecc 100644 --- a/src/lib/QtWidgets/QAction.ts +++ b/src/lib/QtWidgets/QAction.ts @@ -9,6 +9,7 @@ import { ShortcutContext } from '../QtEnums'; import { QObject, QObjectSignals } from '../QtCore/QObject'; import { checkIfNativeElement } from '../utils/helpers'; import { QVariant } from '../QtCore/QVariant'; +import { wrapperCache } from '../core/WrapperCache'; /** @@ -34,11 +35,12 @@ export class QAction extends QObject { constructor(); constructor(native: NativeElement); constructor(parent: QWidget); - constructor(parent?: NativeElement | QWidget) { + constructor(arg?: NativeElement | QWidget) { let native: NativeElement; - if (checkIfNativeElement(parent)) { - native = parent as NativeElement; - } else if (parent) { + if (checkIfNativeElement(arg)) { + native = arg as NativeElement; + } else if (arg) { + const parent = arg as QWidget; native = new addon.QAction(parent.native); } else { native = new addon.QAction(); @@ -101,3 +103,4 @@ export interface QActionSignals extends QObjectSignals { hovered: () => void; toggled: (checked: boolean) => void; } +wrapperCache.registerWrapper('QActionWrap', QAction); diff --git a/src/lib/QtWidgets/QBoxLayout.ts b/src/lib/QtWidgets/QBoxLayout.ts index 5c57c4935..731939284 100644 --- a/src/lib/QtWidgets/QBoxLayout.ts +++ b/src/lib/QtWidgets/QBoxLayout.ts @@ -3,6 +3,8 @@ import { QWidget } from './QWidget'; import { QLayout, QLayoutSignals } from './QLayout'; import { NativeElement } from '../core/Component'; import { AlignmentFlag, Direction } from '../QtEnums'; +import { checkIfNativeElement } from '../utils/helpers'; +import { wrapperCache } from '../core/WrapperCache'; /** @@ -26,21 +28,19 @@ centralWidget.setLayout(boxLayout); ``` */ export class QBoxLayout extends QLayout { - childLayouts: Set; - constructor(dir: Direction, parent?: QWidget) { + constructor(arg: NativeElement | Direction, parent?: QWidget) { let native: NativeElement; - if (parent) { - native = new addon.QBoxLayout(dir, parent.native); + if (checkIfNativeElement(arg)) { + native = arg as NativeElement; + } else if (parent) { + native = new addon.QBoxLayout(arg as Direction, parent.native); } else { - native = new addon.QBoxLayout(dir); + native = new addon.QBoxLayout(arg as Direction); } super(native); - this.setNodeParent(parent); - this.childLayouts = new Set(); } - addLayout(layout: QLayout, stretch = 0): void { + addLayout(layout: QLayout, stretch = 0): void { this.native.addLayout(layout.native, stretch); - this.childLayouts.add(layout); } addSpacing(size: number): void { this.native.addSpacing(size); @@ -53,18 +53,15 @@ export class QBoxLayout extends QLayout { } addWidget(widget: QWidget, stretch = 0, alignment: AlignmentFlag = 0): void { this.native.addWidget(widget.native, stretch, alignment); - this.nodeChildren.add(widget); } insertWidget(index: number, widget: QWidget, stretch = 0): void { this.native.insertWidget(index, widget.native, stretch); - this.nodeChildren.add(widget); } direction(): Direction { return this.native.direction(); } insertLayout(index: number, layout: QLayout, stretch = 0): void { this.native.insertLayout(index, layout.native, stretch); - this.childLayouts.add(layout); } insertSpacing(index: number, size: number): void { this.native.insertSpacing(index, size); @@ -74,7 +71,6 @@ export class QBoxLayout extends QLayout { } removeWidget(widget: QWidget): void { this.native.removeWidget(widget.native); - this.nodeChildren.delete(widget); } setDirection(dir: Direction): void { this.native.setDirection(dir); @@ -86,5 +82,6 @@ export class QBoxLayout extends QLayout { return this.native.count(); } } +wrapperCache.registerWrapper('QBoxLayoutWrap', QBoxLayout); export type QBoxLayoutSignals = QLayoutSignals; diff --git a/src/lib/QtWidgets/QButtonGroup.ts b/src/lib/QtWidgets/QButtonGroup.ts index acfccc633..c18cd8e9d 100644 --- a/src/lib/QtWidgets/QButtonGroup.ts +++ b/src/lib/QtWidgets/QButtonGroup.ts @@ -1,31 +1,33 @@ import addon from '../utils/addon'; import { QWidget } from './QWidget'; -import { NativeRawPointer } from '../core/Component'; +import { NativeElement, NativeRawPointer } from '../core/Component'; import { QObject, QObjectSignals } from '../QtCore/QObject'; import { QAbstractButton, QAbstractButtonSignals } from './QAbstractButton'; +import { checkIfNativeElement } from '../utils/helpers'; +import { wrapperCache } from '../core/WrapperCache'; export interface QButtonGroupSignals extends QObjectSignals { buttonClicked: (id?: number) => void; } export class QButtonGroup extends QObject { - constructor(parent?: QWidget) { + constructor(arg?: NativeElement | QWidget) { let native; - if (parent) { + if (checkIfNativeElement(arg)) { + native = arg as NativeElement; + } else if (arg) { + const parent = arg as QWidget; native = new addon.QButtonGroup(parent.native); } else { native = new addon.QButtonGroup(); } super(native); - parent && parent.nodeChildren.add(this); } addButton(button: QAbstractButton, id = -1): void { this.native.addButton(button.native, id); - this.nodeChildren.add(button); } removeButton(button: QAbstractButton): void { this.native.removeButton(button.native); - this.nodeChildren.delete(button); } setExclusive(exculsive: boolean): void { this.native.setProperty('exclusive', exculsive); @@ -52,3 +54,4 @@ export class QButtonGroup extends QObject { return this.native.button(id); } } +wrapperCache.registerWrapper('QButtonGroupWrap', QButtonGroup); diff --git a/src/lib/QtWidgets/QCalendarWidget.ts b/src/lib/QtWidgets/QCalendarWidget.ts index 82c4f026f..b3cd0154d 100644 --- a/src/lib/QtWidgets/QCalendarWidget.ts +++ b/src/lib/QtWidgets/QCalendarWidget.ts @@ -3,6 +3,8 @@ import { QWidget, QWidgetSignals } from './QWidget'; import { NativeElement } from '../core/Component'; import { QDate } from '../QtCore/QDate'; import { DayOfWeek } from '../QtEnums'; +import { checkIfNativeElement } from '../utils/helpers'; +import { wrapperCache } from '../core/WrapperCache'; /** @@ -22,15 +24,17 @@ const calendarWidget = new QCalendarWidget(); ``` */ export class QCalendarWidget extends QWidget { - constructor(parent?: QWidget) { + constructor(arg?: NativeElement | QWidget) { let native: NativeElement; - if (parent) { + if (checkIfNativeElement(arg)) { + native = arg as NativeElement; + } else if (arg as QWidget) { + const parent = arg as QWidget; native = new addon.QCalendarWidget(parent.native); } else { native = new addon.QCalendarWidget(); } super(native); - this.setNodeParent(parent); } setDateEditAcceptDelay(delay: number): void { this.setProperty('dateEditAcceptDelay', delay); @@ -81,6 +85,7 @@ export class QCalendarWidget extends QWidget { return this.property('verticalHeaderFormat').toInt(); } } +wrapperCache.registerWrapper('QCalendarWidgetWrap', QCalendarWidget); export enum HorizontalHeaderFormat { NoHorizontalHeader, diff --git a/src/lib/QtWidgets/QCheckBox.ts b/src/lib/QtWidgets/QCheckBox.ts index 8507ade5f..eeddd433c 100644 --- a/src/lib/QtWidgets/QCheckBox.ts +++ b/src/lib/QtWidgets/QCheckBox.ts @@ -1,9 +1,10 @@ import addon from '../utils/addon'; import { QWidget } from './QWidget'; -import { NativeElement, NativeRawPointer, Component } from '../core/Component'; +import { NativeElement, NativeRawPointer } from '../core/Component'; import { QAbstractButton, QAbstractButtonSignals } from './QAbstractButton'; import { checkIfNativeElement, checkIfNapiExternal } from '../utils/helpers'; import { CheckState } from '../QtEnums'; +import { wrapperCache } from '../core/WrapperCache'; /** @@ -25,23 +26,20 @@ checkbox.setText("Hello"); export class QCheckBox extends QAbstractButton { constructor(); constructor(parent: QWidget); - constructor(rawPointer: NativeRawPointer, disableNativeDeletion?: boolean); - constructor(arg?: QWidget | NativeRawPointer | NativeElement, disableNativeDeletion = true) { + constructor(rawPointer: NativeRawPointer); + constructor(arg?: QWidget | NativeRawPointer | NativeElement) { let native; - let parent: Component | undefined; if (checkIfNativeElement(arg)) { native = arg as NativeElement; } else if (checkIfNapiExternal(arg)) { - native = new addon.QCheckBox(arg, disableNativeDeletion); + native = new addon.QCheckBox(arg); } else if (arg) { const parentWidget = arg as QWidget; native = new addon.QCheckBox(parentWidget.native); - parent = parentWidget; } else { native = new addon.QCheckBox(); } super(native); - parent && this.setNodeParent(parent); } setTristate(y = true): void { this.setProperty('tristate', y); @@ -56,6 +54,7 @@ export class QCheckBox extends QAbstractButton { this.native.setCheckState(state); } } +wrapperCache.registerWrapper('QCheckBoxWrap', QCheckBox); export interface QCheckBoxSignals extends QAbstractButtonSignals { stateChanged: (state: number) => void; diff --git a/src/lib/QtWidgets/QColorDialog.ts b/src/lib/QtWidgets/QColorDialog.ts index fcd6941cc..8699f5843 100644 --- a/src/lib/QtWidgets/QColorDialog.ts +++ b/src/lib/QtWidgets/QColorDialog.ts @@ -35,7 +35,6 @@ export class QColorDialog extends QDialog { native = new addon.QColorDialog(); } super(native); - parent && this.setNodeParent(parent); } setCurrentColor(color: QColor): void { this.setProperty('currentColor', color.native); diff --git a/src/lib/QtWidgets/QComboBox.ts b/src/lib/QtWidgets/QComboBox.ts index f25812da8..19b00ba06 100644 --- a/src/lib/QtWidgets/QComboBox.ts +++ b/src/lib/QtWidgets/QComboBox.ts @@ -45,7 +45,6 @@ export class QComboBox extends QWidget { native = new addon.QComboBox(); } super(native); - this.setNodeParent(parent); } // *** Public Functions *** addItem(icon: QIcon | undefined, text: string, userData: QVariant = new QVariant()): void { diff --git a/src/lib/QtWidgets/QDateEdit.ts b/src/lib/QtWidgets/QDateEdit.ts index a80e4ce3a..d1f9a9530 100644 --- a/src/lib/QtWidgets/QDateEdit.ts +++ b/src/lib/QtWidgets/QDateEdit.ts @@ -29,6 +29,5 @@ export class QDateEdit extends QDateTimeEdit { native = new addon.QDateEdit(); } super(native); - this.setNodeParent(parent); } } diff --git a/src/lib/QtWidgets/QDateTimeEdit.ts b/src/lib/QtWidgets/QDateTimeEdit.ts index b09d8360f..140569098 100644 --- a/src/lib/QtWidgets/QDateTimeEdit.ts +++ b/src/lib/QtWidgets/QDateTimeEdit.ts @@ -37,19 +37,15 @@ export class QDateTimeEdit extends QAbstractSpinBox { constructor(arg?: QWidget | NativeElement) { let native: NativeElement; - let parent: QWidget = null; if (checkIfNativeElement(arg)) { native = arg as NativeElement; } else if (arg) { - parent = arg as QWidget; + const parent = arg as QWidget; native = new addon.QDateTimeEdit(parent.native); } else { native = new addon.QDateTimeEdit(); } super(native); - if (parent != null) { - this.setNodeParent(parent); - } } setCalendarWidget(calendarWidget: QCalendarWidget): void { diff --git a/src/lib/QtWidgets/QDial.ts b/src/lib/QtWidgets/QDial.ts index 5fa4c8abd..8982bc018 100644 --- a/src/lib/QtWidgets/QDial.ts +++ b/src/lib/QtWidgets/QDial.ts @@ -30,7 +30,6 @@ export class QDial extends QAbstractSlider { native = new addon.QDial(); } super(native); - this.setNodeParent(parent); } notchSize(): number { return this.property('notchSize').toInt(); diff --git a/src/lib/QtWidgets/QDialog.ts b/src/lib/QtWidgets/QDialog.ts index fdf692670..26e22bd49 100644 --- a/src/lib/QtWidgets/QDialog.ts +++ b/src/lib/QtWidgets/QDialog.ts @@ -26,7 +26,6 @@ export class QDialog extends QW native = new addon.QDialog(); } super(native); - this.setNodeParent(parent); } setResult(i: number): void { diff --git a/src/lib/QtWidgets/QDoubleSpinBox.ts b/src/lib/QtWidgets/QDoubleSpinBox.ts index 589c96805..8e1fe54f9 100644 --- a/src/lib/QtWidgets/QDoubleSpinBox.ts +++ b/src/lib/QtWidgets/QDoubleSpinBox.ts @@ -28,7 +28,6 @@ export class QDoubleSpinBox extends QAbstractSpinBox { native = new addon.QDoubleSpinBox(); } super(native); - parent && this.setNodeParent(parent); } cleanText(): string { return this.property('cleanText').toString(); diff --git a/src/lib/QtWidgets/QErrorMessage.ts b/src/lib/QtWidgets/QErrorMessage.ts index 431a503be..03fee08b6 100644 --- a/src/lib/QtWidgets/QErrorMessage.ts +++ b/src/lib/QtWidgets/QErrorMessage.ts @@ -29,7 +29,6 @@ export class QErrorMessage extends QDialog { native = new addon.QErrorMessage(); } super(native); - parent && this.setNodeParent(parent); } showMessage(message: string): void { this.native.showMessage(message); diff --git a/src/lib/QtWidgets/QFileDialog.ts b/src/lib/QtWidgets/QFileDialog.ts index 0d5243f41..a5b0c55f4 100644 --- a/src/lib/QtWidgets/QFileDialog.ts +++ b/src/lib/QtWidgets/QFileDialog.ts @@ -38,7 +38,6 @@ export class QFileDialog extends QDialog { native = new addon.QFileDialog(); } super(native); - this.setNodeParent(parent); } supportedSchemes(): string[] { return this.native.supportedSchemes(); diff --git a/src/lib/QtWidgets/QFontDialog.ts b/src/lib/QtWidgets/QFontDialog.ts index f8c6bb308..41b9f1857 100644 --- a/src/lib/QtWidgets/QFontDialog.ts +++ b/src/lib/QtWidgets/QFontDialog.ts @@ -33,7 +33,6 @@ export class QFontDialog extends QDialog { native = new addon.QFontDialog(); } super(native); - parent && this.setNodeParent(parent); } setCurrentFont(font: QFont): void { this.setProperty('currentFont', font.native); diff --git a/src/lib/QtWidgets/QFrame.ts b/src/lib/QtWidgets/QFrame.ts index bac971517..aabdaaace 100644 --- a/src/lib/QtWidgets/QFrame.ts +++ b/src/lib/QtWidgets/QFrame.ts @@ -32,7 +32,6 @@ export class QFrame extends QWidg native = new addon.QFrame(); } super(native); - this.setNodeParent(parent); } setFrameRect(r: QRect): void { diff --git a/src/lib/QtWidgets/QGridLayout.ts b/src/lib/QtWidgets/QGridLayout.ts index 9672d8fe0..89485aed6 100644 --- a/src/lib/QtWidgets/QGridLayout.ts +++ b/src/lib/QtWidgets/QGridLayout.ts @@ -38,7 +38,6 @@ export class QGridLayout extends QLayout { native = new addon.QGridLayout(); } super(native); - this.setNodeParent(parent); } addLayout( @@ -54,11 +53,9 @@ export class QGridLayout extends QLayout { addWidget(widget: QWidget, row = 0, col = 0, rowSpan = 1, colSpan = 1, alignment: AlignmentFlag = 0): void { this.native.addWidget(widget.native, row, col, rowSpan, colSpan, alignment); - this.nodeChildren.add(widget); } removeWidget(widget: QWidget): void { this.native.removeWidget(widget.native); - this.nodeChildren.delete(widget); } columnStretch(column: number): number { return this.native.columnStretch(column); diff --git a/src/lib/QtWidgets/QGroupBox.ts b/src/lib/QtWidgets/QGroupBox.ts index 13f590a32..98e613f0a 100644 --- a/src/lib/QtWidgets/QGroupBox.ts +++ b/src/lib/QtWidgets/QGroupBox.ts @@ -48,7 +48,6 @@ export class QGroupBox extends QWidget { native = new addon.QGroupBox(); } super(native); - this.setNodeParent(parent); } setAlignment(alignment: AlignmentFlag): void { this.setProperty('alignment', alignment); diff --git a/src/lib/QtWidgets/QHeaderView.ts b/src/lib/QtWidgets/QHeaderView.ts index 70f68f803..1ae937c71 100644 --- a/src/lib/QtWidgets/QHeaderView.ts +++ b/src/lib/QtWidgets/QHeaderView.ts @@ -24,7 +24,6 @@ export class QHeaderView { native = new addon.QInputDialog(); } super(native); - this.setNodeParent(parent); } setCancelButtonText(text: string): void { this.native.setCancelButtonText(text); diff --git a/src/lib/QtWidgets/QLCDNumber.ts b/src/lib/QtWidgets/QLCDNumber.ts index 79ee70293..53c1d6475 100644 --- a/src/lib/QtWidgets/QLCDNumber.ts +++ b/src/lib/QtWidgets/QLCDNumber.ts @@ -28,7 +28,6 @@ export class QLCDNumber extends QWidget { native = new addon.QLCDNumber(); } super(native); - parent && this.setNodeParent(parent); } setDigitCount(numDigits: number): void { this.setProperty('digitCount', numDigits); diff --git a/src/lib/QtWidgets/QLabel.ts b/src/lib/QtWidgets/QLabel.ts index b71c10679..0afcd2c86 100644 --- a/src/lib/QtWidgets/QLabel.ts +++ b/src/lib/QtWidgets/QLabel.ts @@ -40,7 +40,6 @@ export class QLabel extends QFrame { native = new addon.QLabel(); } super(native); - this.setNodeParent(parent); } setAlignment(alignment: AlignmentFlag): void { this.setProperty('alignment', alignment); diff --git a/src/lib/QtWidgets/QLineEdit.ts b/src/lib/QtWidgets/QLineEdit.ts index 9fb2bc46d..3ad55ee80 100644 --- a/src/lib/QtWidgets/QLineEdit.ts +++ b/src/lib/QtWidgets/QLineEdit.ts @@ -30,7 +30,6 @@ export class QLineEdit extends QWidget { native = new addon.QLineEdit(); } super(native); - this.setNodeParent(parent); } // TODO: void addAction(QAction *action, QLineEdit::ActionPosition position) // TODO: QAction * addAction(const QIcon &icon, QLineEdit::ActionPosition position) diff --git a/src/lib/QtWidgets/QListView.ts b/src/lib/QtWidgets/QListView.ts index 745d131c7..1e0c26873 100644 --- a/src/lib/QtWidgets/QListView.ts +++ b/src/lib/QtWidgets/QListView.ts @@ -4,6 +4,7 @@ import { NativeElement } from '../core/Component'; import { QAbstractItemView, QAbstractItemViewSignals } from './QAbstractItemView'; import { QSize } from '../QtCore/QSize'; import { AlignmentFlag } from '../..'; +import { checkIfNativeElement } from '../utils/helpers'; /** @@ -21,15 +22,17 @@ const listview = new QListView(); ``` */ export class QListView extends QAbstractItemView { - constructor(parent?: QWidget) { + constructor(arg?: QWidget | NativeElement) { let native: NativeElement; - if (parent) { + if (checkIfNativeElement(arg)) { + native = arg as NativeElement; + } else if (arg != null) { + const parent = arg as QWidget; native = new addon.QListView(parent.native); } else { native = new addon.QListView(); } super(native); - parent && this.setNodeParent(parent); } setBatchSize(batchSize: number): void { this.setProperty('batchSize', batchSize); diff --git a/src/lib/QtWidgets/QListWidget.ts b/src/lib/QtWidgets/QListWidget.ts index a74b300ef..c7d1d0c88 100644 --- a/src/lib/QtWidgets/QListWidget.ts +++ b/src/lib/QtWidgets/QListWidget.ts @@ -43,7 +43,6 @@ export class QListWidget extends QListView { native = new addon.QListWidget(); } super(native); - parent && this.setNodeParent(parent); this.items = new Set(); } count(): number { diff --git a/src/lib/QtWidgets/QMainWindow.ts b/src/lib/QtWidgets/QMainWindow.ts index bd906c702..90b2710d7 100644 --- a/src/lib/QtWidgets/QMainWindow.ts +++ b/src/lib/QtWidgets/QMainWindow.ts @@ -44,14 +44,12 @@ export class QMainWindow extends QWidget { native = new addon.QMainWindow(); } super(native); - this.setNodeParent(parent); this.setLayout = (parentLayout: QLayout): void => { if (this.centralWidget) { this.centralWidget.setLayout(parentLayout); } else { this.native.setLayout(parentLayout.native); - super.layout = parentLayout; } }; } @@ -80,11 +78,11 @@ export class QMainWindow extends QWidget { setMenuWidget(menuWidget: QWidget): void { this.native.setMenuWidget(menuWidget.native); } - get layout(): QLayout | undefined { + layout(): QLayout | undefined { if (this.centralWidget) { - return this.centralWidget.layout; + return this.centralWidget.layout(); } - return super.layout; + return super.layout(); } center(): void { this.native.center(); diff --git a/src/lib/QtWidgets/QMenu.ts b/src/lib/QtWidgets/QMenu.ts index c9569ed06..e5f59ae8b 100644 --- a/src/lib/QtWidgets/QMenu.ts +++ b/src/lib/QtWidgets/QMenu.ts @@ -27,7 +27,6 @@ export class QMenu extends QWidget { native = new addon.QMenu(); } super(native); - this.setNodeParent(parent); } clear(): void { this.native.clear(); diff --git a/src/lib/QtWidgets/QMenuBar.ts b/src/lib/QtWidgets/QMenuBar.ts index e74e0c779..01a2f8ffc 100644 --- a/src/lib/QtWidgets/QMenuBar.ts +++ b/src/lib/QtWidgets/QMenuBar.ts @@ -28,18 +28,15 @@ export class QMenuBar extends QWidget { constructor(arg?: QWidget | NativeElement) { let native; - let parent; if (checkIfNativeElement(arg)) { native = arg as NativeElement; } else if (typeof arg === 'object') { native = new addon.QMenuBar(arg.native); - parent = arg as QWidget; } else { native = new addon.QMenuBar(); } super(native); this._menus = new Set(); - this.setNodeParent(parent); } addMenu(menu: QMenu | string): QMenu { if (typeof menu === 'string') { diff --git a/src/lib/QtWidgets/QMessageBox.ts b/src/lib/QtWidgets/QMessageBox.ts index 7c08774e3..c120b7be6 100644 --- a/src/lib/QtWidgets/QMessageBox.ts +++ b/src/lib/QtWidgets/QMessageBox.ts @@ -48,7 +48,6 @@ export class QMessageBox extends QDialog { native = new addon.QMessageBox(); } super(native); - this.setNodeParent(parent); } accept(): void { this.native.accept(); @@ -78,12 +77,10 @@ export class QMessageBox extends QDialog { setDefaultButton(button: QPushButton): void { this.native.setDefaultButton(button); - this.nodeChildren.add(button); } addButton(button: QAbstractButton, role: ButtonRole = ButtonRole.NoRole): void { this.native.addButton(button.native, role); - this.nodeChildren.add(button); } static about(parent: QWidget, title: string, text: string): void { diff --git a/src/lib/QtWidgets/QPlainTextEdit.ts b/src/lib/QtWidgets/QPlainTextEdit.ts index a620ab5b0..f1daa7b60 100644 --- a/src/lib/QtWidgets/QPlainTextEdit.ts +++ b/src/lib/QtWidgets/QPlainTextEdit.ts @@ -41,7 +41,6 @@ export class QPlainTextEdit extends QAbstractScrollArea { native = new addon.QPlainTextEdit(); } super(native); - this.setNodeParent(parent); } setPlainText(text: string | number): void { // react:✓ diff --git a/src/lib/QtWidgets/QProgressBar.ts b/src/lib/QtWidgets/QProgressBar.ts index c075e28a1..5b6a91012 100644 --- a/src/lib/QtWidgets/QProgressBar.ts +++ b/src/lib/QtWidgets/QProgressBar.ts @@ -28,7 +28,6 @@ export class QProgressBar extends QWidget { native = new addon.QProgressBar(); } super(native); - this.setNodeParent(parent); } setAlignment(alignment: AlignmentFlag): void { this.setProperty('alignment', alignment); diff --git a/src/lib/QtWidgets/QProgressDialog.ts b/src/lib/QtWidgets/QProgressDialog.ts index 031d82e70..5226948e3 100644 --- a/src/lib/QtWidgets/QProgressDialog.ts +++ b/src/lib/QtWidgets/QProgressDialog.ts @@ -28,7 +28,6 @@ export class QProgressDialog extends QDialog { native = new addon.QProgressDialog(); } super(native); - parent && this.setNodeParent(parent); } setAutoClose(close: boolean): void { this.setProperty('autoClose', close); diff --git a/src/lib/QtWidgets/QPushButton.ts b/src/lib/QtWidgets/QPushButton.ts index dcdf7b724..c13aa042c 100644 --- a/src/lib/QtWidgets/QPushButton.ts +++ b/src/lib/QtWidgets/QPushButton.ts @@ -1,6 +1,6 @@ import addon from '../utils/addon'; import { QWidget } from './QWidget'; -import { NativeElement, NativeRawPointer, Component } from '../core/Component'; +import { NativeElement, NativeRawPointer } from '../core/Component'; import { QAbstractButton, QAbstractButtonSignals } from './QAbstractButton'; import { checkIfNativeElement, checkIfNapiExternal } from '../utils/helpers'; import { QMenu } from './QMenu'; @@ -27,7 +27,6 @@ export class QPushButton extends QAbstractButton { constructor(arg?: QWidget | NativeRawPointer | NativeElement, disableNativeDeletion = true) { let native; - let parent: Component | undefined; if (checkIfNativeElement(arg)) { native = arg as NativeElement; } else if (checkIfNapiExternal(arg)) { @@ -35,12 +34,10 @@ export class QPushButton extends QAbstractButton { } else if (arg) { const parentWidget = arg as QWidget; native = new addon.QPushButton(parentWidget.native); - parent = parentWidget; } else { native = new addon.QPushButton(); } super(native); - parent && this.setNodeParent(parent); } setAutoDefault(auto: boolean): void { this.setProperty('autoDefault', auto); diff --git a/src/lib/QtWidgets/QRadioButton.ts b/src/lib/QtWidgets/QRadioButton.ts index a274eac9c..f0ee99cf1 100644 --- a/src/lib/QtWidgets/QRadioButton.ts +++ b/src/lib/QtWidgets/QRadioButton.ts @@ -1,6 +1,6 @@ import addon from '../utils/addon'; import { QWidget } from './QWidget'; -import { NativeElement, NativeRawPointer, Component } from '../core/Component'; +import { NativeElement, NativeRawPointer } from '../core/Component'; import { QAbstractButton, QAbstractButtonSignals } from './QAbstractButton'; import { checkIfNativeElement, checkIfNapiExternal } from '../utils/helpers'; @@ -25,7 +25,6 @@ radioButton.setText("Hello"); export class QRadioButton extends QAbstractButton { constructor(arg?: QWidget | NativeRawPointer | NativeElement, disableNativeDeletion = true) { let native; - let parent: Component | undefined; if (checkIfNativeElement(arg)) { native = arg as NativeElement; } else if (checkIfNapiExternal(arg)) { @@ -33,12 +32,10 @@ export class QRadioButton extends QAbstractButton { } else if (arg) { const parentWidget = arg as QWidget; native = new addon.QRadioButton(parentWidget.native); - parent = parentWidget; } else { native = new addon.QRadioButton(); } super(native); - parent && this.setNodeParent(parent); } } diff --git a/src/lib/QtWidgets/QScrollArea.ts b/src/lib/QtWidgets/QScrollArea.ts index c601bd83f..1dc6eb8db 100644 --- a/src/lib/QtWidgets/QScrollArea.ts +++ b/src/lib/QtWidgets/QScrollArea.ts @@ -4,6 +4,7 @@ import { NativeElement } from '../core/Component'; import { QAbstractScrollArea, QAbstractScrollAreaSignals } from './QAbstractScrollArea'; import { AlignmentFlag } from '../QtEnums'; import { Margins } from '../utils/Margins'; +import { wrapperCache } from '../core/WrapperCache'; /** @@ -29,7 +30,6 @@ scrollArea.setWidget(imageLabel); ``` */ export class QScrollArea extends QAbstractScrollArea { - contentWidget?: QWidget | null; constructor(parent?: QWidget) { let native: NativeElement; if (parent) { @@ -38,7 +38,6 @@ export class QScrollArea extends QAbstractScrollArea { native = new addon.QScrollArea(); } super(native); - this.setNodeParent(parent); } setAlignment(alignment: AlignmentFlag): void { this.setProperty('alignment', alignment); @@ -59,24 +58,13 @@ export class QScrollArea extends QAbstractScrollArea { this.native.ensureWidgetVisible(childWidget.native, xmargin, ymargin); } setWidget(widget: QWidget): void { - this.contentWidget = widget; this.native.setWidget(widget.native); } widget(): QWidget | null { - if (this.contentWidget) { - return this.contentWidget; - } - return null; + return wrapperCache.getWrapper(this.native.widget()) as QWidget; } takeWidget(): QWidget | null { - // react:✓ - const contentWidget = this.contentWidget; - this.contentWidget = null; - if (contentWidget) { - this.native.takeWidget(); - return contentWidget; - } - return null; + return wrapperCache.getWrapper(this.native.takeWidget()) as QWidget; } setViewportMargins(left: number, top: number, right: number, bottom: number): void { // Technically part of QAbstractScrollArea, but the C++ side has subclass specific diff --git a/src/lib/QtWidgets/QScrollBar.ts b/src/lib/QtWidgets/QScrollBar.ts index 36083d2f7..e3557473b 100644 --- a/src/lib/QtWidgets/QScrollBar.ts +++ b/src/lib/QtWidgets/QScrollBar.ts @@ -28,7 +28,6 @@ export class QScrollBar extends QAbstractSlider { native = new addon.QScrollBar(); } super(native); - this.setNodeParent(parent); } } diff --git a/src/lib/QtWidgets/QSlider.ts b/src/lib/QtWidgets/QSlider.ts index 9b2667c62..bb3c4e170 100644 --- a/src/lib/QtWidgets/QSlider.ts +++ b/src/lib/QtWidgets/QSlider.ts @@ -28,7 +28,6 @@ export class QSlider extends QAbstractSlider { native = new addon.QSlider(); } super(native); - this.setNodeParent(parent); } setTickInterval(ti: number): void { this.setProperty('tickInterval', ti); diff --git a/src/lib/QtWidgets/QSpinBox.ts b/src/lib/QtWidgets/QSpinBox.ts index 899efa74b..37b7462a9 100644 --- a/src/lib/QtWidgets/QSpinBox.ts +++ b/src/lib/QtWidgets/QSpinBox.ts @@ -27,7 +27,6 @@ export class QSpinBox extends QAbstractSpinBox { native = new addon.QSpinBox(); } super(native); - this.setNodeParent(parent); } cleanText(): string { return this.property('cleanText').toString(); diff --git a/src/lib/QtWidgets/QSplitter.ts b/src/lib/QtWidgets/QSplitter.ts index 807813cd5..5218eb658 100644 --- a/src/lib/QtWidgets/QSplitter.ts +++ b/src/lib/QtWidgets/QSplitter.ts @@ -43,7 +43,6 @@ export class QSplitter extends QFrame { native = new addon.QSplitter(); } super(native); - this.setNodeParent(parent); } addWidget(widget: QWidget): void { this.native.addWidget(widget.native); diff --git a/src/lib/QtWidgets/QStackedWidget.ts b/src/lib/QtWidgets/QStackedWidget.ts index a0c45831f..289d4feae 100644 --- a/src/lib/QtWidgets/QStackedWidget.ts +++ b/src/lib/QtWidgets/QStackedWidget.ts @@ -52,13 +52,11 @@ export class QStackedWidget extends QFrame { native = new addon.QStackedWidget(); } super(native); - this.setNodeParent(parent); } // *** Public Function *** addWidget(widget: QWidget): void { this.native.addWidget(widget.native); - this.nodeChildren.add(widget); widget.setFlexNodeSizeControlled(true); } count(): number { @@ -72,7 +70,6 @@ export class QStackedWidget extends QFrame { // TODO: int insertWidget(int index, QWidget *widget) removeWidget(widget: QWidget): void { this.native.removeWidget(widget.native); - this.nodeChildren.delete(widget); } // TODO: QWidget * widget(int index) const diff --git a/src/lib/QtWidgets/QStandardItemModel.ts b/src/lib/QtWidgets/QStandardItemModel.ts index 7928094f9..f0ed26305 100644 --- a/src/lib/QtWidgets/QStandardItemModel.ts +++ b/src/lib/QtWidgets/QStandardItemModel.ts @@ -16,7 +16,6 @@ export class QStandardItemModel extends QObject { native = new addon.QStandardItemModel(); } super(native); - parent && parent.nodeChildren.add(this); } item(row: number, column = 0): QStandardItem | void { const item = this.native.item(row, column); diff --git a/src/lib/QtWidgets/QStatusBar.ts b/src/lib/QtWidgets/QStatusBar.ts index 175b0ff91..08cbe9f44 100644 --- a/src/lib/QtWidgets/QStatusBar.ts +++ b/src/lib/QtWidgets/QStatusBar.ts @@ -35,7 +35,6 @@ export class QStatusBar extends QWidget { } super(native); - this.setNodeParent(parent); this.permanentWidgets = new Set(); this.widgets = new Set(); diff --git a/src/lib/QtWidgets/QSvgWidget.ts b/src/lib/QtWidgets/QSvgWidget.ts index b4bb4a8b9..fce3feb85 100644 --- a/src/lib/QtWidgets/QSvgWidget.ts +++ b/src/lib/QtWidgets/QSvgWidget.ts @@ -35,7 +35,6 @@ export class QSvgWidget extends QWidget { native = new addon.QSvgWidget(); } super(native); - parent && this.setNodeParent(parent); } load(file: string | Buffer): void { if (file instanceof Buffer) { diff --git a/src/lib/QtWidgets/QTabBar.ts b/src/lib/QtWidgets/QTabBar.ts index 944b87c1d..004a8e16f 100644 --- a/src/lib/QtWidgets/QTabBar.ts +++ b/src/lib/QtWidgets/QTabBar.ts @@ -34,7 +34,6 @@ export class QTabBar extends QWidget { native = new addon.QTabBar(); } super(native); - parent && this.setNodeParent(parent); } setAutoHide(hide: boolean): void { this.setProperty('autoHide', hide); diff --git a/src/lib/QtWidgets/QTabWidget.ts b/src/lib/QtWidgets/QTabWidget.ts index 247e0d284..27869568d 100644 --- a/src/lib/QtWidgets/QTabWidget.ts +++ b/src/lib/QtWidgets/QTabWidget.ts @@ -35,7 +35,6 @@ export class QTabWidget extends QWidget { native = new addon.QTabWidget(); } super(native); - this.setNodeParent(parent); this.tabs = []; } diff --git a/src/lib/QtWidgets/QTableView.ts b/src/lib/QtWidgets/QTableView.ts index 1aeab815e..734bdfb1a 100644 --- a/src/lib/QtWidgets/QTableView.ts +++ b/src/lib/QtWidgets/QTableView.ts @@ -28,7 +28,6 @@ export class QTableView e native = new addon.QTableView(); } super(native); - parent && this.setNodeParent(parent); } // *** Public Functions *** clearSpans(): void { diff --git a/src/lib/QtWidgets/QTableWidget.ts b/src/lib/QtWidgets/QTableWidget.ts index 63cf79260..dd1205d7c 100644 --- a/src/lib/QtWidgets/QTableWidget.ts +++ b/src/lib/QtWidgets/QTableWidget.ts @@ -47,7 +47,6 @@ export class QTableWidget extends QAbstractScrollArea { native = new addon.QTableWidget(rows, columns); } super(native); - this.setNodeParent(parent); this.items = new Set(); } selectedRanges(): Range[] { diff --git a/src/lib/QtWidgets/QTextBrowser.ts b/src/lib/QtWidgets/QTextBrowser.ts index ca22adb1a..7e4e67a55 100644 --- a/src/lib/QtWidgets/QTextBrowser.ts +++ b/src/lib/QtWidgets/QTextBrowser.ts @@ -30,7 +30,6 @@ export class QTextBrowser extends QTextEdit { native = new addon.QTextBrowser(); } super(native); - parent && this.setNodeParent(parent); } setOpenExternalLinks(open: boolean): void { this.setProperty('openExternalLinks', open); diff --git a/src/lib/QtWidgets/QTextEdit.ts b/src/lib/QtWidgets/QTextEdit.ts index fe1e6e74c..9c5ddf12c 100644 --- a/src/lib/QtWidgets/QTextEdit.ts +++ b/src/lib/QtWidgets/QTextEdit.ts @@ -37,7 +37,6 @@ export class QTextEdit exte native = new addon.QTextEdit(); } super(native); - parent && this.setNodeParent(parent); } setAcceptRichText(accept: boolean): void { diff --git a/src/lib/QtWidgets/QTimeEdit.ts b/src/lib/QtWidgets/QTimeEdit.ts index 69b2d3a2e..7c49aae6a 100644 --- a/src/lib/QtWidgets/QTimeEdit.ts +++ b/src/lib/QtWidgets/QTimeEdit.ts @@ -28,6 +28,5 @@ export class QTimeEdit extends QDateTimeEdit { native = new addon.QTimeEdit(); } super(native); - this.setNodeParent(parent); } } diff --git a/src/lib/QtWidgets/QToolButton.ts b/src/lib/QtWidgets/QToolButton.ts index 9fd78bbdd..cf8c24bd6 100644 --- a/src/lib/QtWidgets/QToolButton.ts +++ b/src/lib/QtWidgets/QToolButton.ts @@ -1,6 +1,6 @@ import addon from '../utils/addon'; import { QWidget } from './QWidget'; -import { NativeElement, NativeRawPointer, Component } from '../core/Component'; +import { NativeElement, NativeRawPointer } from '../core/Component'; import { QAbstractButton, QAbstractButtonSignals } from './QAbstractButton'; import { ToolButtonStyle } from '../QtEnums/ToolButtonStyle'; import { ArrowType } from '../QtEnums/ArrowType'; @@ -31,7 +31,6 @@ export class QToolButton extends QAbstractButton { constructor(arg?: QWidget | NativeRawPointer | NativeElement, disableNativeDeletion = true) { let native; - let parent: Component | undefined; if (checkIfNativeElement(arg)) { native = arg as NativeElement; } else if (checkIfNapiExternal(arg)) { @@ -39,12 +38,10 @@ export class QToolButton extends QAbstractButton { } else if (arg) { const parentWidget = arg as QWidget; native = new addon.QToolButton(parentWidget.native); - parent = parentWidget; } else { native = new addon.QToolButton(); } super(native); - parent && this.setNodeParent(parent); } setArrowType(type: ArrowType): void { this.setProperty('arrowType', type); diff --git a/src/lib/QtWidgets/QTreeWidget.ts b/src/lib/QtWidgets/QTreeWidget.ts index 27b38a218..10fc06032 100644 --- a/src/lib/QtWidgets/QTreeWidget.ts +++ b/src/lib/QtWidgets/QTreeWidget.ts @@ -60,7 +60,6 @@ export class QTreeWidget extends QAbstractScrollArea { native = new addon.QTreeWidget(); } super(native); - this.setNodeParent(parent); this.topLevelItems = new Set(); this.itemWidgets = new Map(); } diff --git a/src/lib/QtWidgets/QTreeWidgetItem.ts b/src/lib/QtWidgets/QTreeWidgetItem.ts index c8e931c28..1cb8cd193 100644 --- a/src/lib/QtWidgets/QTreeWidgetItem.ts +++ b/src/lib/QtWidgets/QTreeWidgetItem.ts @@ -8,7 +8,7 @@ import { CheckState, ItemDataRole } from '../QtEnums'; import { QVariantType, QVariant } from '../QtCore/QVariant'; /** - + > Creates an item for QTreeWidget. * **This class is a JS wrapper around Qt's [QTreeWidgetItem class](https://doc.qt.io/qt-5/qtreewidgetitem.html)** @@ -54,13 +54,11 @@ export class QTreeWidgetItem extends Component { constructor(strings: string[]); constructor(parent?: NativeElement | QTreeWidgetItem | QTreeWidget | string[], strings?: string[]) { let native: NativeElement; - let parentTreeWidgetItem: QTreeWidgetItem | QTreeWidget = null; if (checkIfNativeElement(parent)) { native = parent as NativeElement; } else { if (parent instanceof QTreeWidgetItem || parent instanceof QTreeWidget) { const type = parent instanceof QTreeWidgetItem ? 'item' : 'tree'; - parentTreeWidgetItem = parent; if (strings) { native = new addon.QTreeWidgetItem(parent.native, strings, type); } else { @@ -75,9 +73,6 @@ export class QTreeWidgetItem extends Component { } super(native); this.items = new Set(); - if (parentTreeWidgetItem != null) { - this.setNodeParent(parentTreeWidgetItem); - } } setText(column: number, text: string): void { this.native.setText(column, text); diff --git a/src/lib/QtWidgets/QWidget.ts b/src/lib/QtWidgets/QWidget.ts index d514a24c4..2b088b151 100644 --- a/src/lib/QtWidgets/QWidget.ts +++ b/src/lib/QtWidgets/QWidget.ts @@ -41,18 +41,15 @@ view.setLayout(new FlexLayout()); ``` */ export class QWidget extends YogaWidget { - _layout?: QLayout; _rawInlineStyle: string; type: string; - private _effect?: QGraphicsEffect | null; constructor(arg?: QWidget | NativeElement) { let native: NativeElement; - let parent: QWidget = null; if (checkIfNativeElement(arg)) { native = arg as NativeElement; - } else if (arg as QWidget) { - parent = arg as QWidget; + } else if (arg != null) { + const parent = arg as QWidget; native = new addon.QWidget(parent.native); } else { native = new addon.QWidget(); @@ -61,18 +58,22 @@ export class QWidget extends Yo this._rawInlineStyle = ''; this.type = 'widget'; - this.setNodeParent(parent); - this.setStyleSheet = memoizeOne(this.setStyleSheet); this.setInlineStyle = memoizeOne(this.setInlineStyle); this.setObjectName = memoizeOne(this.setObjectName); } - get layout(): QLayout | undefined { - return this._layout; + layout(): QLayout | null { + return wrapperCache.getWrapper(this.native.layout()) as QLayout; } - set layout(l: QLayout | undefined) { - this._layout = l; + setLayout(layout: QLayout): void { + this.native.setLayout(layout == null ? null : layout.native); + + const flexLayout = layout as FlexLayout; + if (flexLayout?.setFlexNode) { + //if flex layout set the flexnode + flexLayout.setFlexNode(this.getFlexNode()); + } } // *** Public Functions *** acceptDrops(): boolean { @@ -367,7 +368,6 @@ export class QWidget extends Yo this.native.setGeometry(x, y, w, h); } setGraphicsEffect(effect: QGraphicsEffect): void { - this._effect = effect; this.native.setGraphicsEffect(effect.native); } // TODO: void setInputMethodHints(Qt::InputMethodHints hints) @@ -380,15 +380,6 @@ export class QWidget extends Yo this.native.setStyleSheet(style); } } - setLayout(parentLayout: QLayout): void { - const flexLayout = parentLayout as FlexLayout; - this.native.setLayout(parentLayout.native); - if (flexLayout.setFlexNode) { - //if flex layout set the flexnode - flexLayout.setFlexNode(this.getFlexNode()); - } - this._layout = parentLayout; - } // TODO: void setLayoutDirection(Qt::LayoutDirection direction) // TODO: void setLocale(const QLocale &locale) // TODO: void setMask(const QBitmap &bitmap) @@ -661,3 +652,4 @@ export interface QWidgetSignals extends QObjectSignals { windowIconChanged: (iconNative: NativeElement) => void; customContextMenuRequested: (pos: { x: number; y: number }) => void; } +wrapperCache.registerWrapper('QWidgetWrap', QWidget); diff --git a/src/lib/core/Component.ts b/src/lib/core/Component.ts index d5dbe5407..9c62cb5d2 100644 --- a/src/lib/core/Component.ts +++ b/src/lib/core/Component.ts @@ -18,17 +18,8 @@ Its the root base class in NodeGui world. */ export abstract class Component { - nodeChildren: Set; - nodeParent?: Component; - native: NativeElement | null; - constructor(native: NativeElement) { this.native = native; - this.nodeChildren = new Set(); - } - setNodeParent(parent?: Component): void { - this.nodeParent = parent; - parent?.nodeChildren.add(this); } } diff --git a/src/lib/core/FlexLayout.ts b/src/lib/core/FlexLayout.ts index 2f8d56d57..d930489de 100644 --- a/src/lib/core/FlexLayout.ts +++ b/src/lib/core/FlexLayout.ts @@ -49,10 +49,9 @@ export class FlexLayout extends QLayout { addWidget(childWidget: QWidget, childFlexNode?: FlexNode): void { const childYogaNode = childFlexNode || childWidget.getFlexNode(); - if (this.nodeChildren.has(childWidget)) { + if (this.children().includes(childWidget)) { this.removeWidget(childWidget, childYogaNode); } - this.nodeChildren.add(childWidget); this.native.addWidget(childWidget.native, childYogaNode); } @@ -63,27 +62,16 @@ export class FlexLayout extends QLayout { beforeChildFlexNode?: FlexNode, ): void { const childYogaNode = childFlexNode || childWidget.getFlexNode(); - if (this.nodeChildren.has(childWidget)) { + if (this.children().includes(childWidget)) { this.removeWidget(childWidget, childYogaNode); } const beforeChildYogaNode = beforeChildFlexNode || beforeChildWidget.getFlexNode(); - - const widgetArr = Array.from(this.nodeChildren); - const beforeChildIndex = this.getChildIndex(beforeChildWidget); - if (beforeChildIndex !== -1) { - widgetArr.splice(beforeChildIndex, 0, childWidget); - } - this.nodeChildren = new Set(widgetArr); this.native.insertChildBefore(childWidget.native, beforeChildYogaNode, childYogaNode); } removeWidget(childWidget: QWidget, childFlexNode?: FlexNode): void { - if (!this.nodeChildren.has(childWidget)) { - return; - } const childYogaNode = childFlexNode || childWidget.getFlexNode(); this.native.removeWidget(childWidget.native, childYogaNode); - this.nodeChildren.delete(childWidget); } setFlexNode(flexNode: FlexNode): void { @@ -92,13 +80,12 @@ export class FlexLayout extends QLayout { } getChildIndex(childWidget: QWidget): number { - const widgetArr = Array.from(this.nodeChildren); - return widgetArr.indexOf(childWidget); + return this.children().indexOf(childWidget); } getNextSibling(childWidget: QWidget): QWidget | null { const childIndex = this.getChildIndex(childWidget); - const widgetArr = Array.from(this.nodeChildren); + const widgetArr = this.children(); if (childIndex !== -1) { return (widgetArr[childIndex + 1] as QWidget) || null; } diff --git a/src/lib/core/__test__/CacheTestQObject.ts b/src/lib/core/__test__/CacheTestQObject.ts index 3ee23ea0e..865102699 100644 --- a/src/lib/core/__test__/CacheTestQObject.ts +++ b/src/lib/core/__test__/CacheTestQObject.ts @@ -12,7 +12,6 @@ export class CacheTestQObject extends QObject { native = arg; } super(native); - this.native = native; } foo(): CacheTestQObject { diff --git a/src/lib/utils/helpers.ts b/src/lib/utils/helpers.ts index b786850c2..8c621ad4f 100644 --- a/src/lib/utils/helpers.ts +++ b/src/lib/utils/helpers.ts @@ -4,7 +4,7 @@ import addon from './addon'; // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types export function checkIfNativeElement(arg: any): boolean { const nativeArg = arg as NativeElement; - return typeof nativeArg === 'object' && nativeArg.type === 'native'; + return nativeArg != null && typeof nativeArg === 'object' && nativeArg.type === 'native'; } // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types From bfa531f1f45ed48863ed554ddeaabca32853dcc9 Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Wed, 11 May 2022 22:28:51 +0200 Subject: [PATCH 22/28] Massive TS wrapper update --- .../QDateTimeEdit/qdatetimeedit_macro.h | 16 +++++-- .../QtWidgets/QPushButton/qpushbutton_wrap.h | 1 + .../QtWidgets/QTabWidget/qtabwidget_wrap.h | 1 + .../QtWidgets/QToolButton/qtoolbutton_wrap.h | 1 + .../QPushButton/qpushbutton_wrap.cpp | 11 +++++ .../QtWidgets/QTabWidget/qtabwidget_wrap.cpp | 14 +++++- .../QToolButton/qtoolbutton_wrap.cpp | 11 +++++ src/lib/QtCore/QItemSelectionModel.ts | 2 + src/lib/QtCore/QObject.ts | 6 +-- src/lib/QtGui/QApplication.ts | 9 ++-- src/lib/QtGui/QClipboard.ts | 1 + src/lib/QtGui/QMovie.ts | 16 +++---- src/lib/QtGui/QScreen.ts | 1 + src/lib/QtGui/QWindow.ts | 1 + src/lib/QtWidgets/QAbstractItemView.ts | 5 ++- src/lib/QtWidgets/QAction.ts | 8 ++-- src/lib/QtWidgets/QButtonGroup.ts | 8 ++-- src/lib/QtWidgets/QCalendarWidget.ts | 4 +- src/lib/QtWidgets/QCheckBox.ts | 22 ++++------ src/lib/QtWidgets/QColorDialog.ts | 14 ++++-- src/lib/QtWidgets/QComboBox.ts | 11 ++++- src/lib/QtWidgets/QDateEdit.ts | 12 +++-- src/lib/QtWidgets/QDateTimeEdit.ts | 18 +++----- src/lib/QtWidgets/QDial.ts | 14 +++--- src/lib/QtWidgets/QDialog.ts | 11 ++--- src/lib/QtWidgets/QDoubleSpinBox.ts | 12 +++-- src/lib/QtWidgets/QErrorMessage.ts | 12 +++-- src/lib/QtWidgets/QFileDialog.ts | 11 +++-- src/lib/QtWidgets/QFontDialog.ts | 12 +++-- src/lib/QtWidgets/QFrame.ts | 10 ++--- src/lib/QtWidgets/QGraphicsBlurEffect.ts | 20 ++++----- .../QtWidgets/QGraphicsDropShadowEffect.ts | 22 +++++----- src/lib/QtWidgets/QGridLayout.ts | 13 ++++-- src/lib/QtWidgets/QGroupBox.ts | 11 ++++- src/lib/QtWidgets/QHeaderView.ts | 2 + src/lib/QtWidgets/QInputDialog.ts | 15 +++++-- src/lib/QtWidgets/QLCDNumber.ts | 13 ++++-- src/lib/QtWidgets/QLabel.ts | 17 ++++--- src/lib/QtWidgets/QLineEdit.ts | 13 ++++-- src/lib/QtWidgets/QListView.ts | 6 ++- src/lib/QtWidgets/QListWidget.ts | 16 ++++--- src/lib/QtWidgets/QMainWindow.ts | 2 +- src/lib/QtWidgets/QMenu.ts | 12 +++-- src/lib/QtWidgets/QMenuBar.ts | 17 ++++--- src/lib/QtWidgets/QMessageBox.ts | 16 ++++--- src/lib/QtWidgets/QPlainTextEdit.ts | 14 +++--- src/lib/QtWidgets/QProgressBar.ts | 10 ++++- src/lib/QtWidgets/QProgressDialog.ts | 15 +++++-- src/lib/QtWidgets/QPushButton.ts | 28 +++++------- src/lib/QtWidgets/QRadioButton.ts | 20 ++++----- src/lib/QtWidgets/QScrollArea.ts | 11 +++-- src/lib/QtWidgets/QScrollBar.ts | 12 +++-- src/lib/QtWidgets/QShortcut.ts | 19 ++++++-- src/lib/QtWidgets/QSlider.ts | 12 +++-- src/lib/QtWidgets/QSpinBox.ts | 15 +++++-- src/lib/QtWidgets/QSplitter.ts | 12 +++-- src/lib/QtWidgets/QStackedWidget.ts | 16 ++++--- src/lib/QtWidgets/QStandardItemModel.ts | 14 ++++-- src/lib/QtWidgets/QStatusBar.ts | 44 +++++-------------- src/lib/QtWidgets/QSvgWidget.ts | 10 ++++- src/lib/QtWidgets/QSystemTrayIcon.ts | 20 +++++---- src/lib/QtWidgets/QTabBar.ts | 13 ++++-- src/lib/QtWidgets/QTabWidget.ts | 22 ++++++---- src/lib/QtWidgets/QTableView.ts | 15 +++++-- src/lib/QtWidgets/QTableWidget.ts | 23 +++++++--- src/lib/QtWidgets/QTextBrowser.ts | 12 +++-- src/lib/QtWidgets/QTextEdit.ts | 12 ++--- src/lib/QtWidgets/QTimeEdit.ts | 15 +++++-- src/lib/QtWidgets/QToolButton.ts | 35 +++++---------- src/lib/QtWidgets/QTreeWidget.ts | 15 ++++--- src/lib/utils/helpers.ts | 2 +- 71 files changed, 572 insertions(+), 334 deletions(-) diff --git a/src/cpp/include/nodegui/QtWidgets/QDateTimeEdit/qdatetimeedit_macro.h b/src/cpp/include/nodegui/QtWidgets/QDateTimeEdit/qdatetimeedit_macro.h index c96c1cb2c..06180553c 100644 --- a/src/cpp/include/nodegui/QtWidgets/QDateTimeEdit/qdatetimeedit_macro.h +++ b/src/cpp/include/nodegui/QtWidgets/QDateTimeEdit/qdatetimeedit_macro.h @@ -24,14 +24,24 @@ this->instance->setCalendarWidget( \ calendarWidgetWrap->getInternalInstance()); \ return env.Null(); \ + } \ + Napi::Value calendarWidget(const Napi::CallbackInfo &info) { \ + Napi::Env env = info.Env(); \ + QObject *calendarWidget = this->instance->calendarWidget(); \ + if (calendarWidget) { \ + return WrapperCache::instance.getWrapper(env, calendarWidget); \ + } else { \ + return env.Null(); \ + } \ } #endif // QDATETIMEEDIT_WRAPPED_METHODS_DECLARATION #ifndef QDATETIMEEDIT_WRAPPED_METHODS_EXPORT_DEFINE -#define QDATETIMEEDIT_WRAPPED_METHODS_EXPORT_DEFINE(WidgetWrapName) \ - QABSTRACTSPINBOX_WRAPPED_METHODS_EXPORT_DEFINE(WidgetWrapName) \ - InstanceMethod("setCalendarWidget", &WidgetWrapName::setCalendarWidget), +#define QDATETIMEEDIT_WRAPPED_METHODS_EXPORT_DEFINE(WidgetWrapName) \ + QABSTRACTSPINBOX_WRAPPED_METHODS_EXPORT_DEFINE(WidgetWrapName) \ + InstanceMethod("setCalendarWidget", &WidgetWrapName::setCalendarWidget), \ + InstanceMethod("calendarWidget", &WidgetWrapName::calendarWidget), #endif // QDATETIMEEDIT_WRAPPED_METHODS_EXPORT_DEFINE diff --git a/src/cpp/include/nodegui/QtWidgets/QPushButton/qpushbutton_wrap.h b/src/cpp/include/nodegui/QtWidgets/QPushButton/qpushbutton_wrap.h index 824bfabd9..941797bb8 100644 --- a/src/cpp/include/nodegui/QtWidgets/QPushButton/qpushbutton_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QPushButton/qpushbutton_wrap.h @@ -23,5 +23,6 @@ class DLL_EXPORT QPushButtonWrap : public Napi::ObjectWrap { static Napi::FunctionReference constructor; // wrapped methods Napi::Value setMenu(const Napi::CallbackInfo& info); + Napi::Value menu(const Napi::CallbackInfo& info); Napi::Value showMenu(const Napi::CallbackInfo& info); }; diff --git a/src/cpp/include/nodegui/QtWidgets/QTabWidget/qtabwidget_wrap.h b/src/cpp/include/nodegui/QtWidgets/QTabWidget/qtabwidget_wrap.h index f2ef97a9a..b58165901 100644 --- a/src/cpp/include/nodegui/QtWidgets/QTabWidget/qtabwidget_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QTabWidget/qtabwidget_wrap.h @@ -31,4 +31,5 @@ class DLL_EXPORT QTabWidgetWrap : public Napi::ObjectWrap { Napi::Value setTabsClosable(const Napi::CallbackInfo &info); Napi::Value setTabText(const Napi::CallbackInfo &info); Napi::Value setTabIcon(const Napi::CallbackInfo &info); + Napi::Value widget(const Napi::CallbackInfo &info); }; diff --git a/src/cpp/include/nodegui/QtWidgets/QToolButton/qtoolbutton_wrap.h b/src/cpp/include/nodegui/QtWidgets/QToolButton/qtoolbutton_wrap.h index 94223291c..ef153296f 100644 --- a/src/cpp/include/nodegui/QtWidgets/QToolButton/qtoolbutton_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QToolButton/qtoolbutton_wrap.h @@ -25,4 +25,5 @@ class DLL_EXPORT QToolButtonWrap : public Napi::ObjectWrap { Napi::Value setMenu(const Napi::CallbackInfo& info); Napi::Value setDefaultAction(const Napi::CallbackInfo& info); Napi::Value showMenu(const Napi::CallbackInfo& info); + Napi::Value defaultAction(const Napi::CallbackInfo& info); }; diff --git a/src/cpp/lib/QtWidgets/QPushButton/qpushbutton_wrap.cpp b/src/cpp/lib/QtWidgets/QPushButton/qpushbutton_wrap.cpp index 916714ce1..6f5c64b30 100644 --- a/src/cpp/lib/QtWidgets/QPushButton/qpushbutton_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QPushButton/qpushbutton_wrap.cpp @@ -12,6 +12,7 @@ Napi::Object QPushButtonWrap::init(Napi::Env env, Napi::Object exports) { Napi::Function func = DefineClass( env, CLASSNAME, {InstanceMethod("setMenu", &QPushButtonWrap::setMenu), + InstanceMethod("menu", &QPushButtonWrap::menu), InstanceMethod("showMenu", &QPushButtonWrap::showMenu), QABSTRACTBUTTON_WRAPPED_METHODS_EXPORT_DEFINE(QPushButtonWrap)}); constructor = Napi::Persistent(func); @@ -60,6 +61,16 @@ Napi::Value QPushButtonWrap::setMenu(const Napi::CallbackInfo& info) { return env.Null(); } +Napi::Value QPushButtonWrap::menu(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + QObject* menu = this->instance->menu(); + if (menu) { + return WrapperCache::instance.getWrapper(env, menu); + } else { + return env.Null(); + } +} + Napi::Value QPushButtonWrap::showMenu(const Napi::CallbackInfo& info) { Napi::Env env = info.Env(); this->instance->showMenu(); diff --git a/src/cpp/lib/QtWidgets/QTabWidget/qtabwidget_wrap.cpp b/src/cpp/lib/QtWidgets/QTabWidget/qtabwidget_wrap.cpp index fa873bd85..def4ccd53 100644 --- a/src/cpp/lib/QtWidgets/QTabWidget/qtabwidget_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QTabWidget/qtabwidget_wrap.cpp @@ -23,6 +23,7 @@ Napi::Object QTabWidgetWrap::init(Napi::Env env, Napi::Object exports) { InstanceMethod("currentIndex", &QTabWidgetWrap::currentIndex), InstanceMethod("removeTab", &QTabWidgetWrap::removeTab), InstanceMethod("setTabsClosable", &QTabWidgetWrap::setTabsClosable), + InstanceMethod("widget", &QTabWidgetWrap::widget), QWIDGET_WRAPPED_METHODS_EXPORT_DEFINE(QTabWidgetWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); @@ -159,4 +160,15 @@ Napi::Value QTabWidgetWrap::setTabsClosable(const Napi::CallbackInfo& info) { Napi::Boolean closable = info[0].As(); this->instance->setTabsClosable(closable.Value()); return env.Null(); -} \ No newline at end of file +} + +Napi::Value QTabWidgetWrap::widget(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::Number index = info[0].As(); + QWidget* widget = this->instance->widget(index.Int32Value()); + if (widget) { + return WrapperCache::instance.getWrapper(env, widget); + } else { + return env.Null(); + } +} diff --git a/src/cpp/lib/QtWidgets/QToolButton/qtoolbutton_wrap.cpp b/src/cpp/lib/QtWidgets/QToolButton/qtoolbutton_wrap.cpp index d809aa9d1..2bd7bf837 100644 --- a/src/cpp/lib/QtWidgets/QToolButton/qtoolbutton_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QToolButton/qtoolbutton_wrap.cpp @@ -15,6 +15,7 @@ Napi::Object QToolButtonWrap::init(Napi::Env env, Napi::Object exports) { {InstanceMethod("setMenu", &QToolButtonWrap::setMenu), InstanceMethod("setDefaultAction", &QToolButtonWrap::setDefaultAction), InstanceMethod("showMenu", &QToolButtonWrap::showMenu), + InstanceMethod("defaultAction", &QToolButtonWrap::defaultAction), QABSTRACTBUTTON_WRAPPED_METHODS_EXPORT_DEFINE(QToolButtonWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); @@ -75,3 +76,13 @@ Napi::Value QToolButtonWrap::showMenu(const Napi::CallbackInfo& info) { this->instance->showMenu(); return env.Null(); } + +Napi::Value QToolButtonWrap::defaultAction(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + QAction* action = this->instance->defaultAction(); + if (action) { + return WrapperCache::instance.getWrapper(env, action); + } else { + return env.Null(); + } +} diff --git a/src/lib/QtCore/QItemSelectionModel.ts b/src/lib/QtCore/QItemSelectionModel.ts index 665c4c47f..fee8fb14e 100644 --- a/src/lib/QtCore/QItemSelectionModel.ts +++ b/src/lib/QtCore/QItemSelectionModel.ts @@ -3,6 +3,7 @@ import { NativeElement } from '../core/Component'; import { QObject, QObjectSignals } from '../QtCore/QObject'; import { QModelIndex } from './QModelIndex'; import { checkIfNativeElement } from '../utils/helpers'; +import { wrapperCache } from '../core/WrapperCache'; export type QItemSelectionModelSignals = QObjectSignals; @@ -102,6 +103,7 @@ export class QItemSelectionModel extends QObject { // TODO: void modelChanged(QAbstractItemModel *model) // TODO: void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected) } +wrapperCache.registerWrapper('QItemSelectionModelWrap', QItemSelectionModel); export enum SelectionFlag { NoUpdate = 0x0000, diff --git a/src/lib/QtCore/QObject.ts b/src/lib/QtCore/QObject.ts index 34899473f..d849e3a12 100644 --- a/src/lib/QtCore/QObject.ts +++ b/src/lib/QtCore/QObject.ts @@ -8,12 +8,11 @@ import { wrapperCache } from '../core/WrapperCache'; export class QObject extends EventWidget { constructor(nativeElementOrParent?: NativeElement | QObject) { - let native; - let parent; + let native: NativeElement; if (checkIfNativeElement(nativeElementOrParent)) { native = nativeElementOrParent as NativeElement; } else if (nativeElementOrParent) { - parent = nativeElementOrParent as QObject; + const parent = nativeElementOrParent as QObject; native = new addon.QObject(parent.native); } else { native = new addon.QObject(); @@ -72,6 +71,7 @@ export class QObject extends Ev return this.native.children().map((kid: any) => wrapperCache.getWrapper(kid)); } } +wrapperCache.registerWrapper('QObjectWrap', QObject); export interface QObjectSignals { objectNameChanged: (objectName: string) => void; diff --git a/src/lib/QtGui/QApplication.ts b/src/lib/QtGui/QApplication.ts index eedf26587..63a9bfeb7 100644 --- a/src/lib/QtGui/QApplication.ts +++ b/src/lib/QtGui/QApplication.ts @@ -28,17 +28,17 @@ qApp.quit(); ``` */ export class QApplication extends QObject { - constructor(); - constructor(native: NativeElement); - constructor(arg?: NativeElement) { + constructor(arg?: QObject | NativeElement) { let native: NativeElement; if (checkIfNativeElement(arg)) { native = arg as NativeElement; + } else if (arg != null) { + const parent = arg as QObject; + native = new addon.QApplication(parent.native); } else { native = new addon.QApplication(); } super(native); - this.setStyleSheet = memoizeOne(this.setStyleSheet); } devicePixelRatio(): number { @@ -102,6 +102,7 @@ export class QApplication extends QObject { return new QStyle(addon.QApplication.style()); } } +wrapperCache.registerWrapper('QApplicationWrap', QApplication); export interface QApplicationSignals extends QObjectSignals { focusWindowChanged: () => void; diff --git a/src/lib/QtGui/QClipboard.ts b/src/lib/QtGui/QClipboard.ts index 5799a741b..8326db858 100644 --- a/src/lib/QtGui/QClipboard.ts +++ b/src/lib/QtGui/QClipboard.ts @@ -46,6 +46,7 @@ export class QClipboard extends QObject { return new QPixmap(this.native.pixmap(mode)); } } +wrapperCache.registerWrapper('QClipboardWrap', QClipboard); export enum QClipboardMode { Clipboard = 0, diff --git a/src/lib/QtGui/QMovie.ts b/src/lib/QtGui/QMovie.ts index 14639dd0e..c322cd3c8 100644 --- a/src/lib/QtGui/QMovie.ts +++ b/src/lib/QtGui/QMovie.ts @@ -4,19 +4,16 @@ import { checkIfNativeElement } from '../utils/helpers'; import { QObject, QObjectSignals } from '../QtCore/QObject'; import { QSize } from '../QtCore/QSize'; import { QPixmap } from './QPixmap'; +import { wrapperCache } from '../core/WrapperCache'; export class QMovie extends QObject { - constructor(); - constructor(native: NativeElement); - constructor(parent: QObject); constructor(arg?: QObject | NativeElement) { let native: NativeElement; - if (arg) { - if (checkIfNativeElement(arg)) { - native = arg as NativeElement; - } else { - native = new addon.QMovie(arg); - } + if (checkIfNativeElement(arg)) { + native = arg as NativeElement; + } else if (arg != null) { + const parent = arg as QObject; + native = new addon.QMovie(parent.native); } else { native = new addon.QMovie(); } @@ -76,6 +73,7 @@ export class QMovie extends QObject { return this.native.frameCount(); } } +wrapperCache.registerWrapper('QMovieWrap', QMovie); export enum CacheMode { CacheNone, diff --git a/src/lib/QtGui/QScreen.ts b/src/lib/QtGui/QScreen.ts index 68debebcb..f7cd375f6 100644 --- a/src/lib/QtGui/QScreen.ts +++ b/src/lib/QtGui/QScreen.ts @@ -94,6 +94,7 @@ export class QScreen extends QObject { return QSize.fromQVariant(this.property('virtualSize')); } } +wrapperCache.registerWrapper('QScreenWrap', QScreen); export interface QScreenSignals extends QObjectSignals { availableGeometryChanged: (geometry: QRect) => void; diff --git a/src/lib/QtGui/QWindow.ts b/src/lib/QtGui/QWindow.ts index c8f98b8e4..2dd0634e3 100644 --- a/src/lib/QtGui/QWindow.ts +++ b/src/lib/QtGui/QWindow.ts @@ -69,6 +69,7 @@ export class QWindow extends QObject { return this.native.setVisibility(visibility); } } +wrapperCache.registerWrapper('QWindowWrap', QWindow); export interface QWindowSignals extends QObjectSignals { screenChanged: (screen: QScreen) => void; diff --git a/src/lib/QtWidgets/QAbstractItemView.ts b/src/lib/QtWidgets/QAbstractItemView.ts index a7f0d482e..472163564 100644 --- a/src/lib/QtWidgets/QAbstractItemView.ts +++ b/src/lib/QtWidgets/QAbstractItemView.ts @@ -8,6 +8,7 @@ import { QAbstractItemModel } from '../QtCore/QAbstractItemModel'; import { QPoint } from '../QtCore/QPoint'; import { QItemSelectionModel } from '../QtCore/QItemSelectionModel'; import { NativeElement } from '../core/Component'; +import { wrapperCache } from '../core/WrapperCache'; /** @@ -63,7 +64,7 @@ export abstract class QAbstractItemView { constructor(); constructor(native: NativeElement); - constructor(parent: QWidget); - constructor(arg?: NativeElement | QWidget) { + constructor(parent: QObject); + constructor(arg?: NativeElement | QObject) { let native: NativeElement; if (checkIfNativeElement(arg)) { native = arg as NativeElement; } else if (arg) { - const parent = arg as QWidget; + const parent = arg as QObject; native = new addon.QAction(parent.native); } else { native = new addon.QAction(); @@ -96,6 +95,7 @@ export class QAction extends QObject { return new QVariant(this.native.data()); } } +wrapperCache.registerWrapper('QActionWrap', QAction); export interface QActionSignals extends QObjectSignals { triggered: (checked: boolean) => void; diff --git a/src/lib/QtWidgets/QButtonGroup.ts b/src/lib/QtWidgets/QButtonGroup.ts index c18cd8e9d..3fbecdafb 100644 --- a/src/lib/QtWidgets/QButtonGroup.ts +++ b/src/lib/QtWidgets/QButtonGroup.ts @@ -1,5 +1,5 @@ import addon from '../utils/addon'; -import { QWidget } from './QWidget'; +import { QWidget, QWidgetSignals } from './QWidget'; import { NativeElement, NativeRawPointer } from '../core/Component'; import { QObject, QObjectSignals } from '../QtCore/QObject'; import { QAbstractButton, QAbstractButtonSignals } from './QAbstractButton'; @@ -11,11 +11,11 @@ export interface QButtonGroupSignals extends QObjectSignals { } export class QButtonGroup extends QObject { - constructor(arg?: NativeElement | QWidget) { - let native; + constructor(arg?: QWidget | NativeElement) { + let native: NativeElement; if (checkIfNativeElement(arg)) { native = arg as NativeElement; - } else if (arg) { + } else if (arg != null) { const parent = arg as QWidget; native = new addon.QButtonGroup(parent.native); } else { diff --git a/src/lib/QtWidgets/QCalendarWidget.ts b/src/lib/QtWidgets/QCalendarWidget.ts index b3cd0154d..1b3430147 100644 --- a/src/lib/QtWidgets/QCalendarWidget.ts +++ b/src/lib/QtWidgets/QCalendarWidget.ts @@ -24,11 +24,11 @@ const calendarWidget = new QCalendarWidget(); ``` */ export class QCalendarWidget extends QWidget { - constructor(arg?: NativeElement | QWidget) { + constructor(arg?: QWidget | NativeElement) { let native: NativeElement; if (checkIfNativeElement(arg)) { native = arg as NativeElement; - } else if (arg as QWidget) { + } else if (arg != null) { const parent = arg as QWidget; native = new addon.QCalendarWidget(parent.native); } else { diff --git a/src/lib/QtWidgets/QCheckBox.ts b/src/lib/QtWidgets/QCheckBox.ts index eeddd433c..4d24bc1fd 100644 --- a/src/lib/QtWidgets/QCheckBox.ts +++ b/src/lib/QtWidgets/QCheckBox.ts @@ -1,8 +1,8 @@ import addon from '../utils/addon'; -import { QWidget } from './QWidget'; -import { NativeElement, NativeRawPointer } from '../core/Component'; +import { QWidget, QWidgetSignals } from './QWidget'; +import { NativeElement } from '../core/Component'; import { QAbstractButton, QAbstractButtonSignals } from './QAbstractButton'; -import { checkIfNativeElement, checkIfNapiExternal } from '../utils/helpers'; +import { checkIfNativeElement } from '../utils/helpers'; import { CheckState } from '../QtEnums'; import { wrapperCache } from '../core/WrapperCache'; @@ -24,23 +24,19 @@ checkbox.setText("Hello"); ``` */ export class QCheckBox extends QAbstractButton { - constructor(); - constructor(parent: QWidget); - constructor(rawPointer: NativeRawPointer); - constructor(arg?: QWidget | NativeRawPointer | NativeElement) { - let native; + constructor(arg?: QWidget | NativeElement) { + let native: NativeElement; if (checkIfNativeElement(arg)) { native = arg as NativeElement; - } else if (checkIfNapiExternal(arg)) { - native = new addon.QCheckBox(arg); - } else if (arg) { - const parentWidget = arg as QWidget; - native = new addon.QCheckBox(parentWidget.native); + } else if (arg != null) { + const parent = arg as QWidget; + native = new addon.QCheckBox(parent.native); } else { native = new addon.QCheckBox(); } super(native); } + setTristate(y = true): void { this.setProperty('tristate', y); } diff --git a/src/lib/QtWidgets/QColorDialog.ts b/src/lib/QtWidgets/QColorDialog.ts index 8699f5843..5656810ef 100644 --- a/src/lib/QtWidgets/QColorDialog.ts +++ b/src/lib/QtWidgets/QColorDialog.ts @@ -1,8 +1,10 @@ import addon from '../utils/addon'; -import { QWidget } from './QWidget'; +import { QWidget, QWidgetSignals } from './QWidget'; import { NativeElement } from '../core/Component'; import { QDialog, QDialogSignals } from './QDialog'; import { QColor } from '../QtGui/QColor'; +import { wrapperCache } from '../core/WrapperCache'; +import { checkIfNativeElement } from '../utils/helpers'; /** @@ -27,15 +29,19 @@ console.log(color.red(), color.green(), color.blue()); ``` */ export class QColorDialog extends QDialog { - constructor(parent?: QWidget) { + constructor(arg?: QWidget | NativeElement) { let native: NativeElement; - if (parent) { + if (checkIfNativeElement(arg)) { + native = arg as NativeElement; + } else if (arg != null) { + const parent = arg as QWidget; native = new addon.QColorDialog(parent.native); } else { native = new addon.QColorDialog(); } super(native); } + setCurrentColor(color: QColor): void { this.setProperty('currentColor', color.native); } @@ -84,3 +90,5 @@ export interface QColorDialogSignals extends QDialogSignals { colorSelected: (color: QColor) => void; currentColorChanged: (color: QColor) => void; } + +wrapperCache.registerWrapper('QColorDialogWrap', QColorDialog); diff --git a/src/lib/QtWidgets/QComboBox.ts b/src/lib/QtWidgets/QComboBox.ts index 19b00ba06..17f4ccadd 100644 --- a/src/lib/QtWidgets/QComboBox.ts +++ b/src/lib/QtWidgets/QComboBox.ts @@ -7,6 +7,8 @@ import { QVariant } from '../QtCore/QVariant'; import { QStandardItemModel } from './QStandardItemModel'; import { QSize } from '../QtCore/QSize'; import { QModelIndex } from '../QtCore/QModelIndex'; +import { checkIfNativeElement } from '../utils/helpers'; +import { wrapperCache } from '../core/WrapperCache'; /** @@ -37,9 +39,12 @@ comboBox.addEventListener('currentIndexChanged', (index) => { ``` */ export class QComboBox extends QWidget { - constructor(parent?: QWidget) { + constructor(arg?: QWidget | NativeElement) { let native: NativeElement; - if (parent) { + if (checkIfNativeElement(arg)) { + native = arg as NativeElement; + } else if (arg != null) { + const parent = arg as QWidget; native = new addon.QComboBox(parent.native); } else { native = new addon.QComboBox(); @@ -221,3 +226,5 @@ export interface QComboBoxSignals extends QWidgetSignals { textActivated: (text: string) => void; textHighlighted: (text: string) => void; } + +wrapperCache.registerWrapper('QComboBoxWrap', QComboBox); diff --git a/src/lib/QtWidgets/QDateEdit.ts b/src/lib/QtWidgets/QDateEdit.ts index d1f9a9530..6b58cd75c 100644 --- a/src/lib/QtWidgets/QDateEdit.ts +++ b/src/lib/QtWidgets/QDateEdit.ts @@ -1,7 +1,9 @@ import addon from '../utils/addon'; -import { QWidget } from './QWidget'; +import { QWidget, QWidgetSignals } from './QWidget'; import { NativeElement } from '../core/Component'; import { QDateTimeEdit } from './QDateTimeEdit'; +import { checkIfNativeElement } from '../utils/helpers'; +import { wrapperCache } from '../core/WrapperCache'; /** @@ -21,9 +23,12 @@ const dateEdit = new QDateEdit(); ``` */ export class QDateEdit extends QDateTimeEdit { - constructor(parent?: QWidget) { + constructor(arg?: QWidget | NativeElement) { let native: NativeElement; - if (parent) { + if (checkIfNativeElement(arg)) { + native = arg as NativeElement; + } else if (arg != null) { + const parent = arg as QWidget; native = new addon.QDateEdit(parent.native); } else { native = new addon.QDateEdit(); @@ -31,3 +36,4 @@ export class QDateEdit extends QDateTimeEdit { super(native); } } +wrapperCache.registerWrapper('QDateEditWrap', QDateEdit); diff --git a/src/lib/QtWidgets/QDateTimeEdit.ts b/src/lib/QtWidgets/QDateTimeEdit.ts index 140569098..bcd46c17f 100644 --- a/src/lib/QtWidgets/QDateTimeEdit.ts +++ b/src/lib/QtWidgets/QDateTimeEdit.ts @@ -1,5 +1,5 @@ import addon from '../utils/addon'; -import { QWidget } from './QWidget'; +import { QWidget, QWidgetSignals } from './QWidget'; import { QAbstractSpinBox, QAbstractSpinBoxSignals } from './QAbstractSpinBox'; import { QCalendarWidget } from './QCalendarWidget'; import { QDate } from '../QtCore/QDate'; @@ -8,6 +8,7 @@ import { QTime } from '../QtCore/QTime'; import { TimeSpec } from '../QtEnums'; import { NativeElement } from '../core/Component'; import { checkIfNativeElement } from '../utils/helpers'; +import { wrapperCache } from '../core/WrapperCache'; /** @@ -33,13 +34,11 @@ dateTimeEdit.setTime(time); ``` */ export class QDateTimeEdit extends QAbstractSpinBox { - calendar?: QCalendarWidget; - - constructor(arg?: QWidget | NativeElement) { + constructor(arg?: QWidget | NativeElement) { let native: NativeElement; if (checkIfNativeElement(arg)) { native = arg as NativeElement; - } else if (arg) { + } else if (arg != null) { const parent = arg as QWidget; native = new addon.QDateTimeEdit(parent.native); } else { @@ -47,17 +46,11 @@ export class QDateTimeEdit extends QAbstractSpinBox { } super(native); } - setCalendarWidget(calendarWidget: QCalendarWidget): void { - this.calendar = calendarWidget; this.native.setCalendarWidget(calendarWidget.native); } calendarWidget(): QCalendarWidget | null { - const calendar = this.calendar; - if (calendar) { - return calendar; - } - return null; + return wrapperCache.getWrapper(this.native.calendarWidget()) as QCalendarWidget; } setCalendarPopup(enable: boolean): void { this.setProperty('calendarPopup', enable); @@ -99,6 +92,7 @@ export class QDateTimeEdit extends QAbstractSpinBox { return this.property('timeSpec').toInt(); } } +wrapperCache.registerWrapper('QDateTimeEditWrap', QDateTimeEdit); export interface QDateTimeEditSignals extends QAbstractSpinBoxSignals { dateChanged: (date: QDate) => void; diff --git a/src/lib/QtWidgets/QDial.ts b/src/lib/QtWidgets/QDial.ts index 8982bc018..c7ef89654 100644 --- a/src/lib/QtWidgets/QDial.ts +++ b/src/lib/QtWidgets/QDial.ts @@ -1,7 +1,9 @@ import addon from '../utils/addon'; -import { QWidget } from './QWidget'; +import { QWidget, QWidgetSignals } from './QWidget'; import { NativeElement } from '../core/Component'; import { QAbstractSlider, QAbstractSliderSignals } from './QAbstractSlider'; +import { wrapperCache } from '../core/WrapperCache'; +import { checkIfNativeElement } from '../utils/helpers'; /** @@ -20,11 +22,12 @@ const dial = new QDial(); ``` */ export class QDial extends QAbstractSlider { - constructor(); - constructor(parent: QWidget); - constructor(parent?: QWidget) { + constructor(arg?: QWidget | NativeElement) { let native: NativeElement; - if (parent) { + if (checkIfNativeElement(arg)) { + native = arg as NativeElement; + } else if (arg != null) { + const parent = arg as QWidget; native = new addon.QDial(parent.native); } else { native = new addon.QDial(); @@ -53,5 +56,6 @@ export class QDial extends QAbstractSlider { return this.property('wrapping').toBool(); } } +wrapperCache.registerWrapper('QDialWrap', QDial); export type QDialSignals = QAbstractSliderSignals; diff --git a/src/lib/QtWidgets/QDialog.ts b/src/lib/QtWidgets/QDialog.ts index 26e22bd49..f0f93639b 100644 --- a/src/lib/QtWidgets/QDialog.ts +++ b/src/lib/QtWidgets/QDialog.ts @@ -4,6 +4,7 @@ import { NativeElement } from '../core/Component'; import { checkIfNativeElement } from '../utils/helpers'; import { QWidget, QWidgetSignals } from './QWidget'; import { DialogCode } from '../QtEnums'; +import { wrapperCache } from '../core/WrapperCache'; /** @@ -14,13 +15,12 @@ import { DialogCode } from '../QtEnums'; It is inherited by QFileDialog and QMessageBox (n/a QColorDialog, QErrorMessage, QFontDialog, QInputDialog, QMessageBox, QProgressDialog, and QWizard) */ export class QDialog extends QWidget { - constructor(arg?: QDialog | NativeElement) { - let native; - let parent; + constructor(arg?: QWidget | NativeElement) { + let native: NativeElement; if (checkIfNativeElement(arg)) { native = arg as NativeElement; - } else if (arg as QDialog) { - parent = arg as QDialog; + } else if (arg != null) { + const parent = arg as QWidget; native = new addon.QDialog(parent.native); } else { native = new addon.QDialog(); @@ -53,6 +53,7 @@ export class QDialog extends QW this.native.reject(); } } +wrapperCache.registerWrapper('QDialogWrap', QDialog); export interface QDialogSignals extends QWidgetSignals { accepted: () => void; diff --git a/src/lib/QtWidgets/QDoubleSpinBox.ts b/src/lib/QtWidgets/QDoubleSpinBox.ts index 8e1fe54f9..8cbc73e03 100644 --- a/src/lib/QtWidgets/QDoubleSpinBox.ts +++ b/src/lib/QtWidgets/QDoubleSpinBox.ts @@ -1,7 +1,9 @@ import addon from '../utils/addon'; -import { QWidget } from './QWidget'; +import { QWidget, QWidgetSignals } from './QWidget'; import { NativeElement } from '../core/Component'; import { QAbstractSpinBox, QAbstractSpinBoxSignals, StepType } from './QAbstractSpinBox'; +import { checkIfNativeElement } from '../utils/helpers'; +import { wrapperCache } from '../core/WrapperCache'; /** @@ -20,9 +22,12 @@ const doublespinBox = new QDoubleSpinBox(); ``` */ export class QDoubleSpinBox extends QAbstractSpinBox { - constructor(parent?: QWidget) { + constructor(arg?: QWidget | NativeElement) { let native: NativeElement; - if (parent) { + if (checkIfNativeElement(arg)) { + native = arg as NativeElement; + } else if (arg != null) { + const parent = arg as QWidget; native = new addon.QDoubleSpinBox(parent.native); } else { native = new addon.QDoubleSpinBox(); @@ -90,6 +95,7 @@ export class QDoubleSpinBox extends QAbstractSpinBox { return this.native.valueFromText(text); } } +wrapperCache.registerWrapper('QDoubleSpinBoxWrap', QDoubleSpinBox); export interface QDoubleSpinBoxSignals extends QAbstractSpinBoxSignals { valueChanged: (value: number) => void; diff --git a/src/lib/QtWidgets/QErrorMessage.ts b/src/lib/QtWidgets/QErrorMessage.ts index 03fee08b6..b6188b803 100644 --- a/src/lib/QtWidgets/QErrorMessage.ts +++ b/src/lib/QtWidgets/QErrorMessage.ts @@ -1,7 +1,9 @@ import addon from '../utils/addon'; -import { QWidget } from './QWidget'; +import { QWidget, QWidgetSignals } from './QWidget'; import { NativeElement } from '../core/Component'; import { QDialog, QDialogSignals } from './QDialog'; +import { checkIfNativeElement } from '../utils/helpers'; +import { wrapperCache } from '../core/WrapperCache'; /** @@ -21,9 +23,12 @@ const errorMessage = new QErrorMessage(); ``` */ export class QErrorMessage extends QDialog { - constructor(parent?: QWidget) { + constructor(arg?: QWidget | NativeElement) { let native: NativeElement; - if (parent) { + if (checkIfNativeElement(arg)) { + native = arg as NativeElement; + } else if (arg != null) { + const parent = arg as QWidget; native = new addon.QErrorMessage(parent.native); } else { native = new addon.QErrorMessage(); @@ -34,5 +39,6 @@ export class QErrorMessage extends QDialog { this.native.showMessage(message); } } +wrapperCache.registerWrapper('QErrorMessageWrap', QErrorMessage); export type QErrorMessageSignals = QDialogSignals; diff --git a/src/lib/QtWidgets/QFileDialog.ts b/src/lib/QtWidgets/QFileDialog.ts index a5b0c55f4..d79ef7724 100644 --- a/src/lib/QtWidgets/QFileDialog.ts +++ b/src/lib/QtWidgets/QFileDialog.ts @@ -3,6 +3,8 @@ import { QWidget } from './QWidget'; import { NativeElement } from '../core/Component'; import { AcceptMode, DialogLabel, FileMode, Option, ViewMode } from '../QtEnums'; import { QDialog, QDialogSignals } from './QDialog'; +import { wrapperCache } from '../core/WrapperCache'; +import { checkIfNativeElement } from '../utils/helpers'; /** @@ -30,10 +32,12 @@ console.log(selectedFiles); export class QFileDialog extends QDialog { constructor(); constructor(parent: QWidget, caption?: string, directory?: string, filter?: string); - constructor(parent?: QWidget, caption = 'Select File', directory = '', filter = '') { + constructor(arg?: QWidget, caption = 'Select File', directory = '', filter = '') { let native: NativeElement; - if (parent) { - native = new addon.QFileDialog(parent.native, caption, directory, filter); + if (checkIfNativeElement(arg)) { + native = arg as NativeElement; + } else if (arg != null) { + native = new addon.QFileDialog(arg.native, caption, directory, filter); } else { native = new addon.QFileDialog(); } @@ -88,6 +92,7 @@ export class QFileDialog extends QDialog { this.setProperty('options', options); } } +wrapperCache.registerWrapper('QFileDialogWrap', QFileDialog); export interface QFileDialogSignals extends QDialogSignals { currentChanged: (path: string) => void; diff --git a/src/lib/QtWidgets/QFontDialog.ts b/src/lib/QtWidgets/QFontDialog.ts index 41b9f1857..ccf22b759 100644 --- a/src/lib/QtWidgets/QFontDialog.ts +++ b/src/lib/QtWidgets/QFontDialog.ts @@ -1,8 +1,10 @@ import addon from '../utils/addon'; -import { QWidget } from './QWidget'; +import { QWidget, QWidgetSignals } from './QWidget'; import { NativeElement } from '../core/Component'; import { QDialog, QDialogSignals } from './QDialog'; import { QFont } from '../QtGui/QFont'; +import { wrapperCache } from '../core/WrapperCache'; +import { checkIfNativeElement } from '../utils/helpers'; /** @@ -25,9 +27,12 @@ console.log(font); ``` */ export class QFontDialog extends QDialog { - constructor(parent?: QWidget) { + constructor(arg?: QWidget | NativeElement) { let native: NativeElement; - if (parent) { + if (checkIfNativeElement(arg)) { + native = arg as NativeElement; + } else if (arg != null) { + const parent = arg as QWidget; native = new addon.QFontDialog(parent.native); } else { native = new addon.QFontDialog(); @@ -56,6 +61,7 @@ export class QFontDialog extends QDialog { return this.native.testOption(option); } } +wrapperCache.registerWrapper('QFontDialogWrap', QFontDialog); export enum FontDialogOption { NoButtons = 0x00000001, diff --git a/src/lib/QtWidgets/QFrame.ts b/src/lib/QtWidgets/QFrame.ts index aabdaaace..13d0f25c9 100644 --- a/src/lib/QtWidgets/QFrame.ts +++ b/src/lib/QtWidgets/QFrame.ts @@ -3,6 +3,7 @@ import { QWidget, QWidgetSignals } from './QWidget'; import { NativeElement } from '../core/Component'; import { checkIfNativeElement } from '../utils/helpers'; import { QRect } from '../QtCore/QRect'; +import { wrapperCache } from '../core/WrapperCache'; /** > Create and control frame. @@ -20,20 +21,18 @@ const frame = new QFrame(); ``` */ export class QFrame extends QWidget { - constructor(arg?: QWidget | NativeElement) { + constructor(arg?: QWidget | NativeElement) { let native: NativeElement; - let parent; if (checkIfNativeElement(arg)) { native = arg as NativeElement; - } else if (arg as QWidget) { - parent = arg as QWidget; + } else if (arg != null) { + const parent = arg as QWidget; native = new addon.QFrame(parent.native); } else { native = new addon.QFrame(); } super(native); } - setFrameRect(r: QRect): void { this.setProperty('frameRect', r.native); } @@ -74,6 +73,7 @@ export class QFrame extends QWidg return this.native.frameStyle(); } } +wrapperCache.registerWrapper('QFrameWrap', QFrame); export enum Shadow { Plain = 0x0010, diff --git a/src/lib/QtWidgets/QGraphicsBlurEffect.ts b/src/lib/QtWidgets/QGraphicsBlurEffect.ts index ce2bacf7e..e7b70e2d4 100644 --- a/src/lib/QtWidgets/QGraphicsBlurEffect.ts +++ b/src/lib/QtWidgets/QGraphicsBlurEffect.ts @@ -3,9 +3,10 @@ import { NativeElement } from '../core/Component'; import { checkIfNativeElement } from '../utils/helpers'; import { QObject } from '../QtCore/QObject'; import { QGraphicsEffect, QGraphicsEffectSignals } from './QGraphicsEffect'; +import { wrapperCache } from '../core/WrapperCache'; /** - + > The QGraphicsBlurEffect class provides a blur effect. * **This class is a JS wrapper around Qt's [QGraphicsBlurEffect class](https://doc.qt.io/qt-5/qgraphicsblureffect.html)** @@ -22,17 +23,13 @@ blur.setBlurRadius(8); ``` */ export class QGraphicsBlurEffect extends QGraphicsEffect { - constructor(); - constructor(native: NativeElement); - constructor(parent: QObject); - constructor(arg?: QObject | NativeElement) { + constructor(arg?: QObject | NativeElement) { let native: NativeElement; - if (arg) { - if (checkIfNativeElement(arg)) { - native = arg as NativeElement; - } else { - native = new addon.QGraphicsBlurEffect(arg.native); - } + if (checkIfNativeElement(arg)) { + native = arg as NativeElement; + } else if (arg != null) { + const parent = arg as QObject; + native = new addon.QGraphicsBlurEffect(parent.native); } else { native = new addon.QGraphicsBlurEffect(); } @@ -51,6 +48,7 @@ export class QGraphicsBlurEffect extends QGraphicsEffect The QGraphicsDropShadowEffect class provides a drop shadow effect. * **This class is a JS wrapper around Qt's [QGraphicsDropShadowEffect class](https://doc.qt.io/qt-5/qgraphicsdropshadoweffect.html)** -A drop shadow effect renders the source with a drop shadow. +A drop shadow effect renders the source with a drop shadow. ### Example @@ -23,17 +24,13 @@ shadow.setBlurRadius(8); ``` */ export class QGraphicsDropShadowEffect extends QGraphicsEffect { - constructor(); - constructor(native: NativeElement); - constructor(parent: QObject); - constructor(arg?: QObject | NativeElement) { + constructor(arg?: QObject | NativeElement) { let native: NativeElement; - if (arg) { - if (checkIfNativeElement(arg)) { - native = arg as NativeElement; - } else { - native = new addon.QGraphicsDropShadowEffect(arg.native); - } + if (checkIfNativeElement(arg)) { + native = arg as NativeElement; + } else if (arg != null) { + const parent = arg as QObject; + native = new addon.QGraphicsDropShadowEffect(parent.native); } else { native = new addon.QGraphicsDropShadowEffect(); } @@ -64,6 +61,7 @@ export class QGraphicsDropShadowEffect extends QGraphicsEffect void; diff --git a/src/lib/QtWidgets/QGridLayout.ts b/src/lib/QtWidgets/QGridLayout.ts index 89485aed6..ae054ffff 100644 --- a/src/lib/QtWidgets/QGridLayout.ts +++ b/src/lib/QtWidgets/QGridLayout.ts @@ -1,8 +1,10 @@ import addon from '../utils/addon'; -import { QWidget } from './QWidget'; +import { QWidget, QWidgetSignals } from './QWidget'; import { QLayout, QLayoutSignals } from './QLayout'; import { NativeElement } from '../core/Component'; import { AlignmentFlag } from '../QtEnums'; +import { wrapperCache } from '../core/WrapperCache'; +import { checkIfNativeElement } from '../utils/helpers'; /** @@ -30,16 +32,18 @@ layout.addWidget(label2); */ export class QGridLayout extends QLayout { - constructor(parent?: QWidget) { + constructor(arg?: QWidget | NativeElement) { let native: NativeElement; - if (parent) { + if (checkIfNativeElement(arg)) { + native = arg as NativeElement; + } else if (arg != null) { + const parent = arg as QWidget; native = new addon.QGridLayout(parent.native); } else { native = new addon.QGridLayout(); } super(native); } - addLayout( layout: QLayout, row: number, @@ -100,5 +104,6 @@ export class QGridLayout extends QLayout { return this.native.rowCount(); } } +wrapperCache.registerWrapper('QGridLayoutWrap', QGridLayout); export type QGridLayoutSignals = QLayoutSignals; diff --git a/src/lib/QtWidgets/QGroupBox.ts b/src/lib/QtWidgets/QGroupBox.ts index 98e613f0a..b6bb1caa1 100644 --- a/src/lib/QtWidgets/QGroupBox.ts +++ b/src/lib/QtWidgets/QGroupBox.ts @@ -2,6 +2,8 @@ import addon from '../utils/addon'; import { QWidget, QWidgetSignals } from './QWidget'; import { NativeElement } from '../core/Component'; import { AlignmentFlag } from '../QtEnums/AlignmentFlag'; +import { wrapperCache } from '../core/WrapperCache'; +import { checkIfNativeElement } from '../utils/helpers'; /** @@ -40,15 +42,19 @@ win.show(); ``` */ export class QGroupBox extends QWidget { - constructor(parent?: QWidget) { + constructor(arg?: QWidget | NativeElement) { let native: NativeElement; - if (parent) { + if (checkIfNativeElement(arg)) { + native = arg as NativeElement; + } else if (arg != null) { + const parent = arg as QWidget; native = new addon.QGroupBox(parent.native); } else { native = new addon.QGroupBox(); } super(native); } + setAlignment(alignment: AlignmentFlag): void { this.setProperty('alignment', alignment); } @@ -80,6 +86,7 @@ export class QGroupBox extends QWidget { return this.property('title').toString(); } } +wrapperCache.registerWrapper('QGroupBoxWrap', QGroupBox); export interface QGroupBoxSignals extends QWidgetSignals { clicked: (checked: boolean) => void; diff --git a/src/lib/QtWidgets/QHeaderView.ts b/src/lib/QtWidgets/QHeaderView.ts index 1ae937c71..9c646b023 100644 --- a/src/lib/QtWidgets/QHeaderView.ts +++ b/src/lib/QtWidgets/QHeaderView.ts @@ -3,6 +3,7 @@ import { QWidget } from './QWidget'; import { NativeElement } from '../core/Component'; import { QAbstractItemView, QAbstractItemViewSignals } from './QAbstractItemView'; import { AlignmentFlag, checkIfNativeElement, Orientation, QPoint, SortOrder } from '../..'; +import { wrapperCache } from '../core/WrapperCache'; /** @@ -217,6 +218,7 @@ export class QHeaderView { - constructor(parent?: QWidget) { - let native; - if (parent) { + constructor(arg?: QWidget | NativeElement) { + let native: NativeElement; + if (checkIfNativeElement(arg)) { + native = arg as NativeElement; + } else if (arg != null) { + const parent = arg as QWidget; native = new addon.QInputDialog(parent.native); } else { native = new addon.QInputDialog(); @@ -134,6 +140,7 @@ export class QInputDialog extends QDialog { this.native.setTextValue(value); } } +wrapperCache.registerWrapper('QInputDialogWrap', QInputDialog); export interface QInputDialogSignals extends QDialogSignals { doubleValueChanged: (value: number) => void; diff --git a/src/lib/QtWidgets/QLCDNumber.ts b/src/lib/QtWidgets/QLCDNumber.ts index 53c1d6475..0da1494b4 100644 --- a/src/lib/QtWidgets/QLCDNumber.ts +++ b/src/lib/QtWidgets/QLCDNumber.ts @@ -1,4 +1,7 @@ +import { NativeElement } from '../core/Component'; +import { wrapperCache } from '../core/WrapperCache'; import addon from '../utils/addon'; +import { checkIfNativeElement } from '../utils/helpers'; import { QWidget, QWidgetSignals } from './QWidget'; /** @@ -20,9 +23,12 @@ const lcd = new QLCDNumber(); */ export class QLCDNumber extends QWidget { - constructor(parent?: QWidget) { - let native; - if (parent) { + constructor(arg?: QWidget | NativeElement) { + let native: NativeElement; + if (checkIfNativeElement(arg)) { + native = arg as NativeElement; + } else if (arg != null) { + const parent = arg as QWidget; native = new addon.QLCDNumber(parent.native); } else { native = new addon.QLCDNumber(); @@ -78,6 +84,7 @@ export class QLCDNumber extends QWidget { this.native.setOctMode(); } } +wrapperCache.registerWrapper('QLCDNumberWrap', QLCDNumber); export enum Mode { Hex, diff --git a/src/lib/QtWidgets/QLabel.ts b/src/lib/QtWidgets/QLabel.ts index 0afcd2c86..ebeb608f5 100644 --- a/src/lib/QtWidgets/QLabel.ts +++ b/src/lib/QtWidgets/QLabel.ts @@ -1,5 +1,5 @@ import addon from '../utils/addon'; -import { QWidget } from './QWidget'; +import { QWidget, QWidgetSignals } from './QWidget'; import { QFrame, QFrameSignals } from './QFrame'; import { QPixmap } from '../QtGui/QPixmap'; import { QMovie } from '../QtGui/QMovie'; @@ -7,6 +7,9 @@ import { AlignmentFlag } from '../QtEnums/AlignmentFlag'; import { TextFormat } from '../QtEnums/TextFormat'; import { TextInteractionFlag } from '../QtEnums'; import { QPicture } from '../QtGui/QPicture'; +import { wrapperCache } from '../core/WrapperCache'; +import { NativeElement } from '../core/Component'; +import { checkIfNativeElement } from '../utils/helpers'; /** @@ -31,10 +34,13 @@ export class QLabel extends QFrame { private _pixmap?: QPixmap; private _movie?: QMovie; private _buddy?: QWidget | null; - - constructor(parent?: QWidget) { - let native; - if (parent) { + // TODO + constructor(arg?: QWidget | NativeElement) { + let native: NativeElement; + if (checkIfNativeElement(arg)) { + native = arg as NativeElement; + } else if (arg != null) { + const parent = arg as QWidget; native = new addon.QLabel(parent.native); } else { native = new addon.QLabel(); @@ -148,6 +154,7 @@ export class QLabel extends QFrame { this.native.clear(); } } +wrapperCache.registerWrapper('QLabelWrap', QLabel); export interface QLabelSignals extends QFrameSignals { linkActivated: (link: string) => void; diff --git a/src/lib/QtWidgets/QLineEdit.ts b/src/lib/QtWidgets/QLineEdit.ts index 3ad55ee80..5a11e97d1 100644 --- a/src/lib/QtWidgets/QLineEdit.ts +++ b/src/lib/QtWidgets/QLineEdit.ts @@ -3,6 +3,9 @@ import { QWidget, QWidgetSignals } from './QWidget'; import { AlignmentFlag } from '../QtEnums/AlignmentFlag'; import { CursorMoveStyle } from '../QtEnums/CursorMoveStyle'; import { QPoint } from '../QtCore/QPoint'; +import { wrapperCache } from '../core/WrapperCache'; +import { NativeElement } from '../core/Component'; +import { checkIfNativeElement } from '../utils/helpers'; /** @@ -22,9 +25,12 @@ const lineEdit = new QLineEdit(); */ export class QLineEdit extends QWidget { - constructor(parent?: QWidget) { - let native; - if (parent) { + constructor(arg?: QWidget | NativeElement) { + let native: NativeElement; + if (checkIfNativeElement(arg)) { + native = arg as NativeElement; + } else if (arg != null) { + const parent = arg as QWidget; native = new addon.QLineEdit(parent.native); } else { native = new addon.QLineEdit(); @@ -208,6 +214,7 @@ export class QLineEdit extends QWidget { this.native.undo(); } } +wrapperCache.registerWrapper('QLineEditWrap', QLineEdit); export enum EchoMode { Normal, diff --git a/src/lib/QtWidgets/QListView.ts b/src/lib/QtWidgets/QListView.ts index 1e0c26873..7e7ccb697 100644 --- a/src/lib/QtWidgets/QListView.ts +++ b/src/lib/QtWidgets/QListView.ts @@ -1,10 +1,11 @@ import addon from '../utils/addon'; -import { QWidget } from './QWidget'; +import { QWidget, QWidgetSignals } from './QWidget'; import { NativeElement } from '../core/Component'; import { QAbstractItemView, QAbstractItemViewSignals } from './QAbstractItemView'; import { QSize } from '../QtCore/QSize'; import { AlignmentFlag } from '../..'; import { checkIfNativeElement } from '../utils/helpers'; +import { wrapperCache } from '../core/WrapperCache'; /** @@ -22,7 +23,7 @@ const listview = new QListView(); ``` */ export class QListView extends QAbstractItemView { - constructor(arg?: QWidget | NativeElement) { + constructor(arg?: QWidget | NativeElement) { let native: NativeElement; if (checkIfNativeElement(arg)) { native = arg as NativeElement; @@ -129,6 +130,7 @@ export class QListView exte return this.native.isRowHidden(row); } } +wrapperCache.registerWrapper('QListViewWrap', QListView); export enum Flow { LeftToRight, diff --git a/src/lib/QtWidgets/QListWidget.ts b/src/lib/QtWidgets/QListWidget.ts index c7d1d0c88..b2e1619bc 100644 --- a/src/lib/QtWidgets/QListWidget.ts +++ b/src/lib/QtWidgets/QListWidget.ts @@ -1,11 +1,13 @@ import addon from '../utils/addon'; -import { QWidget } from './QWidget'; +import { QWidget, QWidgetSignals } from './QWidget'; import { NativeElement, Component } from '../core/Component'; import { QListWidgetItem } from './QListWidgetItem'; import { QListView, QListViewSignals } from './QListView'; import { QRect } from '../QtCore/QRect'; import { SortOrder, ScrollHint, MatchFlag } from '../QtEnums'; import { QModelIndex } from '../QtCore/QModelIndex'; +import { wrapperCache } from '../core/WrapperCache'; +import { checkIfNativeElement } from '../utils/helpers'; /** @@ -33,11 +35,14 @@ for (let i = 0; i < 30; i++) { ``` */ export class QListWidget extends QListView { - items: Set; + items: Set; - constructor(parent?: QWidget) { - let native; - if (parent) { + constructor(arg?: QWidget | NativeElement) { + let native: NativeElement; + if (checkIfNativeElement(arg)) { + native = arg as NativeElement; + } else if (arg != null) { + const parent = arg as QWidget; native = new addon.QListWidget(parent.native); } else { native = new addon.QListWidget(); @@ -150,6 +155,7 @@ export class QListWidget extends QListView { this.native.scrollToItem(item.native, hint); } } +wrapperCache.registerWrapper('QListWidgetWrap', QListWidget); export interface QListWidgetSignals extends QListViewSignals { currentItemChanged: (current: QListWidgetItem, previous: QListWidgetItem) => void; diff --git a/src/lib/QtWidgets/QMainWindow.ts b/src/lib/QtWidgets/QMainWindow.ts index 90b2710d7..8cd3abce1 100644 --- a/src/lib/QtWidgets/QMainWindow.ts +++ b/src/lib/QtWidgets/QMainWindow.ts @@ -35,7 +35,7 @@ export class QMainWindow extends QWidget { public centralWidget?: QWidget | null; private _menuBar?: QMenuBar; private _statusBar?: QStatusBar | null; - + // TODO constructor(parent?: QWidget) { let native: NativeElement; if (parent) { diff --git a/src/lib/QtWidgets/QMenu.ts b/src/lib/QtWidgets/QMenu.ts index e5f59ae8b..ca8f639b6 100644 --- a/src/lib/QtWidgets/QMenu.ts +++ b/src/lib/QtWidgets/QMenu.ts @@ -3,6 +3,8 @@ import { QWidget, QWidgetSignals } from './QWidget'; import addon from '../utils/addon'; import { QAction } from './QAction'; import { QPoint } from '../QtCore/QPoint'; +import { wrapperCache } from '../core/WrapperCache'; +import { checkIfNativeElement } from '../utils/helpers'; /** @@ -19,9 +21,12 @@ const menu = new QMenu(); ``` */ export class QMenu extends QWidget { - constructor(parent?: QWidget) { - let native; - if (parent) { + constructor(arg?: QWidget | NativeElement) { + let native: NativeElement; + if (checkIfNativeElement(arg)) { + native = arg as NativeElement; + } else if (arg != null) { + const parent = arg as QWidget; native = new addon.QMenu(parent.native); } else { native = new addon.QMenu(); @@ -50,6 +55,7 @@ export class QMenu extends QWidget { this.native.popup(point.native, action?.native); } } +wrapperCache.registerWrapper('QMenuWrap', QMenu); export interface QMenuSignals extends QWidgetSignals { triggered: (action: NativeElement) => void; diff --git a/src/lib/QtWidgets/QMenuBar.ts b/src/lib/QtWidgets/QMenuBar.ts index 01a2f8ffc..8491ce771 100644 --- a/src/lib/QtWidgets/QMenuBar.ts +++ b/src/lib/QtWidgets/QMenuBar.ts @@ -4,6 +4,7 @@ import { QWidget, QWidgetSignals } from './QWidget'; import addon from '../utils/addon'; import { checkIfNativeElement } from '../utils/helpers'; import { QAction } from './QAction'; +import { wrapperCache } from '../core/WrapperCache'; /** @@ -24,30 +25,27 @@ global.win = win; ``` */ export class QMenuBar extends QWidget { - _menus: Set; - - constructor(arg?: QWidget | NativeElement) { - let native; + constructor(arg?: QWidget | NativeElement) { + let native: NativeElement; if (checkIfNativeElement(arg)) { native = arg as NativeElement; - } else if (typeof arg === 'object') { - native = new addon.QMenuBar(arg.native); + } else if (arg != null) { + const parent = arg as QWidget; + native = new addon.QMenuBar(parent.native); } else { native = new addon.QMenuBar(); } super(native); - this._menus = new Set(); } + addMenu(menu: QMenu | string): QMenu { if (typeof menu === 'string') { const qmenu = new QMenu(); qmenu.setTitle(menu); this.native.addMenu(qmenu.native); - this._menus.add(qmenu); return qmenu; } this.native.addMenu(menu.native); - this._menus.add(menu); return menu; } addSeparator(): QAction { @@ -57,5 +55,6 @@ export class QMenuBar extends QWidget { this.native.setNativeMenuBar(nativeMenuBar); } } +wrapperCache.registerWrapper('QMenuBarWrap', QMenuBar); export type QMenuBarSignals = QWidgetSignals; diff --git a/src/lib/QtWidgets/QMessageBox.ts b/src/lib/QtWidgets/QMessageBox.ts index c120b7be6..8a69ef93a 100644 --- a/src/lib/QtWidgets/QMessageBox.ts +++ b/src/lib/QtWidgets/QMessageBox.ts @@ -1,9 +1,11 @@ import addon from '../utils/addon'; -import { QWidget } from './QWidget'; -import { NativeRawPointer } from '../core/Component'; +import { QWidget, QWidgetSignals } from './QWidget'; +import { NativeElement, NativeRawPointer } from '../core/Component'; import { QDialog, QDialogSignals } from './QDialog'; import { QAbstractButton, QAbstractButtonSignals } from './QAbstractButton'; import { QPushButton } from './QPushButton'; +import { wrapperCache } from '../core/WrapperCache'; +import { checkIfNativeElement } from '../utils/helpers'; export enum ButtonRole { InvalidRole, @@ -40,9 +42,12 @@ messageBox.exec(); ``` */ export class QMessageBox extends QDialog { - constructor(parent?: QWidget) { - let native; - if (parent) { + constructor(arg?: QWidget | NativeElement) { + let native: NativeElement; + if (checkIfNativeElement(arg)) { + native = arg as NativeElement; + } else if (arg != null) { + const parent = arg as QWidget; native = new addon.QMessageBox(parent.native); } else { native = new addon.QMessageBox(); @@ -91,6 +96,7 @@ export class QMessageBox extends QDialog { addon.QMessageBox.aboutQt(parent.native, title); } } +wrapperCache.registerWrapper('QMessageBoxWrap', QMessageBox); export interface QMessageBoxSignals extends QDialogSignals { buttonClicked: (buttonRawPointer: NativeRawPointer<'QAbstractButton*'>) => void; diff --git a/src/lib/QtWidgets/QPlainTextEdit.ts b/src/lib/QtWidgets/QPlainTextEdit.ts index f1daa7b60..191c568db 100644 --- a/src/lib/QtWidgets/QPlainTextEdit.ts +++ b/src/lib/QtWidgets/QPlainTextEdit.ts @@ -1,8 +1,10 @@ import addon from '../utils/addon'; -import { QWidget } from './QWidget'; +import { QWidget, QWidgetSignals } from './QWidget'; import { NativeElement } from '../core/Component'; import { QAbstractScrollArea, QAbstractScrollAreaSignals } from './QAbstractScrollArea'; import { QTextOptionWrapMode } from '../QtGui/QTextOption'; +import { wrapperCache } from '../core/WrapperCache'; +import { checkIfNativeElement } from '../utils/helpers'; export interface QPlainTextEditSignals extends QAbstractScrollAreaSignals { textChanged: () => void; @@ -32,10 +34,12 @@ const plainTextEdit = new QPlainTextEdit(); ``` */ export class QPlainTextEdit extends QAbstractScrollArea { - placeholderText?: string; - constructor(parent?: QWidget) { + constructor(arg?: QWidget | NativeElement) { let native: NativeElement; - if (parent) { + if (checkIfNativeElement(arg)) { + native = arg as NativeElement; + } else if (arg != null) { + const parent = arg as QWidget; native = new addon.QPlainTextEdit(parent.native); } else { native = new addon.QPlainTextEdit(); @@ -48,7 +52,6 @@ export class QPlainTextEdit extends QAbstractScrollArea { } setPlaceholderText(text: string): void { // react:✓, //TODO:getter - this.placeholderText = text; this.native.setPlaceholderText(text); } toPlainText(): string { @@ -79,6 +82,7 @@ export class QPlainTextEdit extends QAbstractScrollArea { this.native.insertPlainText(`${text}`); } } +wrapperCache.registerWrapper('QPlainTextEditWrap', QPlainTextEdit); export enum LineWrapMode { NoWrap, diff --git a/src/lib/QtWidgets/QProgressBar.ts b/src/lib/QtWidgets/QProgressBar.ts index 5b6a91012..c893ce35f 100644 --- a/src/lib/QtWidgets/QProgressBar.ts +++ b/src/lib/QtWidgets/QProgressBar.ts @@ -2,6 +2,8 @@ import addon from '../utils/addon'; import { QWidget, QWidgetSignals } from './QWidget'; import { NativeElement } from '../core/Component'; import { Orientation, AlignmentFlag } from '../QtEnums'; +import { wrapperCache } from '../core/WrapperCache'; +import { checkIfNativeElement } from '../utils/helpers'; /** @@ -20,9 +22,12 @@ const progressBar = new QProgressBar(); ``` */ export class QProgressBar extends QWidget { - constructor(parent?: QWidget) { + constructor(arg?: QWidget | NativeElement) { let native: NativeElement; - if (parent) { + if (checkIfNativeElement(arg)) { + native = arg as NativeElement; + } else if (arg != null) { + const parent = arg as QWidget; native = new addon.QProgressBar(parent.native); } else { native = new addon.QProgressBar(); @@ -96,6 +101,7 @@ export class QProgressBar extends QWidget { this.native.setRange(minimum, maximum); } } +wrapperCache.registerWrapper('QProgressBarWrap', QProgressBar); export enum QProgressBarDirection { TopToBottom, diff --git a/src/lib/QtWidgets/QProgressDialog.ts b/src/lib/QtWidgets/QProgressDialog.ts index 5226948e3..baed5ef64 100644 --- a/src/lib/QtWidgets/QProgressDialog.ts +++ b/src/lib/QtWidgets/QProgressDialog.ts @@ -1,6 +1,9 @@ import addon from '../utils/addon'; -import { QWidget } from './QWidget'; +import { QWidget, QWidgetSignals } from './QWidget'; import { QDialog, QDialogSignals } from './QDialog'; +import { wrapperCache } from '../core/WrapperCache'; +import { NativeElement } from '../core/Component'; +import { checkIfNativeElement } from '../utils/helpers'; /** @@ -20,9 +23,12 @@ const progressDialog = new QProgressDialog(); ``` */ export class QProgressDialog extends QDialog { - constructor(parent?: QWidget) { - let native; - if (parent) { + constructor(arg?: QWidget | NativeElement) { + let native: NativeElement; + if (checkIfNativeElement(arg)) { + native = arg as NativeElement; + } else if (arg != null) { + const parent = arg as QWidget; native = new addon.QProgressDialog(parent.native); } else { native = new addon.QProgressDialog(); @@ -87,6 +93,7 @@ export class QProgressDialog extends QDialog { this.native.setRange(minimum, maximum); } } +wrapperCache.registerWrapper('QProgressDialogWrap', QProgressDialog); export interface QProgressDialogSignals extends QDialogSignals { canceled: () => void; diff --git a/src/lib/QtWidgets/QPushButton.ts b/src/lib/QtWidgets/QPushButton.ts index c13aa042c..35413003b 100644 --- a/src/lib/QtWidgets/QPushButton.ts +++ b/src/lib/QtWidgets/QPushButton.ts @@ -1,9 +1,10 @@ import addon from '../utils/addon'; -import { QWidget } from './QWidget'; -import { NativeElement, NativeRawPointer } from '../core/Component'; +import { QWidget, QWidgetSignals } from './QWidget'; +import { NativeElement } from '../core/Component'; import { QAbstractButton, QAbstractButtonSignals } from './QAbstractButton'; -import { checkIfNativeElement, checkIfNapiExternal } from '../utils/helpers'; +import { checkIfNativeElement } from '../utils/helpers'; import { QMenu } from './QMenu'; +import { wrapperCache } from '../core/WrapperCache'; /** @@ -23,17 +24,13 @@ button.setText("Hello"); ``` */ export class QPushButton extends QAbstractButton { - private _menu?: QMenu | null; - - constructor(arg?: QWidget | NativeRawPointer | NativeElement, disableNativeDeletion = true) { - let native; + constructor(arg?: QWidget | NativeElement) { + let native: NativeElement; if (checkIfNativeElement(arg)) { native = arg as NativeElement; - } else if (checkIfNapiExternal(arg)) { - native = new addon.QPushButton(arg, disableNativeDeletion); - } else if (arg) { - const parentWidget = arg as QWidget; - native = new addon.QPushButton(parentWidget.native); + } else if (arg != null) { + const parent = arg as QWidget; + native = new addon.QPushButton(parent.native); } else { native = new addon.QPushButton(); } @@ -58,18 +55,15 @@ export class QPushButton extends QAbstractButton { return this.property('flat').toBool(); } setMenu(menu: QMenu): void { - this._menu = menu; this.native.setMenu(menu.native); } menu(): QMenu | null { - if (this._menu) { - return this._menu; - } - return null; + return wrapperCache.getWrapper(this.native.menu()) as QMenu; } showMenu(): void { this.native.showMenu(); } } +wrapperCache.registerWrapper('QPushButtonWrap', QPushButton); export type QPushButtonSignals = QAbstractButtonSignals; diff --git a/src/lib/QtWidgets/QRadioButton.ts b/src/lib/QtWidgets/QRadioButton.ts index f0ee99cf1..63c352954 100644 --- a/src/lib/QtWidgets/QRadioButton.ts +++ b/src/lib/QtWidgets/QRadioButton.ts @@ -1,8 +1,9 @@ import addon from '../utils/addon'; -import { QWidget } from './QWidget'; -import { NativeElement, NativeRawPointer } from '../core/Component'; +import { QWidget, QWidgetSignals } from './QWidget'; +import { NativeElement } from '../core/Component'; import { QAbstractButton, QAbstractButtonSignals } from './QAbstractButton'; -import { checkIfNativeElement, checkIfNapiExternal } from '../utils/helpers'; +import { checkIfNativeElement } from '../utils/helpers'; +import { wrapperCache } from '../core/WrapperCache'; /** @@ -23,20 +24,19 @@ radioButton.setText("Hello"); */ export class QRadioButton extends QAbstractButton { - constructor(arg?: QWidget | NativeRawPointer | NativeElement, disableNativeDeletion = true) { - let native; + constructor(arg?: QWidget | NativeElement) { + let native: NativeElement; if (checkIfNativeElement(arg)) { native = arg as NativeElement; - } else if (checkIfNapiExternal(arg)) { - native = new addon.QRadioButton(arg, disableNativeDeletion); - } else if (arg) { - const parentWidget = arg as QWidget; - native = new addon.QRadioButton(parentWidget.native); + } else if (arg != null) { + const parent = arg as QWidget; + native = new addon.QRadioButton(parent.native); } else { native = new addon.QRadioButton(); } super(native); } } +wrapperCache.registerWrapper('QRadioButtonWrap', QRadioButton); export type QRadioButtonSignals = QAbstractButtonSignals; diff --git a/src/lib/QtWidgets/QScrollArea.ts b/src/lib/QtWidgets/QScrollArea.ts index 1dc6eb8db..f1153f22a 100644 --- a/src/lib/QtWidgets/QScrollArea.ts +++ b/src/lib/QtWidgets/QScrollArea.ts @@ -1,10 +1,11 @@ import addon from '../utils/addon'; -import { QWidget } from './QWidget'; +import { QWidget, QWidgetSignals } from './QWidget'; import { NativeElement } from '../core/Component'; import { QAbstractScrollArea, QAbstractScrollAreaSignals } from './QAbstractScrollArea'; import { AlignmentFlag } from '../QtEnums'; import { Margins } from '../utils/Margins'; import { wrapperCache } from '../core/WrapperCache'; +import { checkIfNativeElement } from '../utils/helpers'; /** @@ -30,9 +31,12 @@ scrollArea.setWidget(imageLabel); ``` */ export class QScrollArea extends QAbstractScrollArea { - constructor(parent?: QWidget) { + constructor(arg?: QWidget | NativeElement) { let native: NativeElement; - if (parent) { + if (checkIfNativeElement(arg)) { + native = arg as NativeElement; + } else if (arg != null) { + const parent = arg as QWidget; native = new addon.QScrollArea(parent.native); } else { native = new addon.QScrollArea(); @@ -82,5 +86,6 @@ export class QScrollArea extends QAbstractScrollArea { }; } } +wrapperCache.registerWrapper('QScrollAreaWrap', QScrollArea); export type QScrollAreaSignals = QAbstractScrollAreaSignals; diff --git a/src/lib/QtWidgets/QScrollBar.ts b/src/lib/QtWidgets/QScrollBar.ts index e3557473b..d634f6686 100644 --- a/src/lib/QtWidgets/QScrollBar.ts +++ b/src/lib/QtWidgets/QScrollBar.ts @@ -1,7 +1,9 @@ import addon from '../utils/addon'; -import { QWidget } from './QWidget'; +import { QWidget, QWidgetSignals } from './QWidget'; import { NativeElement } from '../core/Component'; import { QAbstractSlider, QAbstractSliderSignals } from './QAbstractSlider'; +import { wrapperCache } from '../core/WrapperCache'; +import { checkIfNativeElement } from '../utils/helpers'; /** @@ -20,9 +22,12 @@ const scrollbar = new QScrollBar(); ``` */ export class QScrollBar extends QAbstractSlider { - constructor(parent?: QWidget) { + constructor(arg?: QWidget | NativeElement) { let native: NativeElement; - if (parent) { + if (checkIfNativeElement(arg)) { + native = arg as NativeElement; + } else if (arg != null) { + const parent = arg as QWidget; native = new addon.QScrollBar(parent.native); } else { native = new addon.QScrollBar(); @@ -30,5 +35,6 @@ export class QScrollBar extends QAbstractSlider { super(native); } } +wrapperCache.registerWrapper('QScrollBarWrap', QScrollBar); export type QScrollBarSignals = QAbstractSliderSignals; diff --git a/src/lib/QtWidgets/QShortcut.ts b/src/lib/QtWidgets/QShortcut.ts index c1d9581c2..df285df23 100644 --- a/src/lib/QtWidgets/QShortcut.ts +++ b/src/lib/QtWidgets/QShortcut.ts @@ -1,8 +1,11 @@ import addon from '../utils/addon'; -import { QWidget } from './QWidget'; +import { QWidget, QWidgetSignals } from './QWidget'; import { QKeySequence } from '../QtGui/QKeySequence'; import { ShortcutContext } from '../QtEnums'; import { QObject, QObjectSignals } from '../QtCore/QObject'; +import { wrapperCache } from '../core/WrapperCache'; +import { NativeElement } from '../core/Component'; +import { checkIfNativeElement } from '../utils/helpers'; /** @@ -29,8 +32,17 @@ global.shortcut = shortcut; ``` */ export class QShortcut extends QObject { - constructor(parent: QWidget) { - super(new addon.QShortcut(parent.native)); + constructor(arg?: QWidget | NativeElement) { + let native: NativeElement; + if (checkIfNativeElement(arg)) { + native = arg as NativeElement; + } else if (arg != null) { + const parent = arg as QWidget; + native = new addon.QShortcut(parent.native); + } else { + native = new addon.QShortcut(); + } + super(native); } setEnabled(enabled: boolean): void { this.native.setEnabled(enabled); @@ -45,6 +57,7 @@ export class QShortcut extends QObject { this.native.setContext(shortcutContext); } } +wrapperCache.registerWrapper('QShortcutWrap', QShortcut); export interface QShortcutSignals extends QObjectSignals { activated: () => void; diff --git a/src/lib/QtWidgets/QSlider.ts b/src/lib/QtWidgets/QSlider.ts index bb3c4e170..e39431d14 100644 --- a/src/lib/QtWidgets/QSlider.ts +++ b/src/lib/QtWidgets/QSlider.ts @@ -1,7 +1,9 @@ import addon from '../utils/addon'; -import { QWidget } from './QWidget'; +import { QWidget, QWidgetSignals } from './QWidget'; import { NativeElement } from '../core/Component'; import { QAbstractSlider, QAbstractSliderSignals } from './QAbstractSlider'; +import { checkIfNativeElement } from '../utils/helpers'; +import { wrapperCache } from '../core/WrapperCache'; /** @@ -20,9 +22,12 @@ const slider = new QSlider(); ``` */ export class QSlider extends QAbstractSlider { - constructor(parent?: QWidget) { + constructor(arg?: QWidget | NativeElement) { let native: NativeElement; - if (parent) { + if (checkIfNativeElement(arg)) { + native = arg as NativeElement; + } else if (arg != null) { + const parent = arg as QWidget; native = new addon.QSlider(parent.native); } else { native = new addon.QSlider(); @@ -42,6 +47,7 @@ export class QSlider extends QAbstractSlider { return this.property('tickPosition').toInt(); } } +wrapperCache.registerWrapper('QSliderWrap', QSlider); export enum TickPosition { NoTicks, diff --git a/src/lib/QtWidgets/QSpinBox.ts b/src/lib/QtWidgets/QSpinBox.ts index 37b7462a9..d75c66a66 100644 --- a/src/lib/QtWidgets/QSpinBox.ts +++ b/src/lib/QtWidgets/QSpinBox.ts @@ -1,6 +1,9 @@ import addon from '../utils/addon'; -import { QWidget } from './QWidget'; +import { QWidget, QWidgetSignals } from './QWidget'; import { QAbstractSpinBox, QAbstractSpinBoxSignals, StepType } from './QAbstractSpinBox'; +import { wrapperCache } from '../core/WrapperCache'; +import { NativeElement } from '../core/Component'; +import { checkIfNativeElement } from '../utils/helpers'; /** @@ -19,9 +22,12 @@ const spinBox = new QSpinBox(); ``` */ export class QSpinBox extends QAbstractSpinBox { - constructor(parent?: QWidget) { - let native; - if (parent) { + constructor(arg?: QWidget | NativeElement) { + let native: NativeElement; + if (checkIfNativeElement(arg)) { + native = arg as NativeElement; + } else if (arg != null) { + const parent = arg as QWidget; native = new addon.QSpinBox(parent.native); } else { native = new addon.QSpinBox(); @@ -83,6 +89,7 @@ export class QSpinBox extends QAbstractSpinBox { this.native.setRange(minimum, maximum); } } +wrapperCache.registerWrapper('QSpinBoxWrap', QSpinBox); export interface QSpinBoxSignals extends QAbstractSpinBoxSignals { valueChanged: (value: number) => void; diff --git a/src/lib/QtWidgets/QSplitter.ts b/src/lib/QtWidgets/QSplitter.ts index 5218eb658..79eb6e410 100644 --- a/src/lib/QtWidgets/QSplitter.ts +++ b/src/lib/QtWidgets/QSplitter.ts @@ -1,8 +1,10 @@ import addon from '../utils/addon'; -import { QWidget } from './QWidget'; +import { QWidget, QWidgetSignals } from './QWidget'; import { QFrame, QFrameSignals } from './QFrame'; import { NativeElement } from '../core/Component'; import { Orientation } from '../QtEnums'; +import { wrapperCache } from '../core/WrapperCache'; +import { checkIfNativeElement } from '../utils/helpers'; /** @@ -35,9 +37,12 @@ splitterHorizontal.addWidget(right); */ export class QSplitter extends QFrame { - constructor(parent?: QWidget) { + constructor(arg?: QWidget | NativeElement) { let native: NativeElement; - if (parent) { + if (checkIfNativeElement(arg)) { + native = arg as NativeElement; + } else if (arg != null) { + const parent = arg as QWidget; native = new addon.QSplitter(parent.native); } else { native = new addon.QSplitter(); @@ -72,6 +77,7 @@ export class QSplitter extends QFrame { this.native.setOrientation(orientation); } } +wrapperCache.registerWrapper('QSplitterWrap', QSplitter); export interface QSplitterSignals extends QFrameSignals { splitterMoved: (pos: number, index: number) => void; diff --git a/src/lib/QtWidgets/QStackedWidget.ts b/src/lib/QtWidgets/QStackedWidget.ts index 289d4feae..3fbbcdc35 100644 --- a/src/lib/QtWidgets/QStackedWidget.ts +++ b/src/lib/QtWidgets/QStackedWidget.ts @@ -1,6 +1,9 @@ import addon from '../utils/addon'; -import { QWidget } from './QWidget'; +import { QWidget, QWidgetSignals } from './QWidget'; import { QFrame, QFrameSignals } from './QFrame'; +import { wrapperCache } from '../core/WrapperCache'; +import { NativeElement } from '../core/Component'; +import { checkIfNativeElement } from '../utils/helpers'; /** @@ -44,16 +47,18 @@ win.show(); ``` */ export class QStackedWidget extends QFrame { - constructor(parent?: QWidget) { - let native; - if (parent) { + constructor(arg?: QWidget | NativeElement) { + let native: NativeElement; + if (checkIfNativeElement(arg)) { + native = arg as NativeElement; + } else if (arg != null) { + const parent = arg as QWidget; native = new addon.QStackedWidget(parent.native); } else { native = new addon.QStackedWidget(); } super(native); } - // *** Public Function *** addWidget(widget: QWidget): void { this.native.addWidget(widget.native); @@ -81,6 +86,7 @@ export class QStackedWidget extends QFrame { this.native.setCurrentWidget(widget.native); } } +wrapperCache.registerWrapper('QStackedWidgetWrap', QStackedWidget); export interface QStackedWidgetSignals extends QFrameSignals { currentChanged: (index: number) => void; diff --git a/src/lib/QtWidgets/QStandardItemModel.ts b/src/lib/QtWidgets/QStandardItemModel.ts index f0ed26305..a5c0893e2 100644 --- a/src/lib/QtWidgets/QStandardItemModel.ts +++ b/src/lib/QtWidgets/QStandardItemModel.ts @@ -1,16 +1,21 @@ import addon from '../utils/addon'; -import { QWidget } from './QWidget'; import { QObject, QObjectSignals } from '../QtCore/QObject'; import { QStandardItem } from './QStandardItem'; +import { wrapperCache } from '../core/WrapperCache'; +import { NativeElement } from '../core/Component'; +import { checkIfNativeElement } from '../utils/helpers'; export interface QStandardItemModelSignals extends QObjectSignals { itemChanged: (item: QStandardItem) => void; } export class QStandardItemModel extends QObject { - constructor(parent?: QWidget) { - let native; - if (parent) { + constructor(arg?: QObject | NativeElement) { + let native: NativeElement; + if (checkIfNativeElement(arg)) { + native = arg as NativeElement; + } else if (arg != null) { + const parent = arg as QObject; native = new addon.QStandardItemModel(parent.native); } else { native = new addon.QStandardItemModel(); @@ -26,3 +31,4 @@ export class QStandardItemModel extends QObject { } } } +wrapperCache.registerWrapper('QStandardItemModelWrap', QStandardItemModel); diff --git a/src/lib/QtWidgets/QStatusBar.ts b/src/lib/QtWidgets/QStatusBar.ts index 08cbe9f44..56a682aa9 100644 --- a/src/lib/QtWidgets/QStatusBar.ts +++ b/src/lib/QtWidgets/QStatusBar.ts @@ -1,6 +1,8 @@ import addon from '../utils/addon'; import { QWidgetSignals, QWidget } from './QWidget'; import { NativeElement } from '../core/Component'; +import { wrapperCache } from '../core/WrapperCache'; +import { checkIfNativeElement } from '../utils/helpers'; export interface QStatusBarSignals extends QWidgetSignals { messageChanged: (message: string) => void; @@ -23,23 +25,18 @@ const progressBar = new QStatusBar(); ``` */ export class QStatusBar extends QWidget { - permanentWidgets: Set; - widgets: Set; - - constructor(parent?: QWidget) { - let native; - if (parent) { + constructor(arg?: QWidget | NativeElement) { + let native: NativeElement; + if (checkIfNativeElement(arg)) { + native = arg as NativeElement; + } else if (arg != null) { + const parent = arg as QWidget; native = new addon.QStatusBar(parent.native); } else { native = new addon.QStatusBar(); } - super(native); - - this.permanentWidgets = new Set(); - this.widgets = new Set(); } - /** * Adds the given widget permanently to this status bar, reparenting the widget if it isn't already a child of this QStatusBar object. The stretch parameter is used to compute a suitable size for the given widget as the status bar grows and shrinks. The default stretch factor is 0, i.e giving the widget a minimum of space. * Permanently means that the widget may not be obscured by temporary messages. It is is located at the far right of the status bar. @@ -48,10 +45,6 @@ export class QStatusBar extends QWidget { */ addPermanentWidget(widget: QWidget, stretch = 0): void { this.native.addPermanentWidget(widget.native, stretch); - - if (!this.permanentWidgets.has(widget.native)) { - this.permanentWidgets.add(widget.native); - } } /** @@ -62,10 +55,6 @@ export class QStatusBar extends QWidget { */ addWidget(widget: QWidget, stretch = 0): void { this.native.addWidget(widget.native, stretch); - - if (!this.widgets.has(widget.native)) { - this.widgets.add(widget.native); - } } /** @@ -91,12 +80,7 @@ export class QStatusBar extends QWidget { * @param stretch Used to compute a suitable size for the given widget as the status bar grows and shrinks. The default stretch factor is 0, i.e giving the widget a minimum of space. */ insertPermanentWidget(index: number, widget: QWidget, stretch = 0): number { - const insertionIndex = this.native.insertPermanentWidget(index, widget.native, stretch); - if (!this.permanentWidgets.has(widget.native)) { - this.permanentWidgets.add(widget.native); - } - - return insertionIndex; + return this.native.insertPermanentWidget(index, widget.native, stretch); } /** @@ -108,12 +92,7 @@ export class QStatusBar extends QWidget { * @param stretch Used to compute a suitable size for the given widget as the status bar grows and shrinks. The default stretch factor is 0, i.e giving the widget a minimum of space. */ insertWidget(index: number, widget: QWidget, stretch = 0): number { - const insertionIndex = this.native.insertWidget(index, widget.native, stretch); - if (!this.widgets.has(widget.native)) { - this.widgets.add(widget.native); - } - - return insertionIndex; + return this.native.insertWidget(index, widget.native, stretch); } /** @@ -130,8 +109,6 @@ export class QStatusBar extends QWidget { */ removeWidget(widget: QWidget): void { this.native.removeWidget(widget.native); - this.widgets.delete(widget.native); - this.permanentWidgets.delete(widget.native); } /** @@ -152,3 +129,4 @@ export class QStatusBar extends QWidget { this.native.setSizeGripEnabled(enabled); } } +wrapperCache.registerWrapper('QStatusBarWrap', QStatusBar); diff --git a/src/lib/QtWidgets/QSvgWidget.ts b/src/lib/QtWidgets/QSvgWidget.ts index fce3feb85..02adf2d8f 100644 --- a/src/lib/QtWidgets/QSvgWidget.ts +++ b/src/lib/QtWidgets/QSvgWidget.ts @@ -1,6 +1,8 @@ import addon from '../utils/addon'; import { QWidget, QWidgetSignals } from './QWidget'; import { NativeElement } from '../core/Component'; +import { wrapperCache } from '../core/WrapperCache'; +import { checkIfNativeElement } from '../utils/helpers'; /** @@ -27,9 +29,12 @@ fs.readFile("icon.svg", (err, buffer) => { */ export class QSvgWidget extends QWidget { - constructor(parent?: QWidget) { + constructor(arg?: QWidget | NativeElement) { let native: NativeElement; - if (parent) { + if (checkIfNativeElement(arg)) { + native = arg as NativeElement; + } else if (arg != null) { + const parent = arg as QWidget; native = new addon.QSvgWidget(parent.native); } else { native = new addon.QSvgWidget(); @@ -44,3 +49,4 @@ export class QSvgWidget extends QWidget { } } } +wrapperCache.registerWrapper('QSvgWidgetWrap', QSvgWidget); diff --git a/src/lib/QtWidgets/QSystemTrayIcon.ts b/src/lib/QtWidgets/QSystemTrayIcon.ts index 9d0d466b4..18bbbdbae 100644 --- a/src/lib/QtWidgets/QSystemTrayIcon.ts +++ b/src/lib/QtWidgets/QSystemTrayIcon.ts @@ -1,8 +1,11 @@ import addon from '../utils/addon'; -import { QWidget } from './QWidget'; +import { QWidget, QWidgetSignals } from './QWidget'; import { QIcon } from '../QtGui/QIcon'; import { QMenu } from './QMenu'; import { QObject, QObjectSignals } from '../QtCore/QObject'; +import { wrapperCache } from '../core/WrapperCache'; +import { NativeElement } from '../core/Component'; +import { checkIfNativeElement } from '../utils/helpers'; /** @@ -28,11 +31,12 @@ global.tray = tray; // prevents garbage collection of tray ``` */ export class QSystemTrayIcon extends QObject { - contextMenu?: QMenu; - - constructor(parent?: QWidget) { - let native; - if (parent) { + constructor(arg?: QWidget | NativeElement) { + let native: NativeElement; + if (checkIfNativeElement(arg)) { + native = arg as NativeElement; + } else if (arg != null) { + const parent = arg as QWidget; native = new addon.QSystemTrayIcon(parent.native); } else { native = new addon.QSystemTrayIcon(); @@ -58,10 +62,10 @@ export class QSystemTrayIcon extends QObject { this.native.setToolTip(tooltip); } setContextMenu(menu: QMenu): void { - this.contextMenu = menu; - this.native.setContextMenu(this.contextMenu.native); + this.native.setContextMenu(menu.native); } } +wrapperCache.registerWrapper('QSystemTrayIconWrap', QSystemTrayIcon); export enum QSystemTrayIconActivationReason { Unknown = 0, diff --git a/src/lib/QtWidgets/QTabBar.ts b/src/lib/QtWidgets/QTabBar.ts index 004a8e16f..546886cd4 100644 --- a/src/lib/QtWidgets/QTabBar.ts +++ b/src/lib/QtWidgets/QTabBar.ts @@ -7,6 +7,9 @@ import { QVariant } from '../QtCore/QVariant'; import { QColor } from '../QtGui/QColor'; import { QPoint } from '../QtCore/QPoint'; import { QRect } from '../QtCore/QRect'; +import { wrapperCache } from '../core/WrapperCache'; +import { NativeElement } from '../core/Component'; +import { checkIfNativeElement } from '../utils/helpers'; /** @@ -26,9 +29,12 @@ const tabBar = new QTabBar(); ``` */ export class QTabBar extends QWidget { - constructor(parent?: QWidget) { - let native; - if (parent) { + constructor(arg?: QWidget | NativeElement) { + let native: NativeElement; + if (checkIfNativeElement(arg)) { + native = arg as NativeElement; + } else if (arg != null) { + const parent = arg as QWidget; native = new addon.QTabBar(parent.native); } else { native = new addon.QTabBar(); @@ -195,6 +201,7 @@ export class QTabBar extends QWidget { return new QRect(this.native.tabRect(index)); } } +wrapperCache.registerWrapper('QTabBarWrap', QTabBar); export enum ButtonPosition { LeftSide = 0, diff --git a/src/lib/QtWidgets/QTabWidget.ts b/src/lib/QtWidgets/QTabWidget.ts index 27869568d..e40ccfdcd 100644 --- a/src/lib/QtWidgets/QTabWidget.ts +++ b/src/lib/QtWidgets/QTabWidget.ts @@ -3,6 +3,8 @@ import { QWidget, QWidgetSignals } from './QWidget'; import { NativeElement } from '../core/Component'; import { QIcon } from '../QtGui/QIcon'; import { TabPosition } from '../QtEnums'; +import { wrapperCache } from '../core/WrapperCache'; +import { checkIfNativeElement } from '../utils/helpers'; /** @@ -25,29 +27,27 @@ tabWidget.addTab(new QCalendarWidget(), new QIcon(), 'Tab 2'); ``` */ export class QTabWidget extends QWidget { - tabs: QWidget[]; - - constructor(parent?: QWidget) { + constructor(arg?: QWidget | NativeElement) { let native: NativeElement; - if (parent) { + if (checkIfNativeElement(arg)) { + native = arg as NativeElement; + } else if (arg != null) { + const parent = arg as QWidget; native = new addon.QTabWidget(parent.native); } else { native = new addon.QTabWidget(); } super(native); - this.tabs = []; } addTab(page: QWidget, icon: QIcon, label: string): number { const index = this.native.addTab(page.native, icon.native, label); - this.tabs.push(page); page.setFlexNodeSizeControlled(true); return index; } insertTab(index: number, page: QWidget, icon: QIcon, label: string): number { const newIndex = this.native.insertTab(index, page.native, icon.native, label); - this.tabs.splice(index, 0, page); return newIndex; } @@ -77,15 +77,19 @@ export class QTabWidget extends QWidget { removeTab(index: number): void { this.native.removeTab(index); - const toRemove = this.tabs[index]; + const toRemove = this.widget(index); toRemove.setFlexNodeSizeControlled(false); - this.tabs.splice(index, 1); } setTabsClosable(closeable: boolean): void { this.native.setTabsClosable(closeable); } + + widget(index: number): QWidget { + return wrapperCache.getWrapper(this.native.widget(index)) as QWidget; + } } +wrapperCache.registerWrapper('QTabWidgetWrap', QTabWidget); export interface QTabWidgetSignals extends QWidgetSignals { currentChanged: (index: number) => void; diff --git a/src/lib/QtWidgets/QTableView.ts b/src/lib/QtWidgets/QTableView.ts index 734bdfb1a..9fce94cb7 100644 --- a/src/lib/QtWidgets/QTableView.ts +++ b/src/lib/QtWidgets/QTableView.ts @@ -1,8 +1,11 @@ import addon from '../utils/addon'; -import { QWidget } from './QWidget'; +import { QWidget, QWidgetSignals } from './QWidget'; import { SortOrder, PenStyle } from '../QtEnums'; import { QAbstractItemView, QAbstractItemViewSignals } from './QAbstractItemView'; import { QHeaderView } from './QHeaderView'; +import { wrapperCache } from '../core/WrapperCache'; +import { NativeElement } from '../core/Component'; +import { checkIfNativeElement } from '../utils/helpers'; /** @@ -20,9 +23,12 @@ const tableview = new QTableView(); ``` */ export class QTableView extends QAbstractItemView { - constructor(parent?: QWidget) { - let native; - if (parent) { + constructor(arg?: QWidget | NativeElement) { + let native: NativeElement; + if (checkIfNativeElement(arg)) { + native = arg as NativeElement; + } else if (arg != null) { + const parent = arg as QWidget; native = new addon.QTableView(parent.native); } else { native = new addon.QTableView(); @@ -185,5 +191,6 @@ export class QTableView e this.native.sortByColumn(column, order); } } +wrapperCache.registerWrapper('QTableViewWrap', QTableView); export type QTableViewSignals = QAbstractItemViewSignals; diff --git a/src/lib/QtWidgets/QTableWidget.ts b/src/lib/QtWidgets/QTableWidget.ts index dd1205d7c..5fba3e109 100644 --- a/src/lib/QtWidgets/QTableWidget.ts +++ b/src/lib/QtWidgets/QTableWidget.ts @@ -5,6 +5,8 @@ import { MatchFlag, ScrollHint, SortOrder } from '../QtEnums'; import { QTableWidgetItem } from './QTableWidgetItem'; import { QAbstractScrollArea, QAbstractScrollAreaSignals } from './QAbstractScrollArea'; import { QRect } from '../QtCore/QRect'; +import { wrapperCache } from '../core/WrapperCache'; +import { checkIfNativeElement } from '../utils/helpers'; /** @@ -39,12 +41,21 @@ win.show(); */ export class QTableWidget extends QAbstractScrollArea { items: Set; - constructor(rows: number, columns: number, parent?: QWidget) { - let native; - if (parent) { - native = new addon.QTableWidget(rows, columns, parent.native); + constructor(rowsOrNativeOrParent: QWidget | NativeElement | number, columns?: number, parent?: QWidget) { + let native: NativeElement; + if (checkIfNativeElement(rowsOrNativeOrParent)) { + native = rowsOrNativeOrParent as NativeElement; + } else if (typeof rowsOrNativeOrParent == 'number') { + const rows = rowsOrNativeOrParent; + if (parent) { + native = new addon.QTableWidget(rows, columns, parent.native); + } else { + native = new addon.QTableWidget(rows, columns); + } + } else if (rowsOrNativeOrParent != null) { + native = new addon.QTableWidget(rowsOrNativeOrParent.native); } else { - native = new addon.QTableWidget(rows, columns); + native = new addon.QTableWidget(); } super(native); this.items = new Set(); @@ -60,7 +71,6 @@ export class QTableWidget extends QAbstractScrollArea { } setCellWidget(row: number, column: number, widget: QWidget): void { this.native.setCellWidget(row, column, widget.native); - this.items.add(widget); } setItem(row: number, column: number, item: QTableWidgetItem): void { this.native.setItem(row, column, item.native); @@ -229,6 +239,7 @@ export class QTableWidget extends QAbstractScrollArea { return this.native.isSortingEnabled(); } } +wrapperCache.registerWrapper('QTableWidgetWrap', QTableWidget); interface Range { topRow: number; diff --git a/src/lib/QtWidgets/QTextBrowser.ts b/src/lib/QtWidgets/QTextBrowser.ts index 7e4e67a55..a64c10311 100644 --- a/src/lib/QtWidgets/QTextBrowser.ts +++ b/src/lib/QtWidgets/QTextBrowser.ts @@ -1,8 +1,10 @@ import addon from '../utils/addon'; -import { QWidget } from './QWidget'; +import { QWidget, QWidgetSignals } from './QWidget'; import { NativeElement } from '../core/Component'; import { QUrl } from '../QtCore/QUrl'; import { QTextEdit, QTextEditSignals } from './QTextEdit'; +import { wrapperCache } from '../core/WrapperCache'; +import { checkIfNativeElement } from '../utils/helpers'; /** @@ -22,9 +24,12 @@ const textBrowser = new QTextBrowser(); */ export class QTextBrowser extends QTextEdit { - constructor(parent?: QWidget) { + constructor(arg?: QWidget | NativeElement) { let native: NativeElement; - if (parent) { + if (checkIfNativeElement(arg)) { + native = arg as NativeElement; + } else if (arg != null) { + const parent = arg as QWidget; native = new addon.QTextBrowser(parent.native); } else { native = new addon.QTextBrowser(); @@ -84,6 +89,7 @@ export class QTextBrowser extends QTextEdit { this.native.reload(); } } +wrapperCache.registerWrapper('QTextBrowserWrap', QTextBrowser); export interface QTextBrowserSignals extends QTextEditSignals { anchorClicked: (link: QUrl) => void; diff --git a/src/lib/QtWidgets/QTextEdit.ts b/src/lib/QtWidgets/QTextEdit.ts index 9c5ddf12c..2dc51447c 100644 --- a/src/lib/QtWidgets/QTextEdit.ts +++ b/src/lib/QtWidgets/QTextEdit.ts @@ -1,11 +1,12 @@ import addon from '../utils/addon'; -import { QWidget } from './QWidget'; +import { QWidget, QWidgetSignals } from './QWidget'; import { QAbstractScrollArea, QAbstractScrollAreaSignals } from './QAbstractScrollArea'; import { AlignmentFlag, TextInteractionFlag } from '../QtEnums'; import { QFont } from '../QtGui/QFont'; import { QColor } from '../QtGui/QColor'; import { checkIfNativeElement } from '../utils/helpers'; import { NativeElement } from '../core/Component'; +import { wrapperCache } from '../core/WrapperCache'; /** @@ -25,20 +26,18 @@ const textEdit = new QTextEdit(); */ export class QTextEdit extends QAbstractScrollArea { - constructor(arg?: QWidget | NativeElement) { + constructor(arg?: QWidget | NativeElement) { let native: NativeElement; - let parent: QWidget = null; if (checkIfNativeElement(arg)) { native = arg as NativeElement; - } else if (arg) { - parent = arg as QWidget; + } else if (arg != null) { + const parent = arg as QWidget; native = new addon.QTextEdit(parent.native); } else { native = new addon.QTextEdit(); } super(native); } - setAcceptRichText(accept: boolean): void { this.setProperty('acceptRichText', accept); } @@ -232,6 +231,7 @@ export class QTextEdit exte this.native.zoomOut(range); } } +wrapperCache.registerWrapper('QTextEditWrap', QTextEdit); export enum AutoFormattingFlag { AutoNone = 0, diff --git a/src/lib/QtWidgets/QTimeEdit.ts b/src/lib/QtWidgets/QTimeEdit.ts index 7c49aae6a..aa63ac1dd 100644 --- a/src/lib/QtWidgets/QTimeEdit.ts +++ b/src/lib/QtWidgets/QTimeEdit.ts @@ -1,6 +1,9 @@ import addon from '../utils/addon'; -import { QWidget } from './QWidget'; +import { QWidget, QWidgetSignals } from './QWidget'; import { QDateTimeEdit } from './QDateTimeEdit'; +import { wrapperCache } from '../core/WrapperCache'; +import { NativeElement } from '../core/Component'; +import { checkIfNativeElement } from '../utils/helpers'; /** @@ -20,9 +23,12 @@ const timeEdit = new QTimeEdit(); ``` */ export class QTimeEdit extends QDateTimeEdit { - constructor(parent?: QWidget) { - let native; - if (parent) { + constructor(arg?: QWidget | NativeElement) { + let native: NativeElement; + if (checkIfNativeElement(arg)) { + native = arg as NativeElement; + } else if (arg != null) { + const parent = arg as QWidget; native = new addon.QTimeEdit(parent.native); } else { native = new addon.QTimeEdit(); @@ -30,3 +36,4 @@ export class QTimeEdit extends QDateTimeEdit { super(native); } } +wrapperCache.registerWrapper('QTimeEditWrap', QTimeEdit); diff --git a/src/lib/QtWidgets/QToolButton.ts b/src/lib/QtWidgets/QToolButton.ts index cf8c24bd6..0d3f8d22d 100644 --- a/src/lib/QtWidgets/QToolButton.ts +++ b/src/lib/QtWidgets/QToolButton.ts @@ -1,12 +1,13 @@ import addon from '../utils/addon'; -import { QWidget } from './QWidget'; -import { NativeElement, NativeRawPointer } from '../core/Component'; +import { QWidget, QWidgetSignals } from './QWidget'; +import { NativeElement } from '../core/Component'; import { QAbstractButton, QAbstractButtonSignals } from './QAbstractButton'; import { ToolButtonStyle } from '../QtEnums/ToolButtonStyle'; import { ArrowType } from '../QtEnums/ArrowType'; import { QAction } from '../QtWidgets/QAction'; import { QMenu } from './QMenu'; -import { checkIfNativeElement, checkIfNapiExternal } from '../utils/helpers'; +import { checkIfNativeElement } from '../utils/helpers'; +import { wrapperCache } from '../core/WrapperCache'; /** @@ -26,18 +27,13 @@ tool.setText('Help'); ``` */ export class QToolButton extends QAbstractButton { - private _defaultAction?: QAction | null; - private _menu?: QMenu | null; - - constructor(arg?: QWidget | NativeRawPointer | NativeElement, disableNativeDeletion = true) { - let native; + constructor(arg?: QWidget | NativeElement) { + let native: NativeElement; if (checkIfNativeElement(arg)) { native = arg as NativeElement; - } else if (checkIfNapiExternal(arg)) { - native = new addon.QToolButton(arg, disableNativeDeletion); - } else if (arg) { - const parentWidget = arg as QWidget; - native = new addon.QToolButton(parentWidget.native); + } else if (arg != null) { + const parent = arg as QWidget; + native = new addon.QToolButton(parent.native); } else { native = new addon.QToolButton(); } @@ -68,29 +64,22 @@ export class QToolButton extends QAbstractButton { return this.property('toolButtonStyle').toInt(); } setMenu(menu: QMenu): void { - this._menu = menu; this.native.setMenu(menu.native); } menu(): QMenu | null { - if (this._menu) { - return this._menu; - } - return null; + return wrapperCache.getWrapper(this.native.menu()) as QMenu; } setDefaultAction(action: QAction): void { - this._defaultAction = action; this.native.setDefaultAction(action.native); } defaultAction(): QAction | null { - if (this._defaultAction) { - return this._defaultAction; - } - return null; + return wrapperCache.getWrapper(this.native.defaultAction()) as QAction; } showMenu(): void { this.native.showMenu(); } } +wrapperCache.registerWrapper('QToolButtonWrap', QToolButton); export enum ToolButtonPopupMode { DelayedPopup, diff --git a/src/lib/QtWidgets/QTreeWidget.ts b/src/lib/QtWidgets/QTreeWidget.ts index 10fc06032..7747187d8 100644 --- a/src/lib/QtWidgets/QTreeWidget.ts +++ b/src/lib/QtWidgets/QTreeWidget.ts @@ -1,9 +1,10 @@ import addon from '../utils/addon'; -import { QWidget } from './QWidget'; +import { QWidget, QWidgetSignals } from './QWidget'; import { NativeElement } from '../core/Component'; import { QAbstractScrollArea, QAbstractScrollAreaSignals } from './QAbstractScrollArea'; import { QTreeWidgetItem } from './QTreeWidgetItem'; -import { MatchFlag } from '../..'; +import { checkIfNativeElement, MatchFlag } from '../..'; +import { wrapperCache } from '../core/WrapperCache'; /** @@ -52,9 +53,12 @@ export class QTreeWidget extends QAbstractScrollArea { topLevelItems: Set; itemWidgets: Map; - constructor(parent?: QWidget) { - let native; - if (parent) { + constructor(arg?: QWidget | NativeElement) { + let native: NativeElement; + if (checkIfNativeElement(arg)) { + native = arg as NativeElement; + } else if (arg != null) { + const parent = arg as QWidget; native = new addon.QTreeWidget(parent.native); } else { native = new addon.QTreeWidget(); @@ -188,6 +192,7 @@ export class QTreeWidget extends QAbstractScrollArea { this.native.clear(); } } +wrapperCache.registerWrapper('QTreeWidgetWrap', QTreeWidget); export interface QTreeWidgetSignals extends QAbstractScrollAreaSignals { itemSelectionChanged: () => void; diff --git a/src/lib/utils/helpers.ts b/src/lib/utils/helpers.ts index 8c621ad4f..8c5022c8a 100644 --- a/src/lib/utils/helpers.ts +++ b/src/lib/utils/helpers.ts @@ -2,7 +2,7 @@ import { NativeElement } from '../core/Component'; import addon from './addon'; // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types -export function checkIfNativeElement(arg: any): boolean { +export function checkIfNativeElement(arg: any): arg is NativeElement { const nativeArg = arg as NativeElement; return nativeArg != null && typeof nativeArg === 'object' && nativeArg.type === 'native'; } From 5191892950b6487d4d2e993c9b6170e556ec7505 Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Thu, 12 May 2022 20:49:17 +0200 Subject: [PATCH 23/28] Less caching in `QMainWindow` --- .../QtWidgets/QMainWindow/qmainwindow_wrap.h | 1 + .../QMainWindow/qmainwindow_wrap.cpp | 48 ++++++++++--- src/lib/QtWidgets/QMainWindow.ts | 69 ++++++++++--------- 3 files changed, 75 insertions(+), 43 deletions(-) diff --git a/src/cpp/include/nodegui/QtWidgets/QMainWindow/qmainwindow_wrap.h b/src/cpp/include/nodegui/QtWidgets/QMainWindow/qmainwindow_wrap.h index 2fbdb6eee..8cf3560c1 100644 --- a/src/cpp/include/nodegui/QtWidgets/QMainWindow/qmainwindow_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QMainWindow/qmainwindow_wrap.h @@ -22,6 +22,7 @@ class DLL_EXPORT QMainWindowWrap : public Napi::ObjectWrap { // class constructor static Napi::FunctionReference constructor; // wrapped methods + Napi::Value centralWidget(const Napi::CallbackInfo& info); Napi::Value setCentralWidget(const Napi::CallbackInfo& info); Napi::Value takeCentralWidget(const Napi::CallbackInfo& info); Napi::Value setMenuBar(const Napi::CallbackInfo& info); diff --git a/src/cpp/lib/QtWidgets/QMainWindow/qmainwindow_wrap.cpp b/src/cpp/lib/QtWidgets/QMainWindow/qmainwindow_wrap.cpp index a5639273a..a97159ea8 100644 --- a/src/cpp/lib/QtWidgets/QMainWindow/qmainwindow_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QMainWindow/qmainwindow_wrap.cpp @@ -16,15 +16,15 @@ Napi::Object QMainWindowWrap::init(Napi::Env env, Napi::Object exports) { Napi::Function func = DefineClass( env, CLASSNAME, {InstanceMethod("setCentralWidget", &QMainWindowWrap::setCentralWidget), + InstanceMethod("centralWidget", &QMainWindowWrap::centralWidget), InstanceMethod("takeCentralWidget", &QMainWindowWrap::takeCentralWidget), InstanceMethod("setMenuBar", &QMainWindowWrap::setMenuBar), + InstanceMethod("menuBar", &QMainWindowWrap::menuBar), InstanceMethod("setMenuWidget", &QMainWindowWrap::setMenuWidget), InstanceMethod("center", &QMainWindowWrap::center), InstanceMethod("setStatusBar", &QMainWindowWrap::setStatusBar), InstanceMethod("statusBar", &QMainWindowWrap::statusBar), - QWIDGET_WRAPPED_METHODS_EXPORT_DEFINE(QMainWindowWrap) - - }); + QWIDGET_WRAPPED_METHODS_EXPORT_DEFINE(QMainWindowWrap)}); constructor = Napi::Persistent(func); exports.Set(CLASSNAME, func); QOBJECT_REGISTER_WRAPPER(QMainWindow, QMainWindowWrap); @@ -67,15 +67,32 @@ Napi::Value QMainWindowWrap::setCentralWidget(const Napi::CallbackInfo& info) { Napi::Object widgetObject = info[0].As(); NodeWidgetWrap* centralWidget = Napi::ObjectWrap::Unwrap(widgetObject); - this->instance->setCentralWidget(centralWidget->getInternalInstance()); + if (centralWidget != nullptr) { + this->instance->setCentralWidget(centralWidget->getInternalInstance()); + } else { + this->instance->setCentralWidget(nullptr); + } return env.Null(); } +Napi::Value QMainWindowWrap::centralWidget(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + QWidget* widget = this->instance->centralWidget(); + if (widget) { + return WrapperCache::instance.getWrapper(env, widget); + } else { + return env.Null(); + } +} + Napi::Value QMainWindowWrap::takeCentralWidget(const Napi::CallbackInfo& info) { Napi::Env env = info.Env(); - this->instance->takeCentralWidget(); - // We will not return the value here since we are doing it in js side anyway - return env.Null(); + QWidget* widget = this->instance->takeCentralWidget(); + if (widget) { + return WrapperCache::instance.getWrapper(env, widget); + } else { + return env.Null(); + } } Napi::Value QMainWindowWrap::setMenuBar(const Napi::CallbackInfo& info) { @@ -129,6 +146,19 @@ Napi::Value QMainWindowWrap::setStatusBar(const Napi::CallbackInfo& info) { Napi::Value QMainWindowWrap::statusBar(const Napi::CallbackInfo& info) { Napi::Env env = info.Env(); QStatusBar* statusBar = this->instance->statusBar(); - - return QStatusBarWrap::fromQStatusBar(env, statusBar); + if (statusBar) { + return WrapperCache::instance.getWrapper(env, statusBar); + } else { + return env.Null(); + } +} + +Napi::Value QMainWindowWrap::menuBar(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + QMenuBar* menuBar = this->instance->menuBar(); + if (menuBar) { + return WrapperCache::instance.getWrapper(env, menuBar); + } else { + return env.Null(); + } } diff --git a/src/lib/QtWidgets/QMainWindow.ts b/src/lib/QtWidgets/QMainWindow.ts index 8cd3abce1..54a6b2ef5 100644 --- a/src/lib/QtWidgets/QMainWindow.ts +++ b/src/lib/QtWidgets/QMainWindow.ts @@ -4,6 +4,8 @@ import { QLayout } from './QLayout'; import { QMenuBar } from './QMenuBar'; import { QStatusBar } from './QStatusBar'; import { NativeElement } from '../core/Component'; +import { wrapperCache } from '../core/WrapperCache'; +import { checkIfNativeElement } from '../utils/helpers'; /** @@ -32,55 +34,58 @@ QMainWindow needs to have a central widget set before other widgets can be added Once a central widget is set you can add children/layout to the central widget. */ export class QMainWindow extends QWidget { - public centralWidget?: QWidget | null; - private _menuBar?: QMenuBar; - private _statusBar?: QStatusBar | null; - // TODO - constructor(parent?: QWidget) { + constructor(arg?: QWidget | NativeElement) { let native: NativeElement; - if (parent) { + if (checkIfNativeElement(arg)) { + native = arg as NativeElement; + } else if (arg != null) { + const parent = arg as QWidget; native = new addon.QMainWindow(parent.native); } else { native = new addon.QMainWindow(); } super(native); - - this.setLayout = (parentLayout: QLayout): void => { - if (this.centralWidget) { - this.centralWidget.setLayout(parentLayout); - } else { - this.native.setLayout(parentLayout.native); - } - }; + } + setLayout(parentLayout: QLayout): void { + const centralWidget = this.centralWidget(); + if (centralWidget) { + centralWidget.setLayout(parentLayout); + } else { + super.setLayout(parentLayout); + } } setCentralWidget(widget: QWidget): void { this.native.setCentralWidget(widget.native); - this.centralWidget = widget; - this.centralWidget.setFlexNodeSizeControlled(true); + const centralWidget = this.centralWidget(); + if (centralWidget) { + centralWidget.setFlexNodeSizeControlled(true); + } + } + centralWidget(): QWidget { + return wrapperCache.getWrapper(this.native.centralWidget()) as QWidget; } takeCentralWidget(): QWidget | null { - const centralWidget = this.centralWidget; + const centralWidget = this.centralWidget(); this.centralWidget = null; if (centralWidget) { centralWidget.setFlexNodeSizeControlled(false); - this.native.takeCentralWidget(); - return centralWidget; + return wrapperCache.getWrapper(this.native.takeCentralWidget()) as QWidget; } return null; } setMenuBar(menuBar: QMenuBar): void { this.native.setMenuBar(menuBar.native); - this._menuBar = menuBar; } menuBar(): QMenuBar | undefined { - return this._menuBar; + return wrapperCache.getWrapper(this.native.menuBar()) as QMenuBar; } setMenuWidget(menuWidget: QWidget): void { this.native.setMenuWidget(menuWidget.native); } layout(): QLayout | undefined { - if (this.centralWidget) { - return this.centralWidget.layout(); + const centralWidget = this.centralWidget(); + if (centralWidget) { + return centralWidget.layout(); } return super.layout(); } @@ -94,24 +99,20 @@ export class QMainWindow extends QWidget { * @param statusBar The status bar. */ setStatusBar(statusBar: QStatusBar): void { - this.native.setStatusBar(statusBar.native); - this._statusBar = statusBar; - } - - /** - * Removes the status bar from the main window. - */ - removeStatusBar(): void { - this.native.setStatusBar(null); - this._statusBar = null; + if (statusBar != null) { + this.native.setStatusBar(statusBar.native); + } else { + this.native.setStatusBar(null); + } } /** * Returns the status bar for the main window. */ statusBar(): QStatusBar { - return new QStatusBar(this.native.statusBar()); + return wrapperCache.getWrapper(this.native.statusBar()) as QStatusBar; } } +wrapperCache.registerWrapper('QMainWindowWrap', QMainWindow); export type QMainWindowSignals = QWidgetSignals; From c28fd5d5c3a41466e7e061d801c2bf75452d7458 Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Thu, 19 May 2022 19:48:23 +0200 Subject: [PATCH 24/28] Add `QLabel.buddy()` --- .../include/nodegui/QtWidgets/QLabel/qlabel_wrap.h | 1 + src/cpp/lib/QtWidgets/QLabel/qlabel_wrap.cpp | 11 +++++++++++ src/lib/QtWidgets/QLabel.ts | 8 ++------ 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/cpp/include/nodegui/QtWidgets/QLabel/qlabel_wrap.h b/src/cpp/include/nodegui/QtWidgets/QLabel/qlabel_wrap.h index c7e6529c5..85e6b3487 100644 --- a/src/cpp/include/nodegui/QtWidgets/QLabel/qlabel_wrap.h +++ b/src/cpp/include/nodegui/QtWidgets/QLabel/qlabel_wrap.h @@ -25,6 +25,7 @@ class DLL_EXPORT QLabelWrap : public Napi::ObjectWrap { Napi::Value setSelection(const Napi::CallbackInfo& info); Napi::Value selectionStart(const Napi::CallbackInfo& info); Napi::Value setBuddy(const Napi::CallbackInfo& info); + Napi::Value buddy(const Napi::CallbackInfo& info); Napi::Value clear(const Napi::CallbackInfo& info); Napi::Value setMovie(const Napi::CallbackInfo& info); Napi::Value setNumDouble(const Napi::CallbackInfo& info); diff --git a/src/cpp/lib/QtWidgets/QLabel/qlabel_wrap.cpp b/src/cpp/lib/QtWidgets/QLabel/qlabel_wrap.cpp index 65b4298b3..abe0ed4ff 100644 --- a/src/cpp/lib/QtWidgets/QLabel/qlabel_wrap.cpp +++ b/src/cpp/lib/QtWidgets/QLabel/qlabel_wrap.cpp @@ -18,6 +18,7 @@ Napi::Object QLabelWrap::init(Napi::Env env, Napi::Object exports) { {InstanceMethod("setSelection", &QLabelWrap::setSelection), InstanceMethod("selectionStart", &QLabelWrap::selectionStart), InstanceMethod("setBuddy", &QLabelWrap::setBuddy), + InstanceMethod("buddy", &QLabelWrap::buddy), InstanceMethod("clear", &QLabelWrap::clear), InstanceMethod("setMovie", &QLabelWrap::setMovie), InstanceMethod("setNumDouble", &QLabelWrap::setNumDouble), @@ -91,6 +92,16 @@ Napi::Value QLabelWrap::setBuddy(const Napi::CallbackInfo& info) { return env.Null(); } +Napi::Value QLabelWrap::buddy(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + QObject* parent = this->instance->buddy(); + if (parent) { + return WrapperCache::instance.getWrapper(env, parent); + } else { + return env.Null(); + } +} + Napi::Value QLabelWrap::clear(const Napi::CallbackInfo& info) { Napi::Env env = info.Env(); this->instance->clear(); diff --git a/src/lib/QtWidgets/QLabel.ts b/src/lib/QtWidgets/QLabel.ts index ebeb608f5..354139a7d 100644 --- a/src/lib/QtWidgets/QLabel.ts +++ b/src/lib/QtWidgets/QLabel.ts @@ -33,7 +33,7 @@ export class QLabel extends QFrame { private _picture?: QPicture; private _pixmap?: QPixmap; private _movie?: QMovie; - private _buddy?: QWidget | null; + // TODO constructor(arg?: QWidget | NativeElement) { let native: NativeElement; @@ -115,13 +115,9 @@ export class QLabel extends QFrame { } setBuddy(buddy: QWidget): void { this.native.setBuddy(buddy.native); - this._buddy = buddy; } buddy(): QWidget | null { - if (this._buddy) { - return this._buddy; - } - return null; + return wrapperCache.getWrapper(this.native.budd()) as QWidget; } setMovie(movie: QMovie): void { this.native.setMovie(movie.native); From 0f9ad1e028ac16082aa498009871574a265d752b Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Fri, 20 May 2022 15:25:18 +0200 Subject: [PATCH 25/28] Add logging/debugging controls for the wrapper lifecycle --- src/index.ts | 3 ++ src/lib/core/WrapperCache.ts | 58 ++++++++++++++++++++++++++++++++---- 2 files changed, 55 insertions(+), 6 deletions(-) diff --git a/src/index.ts b/src/index.ts index 01ab996d1..0928e68c9 100644 --- a/src/index.ts +++ b/src/index.ts @@ -189,3 +189,6 @@ export { Margins } from './lib/utils/Margins'; // Test: export { CacheTestQObject } from './lib/core/__test__/CacheTestQObject'; + +// Debug: +export { setLogCreateQObject, setLogDestroyQObject } from './lib/core/WrapperCache'; diff --git a/src/lib/core/WrapperCache.ts b/src/lib/core/WrapperCache.ts index 61e036cfa..abfb82218 100644 --- a/src/lib/core/WrapperCache.ts +++ b/src/lib/core/WrapperCache.ts @@ -14,14 +14,29 @@ import { NativeElement } from './Component'; * wrapper automatically and unexpectedly garbage collected. */ export class WrapperCache { + // Cache for wrapper where we always hold onto the wrapper until the C++ + // object is destroyed by Qt. We don't let the V8 GC destroy the wrapper + // first. These wrapper often have signal handlers which are kept alive + // by the wrapper themselves, and not because they are part of a + // `NFooBar` subclass. For example, the `QScreen` attaches signal + // handlers to the C++ `QScreen`. If the wrapper is GC'ed, then the + // signals handlers also stop working. private _strongCache = new Map(); + + // WeakCache is for normal wrappers around `QObject` based `NFooBar` + // subclasses. private _weakCache = new Map>(); + private _wrapperRegistry = new Map(); constructor() { addon.WrapperCache_injectCallback(this._objectDestroyedCallback.bind(this)); } + logCreateQObject = false; + logDestoryQObject = false; + + // This is only need for testing purposes _flush(): void { this._strongCache = new Map(); this._weakCache = new Map>(); @@ -32,6 +47,11 @@ export class WrapperCache { const wrapper = this._strongCache.get(objectId); wrapper.native = null; this._strongCache.delete(objectId); + + if (this.logDestoryQObject) { + console.log(`NodeGui: Destroyed C++ object with ID: ${objectId}.`); + } + return; } const wrapperRef = this._weakCache.get(objectId); @@ -40,17 +60,20 @@ export class WrapperCache { if (wrapper != null) { wrapper.native = null; this._weakCache.delete(objectId); + if (this.logDestoryQObject) { + console.log(`NodeGui: Destroyed C++ object with ID: ${objectId}.`); + } } } } get(wrapperConstructor: { new (native: any): T }, native: NativeElement): T { - const id = native.__id__(); - if (this._strongCache.has(id)) { - return this._strongCache.get(id) as T; + const objectId = native.__id__(); + if (this._strongCache.has(objectId)) { + return this._strongCache.get(objectId) as T; } const wrapper = new wrapperConstructor(native); - this._strongCache.set(id, wrapper); + this._strongCache.set(objectId, wrapper); return wrapper; } @@ -90,11 +113,34 @@ export class WrapperCache { store(wrapper: QObject): void { if (wrapper.native != null) { - const id = wrapper.native.__id__(); - this._weakCache.set(id, new WeakRef(wrapper)); + const objectId = wrapper.native.__id__(); + this._weakCache.set(objectId, new WeakRef(wrapper)); addon.WrapperCache_store(wrapper.native, wrapper.native.__external_qobject__()); + if (this.logCreateQObject) { + console.log(`NodeGui: Created C++ object with ID: ${objectId}.`); + } } } } export const wrapperCache = new WrapperCache(); + +/** + * Turn on/off logging when QObjects are created. + * + * @param on When true, logging is written to console when QObjects are + * created by NodeGui. + */ +export function setLogCreateQObject(on: boolean): void { + wrapperCache.logCreateQObject = on; +} + +/** + * Turn on/off logging when QObjects are destoryed. + * + * @param on When true, logging is written to console when QObjects are + * destroyed. + */ +export function setLogDestroyQObject(on: boolean): void { + wrapperCache.logDestoryQObject = on; +} From f606ebdd725df35952d5029adecae8834493d3f6 Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Fri, 20 May 2022 16:31:56 +0200 Subject: [PATCH 26/28] Add `_id()` to `QObject` for debugging purposes --- src/lib/QtCore/QObject.ts | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/lib/QtCore/QObject.ts b/src/lib/QtCore/QObject.ts index d849e3a12..766007298 100644 --- a/src/lib/QtCore/QObject.ts +++ b/src/lib/QtCore/QObject.ts @@ -7,6 +7,8 @@ import { TimerType } from '../QtEnums/TimerType'; import { wrapperCache } from '../core/WrapperCache'; export class QObject extends EventWidget { + private __id: number; + constructor(nativeElementOrParent?: NativeElement | QObject) { let native: NativeElement; if (checkIfNativeElement(nativeElementOrParent)) { @@ -18,10 +20,22 @@ export class QObject extends Ev native = new addon.QObject(); } super(native); - + this.__id = native.__id__(); wrapperCache.store(this); } + /** + * Get an ID identifying the underlying C++ object. + * + * This can be useful when debugging memory problems with help from + * `setLogCreateQObject()` and `setLogDestroyQObject()`. The number is + * hash of the memory address of the C++ object. + * + * @return a unique number which is valid for the lifetime of the C++ object. + */ + _id(): number { + return this.__id; + } inherits(className: string): boolean { return this.native.inherits(className); } From b36caeddd27891672cc28869d681e7e6780e9f84 Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Sat, 21 May 2022 12:47:46 +0200 Subject: [PATCH 27/28] Add documentation about dealing with memory --- website/docs/development/getting-started.md | 2 +- .../development/signal_and_event_handling.md | 6 +- website/docs/guides/understanding-memory.md | 81 +++++++++++++++++++ 3 files changed, 85 insertions(+), 4 deletions(-) create mode 100644 website/docs/guides/understanding-memory.md diff --git a/website/docs/development/getting-started.md b/website/docs/development/getting-started.md index fbe60e723..a7de3d28d 100644 --- a/website/docs/development/getting-started.md +++ b/website/docs/development/getting-started.md @@ -85,7 +85,7 @@ The idea is : 2. Then we will use NLabel and wrap it using NAPI and export it to JS side. This is what qlabel_wrap does. **NLabel**: Since NLabel has inherited from QLabel we can treat is as QLabel with extra methods and properties. Primary reason to extend QLabel to create NLabel is to add support for Event listeners and CSS styling using Flex. -So if you take a look at NLabel you will see, it inherits from QLabel and NodeWidget. NodeWidget inturn inherits from YogaWidget and EventWidget. Event widget adds event handling support. YogaWidget is a class that contains the magic that enables a regular Qt Widget to have Yoga node. A Yoga node is an instance used by yoga library to calculate a widgets position on the screen. Yoga is a library that will layout the widget on the screen. To do so we will specify the flex properties like alignitems, justify content, margin, paddings etc on the Yoga node of the widget. Apart from adding yoga node, YogaWidget adds support for specifying those yoga properties via Qt's stylesheet. (This is done by using Q_PROPERTY). To make this work we need to use something called as Q_OBJECT inside the class which is a C++ macro. Q_OBJECT will be expanded to relevant code by the compiler. In Qt whenever we add Q_OBJECT to a header file, we need to use a pre compiler called Qt MOC (Meta Object Compiler). The way we use it is +So if you take a look at NLabel you will see, it inherits from QLabel and QWidget. QWidget in turn inherits from YogaWidget and EventWidget. Event widget adds event handling support. YogaWidget is a class that contains the magic that enables a regular Qt Widget to have Yoga node. A Yoga node is an instance used by yoga library to calculate a widgets position on the screen. Yoga is a library that will layout the widget on the screen. To do so we will specify the flex properties like alignitems, justify content, margin, paddings etc on the Yoga node of the widget. Apart from adding yoga node, YogaWidget adds support for specifying those yoga properties via Qt's stylesheet. (This is done by using Q_PROPERTY). To make this work we need to use something called as Q_OBJECT inside the class which is a C++ macro. Q_OBJECT will be expanded to relevant code by the compiler. In Qt whenever we add Q_OBJECT to a header file, we need to use a pre compiler called Qt MOC (Meta Object Compiler). The way we use it is ``` moc headername.h -o headername_moc.cpp --include // example : ../../core/YogaWidget/yogawidget.h diff --git a/website/docs/development/signal_and_event_handling.md b/website/docs/development/signal_and_event_handling.md index 2cca815a9..363b00b16 100644 --- a/website/docs/development/signal_and_event_handling.md +++ b/website/docs/development/signal_and_event_handling.md @@ -52,7 +52,7 @@ Example: ```js import addon from '../../core/addon'; -import { NodeWidget } from '../../QtGui/QWidget'; +import { QWidget } from '../../QtGui/QWidget'; import { BaseWidgetEvents } from '../../core/EventWidget'; export const QPushButtonEvents = Object.freeze({ @@ -63,8 +63,8 @@ export const QPushButtonEvents = Object.freeze({ toggled: 'toggled', }); -export class QPushButton extends NodeWidget { - constructor(parent?: NodeWidget) { +export class QPushButton extends QWidget { + constructor(parent?: QWidget) { let native: NativeElement; if (parent) { native = new addon.QPushButton(parent.native); diff --git a/website/docs/guides/understanding-memory.md b/website/docs/guides/understanding-memory.md new file mode 100644 index 000000000..a78344410 --- /dev/null +++ b/website/docs/guides/understanding-memory.md @@ -0,0 +1,81 @@ +--- +sidebar_label: Understanding Memory +title: Understanding Memory +--- + +NodeGui allows you to use a library designed for C++ (Qt) from the JavaScript language. C++ and JavaScript have very different approaches for managing the memory of objects. C++ expects the programmer to manually create objects and later destroy them to free up their memory. It is the job of the programmer to destroy objects at the right time and when it is safe. JavaScript uses a Garbage Collector which detects when an object is longer being used and then automatically destroys it, freeing up its memory. Most of the time NodeGui can coordinate these two systems in a way which is mostly transparent to the JavaScript developer. However, there are situations where it is necessary to have some understanding of what is happening being in the scenes. + +## Qt's QObject Memory Management + +Much of Qt is based around the `QObject` class. It is the base class of many Qt classes including most of the widgets exposed by NodeGui. `QObject` provides many useful features on top of C++ for working with objects. It has support for easier memory management. This system is built around the idea of object ownership and trees of objects which can be freed as a group. Each `QObject` can participate in a tree of objects. Each `QObject` has a list of child objects, and may also have a parent `QObject`. When a `QObject` is destroyed, all of its attached child objects are destroyed with it. + +Trees of objects is a good model for user interfaces which are also structured in hierarchies. Qt's widgets are built on top of `QObject` and its object trees. The same object tree is used by widgets for memory management and UI layout / structuring. + +`QObject` contains a number of methods for examining this tree of objects: + +* `parent()` - Get the parent of an object, or `null`. +* `setParent()` - Set the parent of an object. +* `children()` - Get a list of the child objects belonging to this object. + + +## JavaScript Wrappers + +Node runs on the V8 JavaScript engine. It can't directly work with C++ object like those from Qt. To bridge the gap between V8 and Qt, NodeGui creates "wrapper" C++ and JavaScript objects which can translate between the two worlds. A JavaScript object "wrapper" will wrap a corresponding Qt object in C++. As a JavaScript developer you don't have to pay much attention to this. It happens automatically in the background. + +## QObject End of Life + +There are two ways in which a `QObject` can be destroyed, starting from either the C++ side or JavaScript side. + +The JavaScript side is the most common. If the Garbage Collector discovers that a wrapper is no longer being referenced, then it will destroy the wrapper. When the C++ side of the wrapper is destroyed, it will also destroy its corresponding Qt object *if that object is not part of an object tree*. In other words, if the `QObject` has a parent object set, then it will not be destroyed and NodeGui assumes that the responsibility for destroying and cleaning up that object belongs to the parent object and the Qt `QObject` memory system. + +When a `QObject` is destroyed from the C++ side, then NodeGui detects this and sets the reference to the object itside the JavaScript wrapper object, to `null`. If any attempt is made to use the JS wrapper object, then it will hit the `null` and throw an exception. + +## Problems with Unexpected Object Destruction + +A NodeGui object suddenly throws an exception regarding a `null` if you try to use a method on it. This situation can happen if underlying C++ Qt object is destroyed and afterwards you still try to use it via its wrapper. + +The most common way this can happen is if a `QObject` is part of an object tree and one of its parent objects is destroyed which then also destroys the rest of the tree. If you don't want an object to be destroyed with its parent object, then you need to remove it from the tree before the parent is destroyed. Calling `setParent(null)` on the object is enough to disconnect it from its parent. + +## Debugging + +NodeGui provides some tools to help track the lifecycle of objects and figure out why your application isn't running the way you expect. + +Each `QObject` instance, and subclass also, has an ID to identify it. The method `QObject._id()` can be used to fetch the ID for an object. The ID is valid for the lifetime of the object, although it could be reused once this object is destroyed. + +NodeGui manages the lifecycle of objects and it is possible to turn on logging regarding the creation and destruction of objects. The following functions take a boolean to turn this logging on or off: + +* `setLogDestroyQObject()` - Turn logging of object destruction on/off. +* `setLogCreateQObject()` - Turn logging of object creation on/off. + +These log messages contain the ID of the object as returned from `QObject._id()`. + +A typical usage of this logging would be to narrow down the exact place where an object is being unexpectedly destroyed: + +```js +const { setLogDestroyQObject, setLogCreateQObject } = require('@nodegui/nodegui'); + +setLogCreateQObject(true); +setLogDestroyQObject(true); + +const myWidget = new QWidget(); +console.log(`myWidget has ID: ${myWidget._id()}.`); + +// ... +// ... Code which somehow triggers the destruction of myWidget. +// ... +console.log(`Reached crash point.`); +const size = myWidget.size(); +// ^ line which triggers an exception because the object is destroyed. +``` + +The logging output from the application might be: + +``` +NodeGui: Created C++ object with ID: 17533348349032. +myWidget has ID: 17533348349032. +NodeGui: Destroyed C++ object with ID: 17533348349032. +Reached crash point. +Uncaught TypeError: Cannot read property 'size' of null +``` + +More logging could be added to narrow down which section of code triggers the destruction of the object. From 11bf45466d792495ad7abed73c203eccb4000bfa Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Sat, 21 May 2022 19:54:12 +0200 Subject: [PATCH 28/28] Export `wrapperCache` in `index.ts` too --- src/index.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/index.ts b/src/index.ts index 0928e68c9..15ba532f1 100644 --- a/src/index.ts +++ b/src/index.ts @@ -190,5 +190,4 @@ export { Margins } from './lib/utils/Margins'; // Test: export { CacheTestQObject } from './lib/core/__test__/CacheTestQObject'; -// Debug: -export { setLogCreateQObject, setLogDestroyQObject } from './lib/core/WrapperCache'; +export { wrapperCache, setLogCreateQObject, setLogDestroyQObject } from './lib/core/WrapperCache';