From b7f1a11accd9e538b4e62cf893d83109475a85e2 Mon Sep 17 00:00:00 2001 From: dank074 Date: Sun, 31 Oct 2021 15:42:46 -0500 Subject: [PATCH 1/7] added floorplan editor --- public/ui-config.json | 1 + .../handlers/RoomWidgetChatInputHandler.ts | 5 +- .../floorplaneditor/door-direction-0.png | Bin 0 -> 742 bytes .../floorplaneditor/door-direction-1.png | Bin 0 -> 738 bytes .../floorplaneditor/door-direction-2.png | Bin 0 -> 750 bytes .../floorplaneditor/door-direction-3.png | Bin 0 -> 697 bytes .../floorplaneditor/door-direction-4.png | Bin 0 -> 756 bytes .../floorplaneditor/door-direction-5.png | Bin 0 -> 754 bytes .../floorplaneditor/door-direction-6.png | Bin 0 -> 747 bytes .../floorplaneditor/door-direction-7.png | Bin 0 -> 698 bytes .../images/floorplaneditor/icon-door.png | Bin 0 -> 806 bytes .../images/floorplaneditor/icon-tile-down.png | Bin 0 -> 609 bytes .../images/floorplaneditor/icon-tile-set.png | Bin 0 -> 525 bytes .../floorplaneditor/icon-tile-unset.png | Bin 0 -> 544 bytes .../images/floorplaneditor/icon-tile-up.png | Bin 0 -> 555 bytes .../images/floorplaneditor/preview_tile.png | Bin 0 -> 146 bytes .../floorplaneditor/selected_height_icon.png | Bin 0 -> 175 bytes src/events/chat-history/ChatHistoryEvent.ts | 1 - .../floorplan-editor/FloorplanEditorEvent.ts | 8 + src/views/Styles.scss | 1 + src/views/chat-history/ChatHistoryView.tsx | 7 +- .../floorplan-editor/FloorplanEditorView.scss | 37 ++ .../floorplan-editor/FloorplanEditorView.tsx | 119 +++++ .../floorplan-editor/common/ActionSettings.ts | 39 ++ .../floorplan-editor/common/Constants.ts | 13 + .../common/FloorplanEditor.ts | 412 ++++++++++++++++++ src/views/floorplan-editor/common/Tile.ts | 31 ++ src/views/floorplan-editor/common/Utils.ts | 53 +++ .../context/FloorplanEditorContext.tsx | 14 + .../context/FloorplanEditorContext.types.ts | 32 ++ .../views/FloorplanCanvasView.tsx | 72 +++ .../views/FloorplanOptionsView.tsx | 20 + src/views/main/MainView.tsx | 2 + .../views/room-info/NavigatorRoomInfoView.tsx | 6 +- 34 files changed, 864 insertions(+), 9 deletions(-) create mode 100644 src/assets/images/floorplaneditor/door-direction-0.png create mode 100644 src/assets/images/floorplaneditor/door-direction-1.png create mode 100644 src/assets/images/floorplaneditor/door-direction-2.png create mode 100644 src/assets/images/floorplaneditor/door-direction-3.png create mode 100644 src/assets/images/floorplaneditor/door-direction-4.png create mode 100644 src/assets/images/floorplaneditor/door-direction-5.png create mode 100644 src/assets/images/floorplaneditor/door-direction-6.png create mode 100644 src/assets/images/floorplaneditor/door-direction-7.png create mode 100644 src/assets/images/floorplaneditor/icon-door.png create mode 100644 src/assets/images/floorplaneditor/icon-tile-down.png create mode 100644 src/assets/images/floorplaneditor/icon-tile-set.png create mode 100644 src/assets/images/floorplaneditor/icon-tile-unset.png create mode 100644 src/assets/images/floorplaneditor/icon-tile-up.png create mode 100644 src/assets/images/floorplaneditor/preview_tile.png create mode 100644 src/assets/images/floorplaneditor/selected_height_icon.png create mode 100644 src/events/floorplan-editor/FloorplanEditorEvent.ts create mode 100644 src/views/floorplan-editor/FloorplanEditorView.scss create mode 100644 src/views/floorplan-editor/FloorplanEditorView.tsx create mode 100644 src/views/floorplan-editor/common/ActionSettings.ts create mode 100644 src/views/floorplan-editor/common/Constants.ts create mode 100644 src/views/floorplan-editor/common/FloorplanEditor.ts create mode 100644 src/views/floorplan-editor/common/Tile.ts create mode 100644 src/views/floorplan-editor/common/Utils.ts create mode 100644 src/views/floorplan-editor/context/FloorplanEditorContext.tsx create mode 100644 src/views/floorplan-editor/context/FloorplanEditorContext.types.ts create mode 100644 src/views/floorplan-editor/views/FloorplanCanvasView.tsx create mode 100644 src/views/floorplan-editor/views/FloorplanOptionsView.tsx diff --git a/public/ui-config.json b/public/ui-config.json index 58dfdcc7..6b223dca 100644 --- a/public/ui-config.json +++ b/public/ui-config.json @@ -4,6 +4,7 @@ "camera.url": "https://nitro.nitrots.co/camera", "thumbnails.url": "https://nitro.nitrots.co/camera/thumbnail/%thumbnail%.png", "url.prefix": "http://localhost:3000", + "floorplan.tile.url": "${url.prefix}/floorplan-editor/tiles.json", "chat.viewer.height.percentage": 0.40, "widget.dimmer.colorwheel": false, "hotelview": { diff --git a/src/api/nitro/room/widgets/handlers/RoomWidgetChatInputHandler.ts b/src/api/nitro/room/widgets/handlers/RoomWidgetChatInputHandler.ts index 81f5411d..9e6f234b 100644 --- a/src/api/nitro/room/widgets/handlers/RoomWidgetChatInputHandler.ts +++ b/src/api/nitro/room/widgets/handlers/RoomWidgetChatInputHandler.ts @@ -1,6 +1,8 @@ import { AvatarExpressionEnum, HabboClubLevelEnum, NitroEvent, RoomControllerLevel, RoomSessionChatEvent, RoomSettingsComposer, RoomWidgetEnum, RoomZoomEvent, TextureUtils } from '@nitrots/nitro-renderer'; import { GetConfiguration, GetNitroInstance } from '../../..'; import { GetRoomEngine, GetSessionDataManager } from '../../../..'; +import { FloorplanEditorEvent } from '../../../../../events/floorplan-editor/FloorplanEditorEvent'; +import { dispatchUiEvent } from '../../../../../hooks'; import { SendMessageHook } from '../../../../../hooks/messages'; import { RoomWidgetFloodControlEvent, RoomWidgetUpdateEvent } from '../events'; import { RoomWidgetChatMessage, RoomWidgetChatSelectAvatarMessage, RoomWidgetChatTypingMessage, RoomWidgetMessage, RoomWidgetRequestWidgetMessage } from '../messages'; @@ -143,7 +145,8 @@ export class RoomWidgetChatInputHandler extends RoomWidgetHandler case ':bcfloor': if(this.container.roomSession.controllerLevel >= RoomControllerLevel.ROOM_OWNER) { - this.container.processWidgetMessage(new RoomWidgetRequestWidgetMessage(RoomWidgetRequestWidgetMessage.FLOOR_EDITOR)); + //this.container.processWidgetMessage(new RoomWidgetRequestWidgetMessage(RoomWidgetRequestWidgetMessage.FLOOR_EDITOR)); + dispatchUiEvent(new FloorplanEditorEvent(FloorplanEditorEvent.SHOW_FLOORPLAN_EDITOR)); } return null; diff --git a/src/assets/images/floorplaneditor/door-direction-0.png b/src/assets/images/floorplaneditor/door-direction-0.png new file mode 100644 index 0000000000000000000000000000000000000000..8c272a0a97a0d985431a751038632ad75d1602fe GIT binary patch literal 742 zcmVPx#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0((hBK~!i%?T|Ze z+fWciwSjENdvKR7fVYs|Wr{2yND~)s)3|k!b!7p{jH0oh=N^7VihL9=Z~zG;XYQQC zigQft>6t7pv!@{<>(}3}C+L~6=Nyp};xhEEakCK_B#oeNjhl%aPm&(~+f}L$!ddU&@Q9e$T4&@$r%F8q}@g}k@9pT$+!gCL0yd1M#|Dr zbo`XiPU>c?CQ^=$pkwERI#5?*u}B#zO~-XXbB540i@FhctwiU6b60%2W(=X+6_6|A{SSRa!UAxU&<7D=5i6_+C~lSHQ`k<@W&aXIoaNp#jMk~+;T zE=PuuL}yJRsl&C!<;ZZ7=qxFcb}lV0N0yO9=b9pE$J)f@$a0eC%qfy)u3cP?lp%@E zlp<+HZQ^pI97%L85lP?FE-pvPl0;{SNP1^$;&P-sNp#vo5?dFSBgc?Lr%U9miOZ4W zNTQQP-nzIPIhG_kySVnq@g(ub^UE%-BO;?oAiZnsIY;D#Kze5EX$Z+G+0!!>h&vqq Y0T^NF8ouP(KmY&$07*qoM6N<$f}nd)!~g&Q literal 0 HcmV?d00001 diff --git a/src/assets/images/floorplaneditor/door-direction-1.png b/src/assets/images/floorplaneditor/door-direction-1.png new file mode 100644 index 0000000000000000000000000000000000000000..52e488f68b7ca09a5af96a5550bc83ae327df9df GIT binary patch literal 738 zcmV<80v-K{P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0(VJ7K~!i%?T|52 z<3JEaeSy6Yci3z*s<;9<;RbtvEfNSwNk|FyTpWPyHZ-*RKS>5#(#Y1YdR2C5rswzD zG@RGMnmtp+Rn~MwWZk`7Z=r9-n)isD5LcnI#@R+>kTins8fOz(o+MrUyV!xw&@AI* zBg>MMDy~9zXtr@Ok>yAN$?Ah<&|Ai0Bg@dzBft=4Hs0 z@%e`?)xoV2eMwdq`|O#|1lgJK_T&EX`Ss_o%Pn+?hPOoYBvC}(&FPw#2|qW#|FFPd zi6WyP$;#wi0-BS_;(}g*OB5NsNSc$o2XsF};yML7B+*%d$mlb+I43(ZcK&Q3iB8KR zqsN5ef{(~YlIXN3lDY&#=MEKDBZo<%(~`)c4)p!l;%ekFNpxBfNpI#Z!Pw$zWEe?w zS`q0`hpENY$Z(SA%qf!IoLgLtJVp|oDMiv7t%<9V$4R0yrbwFEy0{uCLlT{1iliA! z6IUbUNTPFyNV>ChaWztwBsyOaNoP(?T#b|`iB6wL;?%{}$TB3+84`JJ;%a0$lIT>C z=Ps^BmL-YKDy~1WJW2ff@U)5>h{)&?NN0^T?-4m6kiHpfIzqBCYxc|n#BDbJ0qsxk UxMV#=Pyhe`07*qoM6N<$f}g=q2LJ#7 literal 0 HcmV?d00001 diff --git a/src/assets/images/floorplaneditor/door-direction-2.png b/src/assets/images/floorplaneditor/door-direction-2.png new file mode 100644 index 0000000000000000000000000000000000000000..da1a1cb52a0f309307d4ccb9b335b0496ad0c88d GIT binary patch literal 750 zcmVPx#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0)t6JK~!i%?T|ZC z+)xljX9M1l_drJGDsO?D&;bi@Ik5v$5>f)z#R72mn8uI3N17+}dz#U$I#n|zsr&Xh zG@RGOp2}o#nLQm5S-)Ryj?gn>&s#)Jh|AEs#>GZtkTin6H7+J{JW2Zg{PhF$4$U&o zHgYUU$>K8f4b3*rCUP7}AX$CT4BBOEHgXIdO>%}nGikT6nMip$l4Oj5c2F0i*+^MB zijJQW+DYAvW+LV22s(C7r~`F1R*RIO(sbOCP$%kcEEZW#CFz(op^kKmFKBD1klKX|YsRah*uAp>g z{QL3e;pz42`r8ruh=wmo?vup@@tkH1q1+XOpW7dIEHG$EWZqBGO5#15RYSQeD8&W6 z0$UK7_mM0j-lv&;l)C~F*D25;iO!ND^L&!jM|?-KiE>xaC(bFI86W-}A&JfsB4ZxO zsiC${yjL<%T<{)wND`enMaCSGQ^Tnq@w{ZLxEy(zBsz15q*EGLQ1oFZvv z>*8{x3`umR6iG9-CN4+Hkwj;VNcv{$;&P-cNpyyYq<79uT#l3{iB6wL;@rjM$T1|* zIVJMa#O26wB+Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0!~RpK~!i%?U1=q z13?f)l>iBm10Eh#q=1i!K>!pE7`QmN7{o;YqFZQS)&K2iPic?&Rj*2`nd#$gCY)`c zq+z1CNJ&jZ*30+Z4mvYR_7OQrT!ii#tBuGYX#~ABRufsCB;9^p9zb`fma*8#vLq#n zi_jaYZ7e3T97!NqIj9EpGG-fDhL$EdZJ?Ue+n7yccv_NV^nrTNEXHIb!_rc;{E$#j zn$4I@WH?%amK_tCfo3(%78!sCyO+vA!(U&LNn4X#%PgdG!zX#C1_^a z%@{0FoQ9xbrwr{tyBeJ%#i%I_Hz#N(+TCazc}z`cm^ni`k_)3Ya+!)!^Cdw$lN;kN za!5s}*^(g#-*>S>iT8}J)+`Eh8!e6_YaROFtKKlv~yKl zA}er>B56kwS1ZsViO!Nm(oQ*XPSu%l@Uep=Izx)28hxN1IjBZUaf!dkAxU)lillc# zK)oXLuCKTlxl9tBt|HT&&GW?|wCP!8XmK&}m?S!FMW!>7(S;_xs*EizMv9R{r>V$z zMpBv(>*RVkrxq6@#Yv(ww#fJ{SJOGSxEN_h5}lz%#(TLM&eX)kNOO|t^c5NZ&%JS` zE-prfA&E{`k%?n><|Zyih9ikiTaol%mAQ+Hkzq-q(^TYI#Kp+)B+Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0*OgPK~!i%?T|Z8 z98nNOX9H}AJveh_i7hyHNZ<@J|2=)BBY~#ht*Uca za9$F7DwD-!_B2Ff{rdm?2>oX4d5_2maT)s7xY~#el19*5<7y(ulcc+Uw-ELGz9@7w7<{W+Bk4d>(KrW2N$j4Ml z!)u@}hrXQ?+L7ECACVuagobq?dJc~_N6K!8-ponf&mmXF=Rfp_$}b`MLg0o(zWwp^ z`|rz_uiuW)BP#Dg^kjiSIm@ArDardd;pfNwPZk)AAu`^RypnR3LtSH%=R2jipjF@) zBI6xNBg$D0bq-0M=a9HYfeuM@h7cLwldLw%Sq^pgA@@6N;+)c%aq`a*lIZji8Q+nl z8fxd%5`85d#RVUcA4#HfiOBe!Ay7m@VMCFI^(sB36(Ir5k! zI<+F{_b!xOwNTI4;&P;nBs#Ssr+{{tT3n8llSF4uku-B|aXB)KBsx=yq!~*Smm|YT zqBEvQ>Rh_G99f1WIzx)2jyCD(?=w|S-ZF#S(YR^T}0A1TN9Tf%acT>O(d~( zaXE4fNp#MMyf$$;avVu?vdC)}mm|lLL}wS*9yy*QK0N=~#hr=BXc9=@8hhR&azY^e mX6$JQ$tu}XnH7jT99{vDLFpO_Y0KUK0000Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0*6UNK~!i%?T|Z? z6G0FKbpbBK9q{mo;0pMd7#x7W0b^YpTnx^|0hTJET59X%OpjLcX-V@UGGevUUHvK# z9p|yIXJV?j%ASFUtZ#ol9HDQN3lh^x?9<8C7|NE$(Rjk}2~Pmq1ndGM3y57Bx?+sL2nsX8(D^yCOPLoGwE&PY9i%nNs@61^agb?x{Z{j zrD*v%p*N|U(M_ZrEkVmJ33Z^Z#%7T+RGOB`|67{eC7|xcYLUmOWNV51eGRAs?P4qz zd5lW6N(cGenot+o&6q7RoJurHetmT$e&_RBkh=x6tMTHLji=fkEyX(C)_M z$Ypw@S)zyw;(NZ|1G#%ZE{ws*VH(o!1+A zw}4z3|9{XW8t&vXBx;D(+}_B02HBbM?~m_4em%Z<`|b!`Y7Hh?M4YeldL!=^grAR} zKC{4Jsz~}y(lT)_&*_Q0OOV9{qXL%{8Q=5$9?0DT5;rK&A&JhMBIE!0-j?L9!I(HF zJ2RgBI6@MgIYh?qe0~dZx8O{1!BgZTNpvm|8RTqVrOb`P*954$j=- zYUDCWbf${j0_wE1xEdKo5}lqzQirw0)yQy?=xiyH-rQPTjXXvYoi#<$8@-9Ek;h4* zv!qCx*}J$JDMJ#SIYrWpYZF%^rEJ<|E5lLrmOLRXBRgfS)L?*dHA`DYeZxW38b^eo>N3l2&8Yu ko`I08%$|w40&$1KUu>K2xa@v&s{jB107*qoM6N<$f|+Sq4*&oF literal 0 HcmV?d00001 diff --git a/src/assets/images/floorplaneditor/door-direction-6.png b/src/assets/images/floorplaneditor/door-direction-6.png new file mode 100644 index 0000000000000000000000000000000000000000..fda613acc0bb4344cb77de60b9a7b7e649caa7e3 GIT binary patch literal 747 zcmVPx#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0)RkJA9#QbasSM` zUBh`vY^h8Zm)X)0k@f5U_dWERvE@A?C&XpwTjOdYGDsRhZ;h*o98Z$&{@orx-%yva z+Q_jaC5y|@8|pSz6FH6~kgPtagJv0vjT}Qqlbj(?C(Sk%6Iq^)BpG9%8MKShY-CwF zijJQWnn}AE%|w=?Bk0&Up&e*f<6@CzXz61|4WaC+g?ear<7|=Pv}Da8r;vMVp)R_` zm@P7lmZIgI_tUV(Fo9Q%Gw%H0AI*D25;iO$p_ zTY_%t6X%r9jDvsnkVI!qBI$;K;)0LJk0jAqvPjx_thgNcm?Sz&5=lEwEiOkMlSHRw zk+jp?;&P;nBswjLq#e#JE=S5qqH{@+H1pEpa%31ubj~S~X0#?QM~0I`XHJpS*}AwK zS%xG!Q;MXHrHRXtSIi4gwJpb9m9f`>35=h?~TizpbLLmKSZ0QKeD%nz* d1&G`2UIAD*=^CG#rx5@E002ovPDHLkV1iyePc;Al literal 0 HcmV?d00001 diff --git a/src/assets/images/floorplaneditor/door-direction-7.png b/src/assets/images/floorplaneditor/door-direction-7.png new file mode 100644 index 0000000000000000000000000000000000000000..96fa8e483b9a17d70c89a2ea3ee67262033a1e95 GIT binary patch literal 698 zcmV;r0!96aP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0#8XqK~!i%?U1oi z!$1&4-2e^I0~r}Jv_MWsKmiO11f(RS1k^@$?-v4xxZQ0hH^k?1-Mt6Jr-)h2H z2bK&>6c<_25s~%seb+$Wj3t|hoFpznXN}oLWRNt1?i#a+lqX5IUzc0Z8JcBO8!1at zNE-dG4b3*HiIgJ=eUhBMGxU~GY@`g8&PiE4Uo^!3=k7T4woy!Ec`BKcki#jFt|UnsLY$L(!=YV`vqhGnrQ4-qIg+vuL*8mb zyBjBqJWfkenM686GWKDYH``Db<7kn`XenAgLifgi-ipvY>Sl}<8BR;kvN>qRA?o6&E9iNupDdNZN61aWQh4 zBsx^yaz6#mHkM(K)3^dShzhV&rj>=p0id z&78Wp7+HoSI%A5Y8KsGfk>yCDbBIW~Q@XeqS(YR^yNIMSwTX+7HG6G_xAE=J0b zM5j;W+{DF5Ig;o^k#iRpBV|dVvxv(_%9F&Ww~s|!PeewSKsswI*+k?df%MH-(h-u? gX34-5Aa1q#0oVTQcxWGecK`qY07*qoM6N<$f{}SLG5`Po literal 0 HcmV?d00001 diff --git a/src/assets/images/floorplaneditor/icon-door.png b/src/assets/images/floorplaneditor/icon-door.png new file mode 100644 index 0000000000000000000000000000000000000000..1b56bb2b56619b00671d9a8db92c13152961597b GIT binary patch literal 806 zcmV+>1KIqEP)aB^>EX>4U6ba`-PAVE-2F#rGvnd3@N%}XuHOjal;%1_J8 zN##-i17i~|6H60IqeKG(0}BHPFf=eQHUyGJK(;wlDA51~n3$WT0in5BvY9D}&jkQa zx)o>}E!d0z00MGJL_t(oh3%I=Xj4HP$G;~op~Rt3uuq?qKspE^kU(l(MXZxhaOe`n zf`W8#bLrT@ZVqX|!GJCfg@RK9rK>i96iPtBKoI*ULLo{Y!Oe5XyYt=U-o3lzIr+ZJ zyWhRv-TQF&yWjmDkSI~2ME|$QnB!?I6dI0k0O?{ei)?0Qj46P2=PS0G?NAm~=g6zF z@$in7|6Z$uY-R@QTf1Q_xTxxUe*d;L-1^oo_F5gQF}HFVeCz+#`X~XfOL1e@uV_iV`jN&02zT#OS+Y+sCbcV=n{|1P3sx<19^`P{lR*2J zFG(=wWXbR3nA8HM%Abb%qS6gLJOFWAt&fegfQ{8O0HCzyS>-|93AU9Mu(amc&E|vA z;*EjrUup8T#gb-L7Upnz*0V}Asyp`eyElTpy!0T_#|Y3=q1BA9#^WD?y}T6d6I3iW ziCoRF(@X(=v0yhg=cP_Y*aBwqlXzQS$RW_6%0-jwqx`r`W6 kwbi))=!p^~N;Hc80F`vvfW6oebpQYW07*qoM6N<$f-F>ep8x;= literal 0 HcmV?d00001 diff --git a/src/assets/images/floorplaneditor/icon-tile-down.png b/src/assets/images/floorplaneditor/icon-tile-down.png new file mode 100644 index 0000000000000000000000000000000000000000..352c48dffb33a7eafce5ade65e44fbb469a859d6 GIT binary patch literal 609 zcmV-n0-pVeP)aB^>EX>4U6ba`-PAVE-2F#rGvnd3@N%}XuHOjal;%1_J8 zN##-i17i~|6H60IqeKG(0}BHPFf=eQHUyGJK(;wlDA51~n3$WT0in5BvY9D}&jkQa zx)o>}E!d0z00FH@L_t(oh3(fdOT$1I2H-d1-l339=u($fLc6(}-PuiW@(*+ohv3pb zkV)t!bko`HZY`nhlBtkQaPSv=4kqcPNiLWB4ytf3lqQ$E?;b9>&;m9#Ha7n%lzxoG zF;s^DV7s0I00tKmWA(WO2mm(gDV($t5q^)!3{-buH7u=|Bh&UF1KM_g6jtbE2&&pq z4OTUZ32o}IfA}j_NEya}N~hUwrX`R#NfSuCPAHBO>kNjITFa>fh>zC@0C0Kjm5LUi zPT^~RAi(mbbe!Yt>&v2ai=Urv)S$vB*@|VbyN8!XN2^WJ8p?pR1u8*_2u_7k2c`>@ zLPabW#s%gcpbRwuV-FOP|9Z)w0*pO}5uh7{0D#ZOdjP<}`SF2%5@WYq;XC>Q0Cc=A zdgBq^&(7I%NMF=Vu)~Iq*Om3tf@<$#KZ)~`-Evjx&>N2m=enzT(wdegnk@iSaB^>EX>4U6ba`-PAVE-2F#rGvnd3@N%}XuHOjal;%1_J8 zN##-i17i~|6H60IqeKG(0}BHPFf=eQHUyGJK(;wlDA51~n3$WT0in5BvY9D}&jkQa zx)o>}E!d0z00CJ^L_t(oh3%F-PQySDM&BS>3eEu$U8HadT4*Rh(9)%$q;W?Jf`SIx zoB~Vfq9o^_-~dCBO|stg`Y%R8XkL?*cRcg7{$vLX!!QiPFe;E9dugJlhJ|hB?|0S- z1eWs*fTO`U5`Frs7eNJB%rnHPsKRoQffhso_{^u9_33EXct{t)QZWHU z+*($ms&G6QcNo!4uu^PIOQA5IQ6`%RHWKqG%UoSeDw9=$+we>AYD&z<&s^PJRVGt{ zx?E(QrdyWDDIkfx9@tB5+!z zXJ3M~q9SRrHo1$2?Z`^>;Q}a#t$XY6`7pZ4J>uH=fBx^5VHk#C{BwQ)UCESH8~f0n P00000NkvXXu0mjftU=#n literal 0 HcmV?d00001 diff --git a/src/assets/images/floorplaneditor/icon-tile-unset.png b/src/assets/images/floorplaneditor/icon-tile-unset.png new file mode 100644 index 0000000000000000000000000000000000000000..3f5e21817a80ef76a79f15eb063775a3c71bfc42 GIT binary patch literal 544 zcmV+*0^j|KP)aB^>EX>4U6ba`-PAVE-2F#rGvnd3@N%}XuHOjal;%1_J8 zN##-i17i~|6H60IqeKG(0}BHPFf=eQHUyGJK(;wlDA51~n3$WT0in5BvY9D}&jkQa zx)o>}E!d0z00C@CL_t(oh3%FxZi6rshJSZ$B@P0pYkG^$j8QI-iKQb8Q!aoqcFrxr z8YLVgQaZm57-}3p;{a8q>U|Ot{223L{J?-92!bF8{{hn5Ser+30Kn5EonhzHoJ%z4 zvOjjUqwUru!{t3{h8QmA5=wP|6d!72_CB_b%xk}VKD=eRtyiXRd+ zWr21M1Hk6vb0}#@aJlU?>sM!snqo%()X7*9T)rp-fT|*+s>r&9f^)HOiz3%KE?=Bq iTW$%0AP9o+w|oP&*#(U`6+X}a0000aB^>EX>4U6ba`-PAVE-2F#rGvnd3@N%}XuHOjal;%1_J8 zN##-i17i~|6H60IqeKG(0}BHPFf=eQHUyGJK(;wlDA51~n3$WT0in5BvY9D}&jkQa zx)o>}E!d0z00DPNL_t(oh3(hBPQx$|2Jr6?uTiN}7gC{i;{m#NX67BbFtX$wkl2{n z%gzR>nk=1=`XI-EZR{lY?=c|xlcK7L&-YWEI4V$6Q&aP=!s-wU3C_iv^9ca3pDo1Z zmICtTe8T7Z2LNEcUWp+kfDTSa3Rw!A#OX*NOMqUSPAM`MXdVcisU^0Pi@Z#xeTVk5 zh1pJq*a6DacHdHM_~8{@4Pf##(jF(u@!G4-H_uk#p8p zsjeH?@OuK(+otc@5y);50@>FYZk;`kT7gN6_a1zEIRF4|w%4Oc9Vj^;&IY7m=9H=< z`kCLCs3m@UxQ&BaRlZ+L!|v{%gN~$!BpF%&O9e(jnHe;p%z@H7cx literal 0 HcmV?d00001 diff --git a/src/assets/images/floorplaneditor/preview_tile.png b/src/assets/images/floorplaneditor/preview_tile.png new file mode 100644 index 0000000000000000000000000000000000000000..607f450134966c1af638374d5da5a42ddeeeadbb GIT binary patch literal 146 zcmeAS@N?(olHy`uVBq!ia0vp^LLkh+1|-AI^@RheNKY5XkcwN$2@zopr0NjHuCIA2c literal 0 HcmV?d00001 diff --git a/src/assets/images/floorplaneditor/selected_height_icon.png b/src/assets/images/floorplaneditor/selected_height_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..f763fde5aa1e825a263cbdc303cf66fd666a780c GIT binary patch literal 175 zcmeAS@N?(olHy`uVBq!ia0vp^JU}eK!3HFi66di4Db50q$YKTtzQZ8Qcszea3Q#c7 z)5S5Q;?~{?2YC-Da4^ig&40P1+3s$`!kjA(7Zyx7_G1VC&Ta(}j|-J7E;^#N$q9U` zJY0CSrI>WrD{<=F?24)EbK2DR#C^}y8TICOxXb2nI%z-sW45QkmU9u0{+opN%vTmY VXpCB}y9sC+gQu&X%Q~loCICHTJ3{~f literal 0 HcmV?d00001 diff --git a/src/events/chat-history/ChatHistoryEvent.ts b/src/events/chat-history/ChatHistoryEvent.ts index bf057561..e038f22e 100644 --- a/src/events/chat-history/ChatHistoryEvent.ts +++ b/src/events/chat-history/ChatHistoryEvent.ts @@ -5,5 +5,4 @@ export class ChatHistoryEvent extends NitroEvent public static SHOW_CHAT_HISTORY: string = 'CHE_SHOW_CHAT_HISTORY'; public static HIDE_CHAT_HISTORY: string = 'CHE_HIDE_CHAT_HISTORY'; public static TOGGLE_CHAT_HISTORY: string = 'CHE_TOGGLE_CHAT_HISTORY'; - public static CHAT_HISTORY_CHANGED: string = 'CHE_CHAT_HISTORY_CHANGED'; } diff --git a/src/events/floorplan-editor/FloorplanEditorEvent.ts b/src/events/floorplan-editor/FloorplanEditorEvent.ts new file mode 100644 index 00000000..62f7f3bf --- /dev/null +++ b/src/events/floorplan-editor/FloorplanEditorEvent.ts @@ -0,0 +1,8 @@ +import { NitroEvent } from '@nitrots/nitro-renderer'; + +export class FloorplanEditorEvent extends NitroEvent +{ + public static SHOW_FLOORPLAN_EDITOR: string = 'FPEE_SHOW_FLOORPLAN_EDITOR'; + public static HIDE_FLOORPLAN_EDITOR: string = 'FPEE_HIDE_FLOORPLAN_EDITOR'; + public static TOGGLE_FLOORPLAN_EDITOR: string = 'FPEE_TOGGLE_FLOORPLAN_EDITOR'; +} diff --git a/src/views/Styles.scss b/src/views/Styles.scss index 77dc121f..6369f546 100644 --- a/src/views/Styles.scss +++ b/src/views/Styles.scss @@ -22,3 +22,4 @@ @import './user-profile/UserProfileVew'; @import './chat-history/ChatHistoryView'; @import './help/HelpView'; +@import './floorplan-editor/FloorplanEditorView'; diff --git a/src/views/chat-history/ChatHistoryView.tsx b/src/views/chat-history/ChatHistoryView.tsx index 2a29cdd8..f80ddbbd 100644 --- a/src/views/chat-history/ChatHistoryView.tsx +++ b/src/views/chat-history/ChatHistoryView.tsx @@ -11,8 +11,6 @@ import { RoomHistoryState } from './common/RoomHistoryState'; import { ChatHistoryContextProvider } from './context/ChatHistoryContext'; import { ChatEntryType } from './context/ChatHistoryContext.types'; - - export const ChatHistoryView: FC<{}> = props => { const [ isVisible, setIsVisible ] = useState(false); @@ -52,18 +50,15 @@ export const ChatHistoryView: FC<{}> = props => case ChatHistoryEvent.TOGGLE_CHAT_HISTORY: setIsVisible(!isVisible); break; - case ChatHistoryEvent.CHAT_HISTORY_CHANGED: - break; } }, [isVisible]); useUiEvent(ChatHistoryEvent.HIDE_CHAT_HISTORY, onChatHistoryEvent); useUiEvent(ChatHistoryEvent.SHOW_CHAT_HISTORY, onChatHistoryEvent); useUiEvent(ChatHistoryEvent.TOGGLE_CHAT_HISTORY, onChatHistoryEvent); - useUiEvent(ChatHistoryEvent.CHAT_HISTORY_CHANGED, onChatHistoryEvent); const cache = useMemo(() => -{ + { return new CellMeasurerCache({ defaultHeight: 25, fixedWidth: true, diff --git a/src/views/floorplan-editor/FloorplanEditorView.scss b/src/views/floorplan-editor/FloorplanEditorView.scss new file mode 100644 index 00000000..138d1c09 --- /dev/null +++ b/src/views/floorplan-editor/FloorplanEditorView.scss @@ -0,0 +1,37 @@ +.nitro-floorplan-editor +{ + width: 760px; + height: 575px; + + .editor-area + { + width: 100%; + height: 300px; + overflow-x: scroll; + } + + .set-tile + { + background-image: url('../../assets/images/floorplaneditor/icon-tile-set.png'); + } + + .unset-tile + { + background-image: url('../../assets/images/floorplaneditor/icon-tile-unset.png'); + } + + .increase-height + { + background-image: url('../../assets/images/floorplaneditor/icon-tile-up.png'); + } + + .decrease-height + { + background-image: url('../../assets/images/floorplaneditor/icon-tile-down.png'); + } + + .set-door + { + background-image: url('../../assets/images/floorplaneditor/icon-door.png'); + } +} diff --git a/src/views/floorplan-editor/FloorplanEditorView.tsx b/src/views/floorplan-editor/FloorplanEditorView.tsx new file mode 100644 index 00000000..dd452c57 --- /dev/null +++ b/src/views/floorplan-editor/FloorplanEditorView.tsx @@ -0,0 +1,119 @@ +import { FloorHeightMapEvent, RoomVisualizationSettingsEvent, UpdateFloorPropertiesMessageComposer } from '@nitrots/nitro-renderer'; +import { FC, useCallback, useEffect, useState } from 'react'; +import { LocalizeText } from '../../api'; +import { FloorplanEditorEvent } from '../../events/floorplan-editor/FloorplanEditorEvent'; +import { CreateMessageHook, SendMessageHook, useUiEvent } from '../../hooks'; +import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../layout'; +import { FloorplanEditor } from './common/FloorplanEditor'; +import { convertNumbersForSaving, convertSettingToNumber } from './common/Utils'; +import { FloorplanEditorContextProvider } from './context/FloorplanEditorContext'; +import { IFloorplanSettings, initialFloorplanSettings } from './context/FloorplanEditorContext.types'; +import { FloorplanCanvasView } from './views/FloorplanCanvasView'; +import { FloorplanOptionsView } from './views/FloorplanOptionsView'; + +export const FloorplanEditorView: FC<{}> = props => +{ + const [isVisible, setIsVisible] = useState(false); + const [floorplanSettings, setFloorplanSettings ] = useState(initialFloorplanSettings); + + const onFloorplanEditorEvent = useCallback((event: FloorplanEditorEvent) => + { + switch(event.type) + { + case FloorplanEditorEvent.HIDE_FLOORPLAN_EDITOR: + setIsVisible(false); + break; + case FloorplanEditorEvent.SHOW_FLOORPLAN_EDITOR: + setIsVisible(true); + break; + case FloorplanEditorEvent.TOGGLE_FLOORPLAN_EDITOR: + setIsVisible(!isVisible); + break; + } + }, [isVisible]); + + useUiEvent(FloorplanEditorEvent.HIDE_FLOORPLAN_EDITOR, onFloorplanEditorEvent); + useUiEvent(FloorplanEditorEvent.SHOW_FLOORPLAN_EDITOR, onFloorplanEditorEvent); + useUiEvent(FloorplanEditorEvent.TOGGLE_FLOORPLAN_EDITOR, onFloorplanEditorEvent); + + useEffect(() => + { + FloorplanEditor.instance.initialize(); + }, []); + + const onFloorHeightMapEvent = useCallback((event: FloorHeightMapEvent) => + { + const parser = event.getParser(); + + if(!parser) return; + + const settings = Object.assign({}, floorplanSettings); + settings.tilemap = parser.model; + settings.wallHeight = parser.wallHeight + 1; + setFloorplanSettings(settings); + }, [floorplanSettings]); + + CreateMessageHook(FloorHeightMapEvent, onFloorHeightMapEvent); + + const onRoomVisualizationSettingsEvent = useCallback((event: RoomVisualizationSettingsEvent) => + { + const parser = event.getParser(); + + if(!parser) return; + + const settings = Object.assign({}, floorplanSettings); + settings.thicknessFloor = convertSettingToNumber(parser.thicknessFloor) + settings.thicknessWall = convertSettingToNumber(parser.thicknessWall); + + setFloorplanSettings(settings); + }, [floorplanSettings]); + + CreateMessageHook(RoomVisualizationSettingsEvent, onRoomVisualizationSettingsEvent); + + const saveFloorChanges = useCallback(() => + { + SendMessageHook(new UpdateFloorPropertiesMessageComposer( + FloorplanEditor.instance.getCurrentTilemapString(), + floorplanSettings.entryPoint[0], + floorplanSettings.entryPoint[1], + floorplanSettings.entryPointDir, + convertNumbersForSaving(floorplanSettings.thicknessWall), + convertNumbersForSaving(floorplanSettings.thicknessFloor), + floorplanSettings.wallHeight - 1 + )); + }, [floorplanSettings.entryPoint, floorplanSettings.entryPointDir, floorplanSettings.thicknessFloor, floorplanSettings.thicknessWall, floorplanSettings.wallHeight]); + + return ( + <> + + {isVisible && + + setIsVisible(false)} /> + +
+
+ +
+
+
+
+ +
+
+
+
+ +
+
+ + + +
+
+
+
+ } +
+ + ); +} diff --git a/src/views/floorplan-editor/common/ActionSettings.ts b/src/views/floorplan-editor/common/ActionSettings.ts new file mode 100644 index 00000000..8ac38251 --- /dev/null +++ b/src/views/floorplan-editor/common/ActionSettings.ts @@ -0,0 +1,39 @@ +import { FloorAction, HEIGHT_SCHEME } from './Constants'; + +export class ActionSettings +{ + private _currentAction: number; + private _currentHeight: string; + + constructor() + { + this._currentAction = FloorAction.SET; + this._currentHeight = HEIGHT_SCHEME[1]; + } + + public get currentAction(): number + { + return this._currentAction; + } + + public set currentAction(value: number) + { + this._currentAction = value; + } + + public get currentHeight(): string + { + return this._currentHeight; + } + + public set currentHeight(value: string) + { + this._currentHeight = value; + } + + public clear(): void + { + this._currentAction = FloorAction.SET; + this._currentHeight = HEIGHT_SCHEME[1]; + } +} diff --git a/src/views/floorplan-editor/common/Constants.ts b/src/views/floorplan-editor/common/Constants.ts new file mode 100644 index 00000000..717f40d0 --- /dev/null +++ b/src/views/floorplan-editor/common/Constants.ts @@ -0,0 +1,13 @@ +export const TILE_SIZE = 32; +export const MAX_NUM_TILE_PER_AXIS = 64; + +export const HEIGHT_SCHEME: string = 'x0123456789abcdefghijklmnopq'; + +export class FloorAction +{ + public static readonly DOOR = 0; + public static readonly UP = 1; + public static readonly DOWN = 2; + public static readonly SET = 3; + public static readonly UNSET = 4; +} diff --git a/src/views/floorplan-editor/common/FloorplanEditor.ts b/src/views/floorplan-editor/common/FloorplanEditor.ts new file mode 100644 index 00000000..bdacb553 --- /dev/null +++ b/src/views/floorplan-editor/common/FloorplanEditor.ts @@ -0,0 +1,412 @@ +import { NitroPoint, NitroTilemap, PixiApplicationProxy, PixiInteractionEventProxy, POINT_STRUCT_SIZE } from '@nitrots/nitro-renderer'; +import { GetConfiguration } from '../../../api'; +import { ActionSettings } from './ActionSettings'; +import { FloorAction, HEIGHT_SCHEME, MAX_NUM_TILE_PER_AXIS, TILE_SIZE } from './Constants'; +import { Tile } from './Tile'; +import { getScreenPositionForTile, getTileFromScreenPosition } from './Utils'; + +export class FloorplanEditor extends PixiApplicationProxy +{ + private static _instance: FloorplanEditor = new FloorplanEditor(); + + private static readonly TILE_BLOCKED = 'r_blocked'; + private static readonly TILE_DOOR = 'r_door'; + + private _tilemap: Tile[][]; + private _width: number; + private _height: number; + private _isHolding: boolean; + private _doorLocation: NitroPoint; + private _lastUsedTile: NitroPoint; + private _tilemapRenderer: NitroTilemap; + private _actionSettings: ActionSettings; + private _isInitialized: boolean; + + private constructor() + { + const width = TILE_SIZE * MAX_NUM_TILE_PER_AXIS + 20; + const height = (TILE_SIZE * MAX_NUM_TILE_PER_AXIS) / 2 + 100; + + super({ + width: width, + height: height, + backgroundColor: 0x2b2b2b, + antialias: true, + autoDensity: true, + resolution: 1, + sharedLoader: true, + sharedTicker: true + }); + + this._tilemap = []; + this._doorLocation = new NitroPoint(0, 0); + this._width = 0; + this._height = 0; + this._isHolding = false; + this._lastUsedTile = new NitroPoint(-1,-1); + this._actionSettings = new ActionSettings(); + } + + public initialize(): void + { + if(!this._isInitialized) + { + this.loader.add('tiles', GetConfiguration('floorplan.tile.url')); + + this.loader.load((_, resources) => + { + this._tilemapRenderer = new NitroTilemap(resources['tiles'].spritesheet.baseTexture); + this.registerEventListeners(); + this.stage.addChild(this._tilemapRenderer); + }); + this._isInitialized = true; + } + } + + private registerEventListeners(): void + { + //this._tilemapRenderer.interactive = true; + + const tempPoint = new NitroPoint(); + // @ts-ignore + this._tilemapRenderer.containsPoint = (position) => + { + this._tilemapRenderer.worldTransform.applyInverse(position, tempPoint); + return this.tileHitDettection(tempPoint, false); + }; + + this._tilemapRenderer.on('pointerup', () => + { + this._isHolding = false; + }); + + this._tilemapRenderer.on('pointerout', () => + { + this._isHolding = false; + }); + + this._tilemapRenderer.on('pointerdown', (event: PixiInteractionEventProxy) => + { + if(!(event.data.originalEvent instanceof PointerEvent)) return; + + const pointerEvent = event.data.originalEvent; + if(pointerEvent.button === 2) return; + + + const location = event.data.global; + this.tileHitDettection(location, true); + }); + + this._tilemapRenderer.on('click', (event: PixiInteractionEventProxy) => + { + if(!(event.data.originalEvent instanceof PointerEvent)) return; + + const pointerEvent = event.data.originalEvent; + if(pointerEvent.button === 2) return; + + const location = event.data.global; + this.tileHitDettection(location, true, true); + }); + } + + private tileHitDettection(tempPoint: NitroPoint, setHolding: boolean, isClick: boolean = false): boolean + { + // @ts-ignore + const buffer = this._tilemapRenderer.pointsBuf; + const bufSize = POINT_STRUCT_SIZE; + + const len = buffer.length; + + if(setHolding) + { + this._isHolding = true; + } + + for(let j = 0; j < len; j += bufSize) + { + const bufIndex = j + bufSize; + const data = buffer.slice(j, bufIndex); + + const width = data[4]; + const height = data[5]; + + + const mousePositionX = Math.floor(tempPoint.x); + const mousePositionY = Math.floor(tempPoint.y); + + const tileStartX = data[2]; + const tileStartY = data[3]; + + + const centreX = tileStartX + (width / 2); + const centreY = tileStartY + (height / 2); + + const dx = Math.abs(mousePositionX - centreX - 2); + const dy = Math.abs(mousePositionY - centreY - 2); + + const solution = (dx / (width * 0.5) + dy / (height * 0.5) <= 1);//todo: improve this + if(solution) + { + if(this._isHolding) + { + const [realX, realY] = getTileFromScreenPosition(tileStartX, tileStartY); + + if(isClick) + { + this.onClick(realX, realY); + } + + else if(this._lastUsedTile.x !== realX || this._lastUsedTile.y !== realY) + { + this._lastUsedTile.x = realX; + this._lastUsedTile.y = realY; + this.onClick(realX, realY); + } + + } + return true; + } + + } + return false; + } + + + private onClick(x: number, y: number): void + { + const tile = this._tilemap[y][x]; + const heightIndex = HEIGHT_SCHEME.indexOf(tile.height); + + let futureHeightIndex = 0; + + switch(this._actionSettings.currentAction) + { + case FloorAction.DOOR: + + if(tile.height !== 'x') + { + this._doorLocation.x = x; + this._doorLocation.y = y; + this.renderTiles(); + } + return; + case FloorAction.UP: + futureHeightIndex = heightIndex + 1; + break; + case FloorAction.DOWN: + futureHeightIndex = heightIndex - 1; + break; + case FloorAction.SET: + futureHeightIndex = HEIGHT_SCHEME.indexOf(this._actionSettings.currentHeight); + break; + case FloorAction.UNSET: + futureHeightIndex = 0; + break; + } + + if(futureHeightIndex === -1) return; + + if(heightIndex === futureHeightIndex) return; + + if(futureHeightIndex > 0) + { + if((x + 1) > this._width) this._width = x + 1; + + if( (y + 1) > this._height) this._height = y + 1; + } + + const newHeight = HEIGHT_SCHEME[futureHeightIndex]; + + if(!newHeight) return; + + if(tile.isBlocked) return; + + this._tilemap[y][x].height = newHeight; + + this.renderTiles(); + } + + public renderTiles(): void + { + this.tilemapRenderer.clear(); + + for(let y = 0; y < this._tilemap.length; y++) + { + for(let x = 0; x < this.tilemap[y].length; x++) + { + const tile = this.tilemap[y][x]; + let assetName = tile.height; + + if(this._doorLocation.x === x && this._doorLocation.y === y) + assetName = FloorplanEditor.TILE_DOOR; + + if(tile.isBlocked) assetName = FloorplanEditor.TILE_BLOCKED; + + //if((tile.height === 'x') || tile.height === 'X') continue; + const [positionX, positionY ] = getScreenPositionForTile(x, y); + this._tilemapRenderer.tile(`${assetName}.png`, positionX, positionY); + } + } + } + + public setTilemap(map: string, blockedTiles: boolean[][]): void + { + this._tilemap = []; + const roomMapStringSplit = map.split('\r'); + + let width = 0; + let height = roomMapStringSplit.length; + + // find the map width, height + for(let y = 0; y < height; y++) + { + const originalRow = roomMapStringSplit[y]; + + if(originalRow.length === 0) + { + roomMapStringSplit.splice(y, 1); + height = roomMapStringSplit.length; + y--; + continue; + } + + if(originalRow.length > width) + { + width = originalRow.length; + } + } + // fill map with room heightmap tiles + for(let y = 0; y < height; y++) + { + this._tilemap[y] = []; + const rowString = roomMapStringSplit[y]; + + for(let x = 0; x < width; x++) + { + const blocked = (blockedTiles[y] && blockedTiles[y][x]) || false; + + const char = rowString[x]; + if(((!(char === 'x')) && (!(char === 'X')) && char)) + { + this._tilemap[y][x] = new Tile(char, blocked); + } + else + { + this._tilemap[y][x] = new Tile('x', blocked); + } + } + + for(let x = width; x < MAX_NUM_TILE_PER_AXIS; x++) + { + this.tilemap[y][x] = new Tile('x', false); + } + } + + // fill remaining map with empty tiles + for(let y = height; y < MAX_NUM_TILE_PER_AXIS; y++) + { + if(!this.tilemap[y]) this.tilemap[y] = []; + for(let x = 0; x < MAX_NUM_TILE_PER_AXIS; x++) + { + this.tilemap[y][x] = new Tile('x', false); + } + } + + this._width = width; + this._height = height; + } + + public getCurrentTilemapString(): string + { + const highestTile = this._tilemap[this._height - 1][this._width - 1]; + + if(highestTile.height === 'x') + { + this._width = -1; + this._height = -1; + + for(let y = MAX_NUM_TILE_PER_AXIS - 1; y >= 0; y--) + { + if(!this._tilemap[y]) continue; + + for(let x = MAX_NUM_TILE_PER_AXIS - 1; x >= 0; x--) + { + if(!this._tilemap[y][x]) continue; + + const tile = this._tilemap[y][x]; + + if(tile.height !== 'x') + { + if( (x + 1) > this._width) + this._width = x + 1; + + if( (y + 1) > this._height) + this._height = y + 1; + } + } + } + } + + + const rows = []; + + for(let y = 0; y < this._height; y++) + { + const row = []; + + for(let x = 0; x < this._width; x++) + { + const tile = this._tilemap[y][x]; + + row[x] = tile.height; + } + + rows[y] = row.join(''); + } + + return rows.join('\r'); + } + + public clear(): void + { + this._tilemapRenderer.interactive = false; + this._tilemap = []; + this._doorLocation.set(-1, -1); + this._width = 0; + this._height = 0; + this._isHolding = false; + this._lastUsedTile.set(-1, -1); + this._actionSettings.clear(); + this._tilemapRenderer.clear(); + } + + public get tilemapRenderer(): NitroTilemap + { + return this._tilemapRenderer; + } + + public get tilemap(): Tile[][] + { + return this._tilemap; + } + + public get doorLocation(): NitroPoint + { + return this._doorLocation; + } + + public set doorLocation(value: NitroPoint) + { + this._doorLocation = value; + } + + public static get instance(): FloorplanEditor + { + if(!FloorplanEditor._instance) + { + FloorplanEditor._instance = new FloorplanEditor(); + } + + return FloorplanEditor._instance; + } +} diff --git a/src/views/floorplan-editor/common/Tile.ts b/src/views/floorplan-editor/common/Tile.ts new file mode 100644 index 00000000..fd9c0596 --- /dev/null +++ b/src/views/floorplan-editor/common/Tile.ts @@ -0,0 +1,31 @@ +export class Tile +{ + private _height: string; + private _isBlocked: boolean; + + constructor(height: string, isBlocked: boolean) + { + this._height = height; + this._isBlocked = isBlocked; + } + + public get height(): string + { + return this._height; + } + + public set height(height: string) + { + this._height = height; + } + + public get isBlocked(): boolean + { + return this._isBlocked; + } + + public set isBlocked(val: boolean) + { + this._isBlocked = val; + } +} diff --git a/src/views/floorplan-editor/common/Utils.ts b/src/views/floorplan-editor/common/Utils.ts new file mode 100644 index 00000000..6ffa52de --- /dev/null +++ b/src/views/floorplan-editor/common/Utils.ts @@ -0,0 +1,53 @@ +import { TILE_SIZE } from './Constants'; + +export const getScreenPositionForTile = (x: number, y: number): [number , number] => +{ + let positionX = (x * TILE_SIZE / 2) - (y * TILE_SIZE / 2); + const positionY = (x * TILE_SIZE / 4) + (y * TILE_SIZE / 4); + + positionX = positionX + 1024; // center the map in the canvas + + return [positionX, positionY]; +} + +export const getTileFromScreenPosition = (x: number, y: number): [number, number] => +{ + const translatedX = x - 1024; // after centering translation + + const realX = ((translatedX /(TILE_SIZE / 2)) + (y / (TILE_SIZE / 4))) / 2; + const realY = ((y /(TILE_SIZE / 4)) - (translatedX / (TILE_SIZE / 2))) / 2; + + return [realX, realY]; +} + +export const convertNumbersForSaving = (value: number): number => +{ + value = parseInt(value.toString()); + switch(value) + { + case 0: + return -2; + case 1: + return -1; + case 3: + return 1; + default: + return 0; + + } +} + +export const convertSettingToNumber = (value: number): number => +{ + switch(value) + { + case 0.25: + return 0; + case 0.5: + return 1; + case 2: + return 3; + default: + return 2; + } +} diff --git a/src/views/floorplan-editor/context/FloorplanEditorContext.tsx b/src/views/floorplan-editor/context/FloorplanEditorContext.tsx new file mode 100644 index 00000000..613c6fe6 --- /dev/null +++ b/src/views/floorplan-editor/context/FloorplanEditorContext.tsx @@ -0,0 +1,14 @@ +import { createContext, FC, useContext } from 'react'; +import { FloorplanEditorContextProps, IFloorplanEditorContext } from './FloorplanEditorContext.types'; + +const FloorplanEditorContext = createContext({ + floorplanSettings: null, + setFloorplanSettings: null +}); + +export const FloorplanEditorContextProvider: FC = props => +{ + return { props.children } +} + +export const useFloorplanEditorContext = () => useContext(FloorplanEditorContext); diff --git a/src/views/floorplan-editor/context/FloorplanEditorContext.types.ts b/src/views/floorplan-editor/context/FloorplanEditorContext.types.ts new file mode 100644 index 00000000..c6d8eb66 --- /dev/null +++ b/src/views/floorplan-editor/context/FloorplanEditorContext.types.ts @@ -0,0 +1,32 @@ +import { ProviderProps } from 'react'; + +export interface IFloorplanEditorContext +{ + floorplanSettings: IFloorplanSettings; + setFloorplanSettings: React.Dispatch>; +} + +export interface IFloorplanSettings { + tilemap: string; + reservedTiles: boolean[][]; + entryPoint: [number, number]; + entryPointDir: number; + wallHeight: number; + thicknessWall: number; + thicknessFloor: number; +} + +export const initialFloorplanSettings: IFloorplanSettings = { + tilemap: '', + reservedTiles: [], + entryPoint: [0, 0], + entryPointDir: 2, + wallHeight: -1, + thicknessWall: 1, + thicknessFloor: 1 +} + +export interface FloorplanEditorContextProps extends ProviderProps +{ + +} diff --git a/src/views/floorplan-editor/views/FloorplanCanvasView.tsx b/src/views/floorplan-editor/views/FloorplanCanvasView.tsx new file mode 100644 index 00000000..a6f9969c --- /dev/null +++ b/src/views/floorplan-editor/views/FloorplanCanvasView.tsx @@ -0,0 +1,72 @@ +import { GetOccupiedTilesMessageComposer, GetRoomEntryTileMessageComposer, NitroPoint, RoomEntryTileMessageEvent, RoomOccupiedTilesMessageEvent } from '@nitrots/nitro-renderer'; +import { FC, useCallback, useEffect, useRef, useState } from 'react'; +import { CreateMessageHook, SendMessageHook } from '../../../hooks'; +import { FloorplanEditor } from '../common/FloorplanEditor'; +import { useFloorplanEditorContext } from '../context/FloorplanEditorContext'; + +export const FloorplanCanvasView: FC<{}> = props => +{ + const { floorplanSettings = null, setFloorplanSettings = null } = useFloorplanEditorContext(); + const [ occupiedTilesReceived , setOccupiedTilesReceived ] = useState(false); + const [ entryTileReceived, setEntryTileReceived ] = useState(false); + const elementRef = useRef(null); + + useEffect(() => + { + SendMessageHook(new GetRoomEntryTileMessageComposer()); + SendMessageHook(new GetOccupiedTilesMessageComposer()); + FloorplanEditor.instance.tilemapRenderer.interactive = true; + elementRef.current.appendChild(FloorplanEditor.instance.renderer.view); + + return ( () => + { + FloorplanEditor.instance.clear(); + }); + }, []); + + const onRoomOccupiedTilesMessageEvent = useCallback((event: RoomOccupiedTilesMessageEvent) => + { + const parser = event.getParser(); + + if(!parser) return; + + const settings = Object.assign({}, floorplanSettings); + settings.reservedTiles = parser.blockedTilesMap; + setFloorplanSettings(settings); + + FloorplanEditor.instance.setTilemap(floorplanSettings.tilemap, parser.blockedTilesMap); + + setOccupiedTilesReceived(true); + + elementRef.current.scrollTo(FloorplanEditor.instance.view.width / 3, 0); + }, [floorplanSettings, setFloorplanSettings]); + + CreateMessageHook(RoomOccupiedTilesMessageEvent, onRoomOccupiedTilesMessageEvent); + + const onRoomEntryTileMessageEvent = useCallback((event: RoomEntryTileMessageEvent) => + { + const parser = event.getParser(); + + if(!parser) return; + + const settings = Object.assign({}, floorplanSettings); + settings.entryPoint = [parser.x, parser.y]; + settings.entryPointDir = parser.direction; + setFloorplanSettings(settings); + + FloorplanEditor.instance.doorLocation = new NitroPoint(settings.entryPoint[0], settings.entryPoint[1]); + setEntryTileReceived(true); + }, [floorplanSettings, setFloorplanSettings]); + + CreateMessageHook(RoomEntryTileMessageEvent, onRoomEntryTileMessageEvent); + + useEffect(() => + { + if(entryTileReceived && occupiedTilesReceived) + FloorplanEditor.instance.renderTiles(); + }, [entryTileReceived, occupiedTilesReceived]) + + return ( +
+ ); +} diff --git a/src/views/floorplan-editor/views/FloorplanOptionsView.tsx b/src/views/floorplan-editor/views/FloorplanOptionsView.tsx new file mode 100644 index 00000000..1132bcf6 --- /dev/null +++ b/src/views/floorplan-editor/views/FloorplanOptionsView.tsx @@ -0,0 +1,20 @@ +import { FC } from 'react'; +import { NitroCardGridItemView, NitroCardGridView } from '../../../layout'; +import { useFloorplanEditorContext } from '../context/FloorplanEditorContext'; + +export const FloorplanOptionsView: FC<{}> = props => +{ + const { floorplanSettings = null, setFloorplanSettings = null } = useFloorplanEditorContext(); + + return ( + <> + + + + + + + + + ); +} diff --git a/src/views/main/MainView.tsx b/src/views/main/MainView.tsx index 2a7e1427..7a5eccdd 100644 --- a/src/views/main/MainView.tsx +++ b/src/views/main/MainView.tsx @@ -8,6 +8,7 @@ import { AvatarEditorView } from '../avatar-editor/AvatarEditorView'; import { CameraWidgetView } from '../camera/CameraWidgetView'; import { CatalogView } from '../catalog/CatalogView'; import { ChatHistoryView } from '../chat-history/ChatHistoryView'; +import { FloorplanEditorView } from '../floorplan-editor/FloorplanEditorView'; import { FriendsView } from '../friends/FriendsView'; import { GroupsView } from '../groups/GroupsView'; import { HelpView } from '../help/HelpView'; @@ -73,6 +74,7 @@ export const MainView: FC = props => +
); } diff --git a/src/views/navigator/views/room-info/NavigatorRoomInfoView.tsx b/src/views/navigator/views/room-info/NavigatorRoomInfoView.tsx index f46de29c..f0a9ab42 100644 --- a/src/views/navigator/views/room-info/NavigatorRoomInfoView.tsx +++ b/src/views/navigator/views/room-info/NavigatorRoomInfoView.tsx @@ -3,6 +3,7 @@ import classNames from 'classnames'; import { FC, useCallback, useEffect, useState } from 'react'; import { GetConfiguration, GetGroupInformation, GetSessionDataManager, LocalizeText } from '../../../../api'; import { NavigatorEvent } from '../../../../events'; +import { FloorplanEditorEvent } from '../../../../events/floorplan-editor/FloorplanEditorEvent'; import { RoomWidgetThumbnailEvent } from '../../../../events/room-widgets/thumbnail'; import { dispatchUiEvent } from '../../../../hooks/events'; import { SendMessageHook } from '../../../../hooks/messages'; @@ -98,6 +99,9 @@ export const NavigatorRoomInfoView: FC = props => setIsRoomMuted(value => !value); SendMessageHook(new RoomMuteComposer()); return; + case 'open_floorplan_editor': + dispatchUiEvent(new FloorplanEditorEvent(FloorplanEditorEvent.TOGGLE_FLOORPLAN_EDITOR)); + return; case 'close': onCloseClick(); return; @@ -155,7 +159,7 @@ export const NavigatorRoomInfoView: FC = props => { hasPermission('settings') && <> - + } { hasPermission('staff_pick') && } From 20510ef057924f99545731f6f924caf9d8a54e7d Mon Sep 17 00:00:00 2001 From: dank074 Date: Sun, 31 Oct 2021 23:25:35 -0500 Subject: [PATCH 2/7] changes --- public/ui-config.json | 2 +- .../floorplan-editor/FloorplanEditorView.scss | 83 +++++++++++++------ .../floorplan-editor/FloorplanEditorView.tsx | 16 ++-- .../common/FloorplanEditor.ts | 5 ++ .../views/FloorplanOptionsView.tsx | 71 ++++++++++++++-- 5 files changed, 133 insertions(+), 44 deletions(-) diff --git a/public/ui-config.json b/public/ui-config.json index 6b223dca..1104aa32 100644 --- a/public/ui-config.json +++ b/public/ui-config.json @@ -4,7 +4,7 @@ "camera.url": "https://nitro.nitrots.co/camera", "thumbnails.url": "https://nitro.nitrots.co/camera/thumbnail/%thumbnail%.png", "url.prefix": "http://localhost:3000", - "floorplan.tile.url": "${url.prefix}/floorplan-editor/tiles.json", + "floorplan.tile.url": "${asset.url}/floorplan-editor/tiles.json", "chat.viewer.height.percentage": 0.40, "widget.dimmer.colorwheel": false, "hotelview": { diff --git a/src/views/floorplan-editor/FloorplanEditorView.scss b/src/views/floorplan-editor/FloorplanEditorView.scss index 138d1c09..8cacb9ff 100644 --- a/src/views/floorplan-editor/FloorplanEditorView.scss +++ b/src/views/floorplan-editor/FloorplanEditorView.scss @@ -1,37 +1,70 @@ -.nitro-floorplan-editor -{ +.nitro-floorplan-editor { width: 760px; height: 575px; - .editor-area - { + .editor-area { width: 100%; height: 300px; overflow-x: scroll; } - .set-tile - { - background-image: url('../../assets/images/floorplaneditor/icon-tile-set.png'); + .tile-options { + + .tile-option { + width: 50px; + height: 50px; + + &.set-tile { + background-image: url("../../assets/images/floorplaneditor/icon-tile-set.png"); + } + + &.unset-tile { + background-image: url("../../assets/images/floorplaneditor/icon-tile-unset.png"); + } + + &.increase-height { + background-image: url("../../assets/images/floorplaneditor/icon-tile-up.png"); + } + + &.decrease-height { + background-image: url("../../assets/images/floorplaneditor/icon-tile-down.png"); + } + + &.set-door { + background-image: url("../../assets/images/floorplaneditor/icon-door.png"); + } + } } - .unset-tile - { - background-image: url('../../assets/images/floorplaneditor/icon-tile-unset.png'); - } - - .increase-height - { - background-image: url('../../assets/images/floorplaneditor/icon-tile-up.png'); - } - - .decrease-height - { - background-image: url('../../assets/images/floorplaneditor/icon-tile-down.png'); - } - - .set-door - { - background-image: url('../../assets/images/floorplaneditor/icon-door.png'); + .visualization-options { + .option { + width: 85px; + height: 50px; + + &.door-direction-0 { + background-image: url("../../assets/images/floorplaneditor/door-direction-0.png"); + } + &.door-direction-1 { + background-image: url("../../assets/images/floorplaneditor/door-direction-1.png"); + } + &.door-direction-2 { + background-image: url("../../assets/images/floorplaneditor/door-direction-2.png"); + } + &.door-direction-3 { + background-image: url("../../assets/images/floorplaneditor/door-direction-3.png"); + } + &.door-direction-4 { + background-image: url("../../assets/images/floorplaneditor/door-direction-4.png"); + } + &.door-direction-5 { + background-image: url("../../assets/images/floorplaneditor/door-direction-5.png"); + } + &.door-direction-6 { + background-image: url("../../assets/images/floorplaneditor/door-direction-6.png"); + } + &.door-direction-7 { + background-image: url("../../assets/images/floorplaneditor/door-direction-7.png"); + } + } } } diff --git a/src/views/floorplan-editor/FloorplanEditorView.tsx b/src/views/floorplan-editor/FloorplanEditorView.tsx index dd452c57..4e562b06 100644 --- a/src/views/floorplan-editor/FloorplanEditorView.tsx +++ b/src/views/floorplan-editor/FloorplanEditorView.tsx @@ -89,12 +89,8 @@ export const FloorplanEditorView: FC<{}> = props => {isVisible && setIsVisible(false)} /> - -
-
- -
-
+ +
@@ -102,12 +98,12 @@ export const FloorplanEditorView: FC<{}> = props =>
- +
- - - + + +
diff --git a/src/views/floorplan-editor/common/FloorplanEditor.ts b/src/views/floorplan-editor/common/FloorplanEditor.ts index bdacb553..99cdd12c 100644 --- a/src/views/floorplan-editor/common/FloorplanEditor.ts +++ b/src/views/floorplan-editor/common/FloorplanEditor.ts @@ -400,6 +400,11 @@ export class FloorplanEditor extends PixiApplicationProxy this._doorLocation = value; } + public get actionSettings(): ActionSettings + { + return this._actionSettings; + } + public static get instance(): FloorplanEditor { if(!FloorplanEditor._instance) diff --git a/src/views/floorplan-editor/views/FloorplanOptionsView.tsx b/src/views/floorplan-editor/views/FloorplanOptionsView.tsx index 1132bcf6..7c925e67 100644 --- a/src/views/floorplan-editor/views/FloorplanOptionsView.tsx +++ b/src/views/floorplan-editor/views/FloorplanOptionsView.tsx @@ -1,20 +1,75 @@ -import { FC } from 'react'; +import { FC, useCallback, useState } from 'react'; +import { LocalizeText } from '../../../api'; import { NitroCardGridItemView, NitroCardGridView } from '../../../layout'; +import { FloorAction } from '../common/Constants'; +import { FloorplanEditor } from '../common/FloorplanEditor'; import { useFloorplanEditorContext } from '../context/FloorplanEditorContext'; export const FloorplanOptionsView: FC<{}> = props => { const { floorplanSettings = null, setFloorplanSettings = null } = useFloorplanEditorContext(); + const [ floorAction, setFloorAction ] = useState(FloorAction.SET); + const selectAction = useCallback((action: number) => + { + setFloorAction(action); + FloorplanEditor.instance.actionSettings.currentAction = action; + }, []); + + const changeDoorDirection = useCallback(() => + { + const settings = Object.assign({}, floorplanSettings); + if(settings.entryPointDir < 7) + { + ++settings.entryPointDir; + } + else + { + settings.entryPointDir = 0; + } + + setFloorplanSettings(settings); + }, [floorplanSettings, setFloorplanSettings]); + + const onWallHeightChange = useCallback((value: number) => + { + if(value > 16) value = 16; + if(value < 0) value = 0; + + const settings = Object.assign({}, floorplanSettings); + + settings.wallHeight = value; + + setFloorplanSettings(settings); + }, [floorplanSettings, setFloorplanSettings]); + return ( <> - - - - - - - +
+
+ + + selectAction(FloorAction.SET)} className="tile-option set-tile" /> + selectAction(FloorAction.UNSET)} className="tile-option unset-tile" /> + selectAction(FloorAction.UP)} className="tile-option increase-height" /> + selectAction(FloorAction.DOWN)} className="tile-option decrease-height" /> + selectAction(FloorAction.DOOR)} className="tile-option set-door" /> + +
+
+
+ + +
+
+ + onWallHeightChange(event.target.valueAsNumber)} id="wallHeight"/> +
+
+
+
+ +
); } From c85113dd2c34cb2efd7563c1d0e102910f4e9d0a Mon Sep 17 00:00:00 2001 From: Bill Date: Mon, 1 Nov 2021 23:39:38 -0400 Subject: [PATCH 3/7] Changes --- src/assets/styles/icons.scss | 330 +++++++++++------- src/layout/button/NitroLayoutButton.tsx | 2 +- .../floorplan-editor/FloorplanEditorView.scss | 60 ---- .../floorplan-editor/FloorplanEditorView.tsx | 18 +- .../views/FloorplanOptionsView.tsx | 161 ++++++--- 5 files changed, 331 insertions(+), 240 deletions(-) diff --git a/src/assets/styles/icons.scss b/src/assets/styles/icons.scss index 930c447d..78679240 100644 --- a/src/assets/styles/icons.scss +++ b/src/assets/styles/icons.scss @@ -10,11 +10,11 @@ background-position: center; &.icon-nitro-light { - background-image: url('../images/nitro/nitro-n-light.svg'); + background-image: url("../images/nitro/nitro-n-light.svg"); } &.icon-nitro-dark { - background-image: url('../images/nitro/nitro-n-dark.svg'); + background-image: url("../images/nitro/nitro-n-dark.svg"); } &.icon-nitro-light, @@ -24,693 +24,771 @@ } &.icon-catalog { - background-image: url('../images/toolbar/icons/catalog.png'); + background-image: url("../images/toolbar/icons/catalog.png"); width: 37px; height: 36px; } &.icon-rooms { - background-image: url('../images/toolbar/icons/rooms.png'); + background-image: url("../images/toolbar/icons/rooms.png"); width: 44px; height: 30px; } &.icon-house { - background-image: url('../images/toolbar/icons/house.png'); + background-image: url("../images/toolbar/icons/house.png"); height: 30px; width: 32px; } &.icon-inventory { - background-image: url('../images/toolbar/icons/inventory.png'); + background-image: url("../images/toolbar/icons/inventory.png"); height: 41px; width: 44px; } &.icon-modtools { - background-image: url('../images/toolbar/icons/modtools.png'); + background-image: url("../images/toolbar/icons/modtools.png"); height: 34px; width: 29px; } &.icon-friendall { - background-image: url('../images/toolbar/icons/friend_all.png'); + background-image: url("../images/toolbar/icons/friend_all.png"); height: 33px; width: 32px; } &.icon-friendsearch { - background-image: url('../images/toolbar/icons/friend_search.png'); + background-image: url("../images/toolbar/icons/friend_search.png"); height: 33px; width: 29px; } &.icon-sendmessage { - background-image: url('../images/toolbar/icons/sendmessage.png'); + background-image: url("../images/toolbar/icons/sendmessage.png"); width: 20px; height: 21px; } &.icon-me-talents { - background-image: url('../images/toolbar/icons/me-menu/talents.png'); + background-image: url("../images/toolbar/icons/me-menu/talents.png"); width: 32px; height: 30px; } &.icon-me-helper-tool { - background-image: url('../images/toolbar/icons/me-menu/helper-tool.png'); + background-image: url("../images/toolbar/icons/me-menu/helper-tool.png"); width: 32px; height: 30px; } &.icon-me-profile { - background-image: url('../images/toolbar/icons/me-menu/profile.png'); + background-image: url("../images/toolbar/icons/me-menu/profile.png"); width: 32px; height: 30px; } &.icon-me-forums { - background-image: url('../images/toolbar/icons/me-menu/forums.png'); + background-image: url("../images/toolbar/icons/me-menu/forums.png"); width: 32px; height: 30px; } &.icon-me-rooms { - background-image: url('../images/toolbar/icons/me-menu/my-rooms.png'); + background-image: url("../images/toolbar/icons/me-menu/my-rooms.png"); width: 30px; height: 30px; } &.icon-me-achievements { - background-image: url('../images/toolbar/icons/me-menu/achievements.png'); + background-image: url("../images/toolbar/icons/me-menu/achievements.png"); width: 31px; height: 30px; } &.icon-me-clothing { - background-image: url('../images/toolbar/icons/me-menu/clothing.png'); + background-image: url("../images/toolbar/icons/me-menu/clothing.png"); width: 27px; height: 30px; } &.icon-me-settings { - background-image: url('../images/toolbar/icons/me-menu/cog.png'); + background-image: url("../images/toolbar/icons/me-menu/cog.png"); width: 28px; height: 34px; } &.icon-cog { - background: url('../images/icons/icon_cog.png'); + background: url("../images/icons/icon_cog.png"); width: 14px; height: 15px; } &.icon-help { - background: url('../images/icons/help.png'); + background: url("../images/icons/help.png"); width: 13px; height: 23px; } &.icon-joinroom { - background-image: url('../images/toolbar/icons/joinroom.png'); + background-image: url("../images/toolbar/icons/joinroom.png"); width: 21px; height: 21px; } &.icon-habbo { - background-image: url('../images/toolbar/icons/habbo.png'); + background-image: url("../images/toolbar/icons/habbo.png"); width: 28px; height: 28px; } &.icon-camera { - background-image: url('../images/toolbar/icons/camera.png'); + background-image: url("../images/toolbar/icons/camera.png"); width: 38px; height: 45px; } &.icon-message { - background-image: url('../images/toolbar/icons/message.png'); + background-image: url("../images/toolbar/icons/message.png"); width: 36px; height: 32px; &.is-unseen { - background-image: url('../images/toolbar/icons/message_unsee.gif'); + background-image: url("../images/toolbar/icons/message_unsee.gif"); } } &.icon-deny { - background: url('../images/icons/deny.png'); + background: url("../images/icons/deny.png"); width: 13px; height: 14px; } &.icon-accept { - background: url('../images/icons/accept.png'); + background: url("../images/icons/accept.png"); width: 13px; height: 14px; } &.icon-wired-trigger { - background-image: url('../images/wired/icon_trigger.png'); + background-image: url("../images/wired/icon_trigger.png"); width: 13px; height: 14px; } &.icon-wired-condition { - background-image: url('../images/wired/icon_condition.png'); + background-image: url("../images/wired/icon_condition.png"); width: 13px; height: 14px; } &.icon-wired-action { - background-image: url('../images/wired/icon_action.png'); + background-image: url("../images/wired/icon_action.png"); width: 13px; height: 14px; } &.arrow-left-icon { - background-image: url('../images/avatareditor/arrow-left-icon.png'); + background-image: url("../images/avatareditor/arrow-left-icon.png"); width: 28px; height: 21px; } &.arrow-right-icon { - background-image: url('../images/avatareditor/arrow-right-icon.png'); + background-image: url("../images/avatareditor/arrow-right-icon.png"); width: 28px; height: 21px; } &.clear-icon { - background-image: url('../images/avatareditor/clear-icon.png'); + background-image: url("../images/avatareditor/clear-icon.png"); width: 27px; height: 27px; } &.ca-icon { - background-image: url('../images/avatareditor/ca-icon.png'); + background-image: url("../images/avatareditor/ca-icon.png"); width: 25px; height: 25px; &.selected { - background-image: url('../images/avatareditor/ca-selected-icon.png'); + background-image: url("../images/avatareditor/ca-selected-icon.png"); } } &.cc-icon { - background-image: url('../images/avatareditor/cc-icon.png'); + background-image: url("../images/avatareditor/cc-icon.png"); width: 31px; height: 29px; &.selected { - background-image: url('../images/avatareditor/cc-selected-icon.png'); + background-image: url("../images/avatareditor/cc-selected-icon.png"); } } &.ch-icon { - background-image: url('../images/avatareditor/ch-icon.png'); + background-image: url("../images/avatareditor/ch-icon.png"); width: 29px; height: 24px; &.selected { - background-image: url('../images/avatareditor/ch-selected-icon.png'); + background-image: url("../images/avatareditor/ch-selected-icon.png"); } } &.cp-icon { - background-image: url('../images/avatareditor/cp-icon.png'); + background-image: url("../images/avatareditor/cp-icon.png"); width: 30px; height: 24px; &.selected { - background-image: url('../images/avatareditor/cp-selected-icon.png'); + background-image: url("../images/avatareditor/cp-selected-icon.png"); } } &.ea-icon { - background-image: url('../images/avatareditor/ea-icon.png'); + background-image: url("../images/avatareditor/ea-icon.png"); width: 35px; height: 16px; &.selected { - background-image: url('../images/avatareditor/ea-selected-icon.png'); + background-image: url("../images/avatareditor/ea-selected-icon.png"); } } &.fa-icon { - background-image: url('../images/avatareditor/fa-icon.png'); + background-image: url("../images/avatareditor/fa-icon.png"); width: 27px; height: 20px; &.selected { - background-image: url('../images/avatareditor/fa-selected-icon.png'); + background-image: url("../images/avatareditor/fa-selected-icon.png"); } } &.female-icon { - background-image: url('../images/avatareditor/female-icon.png'); + background-image: url("../images/avatareditor/female-icon.png"); width: 18px; height: 27px; &.selected { - background-image: url('../images/avatareditor/female-selected-icon.png'); + background-image: url("../images/avatareditor/female-selected-icon.png"); } } &.ha-icon { - background-image: url('../images/avatareditor/ha-icon.png'); + background-image: url("../images/avatareditor/ha-icon.png"); width: 25px; height: 22px; &.selected { - background-image: url('../images/avatareditor/ha-selected-icon.png'); + background-image: url("../images/avatareditor/ha-selected-icon.png"); } } &.he-icon { - background-image: url('../images/avatareditor/he-icon.png'); + background-image: url("../images/avatareditor/he-icon.png"); width: 31px; height: 27px; &.selected { - background-image: url('../images/avatareditor/he-selected-icon.png'); + background-image: url("../images/avatareditor/he-selected-icon.png"); } } &.hr-icon { - background-image: url('../images/avatareditor/hr-icon.png'); + background-image: url("../images/avatareditor/hr-icon.png"); width: 29px; height: 25px; &.selected { - background-image: url('../images/avatareditor/hr-selected-icon.png'); + background-image: url("../images/avatareditor/hr-selected-icon.png"); } } &.lg-icon { - background-image: url('../images/avatareditor/lg-icon.png'); + background-image: url("../images/avatareditor/lg-icon.png"); width: 19px; height: 20px; &.selected { - background-image: url('../images/avatareditor/lg-selected-icon.png'); + background-image: url("../images/avatareditor/lg-selected-icon.png"); } } &.loading-icon { - background-image: url('../images/icons/loading-icon.png'); + background-image: url("../images/icons/loading-icon.png"); width: 17px; height: 21px; } &.male-icon { - background-image: url('../images/avatareditor/male-icon.png'); + background-image: url("../images/avatareditor/male-icon.png"); width: 21px; height: 21px; &.selected { - background-image: url('../images/avatareditor/male-selected-icon.png'); + background-image: url("../images/avatareditor/male-selected-icon.png"); } } &.sh-icon { - background-image: url('../images/avatareditor/sh-icon.png'); + background-image: url("../images/avatareditor/sh-icon.png"); width: 37px; height: 10px; &.selected { - background-image: url('../images/avatareditor/sh-selected-icon.png'); + background-image: url("../images/avatareditor/sh-selected-icon.png"); } } &.wa-icon { - background-image: url('../images/avatareditor/wa-icon.png'); + background-image: url("../images/avatareditor/wa-icon.png"); width: 36px; height: 18px; &.selected { - background-image: url('../images/avatareditor/wa-selected-icon.png'); + background-image: url("../images/avatareditor/wa-selected-icon.png"); } } &.sellable-icon { - background-image: url('../images/avatareditor/sellable-icon.png'); + background-image: url("../images/avatareditor/sellable-icon.png"); width: 17px; height: 15px; } &.chatstyles-icon { - background-image: url('../images/chat/styles-icon.png'); + background-image: url("../images/chat/styles-icon.png"); width: 17px; height: 19px; } &.pencil-icon { - background-image: url('../images/infostand/pencil-icon.png'); + background-image: url("../images/infostand/pencil-icon.png"); width: 17px; height: 18px; } &.trade-locked-icon { - background-image: url('../images/inventory/trading/locked-icon.png'); + background-image: url("../images/inventory/trading/locked-icon.png"); width: 29px; height: 43px; } &.trade-unlocked-icon { - background-image: url('../images/inventory/trading/unlocked-icon.png'); + background-image: url("../images/inventory/trading/unlocked-icon.png"); width: 29px; height: 43px; } &.modtool-room-icon { - background-image: url('../images/modtool/room.png'); + background-image: url("../images/modtool/room.png"); width: 20px; height: 15px; } &.modtool-chatlog-icon { - background-image: url('../images/modtool/chatlog.gif'); + background-image: url("../images/modtool/chatlog.gif"); width: 20px; height: 15px; } - &.modtool-user-icon{ - background-image: url('../images/modtool/user.gif'); + &.modtool-user-icon { + background-image: url("../images/modtool/user.gif"); width: 20px; height: 15px; } &.modtool-reports-icon { - background-image: url('../images/modtool/reports.png'); + background-image: url("../images/modtool/reports.png"); width: 20px; height: 15px; } &.modtool-wrench-icon { - background-image: url('../images/modtool/wrench.gif'); + background-image: url("../images/modtool/wrench.gif"); width: 20px; height: 15px; } &.modtool-key-icon { - background-image: url('../images/modtool/key.gif'); + background-image: url("../images/modtool/key.gif"); width: 20px; height: 15px; } &.icon-catalogue-hc_small { - background-image: url('../images/catalog/hc_small.png'); + background-image: url("../images/catalog/hc_small.png"); height: 17px; width: 31px; } &.icon-catalogue-hc_big { - background: url('../images/catalog/hc_big.png'); + background: url("../images/catalog/hc_big.png"); width: 68px; height: 40px; } &.icon-sign-exclamation { - background: url('../images/icons/sign-exclamation.png'); + background: url("../images/icons/sign-exclamation.png"); width: 7px; height: 17px; } &.icon-sign-heart { - background: url('../images/icons/sign-heart.png'); + background: url("../images/icons/sign-heart.png"); width: 15px; height: 13px; } &.icon-sign-red { - background: url('../images/icons/sign-red.png'); + background: url("../images/icons/sign-red.png"); width: 11px; height: 19px; } &.icon-sign-yellow { - background: url('../images/icons/sign-yellow.png'); + background: url("../images/icons/sign-yellow.png"); width: 11px; height: 19px; } &.icon-sign-skull { - background: url('../images/icons/sign-skull.png'); + background: url("../images/icons/sign-skull.png"); width: 12px; height: 12px; } &.icon-sign-smile { - background: url('../images/icons/sign-smile.png'); + background: url("../images/icons/sign-smile.png"); width: 7px; height: 14px; } - + &.icon-sign-soccer { - background: url('../images/icons/sign-soccer.png'); + background: url("../images/icons/sign-soccer.png"); width: 20px; height: 20px; } - + &.icon-house-small { - background: url('../images/icons/house-small.png'); + background: url("../images/icons/house-small.png"); width: 19px; height: 14px; } &.icon-camera-small { - background: url('../images/icons/camera-small.png'); + background: url("../images/icons/camera-small.png"); width: 17px; height: 15px; } &.icon-arrows { - background: url('../images/icons/arrows.png'); + background: url("../images/icons/arrows.png"); width: 17px; height: 15px; } - + &.icon-fb-profile { - background: url('../images/toolbar/icons/friend-bar/profile.png'); + background: url("../images/toolbar/icons/friend-bar/profile.png"); width: 21px; height: 21px; } &.icon-camera-colormatrix { - background: url('../images/icons/camera-colormatrix.png'); + background: url("../images/icons/camera-colormatrix.png"); width: 32px; height: 21px; } &.icon-camera-composite { - background: url('../images/icons/camera-composite.png'); + background: url("../images/icons/camera-composite.png"); width: 32px; height: 21px; } &.icon-user-profile { - background: url('../images/icons/user-profile.png'); + background: url("../images/icons/user-profile.png"); width: 13px; height: 11px; &:hover { - background: url('../images/icons/user-profile-hover.png'); + background: url("../images/icons/user-profile-hover.png"); } } &.icon-fb-profile { - background: url('../images/toolbar/icons/friend-bar/profile.png'); + background: url("../images/toolbar/icons/friend-bar/profile.png"); width: 21px; height: 21px; } &.icon-fb-chat { - background: url('../images/toolbar/icons/friend-bar/chat.png'); + background: url("../images/toolbar/icons/friend-bar/chat.png"); width: 20px; height: 21px; } &.icon-fb-visit { - background: url('../images/toolbar/icons/friend-bar/visit.png'); + background: url("../images/toolbar/icons/friend-bar/visit.png"); width: 21px; height: 21px; } &.icon-pf-online { - background: url('../images/profile/icons/online.gif'); + background: url("../images/profile/icons/online.gif"); width: 40px; height: 16px; } &.icon-pf-offline { - background: url('../images/profile/icons/offline.png'); + background: url("../images/profile/icons/offline.png"); width: 39px; height: 16px; } &.icon-pf-tick { - background: url('../images/profile/icons/tick.png'); + background: url("../images/profile/icons/tick.png"); width: 11px; height: 10px; } &.icon-relationship-none { - background: url('../images/friendlist/icons/icon_relationship_none.png'); + background: url("../images/friendlist/icons/icon_relationship_none.png"); width: 16px; height: 14px; } &.icon-relationship-heart { - background: url('../images/profile/icons/heart.png'); + background: url("../images/profile/icons/heart.png"); width: 16px; height: 14px; } &.icon-relationship-bobba { - background: url('../images/profile/icons/bobba.png'); + background: url("../images/profile/icons/bobba.png"); width: 16px; height: 14px; } &.icon-relationship-smile { - background: url('../images/profile/icons/smile.png'); + background: url("../images/profile/icons/smile.png"); width: 16px; height: 14px; } &.icon-group-type-0 { - background: url('../images/groups/icons/grouptype_icon_0.png'); + background: url("../images/groups/icons/grouptype_icon_0.png"); width: 16px; height: 16px; } &.icon-group-type-1 { - background: url('../images/groups/icons/grouptype_icon_1.png'); + background: url("../images/groups/icons/grouptype_icon_1.png"); width: 16px; height: 16px; } &.icon-group-type-2 { - background: url('../images/groups/icons/grouptype_icon_2.png'); + background: url("../images/groups/icons/grouptype_icon_2.png"); width: 16px; height: 16px; } &.icon-group-decorate { - background: url('../images/groups/icons/group_decorate_icon.png'); + background: url("../images/groups/icons/group_decorate_icon.png"); width: 15px; height: 15px; } &.icon-group-member { - background: url('../images/groups/icons/group_icon_big_member.png'); + background: url("../images/groups/icons/group_icon_big_member.png"); width: 20px; height: 20px; } &.icon-group-admin { - background: url('../images/groups/icons/group_icon_big_admin.png'); + background: url("../images/groups/icons/group_icon_big_admin.png"); width: 20px; height: 20px; } &.icon-group-owner { - background: url('../images/groups/icons/group_icon_big_owner.png'); + background: url("../images/groups/icons/group_icon_big_owner.png"); width: 20px; height: 20px; } &.icon-group-favorite { - background: url('../images/groups/icons/group_favorite.png'); + background: url("../images/groups/icons/group_favorite.png"); width: 14px; height: 14px; } &.icon-group-not-favorite { - background: url('../images/groups/icons/group_notfavorite.png'); + background: url("../images/groups/icons/group_notfavorite.png"); width: 14px; height: 14px; } &.icon-group-small-admin { - background: url('../images/groups/icons/group_icon_admin.png'); + background: url("../images/groups/icons/group_icon_admin.png"); width: 11px; height: 13px; } &.icon-group-small-not-admin { - background: url('../images/groups/icons/group_icon_not_admin.png'); + background: url("../images/groups/icons/group_icon_not_admin.png"); width: 11px; height: 13px; } &.icon-group-small-owner { - background: url('../images/groups/icons/group_icon_small_owner.png'); + background: url("../images/groups/icons/group_icon_small_owner.png"); width: 13px; height: 13px; } &.icon-navigator-info { - background: url('../images/navigator/icons/info.png'); + background: url("../images/navigator/icons/info.png"); width: 18px; height: 18px; } &.icon-navigator-room-locked { - background: url('../images/navigator/icons/room_locked.png'); + background: url("../images/navigator/icons/room_locked.png"); width: 13px; height: 16px; } &.icon-navigator-room-password { - background: url('../images/navigator/icons/room_password.png'); + background: url("../images/navigator/icons/room_password.png"); width: 13px; height: 16px; } &.icon-navigator-room-invisible { - background: url('../images/navigator/icons/room_invisible.png'); + background: url("../images/navigator/icons/room_invisible.png"); width: 13px; height: 16px; } &.icon-navigator-room-group { - background: url('../images/navigator/icons/room_group.png'); + background: url("../images/navigator/icons/room_group.png"); width: 13px; height: 11px; } &.icon-friendlist-follow { - background: url('../images/friendlist/icons/icon_follow.png'); + background: url("../images/friendlist/icons/icon_follow.png"); width: 16px; height: 14px; } &.icon-friendlist-chat { - background: url('../images/friendlist/icons/icon_chat.png'); + background: url("../images/friendlist/icons/icon_chat.png"); width: 17px; height: 16px; } &.icon-friendlist-warning { - background: url('../images/friendlist/icons/icon_warning.png'); + background: url("../images/friendlist/icons/icon_warning.png"); width: 23px; height: 21px; } &.icon-friendlist-new-message { - background: url('../images/friendlist/icons/icon_new_message.png'); + background: url("../images/friendlist/icons/icon_new_message.png"); width: 14px; height: 16px; } &.icon-hc-banner { - background: url('../images/catalog/hc_big.png'); + background: url("../images/catalog/hc_big.png"); width: 68px; height: 40px; } + &.icon-set-tile { + background-image: url("../images/floorplaneditor/icon-tile-set.png"); + width: 40px; + height: 40px; + } + + &.icon-unset-tile { + background-image: url("../images/floorplaneditor/icon-tile-unset.png"); + width: 40px; + height: 40px; + } + + &.icon-increase-height { + background-image: url("../images/floorplaneditor/icon-tile-up.png"); + width: 40px; + height: 40px; + } + + &.icon-decrease-height { + background-image: url("../images/floorplaneditor/icon-tile-down.png"); + width: 40px; + height: 40px; + } + + &.icon-set-door { + background-image: url("../images/floorplaneditor/icon-door.png"); + width: 40px; + height: 40px; + } + + &.icon-door-direction-0 { + background-image: url("../images/floorplaneditor/door-direction-0.png"); + width: 80px; + height: 45px; + } + + &.icon-door-direction-1 { + background-image: url("../images/floorplaneditor/door-direction-1.png"); + width: 80px; + height: 45px; + } + + &.icon-door-direction-2 { + background-image: url("../images/floorplaneditor/door-direction-2.png"); + width: 80px; + height: 45px; + } + + &.icon-door-direction-3 { + background-image: url("../images/floorplaneditor/door-direction-3.png"); + width: 80px; + height: 45px; + } + + &.icon-door-direction-4 { + background-image: url("../images/floorplaneditor/door-direction-4.png"); + width: 80px; + height: 45px; + } + + &.icon-door-direction-5 { + background-image: url("../images/floorplaneditor/door-direction-5.png"); + width: 80px; + height: 45px; + } + + &.icon-door-direction-6 { + background-image: url("../images/floorplaneditor/door-direction-6.png"); + width: 80px; + height: 45px; + } + + &.icon-door-direction-7 { + background-image: url("../images/floorplaneditor/door-direction-7.png"); + width: 80px; + height: 45px; + } + &.spin { animation: rotating 1s linear infinite; } diff --git a/src/layout/button/NitroLayoutButton.tsx b/src/layout/button/NitroLayoutButton.tsx index 0b66a3d0..68ea060f 100644 --- a/src/layout/button/NitroLayoutButton.tsx +++ b/src/layout/button/NitroLayoutButton.tsx @@ -7,7 +7,7 @@ export const NitroLayoutButton: FC = props => const getClassName = useMemo(() => { - let newClassName = 'btn'; + let newClassName = 'd-flex justify-content-center align-items-center btn'; if(variant && variant.length) newClassName += ` btn-${ variant }`; diff --git a/src/views/floorplan-editor/FloorplanEditorView.scss b/src/views/floorplan-editor/FloorplanEditorView.scss index 8cacb9ff..356af6d1 100644 --- a/src/views/floorplan-editor/FloorplanEditorView.scss +++ b/src/views/floorplan-editor/FloorplanEditorView.scss @@ -7,64 +7,4 @@ height: 300px; overflow-x: scroll; } - - .tile-options { - - .tile-option { - width: 50px; - height: 50px; - - &.set-tile { - background-image: url("../../assets/images/floorplaneditor/icon-tile-set.png"); - } - - &.unset-tile { - background-image: url("../../assets/images/floorplaneditor/icon-tile-unset.png"); - } - - &.increase-height { - background-image: url("../../assets/images/floorplaneditor/icon-tile-up.png"); - } - - &.decrease-height { - background-image: url("../../assets/images/floorplaneditor/icon-tile-down.png"); - } - - &.set-door { - background-image: url("../../assets/images/floorplaneditor/icon-door.png"); - } - } - } - - .visualization-options { - .option { - width: 85px; - height: 50px; - - &.door-direction-0 { - background-image: url("../../assets/images/floorplaneditor/door-direction-0.png"); - } - &.door-direction-1 { - background-image: url("../../assets/images/floorplaneditor/door-direction-1.png"); - } - &.door-direction-2 { - background-image: url("../../assets/images/floorplaneditor/door-direction-2.png"); - } - &.door-direction-3 { - background-image: url("../../assets/images/floorplaneditor/door-direction-3.png"); - } - &.door-direction-4 { - background-image: url("../../assets/images/floorplaneditor/door-direction-4.png"); - } - &.door-direction-5 { - background-image: url("../../assets/images/floorplaneditor/door-direction-5.png"); - } - &.door-direction-6 { - background-image: url("../../assets/images/floorplaneditor/door-direction-6.png"); - } - &.door-direction-7 { - background-image: url("../../assets/images/floorplaneditor/door-direction-7.png"); - } - } - } } diff --git a/src/views/floorplan-editor/FloorplanEditorView.tsx b/src/views/floorplan-editor/FloorplanEditorView.tsx index 4e562b06..49c7dddd 100644 --- a/src/views/floorplan-editor/FloorplanEditorView.tsx +++ b/src/views/floorplan-editor/FloorplanEditorView.tsx @@ -3,7 +3,7 @@ import { FC, useCallback, useEffect, useState } from 'react'; import { LocalizeText } from '../../api'; import { FloorplanEditorEvent } from '../../events/floorplan-editor/FloorplanEditorEvent'; import { CreateMessageHook, SendMessageHook, useUiEvent } from '../../hooks'; -import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../layout'; +import { NitroCardContentView, NitroCardHeaderView, NitroCardView, NitroLayoutGrid, NitroLayoutGridColumn } from '../../layout'; import { FloorplanEditor } from './common/FloorplanEditor'; import { convertNumbersForSaving, convertSettingToNumber } from './common/Utils'; import { FloorplanEditorContextProvider } from './context/FloorplanEditorContext'; @@ -89,14 +89,14 @@ export const FloorplanEditorView: FC<{}> = props => {isVisible && setIsVisible(false)} /> - - -
-
+ + + + -
-
-
+ + + {/*
@@ -105,7 +105,7 @@ export const FloorplanEditorView: FC<{}> = props =>
-
+
*/}
} diff --git a/src/views/floorplan-editor/views/FloorplanOptionsView.tsx b/src/views/floorplan-editor/views/FloorplanOptionsView.tsx index 7c925e67..e15229cc 100644 --- a/src/views/floorplan-editor/views/FloorplanOptionsView.tsx +++ b/src/views/floorplan-editor/views/FloorplanOptionsView.tsx @@ -1,10 +1,14 @@ import { FC, useCallback, useState } from 'react'; import { LocalizeText } from '../../../api'; -import { NitroCardGridItemView, NitroCardGridView } from '../../../layout'; +import { NitroCardGridItemView, NitroCardGridView, NitroLayoutFlex, NitroLayoutFlexColumn, NitroLayoutGrid, NitroLayoutGridColumn } from '../../../layout'; +import { NitroLayoutBase } from '../../../layout/base'; import { FloorAction } from '../common/Constants'; import { FloorplanEditor } from '../common/FloorplanEditor'; import { useFloorplanEditorContext } from '../context/FloorplanEditorContext'; +const MIN_WALL_HEIGHT: number = 0; +const MAX_WALL_HEIGHT: number = 16; + export const FloorplanOptionsView: FC<{}> = props => { const { floorplanSettings = null, setFloorplanSettings = null } = useFloorplanEditorContext(); @@ -18,58 +22,127 @@ export const FloorplanOptionsView: FC<{}> = props => const changeDoorDirection = useCallback(() => { - const settings = Object.assign({}, floorplanSettings); - if(settings.entryPointDir < 7) - { - ++settings.entryPointDir; - } - else - { - settings.entryPointDir = 0; - } + setFloorplanSettings(prevValue => + { + const newValue = Object.assign({}, prevValue); - setFloorplanSettings(settings); - }, [floorplanSettings, setFloorplanSettings]); + if(newValue.entryPointDir < 7) + { + ++newValue.entryPointDir; + } + else + { + newValue.entryPointDir = 0; + } + + return newValue; + }); + }, [ setFloorplanSettings ]); const onWallHeightChange = useCallback((value: number) => { - if(value > 16) value = 16; - if(value < 0) value = 0; + if(isNaN(value) || (value <= 0)) value = MIN_WALL_HEIGHT; - const settings = Object.assign({}, floorplanSettings); + if(value > MAX_WALL_HEIGHT) value = MAX_WALL_HEIGHT; - settings.wallHeight = value; + setFloorplanSettings(prevValue => + { + const newValue = Object.assign({}, prevValue); - setFloorplanSettings(settings); - }, [floorplanSettings, setFloorplanSettings]); + newValue.wallHeight = value; + + return newValue; + }); + }, [ setFloorplanSettings ]); + + function increaseWallHeight(): void + { + let height = (floorplanSettings.wallHeight + 1); + + if(height > MAX_WALL_HEIGHT) height = MAX_WALL_HEIGHT; + + onWallHeightChange(height); + } + + function decreaseWallHeight(): void + { + let height = (floorplanSettings.wallHeight - 1); + + if(height <= 0) height = MIN_WALL_HEIGHT; + + onWallHeightChange(height); + } return ( - <> -
-
- - - selectAction(FloorAction.SET)} className="tile-option set-tile" /> - selectAction(FloorAction.UNSET)} className="tile-option unset-tile" /> - selectAction(FloorAction.UP)} className="tile-option increase-height" /> - selectAction(FloorAction.DOWN)} className="tile-option decrease-height" /> - selectAction(FloorAction.DOOR)} className="tile-option set-door" /> - -
-
-
- - -
-
- - onWallHeightChange(event.target.valueAsNumber)} id="wallHeight"/> -
-
-
-
+ + + + { LocalizeText('floor.plan.editor.draw.mode') } + + selectAction(FloorAction.SET) }> + + + selectAction(FloorAction.UNSET) }> + + + selectAction(FloorAction.UP) }> + + + selectAction(FloorAction.DOWN) }> + + + selectAction(FloorAction.DOOR) }> + + + + + + + + { LocalizeText('floor.plan.editor.enter.direction') } + + + + + + { LocalizeText('floor.editor.wall.height') } + + + onWallHeightChange(event.target.valueAsNumber)} /> + + + + + + // + // + // + // <> + //
+ //
+ // + // + // selectAction(FloorAction.SET)} className="tile-option set-tile" /> + // selectAction(FloorAction.UNSET)} className="tile-option unset-tile" /> + // selectAction(FloorAction.UP)} className="tile-option increase-height" /> + // selectAction(FloorAction.DOWN)} className="tile-option decrease-height" /> + // selectAction(FloorAction.DOOR)} className="tile-option set-door" /> + // + //
+ //
+ //
+ // + // + //
+ //
+ // + // onWallHeightChange(event.target.valueAsNumber)} id="wallHeight"/> + //
+ //
+ //
+ //
-
- + //
+ // ); } From ee060670dc0b3c53105dd972a97392217f1b692f Mon Sep 17 00:00:00 2001 From: dank074 Date: Tue, 2 Nov 2021 18:38:31 -0500 Subject: [PATCH 4/7] add import/export --- .../floorplan-editor/FloorplanEditorView.scss | 11 ++ .../floorplan-editor/FloorplanEditorView.tsx | 116 +++++++++++------ .../floorplan-editor/common/Constants.ts | 31 +++++ .../context/FloorplanEditorContext.tsx | 6 +- .../context/FloorplanEditorContext.types.ts | 11 +- .../views/FloorplanCanvasView.tsx | 25 ++-- .../views/FloorplanImportExportView.tsx | 68 ++++++++++ .../views/FloorplanOptionsView.tsx | 122 ++++++++++++------ 8 files changed, 291 insertions(+), 99 deletions(-) create mode 100644 src/views/floorplan-editor/views/FloorplanImportExportView.tsx diff --git a/src/views/floorplan-editor/FloorplanEditorView.scss b/src/views/floorplan-editor/FloorplanEditorView.scss index 356af6d1..b11b5107 100644 --- a/src/views/floorplan-editor/FloorplanEditorView.scss +++ b/src/views/floorplan-editor/FloorplanEditorView.scss @@ -5,6 +5,17 @@ .editor-area { width: 100%; height: 300px; + min-height: 300px; overflow-x: scroll; } + + .color { + height: 50px; + width: 10px; + } +} + +.floorplan-import-export { + width: 500px; + height: 475px; } diff --git a/src/views/floorplan-editor/FloorplanEditorView.tsx b/src/views/floorplan-editor/FloorplanEditorView.tsx index 49c7dddd..6006e8c1 100644 --- a/src/views/floorplan-editor/FloorplanEditorView.tsx +++ b/src/views/floorplan-editor/FloorplanEditorView.tsx @@ -1,20 +1,29 @@ -import { FloorHeightMapEvent, RoomVisualizationSettingsEvent, UpdateFloorPropertiesMessageComposer } from '@nitrots/nitro-renderer'; +import { FloorHeightMapEvent, NitroPoint, RoomVisualizationSettingsEvent, UpdateFloorPropertiesMessageComposer } from '@nitrots/nitro-renderer'; import { FC, useCallback, useEffect, useState } from 'react'; import { LocalizeText } from '../../api'; import { FloorplanEditorEvent } from '../../events/floorplan-editor/FloorplanEditorEvent'; import { CreateMessageHook, SendMessageHook, useUiEvent } from '../../hooks'; -import { NitroCardContentView, NitroCardHeaderView, NitroCardView, NitroLayoutGrid, NitroLayoutGridColumn } from '../../layout'; +import { NitroCardContentView, NitroCardHeaderView, NitroCardView, NitroLayoutFlex, NitroLayoutGrid, NitroLayoutGridColumn } from '../../layout'; import { FloorplanEditor } from './common/FloorplanEditor'; import { convertNumbersForSaving, convertSettingToNumber } from './common/Utils'; import { FloorplanEditorContextProvider } from './context/FloorplanEditorContext'; -import { IFloorplanSettings, initialFloorplanSettings } from './context/FloorplanEditorContext.types'; +import { IFloorplanSettings, initialFloorplanSettings, IVisualizationSettings } from './context/FloorplanEditorContext.types'; import { FloorplanCanvasView } from './views/FloorplanCanvasView'; +import { FloorplanImportExportView } from './views/FloorplanImportExportView'; import { FloorplanOptionsView } from './views/FloorplanOptionsView'; export const FloorplanEditorView: FC<{}> = props => { const [isVisible, setIsVisible] = useState(false); - const [floorplanSettings, setFloorplanSettings ] = useState(initialFloorplanSettings); + const [ importExportVisible, setImportExportVisible ] = useState(false); + const [originalFloorplanSettings, setOriginalFloorplanSettings] = useState(initialFloorplanSettings); + const [visualizationSettings, setVisualizationSettings] = useState( + { + entryPointDir: 2, + wallHeight: -1, + thicknessWall: 1, + thicknessFloor: 1 + }); const onFloorplanEditorEvent = useCallback((event: FloorplanEditorEvent) => { @@ -47,11 +56,16 @@ export const FloorplanEditorView: FC<{}> = props => if(!parser) return; - const settings = Object.assign({}, floorplanSettings); + const settings = Object.assign({}, originalFloorplanSettings); settings.tilemap = parser.model; settings.wallHeight = parser.wallHeight + 1; - setFloorplanSettings(settings); - }, [floorplanSettings]); + setOriginalFloorplanSettings(settings); + + const vSettings = Object.assign({}, visualizationSettings); + vSettings.wallHeight = parser.wallHeight + 1; + setVisualizationSettings(vSettings); + + }, [originalFloorplanSettings, visualizationSettings]); CreateMessageHook(FloorHeightMapEvent, onFloorHeightMapEvent); @@ -61,12 +75,17 @@ export const FloorplanEditorView: FC<{}> = props => if(!parser) return; - const settings = Object.assign({}, floorplanSettings); - settings.thicknessFloor = convertSettingToNumber(parser.thicknessFloor) + const settings = Object.assign({}, originalFloorplanSettings); + settings.thicknessFloor = convertSettingToNumber(parser.thicknessFloor); settings.thicknessWall = convertSettingToNumber(parser.thicknessWall); - setFloorplanSettings(settings); - }, [floorplanSettings]); + setOriginalFloorplanSettings(settings); + + const vSettings = Object.assign({}, visualizationSettings); + vSettings.thicknessFloor = convertSettingToNumber(parser.thicknessFloor); + vSettings.thicknessWall = convertSettingToNumber(parser.thicknessWall); + setVisualizationSettings(vSettings); + }, [originalFloorplanSettings, visualizationSettings]); CreateMessageHook(RoomVisualizationSettingsEvent, onRoomVisualizationSettingsEvent); @@ -74,42 +93,53 @@ export const FloorplanEditorView: FC<{}> = props => { SendMessageHook(new UpdateFloorPropertiesMessageComposer( FloorplanEditor.instance.getCurrentTilemapString(), - floorplanSettings.entryPoint[0], - floorplanSettings.entryPoint[1], - floorplanSettings.entryPointDir, - convertNumbersForSaving(floorplanSettings.thicknessWall), - convertNumbersForSaving(floorplanSettings.thicknessFloor), - floorplanSettings.wallHeight - 1 + FloorplanEditor.instance.doorLocation.x, + FloorplanEditor.instance.doorLocation.y, + visualizationSettings.entryPointDir, + convertNumbersForSaving(visualizationSettings.thicknessWall), + convertNumbersForSaving(visualizationSettings.thicknessFloor), + visualizationSettings.wallHeight - 1 )); - }, [floorplanSettings.entryPoint, floorplanSettings.entryPointDir, floorplanSettings.thicknessFloor, floorplanSettings.thicknessWall, floorplanSettings.wallHeight]); + }, [visualizationSettings.entryPointDir, visualizationSettings.thicknessFloor, visualizationSettings.thicknessWall, visualizationSettings.wallHeight]); + + const revertChanges = useCallback(() => + { + setVisualizationSettings({ wallHeight: originalFloorplanSettings.wallHeight, thicknessWall: originalFloorplanSettings.thicknessWall, thicknessFloor: originalFloorplanSettings.thicknessFloor, entryPointDir: originalFloorplanSettings.entryPointDir }); + + FloorplanEditor.instance.doorLocation = new NitroPoint(originalFloorplanSettings.entryPoint[0], originalFloorplanSettings.entryPoint[1]); + FloorplanEditor.instance.setTilemap(originalFloorplanSettings.tilemap, originalFloorplanSettings.reservedTiles); + FloorplanEditor.instance.renderTiles(); + }, [originalFloorplanSettings.entryPoint, originalFloorplanSettings.entryPointDir, originalFloorplanSettings.reservedTiles, originalFloorplanSettings.thicknessFloor, originalFloorplanSettings.thicknessWall, originalFloorplanSettings.tilemap, originalFloorplanSettings.wallHeight]) return ( <> - - {isVisible && - - setIsVisible(false)} /> - - - - - - - - {/*
-
- -
-
- - - -
-
*/} -
-
- } -
+ + {isVisible && <> + + setIsVisible(false)} /> + + + + + + +
+ +
+
+ + + +
+
+
+
+
+
+ {importExportVisible && setImportExportVisible(false)}/>} + + } +
); } diff --git a/src/views/floorplan-editor/common/Constants.ts b/src/views/floorplan-editor/common/Constants.ts index 717f40d0..8f52f282 100644 --- a/src/views/floorplan-editor/common/Constants.ts +++ b/src/views/floorplan-editor/common/Constants.ts @@ -11,3 +11,34 @@ export class FloorAction public static readonly SET = 3; public static readonly UNSET = 4; } + +export const COLORMAP: object = { + 'x': '101010', + '0': '0065ff', + '1': '0091ff', + '2': '00bcff', + '3': '00e8ff', + '4': '00ffea', + '5': '00ffbf', + '6': '00ff93', + '7': '00ff68', + '8': '00ff3d', + '9': '19ff00', + 'a': '44ff00', + 'b': '70ff00', + 'c': '9bff00', + 'd': 'f2ff00', + 'e': 'ffe000', + 'f': 'ffb500', + 'g': 'ff8900', + 'h': 'ff5e00', + 'i': 'ff3200', + 'j': 'ff0700', + 'k': 'ff0023', + 'l': 'ff007a', + 'm': 'ff00a5', + 'n': 'ff00d1', + 'o': 'ff00fc', + 'p': 'd600ff', + 'q': 'aa00ff' +}; diff --git a/src/views/floorplan-editor/context/FloorplanEditorContext.tsx b/src/views/floorplan-editor/context/FloorplanEditorContext.tsx index 613c6fe6..8a8ce970 100644 --- a/src/views/floorplan-editor/context/FloorplanEditorContext.tsx +++ b/src/views/floorplan-editor/context/FloorplanEditorContext.tsx @@ -2,8 +2,10 @@ import { createContext, FC, useContext } from 'react'; import { FloorplanEditorContextProps, IFloorplanEditorContext } from './FloorplanEditorContext.types'; const FloorplanEditorContext = createContext({ - floorplanSettings: null, - setFloorplanSettings: null + originalFloorplanSettings: null, + setOriginalFloorplanSettings: null, + visualizationSettings: null, + setVisualizationSettings: null }); export const FloorplanEditorContextProvider: FC = props => diff --git a/src/views/floorplan-editor/context/FloorplanEditorContext.types.ts b/src/views/floorplan-editor/context/FloorplanEditorContext.types.ts index c6d8eb66..581ff6af 100644 --- a/src/views/floorplan-editor/context/FloorplanEditorContext.types.ts +++ b/src/views/floorplan-editor/context/FloorplanEditorContext.types.ts @@ -2,14 +2,19 @@ import { ProviderProps } from 'react'; export interface IFloorplanEditorContext { - floorplanSettings: IFloorplanSettings; - setFloorplanSettings: React.Dispatch>; + originalFloorplanSettings: IFloorplanSettings; + setOriginalFloorplanSettings: React.Dispatch>; + visualizationSettings: IVisualizationSettings; + setVisualizationSettings: React.Dispatch>; } -export interface IFloorplanSettings { +export interface IFloorplanSettings extends IVisualizationSettings { tilemap: string; reservedTiles: boolean[][]; entryPoint: [number, number]; +} + +export interface IVisualizationSettings { entryPointDir: number; wallHeight: number; thicknessWall: number; diff --git a/src/views/floorplan-editor/views/FloorplanCanvasView.tsx b/src/views/floorplan-editor/views/FloorplanCanvasView.tsx index a6f9969c..f9640a2c 100644 --- a/src/views/floorplan-editor/views/FloorplanCanvasView.tsx +++ b/src/views/floorplan-editor/views/FloorplanCanvasView.tsx @@ -6,7 +6,7 @@ import { useFloorplanEditorContext } from '../context/FloorplanEditorContext'; export const FloorplanCanvasView: FC<{}> = props => { - const { floorplanSettings = null, setFloorplanSettings = null } = useFloorplanEditorContext(); + const { originalFloorplanSettings = null, setOriginalFloorplanSettings = null, visualizationSettings = null, setVisualizationSettings = null } = useFloorplanEditorContext(); const [ occupiedTilesReceived , setOccupiedTilesReceived ] = useState(false); const [ entryTileReceived, setEntryTileReceived ] = useState(false); const elementRef = useRef(null); @@ -21,8 +21,9 @@ export const FloorplanCanvasView: FC<{}> = props => return ( () => { FloorplanEditor.instance.clear(); + setVisualizationSettings( prev => {return { wallHeight: originalFloorplanSettings.wallHeight, thicknessWall: originalFloorplanSettings.thicknessWall, thicknessFloor: originalFloorplanSettings.thicknessFloor, entryPointDir: prev.entryPointDir } }); }); - }, []); + }, [originalFloorplanSettings.thicknessFloor, originalFloorplanSettings.thicknessWall, originalFloorplanSettings.wallHeight, setVisualizationSettings]); const onRoomOccupiedTilesMessageEvent = useCallback((event: RoomOccupiedTilesMessageEvent) => { @@ -30,16 +31,16 @@ export const FloorplanCanvasView: FC<{}> = props => if(!parser) return; - const settings = Object.assign({}, floorplanSettings); + const settings = Object.assign({}, originalFloorplanSettings); settings.reservedTiles = parser.blockedTilesMap; - setFloorplanSettings(settings); + setOriginalFloorplanSettings(settings); - FloorplanEditor.instance.setTilemap(floorplanSettings.tilemap, parser.blockedTilesMap); + FloorplanEditor.instance.setTilemap(originalFloorplanSettings.tilemap, parser.blockedTilesMap); setOccupiedTilesReceived(true); elementRef.current.scrollTo(FloorplanEditor.instance.view.width / 3, 0); - }, [floorplanSettings, setFloorplanSettings]); + }, [originalFloorplanSettings, setOriginalFloorplanSettings]); CreateMessageHook(RoomOccupiedTilesMessageEvent, onRoomOccupiedTilesMessageEvent); @@ -49,14 +50,18 @@ export const FloorplanCanvasView: FC<{}> = props => if(!parser) return; - const settings = Object.assign({}, floorplanSettings); + const settings = Object.assign({}, originalFloorplanSettings); settings.entryPoint = [parser.x, parser.y]; settings.entryPointDir = parser.direction; - setFloorplanSettings(settings); + setOriginalFloorplanSettings(settings); + + const vSettings = Object.assign({}, visualizationSettings); + vSettings.entryPointDir = parser.direction; + setVisualizationSettings(vSettings); - FloorplanEditor.instance.doorLocation = new NitroPoint(settings.entryPoint[0], settings.entryPoint[1]); + FloorplanEditor.instance.doorLocation = new NitroPoint(parser.x, parser.y); setEntryTileReceived(true); - }, [floorplanSettings, setFloorplanSettings]); + }, [originalFloorplanSettings, setOriginalFloorplanSettings, setVisualizationSettings, visualizationSettings]); CreateMessageHook(RoomEntryTileMessageEvent, onRoomEntryTileMessageEvent); diff --git a/src/views/floorplan-editor/views/FloorplanImportExportView.tsx b/src/views/floorplan-editor/views/FloorplanImportExportView.tsx new file mode 100644 index 00000000..c707ff15 --- /dev/null +++ b/src/views/floorplan-editor/views/FloorplanImportExportView.tsx @@ -0,0 +1,68 @@ +import { UpdateFloorPropertiesMessageComposer } from '@nitrots/nitro-renderer'; +import { FC, useCallback, useEffect, useState } from 'react'; +import { LocalizeText } from '../../../api'; +import { SendMessageHook } from '../../../hooks'; +import { NitroCardContentView, NitroCardHeaderView, NitroCardView, NitroLayoutFlex, NitroLayoutGridColumn } from '../../../layout'; +import { convertNumbersForSaving } from '../common/Utils'; +import { useFloorplanEditorContext } from '../context/FloorplanEditorContext'; + +export const FloorplanImportExportView: FC = props => +{ + const { originalFloorplanSettings = null, setOriginalFloorplanSettings = null } = useFloorplanEditorContext(); + + const { onCloseClick = null } = props; + const [ map, setMap ] = useState(''); + + const convertMapToString = useCallback((map: string) => + { + return map.replace(/\r\n|\r|\n/g, '\n').toLowerCase(); + }, []); + + const revertChanges= useCallback(() => + { + setMap(convertMapToString(originalFloorplanSettings.tilemap)); + }, [convertMapToString, originalFloorplanSettings.tilemap]); + + const saveFloorChanges = useCallback(() => + { + SendMessageHook(new UpdateFloorPropertiesMessageComposer( + map.split('\n').join('\r'), + originalFloorplanSettings.entryPoint[0], + originalFloorplanSettings.entryPoint[1], + originalFloorplanSettings.entryPointDir, + convertNumbersForSaving(originalFloorplanSettings.thicknessWall), + convertNumbersForSaving(originalFloorplanSettings.thicknessFloor), + originalFloorplanSettings.wallHeight - 1 + )); + }, [map, originalFloorplanSettings.entryPoint, originalFloorplanSettings.entryPointDir, originalFloorplanSettings.thicknessFloor, originalFloorplanSettings.thicknessWall, originalFloorplanSettings.wallHeight]); + + useEffect(() => + { + revertChanges(); + }, [revertChanges]); + + return ( + + + + + + +
+ +
+
+ +
+
+
+ +
+
+ ) +} + +export interface FloorplanImportExportViewProps +{ + onCloseClick(): void; +} diff --git a/src/views/floorplan-editor/views/FloorplanOptionsView.tsx b/src/views/floorplan-editor/views/FloorplanOptionsView.tsx index e15229cc..0c6fc18a 100644 --- a/src/views/floorplan-editor/views/FloorplanOptionsView.tsx +++ b/src/views/floorplan-editor/views/FloorplanOptionsView.tsx @@ -1,18 +1,23 @@ import { FC, useCallback, useState } from 'react'; +import ReactSlider from 'react-slider'; import { LocalizeText } from '../../../api'; import { NitroCardGridItemView, NitroCardGridView, NitroLayoutFlex, NitroLayoutFlexColumn, NitroLayoutGrid, NitroLayoutGridColumn } from '../../../layout'; import { NitroLayoutBase } from '../../../layout/base'; -import { FloorAction } from '../common/Constants'; +import { COLORMAP, FloorAction } from '../common/Constants'; import { FloorplanEditor } from '../common/FloorplanEditor'; import { useFloorplanEditorContext } from '../context/FloorplanEditorContext'; const MIN_WALL_HEIGHT: number = 0; const MAX_WALL_HEIGHT: number = 16; +const MIN_FLOOR_HEIGHT: number = 0; +const MAX_FLOOR_HEIGHT: number = 26; + export const FloorplanOptionsView: FC<{}> = props => { - const { floorplanSettings = null, setFloorplanSettings = null } = useFloorplanEditorContext(); + const { visualizationSettings = null, setVisualizationSettings = null } = useFloorplanEditorContext(); const [ floorAction, setFloorAction ] = useState(FloorAction.SET); + const [ floorHeight, setFloorHeight ] = useState(0); const selectAction = useCallback((action: number) => { @@ -22,7 +27,7 @@ export const FloorplanOptionsView: FC<{}> = props => const changeDoorDirection = useCallback(() => { - setFloorplanSettings(prevValue => + setVisualizationSettings(prevValue => { const newValue = Object.assign({}, prevValue); @@ -37,7 +42,40 @@ export const FloorplanOptionsView: FC<{}> = props => return newValue; }); - }, [ setFloorplanSettings ]); + }, [ setVisualizationSettings ]); + + const onFloorHeightChange = useCallback((value: number) => + { + if(isNaN(value) || (value <= 0)) value = 0; + + if(value > 26) value = 26; + + setFloorHeight(value); + + FloorplanEditor.instance.actionSettings.currentHeight = value.toString(36); + }, []); + + const onFloorThicknessChange = useCallback((value: number) => + { + setVisualizationSettings(prevValue => + { + const newValue = Object.assign({}, prevValue); + newValue.thicknessFloor = value; + + return newValue; + }); + }, [setVisualizationSettings]); + + const onWallThicknessChange = useCallback((value: number) => + { + setVisualizationSettings(prevValue => + { + const newValue = Object.assign({}, prevValue); + newValue.thicknessWall = value; + + return newValue; + }); + }, [setVisualizationSettings]); const onWallHeightChange = useCallback((value: number) => { @@ -45,7 +83,7 @@ export const FloorplanOptionsView: FC<{}> = props => if(value > MAX_WALL_HEIGHT) value = MAX_WALL_HEIGHT; - setFloorplanSettings(prevValue => + setVisualizationSettings(prevValue => { const newValue = Object.assign({}, prevValue); @@ -53,11 +91,11 @@ export const FloorplanOptionsView: FC<{}> = props => return newValue; }); - }, [ setFloorplanSettings ]); + }, [ setVisualizationSettings ]); function increaseWallHeight(): void { - let height = (floorplanSettings.wallHeight + 1); + let height = (visualizationSettings.wallHeight + 1); if(height > MAX_WALL_HEIGHT) height = MAX_WALL_HEIGHT; @@ -66,7 +104,7 @@ export const FloorplanOptionsView: FC<{}> = props => function decreaseWallHeight(): void { - let height = (floorplanSettings.wallHeight - 1); + let height = (visualizationSettings.wallHeight - 1); if(height <= 0) height = MIN_WALL_HEIGHT; @@ -97,10 +135,10 @@ export const FloorplanOptionsView: FC<{}> = props => - + { LocalizeText('floor.plan.editor.enter.direction') } - + @@ -108,41 +146,43 @@ export const FloorplanOptionsView: FC<{}> = props => { LocalizeText('floor.editor.wall.height') } - onWallHeightChange(event.target.valueAsNumber)} /> + onWallHeightChange(event.target.valueAsNumber)} /> + + + { LocalizeText('floor.plan.editor.tile.height') }: { floorHeight } + onFloorHeightChange(event) } + renderThumb={ ({ style, ...rest }, state) =>
{ state.valueNow }
} /> +
+
+ + + { LocalizeText('floor.plan.editor.room.options') } + + + + + + - // - // - // - // <> - //
- //
- // - // - // selectAction(FloorAction.SET)} className="tile-option set-tile" /> - // selectAction(FloorAction.UNSET)} className="tile-option unset-tile" /> - // selectAction(FloorAction.UP)} className="tile-option increase-height" /> - // selectAction(FloorAction.DOWN)} className="tile-option decrease-height" /> - // selectAction(FloorAction.DOOR)} className="tile-option set-door" /> - // - //
- //
- //
- // - // - //
- //
- // - // onWallHeightChange(event.target.valueAsNumber)} id="wallHeight"/> - //
- //
- //
- //
- - //
- // ); } From 96e83fdd31114de4d3e0a7f45f139a36a5881e06 Mon Sep 17 00:00:00 2001 From: dank074 Date: Tue, 2 Nov 2021 18:47:37 -0500 Subject: [PATCH 5/7] close on room leave --- src/views/floorplan-editor/FloorplanEditorView.tsx | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/views/floorplan-editor/FloorplanEditorView.tsx b/src/views/floorplan-editor/FloorplanEditorView.tsx index 6006e8c1..2f057b67 100644 --- a/src/views/floorplan-editor/FloorplanEditorView.tsx +++ b/src/views/floorplan-editor/FloorplanEditorView.tsx @@ -1,8 +1,8 @@ -import { FloorHeightMapEvent, NitroPoint, RoomVisualizationSettingsEvent, UpdateFloorPropertiesMessageComposer } from '@nitrots/nitro-renderer'; +import { FloorHeightMapEvent, NitroPoint, RoomEngineEvent, RoomVisualizationSettingsEvent, UpdateFloorPropertiesMessageComposer } from '@nitrots/nitro-renderer'; import { FC, useCallback, useEffect, useState } from 'react'; import { LocalizeText } from '../../api'; import { FloorplanEditorEvent } from '../../events/floorplan-editor/FloorplanEditorEvent'; -import { CreateMessageHook, SendMessageHook, useUiEvent } from '../../hooks'; +import { CreateMessageHook, SendMessageHook, useRoomEngineEvent, useUiEvent } from '../../hooks'; import { NitroCardContentView, NitroCardHeaderView, NitroCardView, NitroLayoutFlex, NitroLayoutGrid, NitroLayoutGridColumn } from '../../layout'; import { FloorplanEditor } from './common/FloorplanEditor'; import { convertNumbersForSaving, convertSettingToNumber } from './common/Utils'; @@ -50,6 +50,13 @@ export const FloorplanEditorView: FC<{}> = props => FloorplanEditor.instance.initialize(); }, []); + const onRoomEngineEvent = useCallback((event: RoomEngineEvent) => + { + setIsVisible(false); + }, []); + + useRoomEngineEvent(RoomEngineEvent.DISPOSED, onRoomEngineEvent); + const onFloorHeightMapEvent = useCallback((event: FloorHeightMapEvent) => { const parser = event.getParser(); From 5020f1f06357c81294e6f24c3f0d4c4861a0efff Mon Sep 17 00:00:00 2001 From: dank074 Date: Tue, 2 Nov 2021 20:46:48 -0500 Subject: [PATCH 6/7] update stuff to use mounteffect --- .../floorplan-editor/FloorplanEditorView.tsx | 13 ++++++------- .../views/FloorplanCanvasView.tsx | 15 +++++++++------ .../views/FloorplanImportExportView.tsx | 8 ++++---- 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/src/views/floorplan-editor/FloorplanEditorView.tsx b/src/views/floorplan-editor/FloorplanEditorView.tsx index 2f057b67..48a7d34b 100644 --- a/src/views/floorplan-editor/FloorplanEditorView.tsx +++ b/src/views/floorplan-editor/FloorplanEditorView.tsx @@ -1,8 +1,8 @@ import { FloorHeightMapEvent, NitroPoint, RoomEngineEvent, RoomVisualizationSettingsEvent, UpdateFloorPropertiesMessageComposer } from '@nitrots/nitro-renderer'; -import { FC, useCallback, useEffect, useState } from 'react'; +import { FC, useCallback, useState } from 'react'; import { LocalizeText } from '../../api'; import { FloorplanEditorEvent } from '../../events/floorplan-editor/FloorplanEditorEvent'; -import { CreateMessageHook, SendMessageHook, useRoomEngineEvent, useUiEvent } from '../../hooks'; +import { CreateMessageHook, SendMessageHook, UseMountEffect, useRoomEngineEvent, useUiEvent } from '../../hooks'; import { NitroCardContentView, NitroCardHeaderView, NitroCardView, NitroLayoutFlex, NitroLayoutGrid, NitroLayoutGridColumn } from '../../layout'; import { FloorplanEditor } from './common/FloorplanEditor'; import { convertNumbersForSaving, convertSettingToNumber } from './common/Utils'; @@ -45,10 +45,10 @@ export const FloorplanEditorView: FC<{}> = props => useUiEvent(FloorplanEditorEvent.SHOW_FLOORPLAN_EDITOR, onFloorplanEditorEvent); useUiEvent(FloorplanEditorEvent.TOGGLE_FLOORPLAN_EDITOR, onFloorplanEditorEvent); - useEffect(() => + UseMountEffect(() => { FloorplanEditor.instance.initialize(); - }, []); + }); const onRoomEngineEvent = useCallback((event: RoomEngineEvent) => { @@ -121,7 +121,7 @@ export const FloorplanEditorView: FC<{}> = props => return ( <> - {isVisible && <> + {isVisible && setIsVisible(false)} /> @@ -143,9 +143,8 @@ export const FloorplanEditorView: FC<{}> = props => - {importExportVisible && setImportExportVisible(false)}/>} - } + {importExportVisible && setImportExportVisible(false)}/>} ); diff --git a/src/views/floorplan-editor/views/FloorplanCanvasView.tsx b/src/views/floorplan-editor/views/FloorplanCanvasView.tsx index f9640a2c..f68a9248 100644 --- a/src/views/floorplan-editor/views/FloorplanCanvasView.tsx +++ b/src/views/floorplan-editor/views/FloorplanCanvasView.tsx @@ -1,6 +1,6 @@ import { GetOccupiedTilesMessageComposer, GetRoomEntryTileMessageComposer, NitroPoint, RoomEntryTileMessageEvent, RoomOccupiedTilesMessageEvent } from '@nitrots/nitro-renderer'; import { FC, useCallback, useEffect, useRef, useState } from 'react'; -import { CreateMessageHook, SendMessageHook } from '../../../hooks'; +import { CreateMessageHook, SendMessageHook, UseMountEffect } from '../../../hooks'; import { FloorplanEditor } from '../common/FloorplanEditor'; import { useFloorplanEditorContext } from '../context/FloorplanEditorContext'; @@ -13,11 +13,6 @@ export const FloorplanCanvasView: FC<{}> = props => useEffect(() => { - SendMessageHook(new GetRoomEntryTileMessageComposer()); - SendMessageHook(new GetOccupiedTilesMessageComposer()); - FloorplanEditor.instance.tilemapRenderer.interactive = true; - elementRef.current.appendChild(FloorplanEditor.instance.renderer.view); - return ( () => { FloorplanEditor.instance.clear(); @@ -25,6 +20,14 @@ export const FloorplanCanvasView: FC<{}> = props => }); }, [originalFloorplanSettings.thicknessFloor, originalFloorplanSettings.thicknessWall, originalFloorplanSettings.wallHeight, setVisualizationSettings]); + UseMountEffect(() => + { + SendMessageHook(new GetRoomEntryTileMessageComposer()); + SendMessageHook(new GetOccupiedTilesMessageComposer()); + FloorplanEditor.instance.tilemapRenderer.interactive = true; + elementRef.current.appendChild(FloorplanEditor.instance.renderer.view); + }); + const onRoomOccupiedTilesMessageEvent = useCallback((event: RoomOccupiedTilesMessageEvent) => { const parser = event.getParser(); diff --git a/src/views/floorplan-editor/views/FloorplanImportExportView.tsx b/src/views/floorplan-editor/views/FloorplanImportExportView.tsx index c707ff15..274d5ec6 100644 --- a/src/views/floorplan-editor/views/FloorplanImportExportView.tsx +++ b/src/views/floorplan-editor/views/FloorplanImportExportView.tsx @@ -1,7 +1,7 @@ import { UpdateFloorPropertiesMessageComposer } from '@nitrots/nitro-renderer'; -import { FC, useCallback, useEffect, useState } from 'react'; +import { FC, useCallback, useState } from 'react'; import { LocalizeText } from '../../../api'; -import { SendMessageHook } from '../../../hooks'; +import { SendMessageHook, UseMountEffect } from '../../../hooks'; import { NitroCardContentView, NitroCardHeaderView, NitroCardView, NitroLayoutFlex, NitroLayoutGridColumn } from '../../../layout'; import { convertNumbersForSaving } from '../common/Utils'; import { useFloorplanEditorContext } from '../context/FloorplanEditorContext'; @@ -36,10 +36,10 @@ export const FloorplanImportExportView: FC = pro )); }, [map, originalFloorplanSettings.entryPoint, originalFloorplanSettings.entryPointDir, originalFloorplanSettings.thicknessFloor, originalFloorplanSettings.thicknessWall, originalFloorplanSettings.wallHeight]); - useEffect(() => + UseMountEffect(() => { revertChanges(); - }, [revertChanges]); + }); return ( From 4a8f738bb035e4fffdc5e0d9adea881e19ca682c Mon Sep 17 00:00:00 2001 From: dank074 Date: Tue, 2 Nov 2021 21:38:58 -0500 Subject: [PATCH 7/7] fix chooser resize --- .../widgets/choosers/ChooserWidgetView.scss | 15 ++++++++----- .../widgets/choosers/ChooserWidgetView.tsx | 21 ++++++++++++------- 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/src/views/room/widgets/choosers/ChooserWidgetView.scss b/src/views/room/widgets/choosers/ChooserWidgetView.scss index 9a461869..5365dd13 100644 --- a/src/views/room/widgets/choosers/ChooserWidgetView.scss +++ b/src/views/room/widgets/choosers/ChooserWidgetView.scss @@ -1,11 +1,16 @@ .nitro-chooser-widget { + - .list-item { - color: black; - overflow: hidden; + .chooser-container { + min-height: 150px; - &.selected { - background-color: cadetblue; + .list-item { + color: black; + overflow: hidden; + + &.selected { + background-color: cadetblue; + } } } } diff --git a/src/views/room/widgets/choosers/ChooserWidgetView.tsx b/src/views/room/widgets/choosers/ChooserWidgetView.tsx index 638b4999..492b5164 100644 --- a/src/views/room/widgets/choosers/ChooserWidgetView.tsx +++ b/src/views/room/widgets/choosers/ChooserWidgetView.tsx @@ -1,5 +1,5 @@ import { FC, useCallback, useMemo, useState } from 'react'; -import { List, ListRowProps, ListRowRenderer } from 'react-virtualized'; +import { AutoSizer, List, ListRowProps, ListRowRenderer } from 'react-virtualized'; import { RoomObjectItem, RoomWidgetRoomObjectMessage } from '../../../../api'; import { LocalizeText } from '../../../../api/utils'; import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../layout'; @@ -53,12 +53,19 @@ export const ChooserWidgetView: FC = props => setSearchValue(event.target.value)} /> - +
+ + {({ height, width }) => + { + return () + }} + +
);