From 1f749a2975934576996149b1a7a69bc7cb58c204 Mon Sep 17 00:00:00 2001 From: chenhuan Date: Wed, 23 Oct 2019 13:32:13 +0200 Subject: [PATCH 01/39] version1.0 --- CMakeLists.txt | 33 ++++----------------------------- main/main.cpp | 29 ++++++++++++++++++++++++++--- 2 files changed, 30 insertions(+), 32 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ac80de4..463cbc4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,38 +1,13 @@ cmake_minimum_required(VERSION 3.7.2) -if ("${CMAKE_BINARY_DIR}" STREQUAL "${CMAKE_SOURCE_DIR}") - message(FATAL_ERROR "In-source builds are disabled. - Please create a subfolder called build and use `cmake ..` inside it. - NOTE: cmake will now create CMakeCache.txt and CMakeFiles/*. - You must delete them, or cmake will refuse to work.") -endif() -set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "bin" "doc" "CMakeFiles" "lib" "include") - project(GUI) set(CMAKE_CXX_STANDARD 14) -# enable clang_tidy -set(CMAKE_CXX_CLANG_TIDY "clang-tidy;-checks=*") -set(CMAKE_CXX_CLANG_TIDY clang-tidy;-header-filter=.;-checks=*;) - -file(GLOB_RECURSE SOURCES src/*.cpp) -file(GLOB_RECURSE HEADERS src/*.h) -file(GLOB_RECURSE TESTS test/*.cpp) - -set(LIB_PATH "${CMAKE_SOURCE_DIR}/../library") - -include_directories(${LIB_PATH}/include) add_executable(GUI ${SOURCES} ${HEADERS} main/main.cpp) -target_link_libraries(GUI ${LIB_PATH}/lib/liblibrary.a) +set(FLTK_SKIP_FLUID true) +find_package(FLTK REQUIRED) +include_directories(${FLTK_INCLUDE_DIR}) +target_link_libraries(${PROJECT_NAME} ${FLTK_BASE_LIBRARY} ${FLTK_PLATFORM_DEPENDENT_LIBS}) -#TODO: add fltk here -enable_testing() -find_package(Catch2 REQUIRED) -add_executable(UnitTests ${SOURCES} ${HEADERS} ${TESTS}) -target_link_libraries(UnitTests Catch2::Catch2) - -include(CTest) -include(Catch) -catch_discover_tests(UnitTests) diff --git a/main/main.cpp b/main/main.cpp index 53edc26..f6f9ab1 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -1,5 +1,28 @@ -#include "../src/demo.h" +#include +#include +#include +#include -int main() { - return test(); + +using namespace std; + +void button_cb(Fl_Widget* wid){ + Fl_Button* but = (Fl_Button*)wid; + + if(but->label()=="&Good job"){ + but->label("&Click me"); + } else + but->label("&Good job"); + but->redraw(); +} + +int main(int argc, char **argv) { + Fl_Window win(300,200,"Testing"); + int i = 7; + win.begin(); + Fl_Button but(20,150,70,30,"&Click me"); + win.end(); + but.callback(button_cb); + win.show(); + return Fl::run(); } \ No newline at end of file From 71344ec3fd4a05fd1bf4a78504a37abbcecd68bf Mon Sep 17 00:00:00 2001 From: chenhuan Date: Thu, 24 Oct 2019 13:19:17 +0200 Subject: [PATCH 02/39] CMakelist korrigieren. --- CMakeLists.txt | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 463cbc4..d8c4951 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,13 +1,42 @@ cmake_minimum_required(VERSION 3.7.2) +if ("${CMAKE_BINARY_DIR}" STREQUAL "${CMAKE_SOURCE_DIR}") + message(FATAL_ERROR "In-source builds are disabled. + Please create a subfolder called build and use `cmake ..` inside it. + NOTE: cmake will now create CMakeCache.txt and CMakeFiles/*. + You must delete them, or cmake will refuse to work.") +endif() +set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "bin" "doc" "CMakeFiles" "lib" "include") + + project(GUI) set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_CLANG_TIDY "clang-tidy;-checks=*") +set(CMAKE_CXX_CLANG_TIDY clang-tidy;-header-filter=.;-checks=*;) + +file(GLOB_RECURSE SOURCES src/*.cpp) +file(GLOB_RECURSE HEADERS src/*.h) +file(GLOB_RECURSE TESTS test/*.cpp) + +set(LIB_PATH "${CMAKE_SOURCE_DIR}/../library") + +include_directories(${LIB_PATH}/include) add_executable(GUI ${SOURCES} ${HEADERS} main/main.cpp) +target_link_libraries(GUI ${LIB_PATH}/lib/liblibrary.a) + set(FLTK_SKIP_FLUID true) find_package(FLTK REQUIRED) include_directories(${FLTK_INCLUDE_DIR}) target_link_libraries(${PROJECT_NAME} ${FLTK_BASE_LIBRARY} ${FLTK_PLATFORM_DEPENDENT_LIBS}) +enable_testing() +find_package(Catch2 REQUIRED) +add_executable(UnitTests ${SOURCES} ${HEADERS} ${TESTS}) +target_link_libraries(UnitTests Catch2::Catch2) + +include(CTest) +include(Catch) +catch_discover_tests(UnitTests) From 76cc27841e6c85af87d33076a254ecd2fe58ef64 Mon Sep 17 00:00:00 2001 From: chenhuan Date: Sat, 26 Oct 2019 16:39:25 +0200 Subject: [PATCH 03/39] 1.remake the mouse input and the keyboard input 2.add a bild(image/background.png) and display this bild as background --- CMakeLists.txt | 3 +- image/background.png | Bin 0 -> 47790 bytes main/main.cpp | 69 +++++++++++++++++++++++++++++-------------- 3 files changed, 49 insertions(+), 23 deletions(-) create mode 100644 image/background.png diff --git a/CMakeLists.txt b/CMakeLists.txt index d8c4951..bf43ed9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,7 +29,8 @@ target_link_libraries(GUI ${LIB_PATH}/lib/liblibrary.a) set(FLTK_SKIP_FLUID true) find_package(FLTK REQUIRED) include_directories(${FLTK_INCLUDE_DIR}) -target_link_libraries(${PROJECT_NAME} ${FLTK_BASE_LIBRARY} ${FLTK_PLATFORM_DEPENDENT_LIBS}) +target_link_libraries(${PROJECT_NAME} ${FLTK_PLATFORM_DEPENDENT_LIBS} ${FLTK_LIBRARIES} ${OPENGL_LIBRARIES}) + enable_testing() find_package(Catch2 REQUIRED) diff --git a/image/background.png b/image/background.png new file mode 100644 index 0000000000000000000000000000000000000000..6f04f51385a7211134ce1a32d8b27cc205394233 GIT binary patch literal 47790 zcmdSCc|4U{`#-)!N>Qi5n2<_EBue`z>;_UA6*7xNN!b}fhWj)dGBl|ONs}>|%8*?O zP3#5~$yk(mp7~zuzW0`M&U2p6^L&1ve}3!rYTJ9Qb+2`;YhBm-8rIr7pB>va3QQ53 zf)Eneq`g5GAwDDccVRLw)X3%CIS+sM9JCD`5mK0s|8cqA)^LGJQ76qkPP>lmcRIHB zs5M%rhqsFPdenZ>r$1bf ze$>LSU0gA;@&2#K(Wt^?y^xoWV~q_aZ{)r#&u0DvqXQ1)>yCquWx8DY22Ihs(75L99~)c zSL%ya-naJ4?79K64%ef5CA&blQ{EqZeb>5fy&!68&#rY`7<;;Pp2q%%jG^dhWG_U# z?g)z?wV1}zx~097SHZNpn(+mCV8~sg%*hB$Nh6O0=Io!t7G;d z_RBrkr4mY3ff=tK4Y}V2e(X`U1%XP@On_EGQduEK;r~ve{*wgf@)x@{y%IJo1sZC01!M_EHrQ;=%iJf*L$LsvypYLw)a`<2O=7W$W2!f(z?Vg%Ci@!cqT!s z;m8UODiTLt&QCvxkS(Q>Fk+Q4CfZg*jzl?fiUoV#O~G#>Me~dUg=NQhVqFNDe* z&9U{O{C5Up!_ilsB=?3Kk&hdz)ryki3o2c+cJuwWv;6D+O}Fn-996B6=_m@YJNA>D zyz0{#STc&_(h9cRh~K=YgC-6=7%XshTXR0^J`dCdSgu@i^~f5txyCm@dIO$E3Zk}I z{O=$9n5U!==$JU2ny@T#yjbbO{#D)Gnp{~fw6vI7CVfs9C7bk({K?%e_2zE6>_@2q z*st_HJzmte*Aw&Le_5CkGQpN|vr?(YLt@4gHeTK-9O`4}mEZgx{Mffg#eYo$ds;%l zP(W(7@wIysZG)qvzqU?OelLfItKX*yf2+j9Ur~dvST`O9#w*Zx30B1LMisVN!w1@( z!2)doME@W_vgJnFfK|S0eyVkyrsgD30~6zzda0?|5-$`xb})uFX>y)7RPmX;T4~qx zl&|+{)FO9a4l<9VO~d;{7VUpI7kCCwVcT$d5NIiP)DQUF6%O6`rr($SD&y`Yj| ze^bIXyVtjuY@uGJkxCnRF^;{ErumibhXl8b>+xT{ePm184whn3aQWQQmXF-bYg?rQ zS0|jG?%|j zJA;PJ=B_Hj-5=Z?=e@@mf-XlsSxxp@QL@4~abN1g-IHJpCHAuD!dWENpem2>`N>MF zep0KlU4#*V**ng;La6LMh}Av&Xf{p}hX*2H^t4riX!TNQw`P}`Sg@F+C{zjVTBnd_6zVJj^@>herRaQnf`ZIBIAL zT2U}c;RV=I-PYhW9XDb0|Eds@EbR3nq)`V>;`i*r*qVHW6&C)wy7i|#3wGrX=F@(B>B z#Y``=PBY`#+~TF{dn)ajY4KkZ1&p{tBbpsoBD9lR;lSOfC@q;7JiGdMA}CKn;p@T6@4{iFPzv*X z#~EI1wQ#A@{jxD3y-*Dlgeu#P%wBSEUz99yG1Rl&3!;4CrzL-|+aMb<-l%X;3R)>A z3L&RA#}_0rDs}bHqF#f#&0s`LqF~8j0xs;WQ)Lt>b=;BV3>FzH6D%Flo*wM|5iBAW zuZ-{N#z(jn<+T$@9C9BylRTiX8?fVe- z-P5n2@+aAe=pkc+s_9njxkCRHULp(onM+iZz&N$N1e7Se*f1rMIn zhu~pv71J$F-$J}JYgOPIaMqB6I$Hs%*5n1}U++z50bHqA`MKTe-7W#d{P9WkH_i}a zZU|KTvw(sF{87bkjn?-V^0}&0SAtD|P4(8SDQx>KA7s<$Ee-Dc?*JRfL5m_F!#dpX zK8ff(C4WP7iUdBkucYwKv95=x-#UNU&s+043Th>KVT;-0RMl^JIN-f>I3;6rle4+e zhP+Bwg|PSL!Li)oy$KmN4o~-(UZA(}EJc; z`akI*>E}a_9Um4jJVo7h0*Kr1V_RJ!Lt<8G=Ns&_$-}Zyq^IxP`r|P_qBosC9{!PX z_jbI+%_-$p=Z|wxX8}7Qh-aso@w>n9`V^UisLEeDzn`m!RIjRMq}vd$-)915{-bBz z08#%f`0)TL?D^fXTixTX3^+Um6jU-7y6@y-YPxSRF$eu7(mEmkq8$$UG7zws*mCX#Jg#Ttzs_prlTLP|9A zm2J^ry(~A8=X!39L|ax;Yd^HLg_7LX?@((^U#CQlbmQ;V9oIXo=?%UnhOQT}9b+&@ zMM@W9xgz^H`3bS;dv502^^nOqH&G;3INnnH6XO4mUO#x^*w@~?Dwxc}u{H%_P$CM! z_3DPtetp5#TkN<%+*)DGN)VPV)bO zRyYe0)fvlN&0!fE5X!x4JMm++f$QjtS7x*6uScFg?*Hzo(~jB9x}f)T@O>matT+Ya ziy8E7VeAI>DFXe&?07=eb>TE*zd0bQ!jB3~&^eeUYI0+Z~P(SJoyhdJ~O9DR; zlTd3?@}N+mFqQ`02=!e+^O-}7fYyeO>%*eYICrcRpMfn;*L4_8abJ!m9)mtTZpzmX zpGn9P%`)9Jx|mfTuB&dqWGM!Yn0G2df2J7yt`yA#Vl`Jy&w z0fIM2W-tR5K~OgNVsJ@Hq2FRm?wyTfI)%8u#~05>#C(^=f620V|35}@6BbkSB}c+2S-}0btq^AO5?HW&wGo%%#2;rha?Y`X zC1Mu{m*PYna%|}CFm2$!`;1*B=U|XDU$634+r^dR%sdeutK0-dStGa=XyWm31 zq@)M0CX*Jj@oULD;GDw*QlRnDU4?*@6}j*JAiGx>KX+U082%h+KiSo(NH6+KrK6xR za`o{UOvO)QpHbu~YFhjtosT3@QS-;O-bx?R`dS!~TY5F>Hpz&CN#`!U`0O`9WHo#0 z$ZZ<6CVG!5^_`HS_JJ_Hu++r_W)>p6+*R9qjxoYtz-DwY?OjK$8}ILr;wIL19HA+S zVpL>pf9aE+Gn;aA=#Jwz^$uHwfT$ho{!A=ANrMqyGc=O|dFJA!HCc1Nn~5Xw#&taC z^x>KX4Bee*Zl7bH>h66@WUgLP^=?ZC)n0-Zh{QpXB0tGwg~XAajC*+c?DT4l`a9>a z*F(DyB}h-&$lf&nS1N^D_)*xwzbi6o_^J@*?bPQd0-TThosIGp#|2t9enQBjYkuL| zRjr+0xR4RKmf;lO#t&B2jbXv#@EffSFfat+05Gp6%E;%ZOLm< z!}-S~!|?;i_jhoGB6F^=rJnF&OAl_N^RX$1_r%NqPD-cYu6@`w5fmxO(MTf3EAO#t zN18E%6k669&V&aYyr1<(fuvwX5=k(x9yIW^uW8bxoCUN4a{=#*ly6jYIV9+ZvuMH3EkR(atY!*sc&ykdS z2WLI0bdy9DyE)4jiM>1PNDiON1&!hnMTBkvw&FPvbI-y>U)2Rc1}m@mA*1x)sJWrx z0VqjXI)+Qu!wAOVIeU)H5}z@_^Vr<_n>SNKYVhNCHjoqMwaOO8{Nelo@YwU1=r#={ zK4>GB(SG@_e^#>b8^)F!Ov*wIt?+*HV$v|-YINxln<(xpFE-hkv}#5}rH3Y-y5X7h z$IjOe78L4-A#}0FRRmgWFL4ywYUM1T-Wk?q@o?n1o9dfo3_KnbW^a@2L`Bn8)x(c& zo5)U!wDy~BelpfgqA~k9ExfZSKR6fr)gQ$JeSMrLHN)p|aszlpxc| z{+ai&hnrt;xK;^!eN`dz88r=J2LFdj&F=pfX&%oU1+a*S9#~PDWhQ2``l)#5==W>e z7hR2BTDX}%btH55vGD$!tvc^O(&(e4RcG16@|KkQ3SJHJ3`@m~L51~yMbyZthOQdY z-)65)q87js#Cwy`<|=YWZfdtUUx*LnSVXSIR8GAe1xHnf@xY!b=Pq9QB6B`jP>{bw zz0e3O7L%vn478PZGweyjtp%5IGL*e@IJ>}_!rt$zR~l&{E8{Mn?yWco)5)x5OY5C) z^RilHJQMUB_yG~-4f#6?hHZGp^GgDD6sv#wamnZEc!SLu{Z9a3@zd*t+f42qlvv^= zU(Hy$O_n#Z;54}0e|RZh^ueMDS-O`!il`F1I0Fsspblio#{L9VazV;~1E=vsa*?~( zWoXpteoY(JO$56OanX}WF=|K#v(gZ}^h701`akaG=+qq2_e1 zx!|#|F!B!sk4L0-Rff5nPv=q$#JI%l04sm!{fQiNUouGm#LA8rVA9pNXW(_}fbIt) zZ~?U^HEs+G4a5wFlN2;{sHVN2(MN8ix&wj&`^qe6>F&cj-sBPju%|kxfBw|RS(-* z+kYaYw-gkB$pVbHWbEm_dKRd);?BUc_yGckDT~vwLr9h_p(Iu)>Tl91b(^sg*HL~s zQq(t|!Catr`n%ti17WxC!2=dXBGIxz0JSY#-3%gq8pgB`=>hiTHU3_xO99>RpWJ&=Uw$5ytdGC>SQw~-VoHUG zw!ZJ|gg{@&J)pq+Vc@be0ubv&h zhNlbs*)ARMylUTUz>M1Q@)q_h37N%4Yjf&W8!j=V4~{#eak5{Qoll-EiTv}TZZ&?-x#upZu}Iy!dELlR>9TBysAq!A@KY+x zx}9>XQD&{%=?`(LSqVjYm`aKN*(-psKvg%CfIs_vi%GR5yiL#cS}9*o@#~a5NY;yx5i;Se_I#7r z6RjsB`qXiYBL7%y0+wXFx;z6hryG<|;I%}%=uzu74}>Z>QxV@WS&E0)49+^$>0uonb9t(yk;v z7Fw-1)9s~fb3>VOJC;m6kPG|1pO<6I)=q(pOhw)%qbGML0id6Sl#Gf;_h!9BDUKHN zQo?ItqH;6S>N7l#EK)GEL4wKJ8wdn#)*8?Gq@bsBriYz8mbEB#i zepeEb1;I?vz1bqdJn;TXg4HTDENu`=a0)wVG?L2qwpBOChl=9QkgKXP4`d6R`cZ5| zsY2(&ITDp}n(}hAQpe7uQ4@j|Tyk;3Y)8&r<<=a&0QtsHD%Akt6;9SfdcC~XyIqqV z3=d-@$EC~keN|b2E4XO^V^tOU5VO)t|5Fo2jsp+;DS#eR+`K zJ>T>Kf95~W770ThWaBAd>Wi5!B1WPRB1SR;I$7;jpPsvQ-Gq9J7?Q_#mW*243vaA! zuF3M1MBA>6X5Mfb648~!e#srum$kUwF?aceX$hg`j&fd5%NF!VFG$N2ZJ;=zDC$== zG3F$8*>~iy8AkXF&Z?IwG!3(1%+`G}hF5u>@-d+lB^ z8#!52c-!{H?7HpOv!40O4EZ`5w|Utpf$~(kO=)ggx<`i33u^+u@rdW!m^u}?%E28M ziz4ibIW~^&;IooRb4C{Yl)*;yV`IAn3nPOl;y{_RQ-$z5=;8m2%&{>qVY-+r`u8pdvrqp+ zGc09Npp~HbZ8A5?PEtZ>|LTLm5qUE^!Ar}y5HanoCN(F#{y7fhSl++tH^&lMNI#^> zEr+L0b9(MdqA1q;kMcIuIJOnK06Actmb#?;EQI_cyD0MG&j3eEX463vxmnuO9Y@r-T3*Yz^rE3#l2jt?I8>RicK07XGc95>&n;Iz%h5sot#9s8L&3-?eC`K z&BGZih!q+RVO9-;^430JC)j{D|Cn^8j537dzdN3f$0<%IgbLmwQyhq2vwH*C<@h}$ zYC(EQ94@G^%U|=goO;szZF{K`)&)8Gnh8|3#S{>rzNRs!8&2ZP*@{Qkixo<|>^lb{ z2k>FZ?mLQ&fW^$+sK0pNjd`5blHF6+6Q5ZEm!%m+A*Q?x#yQ@Y1j3|Y*Cvy&g6 ztvXC*L*qfVz3{lw`s!Lw6=NUwYk7z{)jgrjB8Gu(YHx;SiwNr0qiOcJr&Js^2D zH@(#)|8dg~tMY+1+{RAyRGIs+Mhac?uM5yh&(eHMxJET#QpFA9-3Jczz*CgthVl-3 zl5PgNN3sx)2jx#m$X}XpyocI%I4i&53~NE>O(FmQA^zBtnj($dqR2Xv)=R0=P45y8KXLd5B&Hjo`!6X zMX|4Gt9LpmXv$sh=$*P-W=dhub3@Ngb;|I93Phh-sk?jv|B2cO_rXMO?U$brc~(7q zmnXlCA-Nx(mnDT$W8B_C<}?MJOq!;0kI)C1QCyf_og%p=nsLRFJMwHtt-yr<$@L>g zVkB!w=1|8LTRz8}CSxpICqmA7=gr|Y@PTz+gK=2QWK^Lr`6?H>cM-&v?)g>BXq68c z(IQ1@a2O9b4C~C`=6|otLyrLX>e}<>@v)? zXlpr9yM;@O0{FaIV12mS9q{-h#cZETZ!62qPxVdispisZ=xJM-AipUr{u38(D>x{% zl+#@s91?c{p7?l{G#?@-{|f%(+=LZm7?_uS9UM^yMY|pbD6ig|rNl{(jgm0eRJ>eww;lY24M9>b$sF0CWa}_rX%bt!` zbQjyTd)wc$GFIb6^89vIRqwXDdtMk0IzX!fHi5(diKEEjQYNcu+A*_7yolaRfyT(? zQA>px>zh>=x&XfKl0lQ%t{~x^&6}yGQoWNz68_@<1W`C97AB_hZp72aevY5ptqMFS zwY@qMvxum6!;r3Tp>W}D|% z>(Cik)xqC8GTVI^Yae>=500i0C6B`jpSH}?u zYrC)hj<>aYf%<`p-oB)GPgleX7<^mJ+h18y2KQftSv_jidN@#bQm4Y$jfP>7Q9xxB2O#A_3SDHuRW%js|~NwyZcI(Cu3XZ+t=bKZ@*ei zDj!$^DEl_UZ5TqP#WG&?(U*fmE!jOT?+tJRT$5M;a!Q}oxo4`q_L(-ZI=eY}t7gVN zkY`=X)o!)A9gm;CqfK70xl_Ays+8RJq$_1;XuIf{xi3u0fDslkJn`sEk{fIXDDVfz zw#Seaqc2iO!Jo-ewPM_59SBM-&7VaVK&<*&av4UDJNeZd>Iqi?8ae5OPzvO46o1)P@_{0L;pGi`syD|`F!JQ(fYfT!X^G`I-W9vS2 z+OeMG9qx}J^KJ`)0MKXHRXqK6#b_#7NuPqbU~AdS=1b7RasKe1xS~j{CBreaKy`Xj z_#u30i&;wXFmko#x<->S1*jqtMaTIgx%^02 zx_@`ryXHojlFQ}4Ay3$f$mUhAW0eaHo|hev#LqajByuGSyK7H9Q~UDVV$F^yxtqkcT%4MIvm~7RX!G05@>%J3?F;0dPZpnNyV6r~)|Yks zE4n}UZ7*D*(fPKc%xd<=@SL&{W{f*`*FC%g^zTAOZSn^0lU=7>^$09657Xya8~e(> zPn`G0f!E$&PM5ZBjaBcT)|K3Nsa5BM{)gV>Pn(|#5WAh)|IoY1mMW)1f+GUWd`4US z*&83^+k1q?h{MWni;M!fQK&;i6NuIs91S6U%zDJzCqs&}NS>)ksmM*Mv?K|8K|ChR z0N;T+V;Xl&MR9rO9>3tkqz7A}-v3K$Qi50Y=yW4q=HoFX)God#gjm8bR9VXO`ni{H ze&k$0%iF@5La1b)Dt)&N4~v-nLY1^5_dOA7Opgdg`>p**WFA|uM*O?2PBoV0xu-zp z1o{7g31L1sY$Z6~_=9RmUJ0V>#{?Byo@$gmBmf<(7&qCFOg|eV+4;sO=C%t2)nluK zgO0sUQqU1e%Fi^kIS`BAHe7^J6}1LgBf=iH(9;Km>5r7dV_(m(2AlSkNIcp!4ML3Ykiz0 z(MWmPQadq1)-^0C(FN}x7u#12bn*?n5MlvrY>9sM&If|Prxb3|j|ut2by|>o*@j7I z$aju&+g_@d=U#FY5j#H}zyix$0ln$UIWGp@J^R*Vm2GQt1yonf)WBJ7jy&bn5IxZ4 z_Y5EB;x_N$j;qJ?3Sw-lj|v@Tn+x;<_T*^SZ)Uj)Ti>Km2!_xj)))>FAH?7J-oK~y zR4r>bJJ30CA)@Cco;{P20s??3n9XOjT+rZV|6&N~63-&-&qb$7&D0E<56ug@_LFhs z4wi-=gT|<*r90+)v?;gk&2OVJ+!wj_(P#PaJ>5Xe{$uWm**?ai=lHMlJMe`4+>0ku=Db`eG>ch&Nt~^;MAoqqoXo7q9#jOwC#&MLsJ4I zI2Doe#|0_2zs`dJvBA!>OXSl!*`!tpoCN2kZ`v^FHis{&^L-sHObbV~8UHNMIklSQtkmv2KyDM7Ny zsakzo@Ka}fhW?eQXvAOyk2MY4Bce90)&v9~K>ztQ8;2X#P?h$LC9cOXlgA)U*C72M zA|czxy+ZSoP>X1e(ucc)xhe>5hng&G}X|DU$uk8wnw+%8S_ zpShg$p@U@cB1F#0x?0Xe1(lGPxY)a}uohMBO589Vd>!1X;H<$KPS6}ZTUzC_2^cb4 z?d)E2kzMYLj3y%bPGo9wt zt0vj$E|`c4b{S_nIX!*XfPw-qxwvlGIoz2gx$#M>5^ah|fj?YKalO3gN$bf1q`hN! z{Wa+%yN(5<*X$AJ^===dZt%*iw+;QwR{7ej0mTzeON`cZ|W9aoTLO^nm7Qf7ak9 zw;#2Iv*X{lDIc1;;vPVWb1h&hjBf8u9&8O=O!j#o zZzyPqJD>b{BQAU(Ls>I+#Tp;ngbOkKyt+VKU!(oyJ=#7|f_1n3 zl}D?Z)gO~>2t_BZX*+&oR?&BZPc2_~Uh2XE;yf+cGFeb^aOue_^wrKGiwsIb2&*r7{mW0} zC;2Bo#2J3(eNMee{t~S=+GZX2j>Apa!mQinT*OWaB0dbiX}i9P5xx}Ck?43R%19FD%$u3NpLzxcL$tB< zM$p|!(6=ieXN=fIfI3!niZAHOSas#F()Vj-#}53!jRVvzUMG9`2{ZAnum!iK42ML@ zC2=DMehxzDwu@bgbe1AH~h2M4bH7)T9B@z}`u$Z4J^7`MkdoHbw+n}~Nkm1YK zn#1p_|JsyoG)`hp=e4LhnO|D+g8zo7u}@N9hmG-*7jEtICL{j>8UDd_*itBwaX2eN z{Z)j$nH*iVCHK**8B=wpoa_^{k;e!QCjk@b30`MjN7z1|IUfSFnQVU=+kj%x6jkoUT>^h4ra<$T?5FeVolRP6eDTJQ}Fs`zg$*Oc4HzxVsQs-&FH>nV|x<)eBAN=pNtEn-3SwV zPDeV9=L?E2a`@3eUgSn?!S!zvy+!Mbl|T#Nm>VZm;CpLIMMDFx*%l+kR)%cD?L;mm z>38Lnv%a6VCZU#wuV*W|bYFa>ncut9N7Uk|1U0FmJShpozGMpDq)EQ+@vX{AS z=Gg}ev^<>$x3Ha6+^Y;)#V+C;8HCS&^BEA+>^1Eh(Q9rTxyI7DsNt2BcFu~f zOeKEvlp5D#*E~H0zBRVA*04Zslf=Q-B+uRM{7}DXcfTgfXeN@{X}->EwbF2l{Nk0U z+&kBoC!togy*2o3!Mzc$JrLhZ&Br+DHYh%zA#-!e=H*s9WSrzXX;XDBq?$w!X2z;0 zpzYD1`@+)1e(}A$tT>T|%7KB(AL73Ho})uAdk-S|LyU?Y`lCUyP5tWiYnSl$eXuI% zGo_;7~ffIAioztHU!1onPn+1&({S< z`5C=W>YIUw?bIWvsn}`Vo9+#c{WI&^Po{@F4X|N}a-bIxSzk^yf0yu%tyJlbDlRou zPt}!3IUsYwPwi}TfM!t?dkiG<(dv^>;m;+{+Y>X09#j4hN>RvW+o}fUYx!K4*vFgk z$pBeSmJRicUZ#ztmI(;&NXhupcoiR0^^543wLLqL)v3UPKf{R*WmlK_F*m&_|gOO0q}wB zrf8p26ZZlIJsAVRhELLk#n*0~;-Sx^j49dgZ*HizzM#$5r}k{oaF7OWX_wl43OB^x ze?s((D~wkGhcjm`L(!BLUyUkav}g_Wm8ex#dN#E9+}=H#yKV}iOXy1@g1i9%sjqtq zhL`7ic^F&~LBy4;)9oQY!RO{2x}&Dfne}Vo#uQeE$FVhUjz1~VZGy>|=XUSC8gc9p z_?tn(KnIbPjjcK{?b0=KFo-;;N;|d!x~;_zBIZVM0g~!A&P9Bp-RR5;7dhuG5S)A_ zJpt$@l2{7QAYsyJfHz0?om~KV1JY+v+^V^*RM!yfR24tz4G)m{=MQjA33|d5?SFF$ zm{+rG9L{S#xCOr9Ab2nU(pyP#+L8tz$me~F@lAf{Pd?m?^+L+oymrkr4}nnH_A3)) z?w(UF>Knsa7J2Bedu&$6SN!WHcMjFM!?Yq(+47oUX|o3gB9rzaM&|j?hW52h+e;wB5HjVL64F|E2_U6xA>Z4@3OS+eFJUet0%tuP| z^1`8Wy>hi{&T%5#f%2JLsgj)K)iwbieFMJ-J2xvHvd z$HR~&ZKaBT@uC?HcZx|Z6fs+Z zg@n3?4e~rfX&WnkOiv&(1X(FdJLl;9-1RmmwGqU=Sc^v_{uFqoX1v|6Q$=yr*p(HME8(`{wE z=lj|U|0=6E@b6%(edMiisp;LzH*20LHO+H-;IZiupNkKdg;C2fbHBRi5tHTyCt%

l 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 XI$ig8<4I6cz)^ -#include -#include +#pragma comment(lib, "fltk.lib") +#pragma comment(lib, "wsock32.lib") +#pragma comment(lib, "comctl32.lib") +#pragma comment(linker, "/NODEFAULTLIB:LIBCMTD.lib") + + #include +#include +#include +#include +#include -using namespace std; +#define window_size 400 +/*****************************************************************************/ +/* This class provides a view to copy the offscreen surface to */ +class My_Window : public Fl_Window{ + int x,y,button; + int handle(int e) + { -void button_cb(Fl_Widget* wid){ - Fl_Button* but = (Fl_Button*)wid; - - if(but->label()=="&Good job"){ - but->label("&Click me"); - } else - but->label("&Good job"); - but->redraw(); -} + switch (e) + { + case FL_MOVE: + x = Fl::event_x(); + y = Fl::event_y(); + std::cout<<"Postion X:"<< x <<" Postion Y:"<< y <begin(); + Fl_PNG_Image* background = new Fl_PNG_Image("../image/background.png"); + std::cout<Fl_Image::fail()<image(background); + box->redraw(); + window->end(); + window->show(argc,argv); + return Fl::run(); +} // main \ No newline at end of file From e6259c46e141fe00ae3d0ef3077f1bac7bb2fb0f Mon Sep 17 00:00:00 2001 From: chenhuan Date: Mon, 28 Oct 2019 22:14:42 +0100 Subject: [PATCH 04/39] remake show the bild the GUI can show a bild with the colormap --- image/background.png | Bin 47790 -> 0 bytes main/main.cpp | 51 ++++++++++++++++++++++++++++--------------- 2 files changed, 34 insertions(+), 17 deletions(-) delete mode 100644 image/background.png diff --git a/image/background.png b/image/background.png deleted file mode 100644 index 6f04f51385a7211134ce1a32d8b27cc205394233..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 47790 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

l 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 XI$ig8<4I6cz)^ #include #include #include -#include +#include -#define window_size 400 + +#define window_height 600 +#define window_width 800 + /*****************************************************************************/ /* This class provides a view to copy the offscreen surface to */ + +int color_map[window_width][window_height]; class My_Window : public Fl_Window{ int x,y,button; int handle(int e) @@ -28,25 +28,42 @@ class My_Window : public Fl_Window{ return 1; case FL_KEYBOARD: button = Fl::event_button(); - std::cout<<"Keyboard:"<< button <(1), x(), y(), w(), h(), color); + } + +public: + Pixel(int x,int y,int w,int h,int RGB) : + Fl_Widget(x,y,w,h,0) { + this->color = fl_rgb_color((uchar)((RGB&0xff000000)>>24),(uchar)((RGB&0xff0000)>>16),(uchar)((RGB&0xff00)>>8)); + } +}; + int main(int argc, char **argv) { - - int x, y, button; - My_Window* window = new My_Window(window_size, window_size, "example"); - Fl_Box* box = new Fl_Box(10,10,380,380); - + for(int i=0;i<100;i++){ + for (int j = 0; j < 100 ; j++) { + color_map[i][j]=0xff000000; + } + } + My_Window* window = new My_Window(window_width, window_height, "example"); window->begin(); - Fl_PNG_Image* background = new Fl_PNG_Image("../image/background.png"); - std::cout<Fl_Image::fail()<image(background); - box->redraw(); + for(int i=0;i<100;i++){ + for (int j = 0; j < 100 ; j++) { + new Pixel(i,j,1,1,color_map[i][j]); + } + } window->end(); window->show(argc,argv); return Fl::run(); From a2f8d82614c66518dd7d88c85794ecb714c9ebec Mon Sep 17 00:00:00 2001 From: Edgar Schkrob Date: Wed, 30 Oct 2019 10:00:41 +0000 Subject: [PATCH 05/39] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 830c863..5d78a92 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # vKVM GUI - +The GUI is based on the FLTK (Fast Light Toolkit) and creates a window, +which processes incoming signals from the Shared Memory into an visual image. +The image refreshes on each change within the Shared Memory and periodically by itself. ## Installation Use the installation script provided in the Scripts repository From 7ddea2b130d75726cd5f0b11828948a1eb621cc4 Mon Sep 17 00:00:00 2001 From: chenhuan Date: Wed, 6 Nov 2019 12:17:23 +0100 Subject: [PATCH 06/39] 1.remake show the bild 2.the GUI can show a bild with the colormap 3.Kommentar --- main/main.cpp | 135 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 102 insertions(+), 33 deletions(-) diff --git a/main/main.cpp b/main/main.cpp index 97583c4..9100a35 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -2,69 +2,138 @@ #include #include #include +#include #include #include - #define window_height 600 #define window_width 800 -/*****************************************************************************/ +/**************************************[[l***************************************/ /* This class provides a view to copy the offscreen surface to */ -int color_map[window_width][window_height]; -class My_Window : public Fl_Window{ - int x,y,button; - int handle(int e) - { +//Pixel ist ein neue Class fuer ein Pixel +class Pixel : public Fl_Widget { + Fl_Color color; + //Pixel zu malen, x,y sind fuer die Postion in Window.w,h ist width und height.color ist die Farbe von Pixel + void draw() { + fl_draw_box(FL_FLAT_BOX, x(), y(), w(), h(), color); + } - switch (e) - { +public: + //Konstruktor + Pixel(int x, int y, int w, int h) : + Fl_Widget(x, y, w, h, 0) {} + //die Farbe von Pixel einstellen + void set_color(int RGB){ + this->color = fl_rgb_color((uchar) ((RGB & 0xff000000) >> 24), (uchar) ((RGB & 0xff0000) >> 16), + (uchar) ((RGB & 0xff00) >> 8)); + } +}; + + +class My_Window : public Fl_Window { + int x, y, button; + int (*color_map)[window_width][window_height]; + Pixel* pixels[window_width][window_height]; + int c=0xff000000; + //die Inputs von Maus und Tastatur behandln + int handle(int e) { + switch (e) { + //Druck vom Maus behandln + case FL_PUSH: + if(Fl::event_button()==FL_LEFT_MOUSE){ + std::cout << "Mouse:left" << std::endl; + }else if(Fl::event_button()==FL_RIGHT_MOUSE){ + std::cout << "Mouse:right" << std::endl; + }else{ + std::cout << "Mouse:middle" << std::endl; + } + return 1; + //Druck und Bewegung vom Maus behandln + case FL_DRAG: + x = Fl::event_x(); + y = Fl::event_y(); + std::cout << "Postion X:" << x << " Postion Y:" << y << std::endl; + if(Fl::event_button()==FL_LEFT_MOUSE){ + std::cout << "Mouse:left" << std::endl; + }else if(Fl::event_button()==FL_RIGHT_MOUSE){ + std::cout << "Mouse:right" << std::endl; + }else{ + std::cout << "Mouse:middle" << std::endl; + } + return 1; + //Bewegung vom Maus behandln case FL_MOVE: x = Fl::event_x(); y = Fl::event_y(); - std::cout<<"Postion X:"<< x <<" Postion Y:"<< y <(1), x(), y(), w(), h(), color); + //Konstruktor + My_Window(int x, int y, const char *l, int (*color_map)[window_width][window_height]) : Fl_Window(x, y, l) { + this->color_map = color_map; + for (int i = 0; i < window_width; i++) { + for (int j = 0; j < window_height; j++) { + pixels[i][j]=new Pixel(i,j,1,1); + } + } } - -public: - Pixel(int x,int y,int w,int h,int RGB) : - Fl_Widget(x,y,w,h,0) { - this->color = fl_rgb_color((uchar)((RGB&0xff000000)>>24),(uchar)((RGB&0xff0000)>>16),(uchar)((RGB&0xff00)>>8)); + //Window akualisieren, refresh + int draw_bild() { + for (int i = 0; i < window_width; i++) { + for (int j = 0; j < window_height; j++) { + pixels[i][j]->set_color((*color_map)[i][j]); + pixels[i][j]->redraw(); + } + } } }; +//draw_bild() wird regelmaessig anrufen +void refresh(void* pointer){ + ((My_Window*)pointer)->draw_bild(); + Fl::repeat_timeout(0.5, refresh,pointer); +} +//die Farbe von Pixels regekmaessig aendern +void change_color(void* pointer){ + int (*color_map)[window_width][window_height]; + color_map = (typeof(color_map))(pointer); + for (int i = 0; i < 100; i++) { + for (int j = 0; j < 100; j++) { + (*color_map)[i][j] ^= 0xffff0000; + } + } + + Fl::repeat_timeout(1, change_color,pointer); +} + int main(int argc, char **argv) { - for(int i=0;i<100;i++){ - for (int j = 0; j < 100 ; j++) { - color_map[i][j]=0xff000000; + + int color_map[window_width][window_height]; + + for (int i = 0; i < 100; i++) { + for (int j = 0; j < 100; j++) { + color_map[i][j] = 0xff000000; } } - My_Window* window = new My_Window(window_width, window_height, "example"); + My_Window *window = new My_Window(window_width, window_height, "example", &color_map); window->begin(); - for(int i=0;i<100;i++){ - for (int j = 0; j < 100 ; j++) { - new Pixel(i,j,1,1,color_map[i][j]); - } - } + Fl::repeat_timeout(0.5, refresh,window);//refresh anrufen nach 0.5 sec + Fl::repeat_timeout(1,change_color, &color_map);// change_color anrufen nach 1 sec + window->end(); - window->show(argc,argv); + window->show(argc, argv); return Fl::run(); } // main \ No newline at end of file From 2a8b11f6d3a91df04396a67fb792791a1e5645f8 Mon Sep 17 00:00:00 2001 From: Edgar Schkrob Date: Thu, 7 Nov 2019 12:43:16 +0100 Subject: [PATCH 07/39] main.cpp comments updated --- main/main.cpp | 217 +++++++++++++++++++++++++++++++------------------- 1 file changed, 136 insertions(+), 81 deletions(-) diff --git a/main/main.cpp b/main/main.cpp index 9100a35..934eceb 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -1,8 +1,8 @@ #include #include -#include -#include +#include +#include #include #include @@ -10,130 +10,185 @@ #define window_height 600 #define window_width 800 -/**************************************[[l***************************************/ -/* This class provides a view to copy the offscreen surface to */ - -//Pixel ist ein neue Class fuer ein Pixel -class Pixel : public Fl_Widget { - Fl_Color color; - //Pixel zu malen, x,y sind fuer die Postion in Window.w,h ist width und height.color ist die Farbe von Pixel - void draw() { - fl_draw_box(FL_FLAT_BOX, x(), y(), w(), h(), color); - } +//Statusbar**************************************/ +/** The class inherits a char *text from the Fl_Box. It also shows the window-resolution and the mouse-position. + * @param text: A pointer to a char-array, that can contain a text like a status or whatever you want. + * @parameter x: The mouse-position on the x-axis. + * @parameter y: The mouse-position on the y-axis: + * @parameter w: The width of a single pixel, + * @parameter h: The height of a single pixel. + */ +class Statusbar: public Fl_Box { + char *text; public: - //Konstruktor - Pixel(int x, int y, int w, int h) : - Fl_Widget(x, y, w, h, 0) {} - //die Farbe von Pixel einstellen - void set_color(int RGB){ - this->color = fl_rgb_color((uchar) ((RGB & 0xff000000) >> 24), (uchar) ((RGB & 0xff0000) >> 16), - (uchar) ((RGB & 0xff00) >> 8)); + /** The constructor of Statusbar has to get additional parameters. + * @param x: The mouse-position on the x-axis. + * @param y: The mouse-position on the y-axis: + * @param w: The width of a single pixel, + * @param h: The height of a single pixel. + */ + Statusbar(int x, int y, int w, int h, char *text) : + Fl_Box(x, y, w, h,text) { + this->text = text; + }; + void set_text(char *text) { + this->text = text; + } + //An exampel to show, how the content of the text can be changed. + void change_text(){ + if(text=="status0") + set_text("status1"); + else + set_text("status0"); + } + //This function refreshes the statusbar + void refresh_label(){ + this->label(text); } }; +//Image**************************************/ +/** The Image-class draws the bitmap that it get from the Shared Memory. + * @param *buf: A pointer to the bitmap, that the image-class has to draw. Three chars are needed to get the RGB-value of a pixel, so the size equals window_height * window_width * 3. + */ +class Image : public Fl_Widget { + uchar *buf; + + //Function to draw a bitmap + void draw() { + fl_draw_image(buf, x(), y(), w(), h()); + } + /** The constructor of the image class, get additional + * @param x: The mouse-position on the x-axis. + * @param y: The mouse-position on the y-axis: + * @param w: The width of a single pixel, + * @param h: The height of a single pixel. + */ + +public: + /*Constructor*/ + Image(int x, int y, int w, int h) : + Fl_Widget(x, y, w, h, 0) { + buf = new uchar[w * h * 3]; + /*Just an example.*/ + for (int i = 0; i < h; i++) { + for (int j = 0; j < w; j++) { + buf[(j + (i * w)) * 3 + 1] = 0xff; + } + } + } +/*A function to change the colors of the image-class. The colors are changing in this order: green, blue, red*/ + void change_color() { + for (int j = 1; j < w() * h() * 3; j++) { + if (buf[j] == 0xff) { + buf[j] = 0; + buf[j - 1] = 0xff; + } + } + if (buf[2] == 0xff) + buf[w() * h() * 3 - 1] = 0xff; + } +}; + +//My_Window*************************************/ +/** The My_Windows-class generates a window, within the window it recognizes the curretn mouse-position. + * It also recognizes if a button is pushed on the keyboard or the mouse. Furthermore the class depict the + * content of the Image-class and provides functions to refresh it. + * @parame x The mouse-position on the x-axis. + * @parame y The mouse-position on the y-axis. + * @parame button The button that was pushed last. + */ class My_Window : public Fl_Window { int x, y, button; - int (*color_map)[window_width][window_height]; - Pixel* pixels[window_width][window_height]; - int c=0xff000000; - //die Inputs von Maus und Tastatur behandln + + /*Function to handle the input*/ int handle(int e) { switch (e) { - //Druck vom Maus behandln + /*Mousebutton*/ case FL_PUSH: - if(Fl::event_button()==FL_LEFT_MOUSE){ + if (Fl::event_button() == FL_LEFT_MOUSE) { std::cout << "Mouse:left" << std::endl; - }else if(Fl::event_button()==FL_RIGHT_MOUSE){ + } else if (Fl::event_button() == FL_RIGHT_MOUSE) { std::cout << "Mouse:right" << std::endl; - }else{ + } else { std::cout << "Mouse:middle" << std::endl; } return 1; - //Druck und Bewegung vom Maus behandln + /*Mousebutton and movement*/ case FL_DRAG: x = Fl::event_x(); y = Fl::event_y(); std::cout << "Postion X:" << x << " Postion Y:" << y << std::endl; - if(Fl::event_button()==FL_LEFT_MOUSE){ + if (Fl::event_button() == FL_LEFT_MOUSE) { std::cout << "Mouse:left" << std::endl; - }else if(Fl::event_button()==FL_RIGHT_MOUSE){ + } else if (Fl::event_button() == FL_RIGHT_MOUSE) { std::cout << "Mouse:right" << std::endl; - }else{ + } else { std::cout << "Mouse:middle" << std::endl; } return 1; - //Bewegung vom Maus behandln + /*Mousemovement*/ case FL_MOVE: x = Fl::event_x(); y = Fl::event_y(); std::cout << "Postion X:" << x << " Postion Y:" << y << std::endl; return 1; - //Druck von der Tastator behandln + /*keyboardbutton*/ case FL_KEYBOARD: button = Fl::event_button(); std::cout << "Keyboard:" << (unsigned short) button << std::endl; return 1; - // case FL_: } } public: - //Konstruktor - My_Window(int x, int y, const char *l, int (*color_map)[window_width][window_height]) : Fl_Window(x, y, l) { - this->color_map = color_map; - for (int i = 0; i < window_width; i++) { - for (int j = 0; j < window_height; j++) { - pixels[i][j]=new Pixel(i,j,1,1); - } - } - } - //Window akualisieren, refresh - int draw_bild() { - for (int i = 0; i < window_width; i++) { - for (int j = 0; j < window_height; j++) { - pixels[i][j]->set_color((*color_map)[i][j]); - pixels[i][j]->redraw(); - } - } - } + /*Constructor*/ + My_Window(int x, int y, const char *l) : Fl_Window(x, y, l) {} }; -//draw_bild() wird regelmaessig anrufen -void refresh(void* pointer){ - ((My_Window*)pointer)->draw_bild(); - Fl::repeat_timeout(0.5, refresh,pointer); -} -//die Farbe von Pixels regekmaessig aendern -void change_color(void* pointer){ - int (*color_map)[window_width][window_height]; - color_map = (typeof(color_map))(pointer); - for (int i = 0; i < 100; i++) { - for (int j = 0; j < 100; j++) { - (*color_map)[i][j] ^= 0xffff0000; - } - } - - Fl::repeat_timeout(1, change_color,pointer); +/*Functions to refresh the image.*/ +void refresh_image(void *pointer) { + ((Image *) pointer)->redraw(); + Fl::repeat_timeout(0.5, refresh_image, pointer);//nach 0.5 sec refresh_bild(pointer) anrufen. Here pointer ist wie ein Parameter } +void change_color(void *pointer) { + ((Image *) pointer)->change_color(); + Fl::repeat_timeout(1, change_color, pointer); +} + +void refresh_statusbar(void *pointer) { + ((Statusbar **) pointer)[0]->refresh_label(); + Fl::repeat_timeout(0.5, refresh_statusbar, pointer); +} + +void change_status(void *pointer) { + ((Status_Leiste **) pointer)[0]->change_text(); + Fl::repeat_timeout(1, change_status, pointer); +} + +//main*************************************/ +/** + * The main function initializes all needed classes and executes the functions. + */ int main(int argc, char **argv) { - - int color_map[window_width][window_height]; - - for (int i = 0; i < 100; i++) { - for (int j = 0; j < 100; j++) { - color_map[i][j] = 0xff000000; - } - } - My_Window *window = new My_Window(window_width, window_height, "example", &color_map); + My_Window *window = new My_Window(window_width, window_height, "example"); + Status_Leiste *status[5]; window->begin(); - Fl::repeat_timeout(0.5, refresh,window);//refresh anrufen nach 0.5 sec - Fl::repeat_timeout(1,change_color, &color_map);// change_color anrufen nach 1 sec - + Bild *bild = new Bild(0, 30, window_width, window_height - 30); + status[0] = new Status_Leiste(0, 0, 60, 30, "status0"); + status[1] = new Status_Leiste(60, 0, 60, 30, "status1"); + status[2] = new Status_Leiste(120, 0, 60, 30, "status2"); + status[3] = new Status_Leiste(180, 0, 60, 30, "status3"); + status[4] = new Status_Leiste(240, 0, 60, 30, "status4"); + Fl::repeat_timeout(0.5, refresh_bild, bild); + Fl::repeat_timeout(1, change_color, bild); + Fl::repeat_timeout(0.5, refresh_status_leiste, status); + Fl::repeat_timeout(1, change_status, status); window->end(); window->show(argc, argv); return Fl::run(); -} // main \ No newline at end of file +}main \ No newline at end of file From de18073b6990a786260effb24b25b14246e545f4 Mon Sep 17 00:00:00 2001 From: Johannes Theiner Date: Thu, 7 Nov 2019 14:01:21 +0000 Subject: [PATCH 08/39] + ci pipeline --- .ci/clang-tidy.sh | 32 ++++++++++++++++++++++ .gitlab-ci.yml | 68 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 100 insertions(+) create mode 100644 .ci/clang-tidy.sh create mode 100644 .gitlab-ci.yml diff --git a/.ci/clang-tidy.sh b/.ci/clang-tidy.sh new file mode 100644 index 0000000..eae5b12 --- /dev/null +++ b/.ci/clang-tidy.sh @@ -0,0 +1,32 @@ +#!/bin/sh + +echo "Doing clang-tidy..." +bool=false +# explicitly set IFS to contain only a line feed +IFS=' +' +filelist="$(find . -not \( -path './client/cpptoml/*' -prune \) -type f ! -name "$(printf "*\n*")")" +for file in $filelist; do + if echo "$file" | grep -q -E ".*\.cpp$" ; then + #Extra check missing dependencies due to clang-tidy doesn't toggle exit code. + clang_tidy_lib_check="$(clang-tidy -warnings-as-errors='*' -header-filter='.*,-cpptoml.hpp' -checks='*,-llvm-header-guard,-fuchsia-statically-constructed-objects,-fuchsia-default-arguments,-cppcoreguidelines-pro-bounds-pointer-arithmetic,-cppcoreguidelines-pro-bounds-constant-array-index,-bugprone-narrowing-conversions,-cppcoreguidelines-narrowing-conversions,-cppcoreguidelines-pro-type-const-cast,-cppcoreguidelines-pro-type-reinterpret-cast,-hicpp-signed-bitwise,-bugprone-exception-escape,-cppcoreguidelines-pro-type-member-init,-cppcoreguidelines-pro-type-cstyle-cast,-hicpp-member-init' "$file" -- -I. -std=c++14 2>&1)" + for tidy_line in $clang_tidy_lib_check; do + echo "$tidy_line" | grep -q -v -E "^Error while processing*" + if [ $? -eq 1 ]; then + bool=true + fi + echo "$tidy_line" | grep -q -v -E ".* error: .*" + if [ $? -eq 1 ]; then + bool=true + fi + echo "$tidy_line" + done + fi +done +if $bool; then + exit 1 +else + echo "No clang-tidy errors found." +fi + +exit 0 diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..32d0eb7 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,68 @@ +--- + +image: samueldebruyn/debian-git:latest + +stages: + - style + - test + - build + + +clang_tidy: + image: jhasse/clang-tidy + stage: style + tags: + - docker-ci + script: + - sh .ci/clang-tidy.sh; + +make_test: + stage: test + tags: + - docker-ci + script: + - apt-get update + - apt-get install -y g++ make cmake clang-tidy libfltk1.3 libfltk1.3-dev + - mkdir current + - ls | grep -v current | xargs mv -t current + - git clone https://github.com/catchorg/Catch2.git + - cd Catch2 + - cmake -Bbuild -H. -DBUILD_TESTING=OFF + - cmake --build build/ --target install + - cd .. + - git clone https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.repo.digitech.hs-emden-leer.de/link/projekte/ws19/vkvm-new/library.git + - mkdir library/build + - cd library/build + - cmake .. + - make + - cd ../../current + - mkdir build + - cd build + - cmake .. + - make + - make test + +cmake_build: + stage: build + tags: + - docker-ci + script: + - apt-get update + - apt-get install -y g++ make cmake clang-tidy libfltk1.3 libfltk1.3-dev + - mkdir current + - ls | grep -v current | xargs mv -t current + - git clone https://github.com/catchorg/Catch2.git + - cd Catch2 + - cmake -Bbuild -H. -DBUILD_TESTING=OFF + - cmake --build build/ --target install + - cd .. + - git clone https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.repo.digitech.hs-emden-leer.de/link/projekte/ws19/vkvm-new/library.git + - mkdir library/build + - cd library/build + - cmake .. + - make + - cd ../../current + - mkdir build + - cd build + - cmake .. + - make \ No newline at end of file From 24a7b22878cf297957551dbf1fcf18410e940ef1 Mon Sep 17 00:00:00 2001 From: Johannes Theiner Date: Tue, 12 Nov 2019 11:12:08 +0000 Subject: [PATCH 09/39] ~ CI: clang_tidy step now contains catch2 & fltk --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 32d0eb7..033cd86 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -9,7 +9,7 @@ stages: clang_tidy: - image: jhasse/clang-tidy + image: joethei/clang_tidy stage: style tags: - docker-ci From f85ff6b45a660107f0fc743a536aacad3f338975 Mon Sep 17 00:00:00 2001 From: Johannes Theiner Date: Tue, 12 Nov 2019 11:41:30 +0000 Subject: [PATCH 10/39] ~ default argument calls are now allowed --- .ci/clang-tidy.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci/clang-tidy.sh b/.ci/clang-tidy.sh index eae5b12..c20c8fb 100644 --- a/.ci/clang-tidy.sh +++ b/.ci/clang-tidy.sh @@ -9,7 +9,7 @@ filelist="$(find . -not \( -path './client/cpptoml/*' -prune \) -type f ! -name for file in $filelist; do if echo "$file" | grep -q -E ".*\.cpp$" ; then #Extra check missing dependencies due to clang-tidy doesn't toggle exit code. - clang_tidy_lib_check="$(clang-tidy -warnings-as-errors='*' -header-filter='.*,-cpptoml.hpp' -checks='*,-llvm-header-guard,-fuchsia-statically-constructed-objects,-fuchsia-default-arguments,-cppcoreguidelines-pro-bounds-pointer-arithmetic,-cppcoreguidelines-pro-bounds-constant-array-index,-bugprone-narrowing-conversions,-cppcoreguidelines-narrowing-conversions,-cppcoreguidelines-pro-type-const-cast,-cppcoreguidelines-pro-type-reinterpret-cast,-hicpp-signed-bitwise,-bugprone-exception-escape,-cppcoreguidelines-pro-type-member-init,-cppcoreguidelines-pro-type-cstyle-cast,-hicpp-member-init' "$file" -- -I. -std=c++14 2>&1)" + clang_tidy_lib_check="$(clang-tidy -warnings-as-errors='*' -header-filter='.*,-cpptoml.hpp' -checks='*,-llvm-header-guard,-fuchsia-statically-constructed-objects,-fuchsia-default-arguments,-fuchsia-default-argument-calls,-cppcoreguidelines-pro-bounds-pointer-arithmetic,-cppcoreguidelines-pro-bounds-constant-array-index,-bugprone-narrowing-conversions,-cppcoreguidelines-narrowing-conversions,-cppcoreguidelines-pro-type-const-cast,-cppcoreguidelines-pro-type-reinterpret-cast,-hicpp-signed-bitwise,-bugprone-exception-escape,-cppcoreguidelines-pro-type-member-init,-cppcoreguidelines-pro-type-cstyle-cast,-hicpp-member-init' "$file" -- -I. -std=c++14 2>&1)" for tidy_line in $clang_tidy_lib_check; do echo "$tidy_line" | grep -q -v -E "^Error while processing*" if [ $? -eq 1 ]; then From ea4c9187583c15d8bd59d67b89d1f1342cc79874 Mon Sep 17 00:00:00 2001 From: Johannes Theiner Date: Tue, 12 Nov 2019 15:20:24 +0100 Subject: [PATCH 11/39] ~ clang-tidy checks all files now --- .ci/clang-tidy.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.ci/clang-tidy.sh b/.ci/clang-tidy.sh index c20c8fb..913c79a 100644 --- a/.ci/clang-tidy.sh +++ b/.ci/clang-tidy.sh @@ -5,11 +5,11 @@ bool=false # explicitly set IFS to contain only a line feed IFS=' ' -filelist="$(find . -not \( -path './client/cpptoml/*' -prune \) -type f ! -name "$(printf "*\n*")")" +filelist="$(find . -not \( -path './*build*' -prune \) -type f ! -name "$(printf "*\n*")")" for file in $filelist; do - if echo "$file" | grep -q -E ".*\.cpp$" ; then + if echo "$file" | grep -q -E ".*(\.cpp|\.h|\.hpp)$" ; then #Extra check missing dependencies due to clang-tidy doesn't toggle exit code. - clang_tidy_lib_check="$(clang-tidy -warnings-as-errors='*' -header-filter='.*,-cpptoml.hpp' -checks='*,-llvm-header-guard,-fuchsia-statically-constructed-objects,-fuchsia-default-arguments,-fuchsia-default-argument-calls,-cppcoreguidelines-pro-bounds-pointer-arithmetic,-cppcoreguidelines-pro-bounds-constant-array-index,-bugprone-narrowing-conversions,-cppcoreguidelines-narrowing-conversions,-cppcoreguidelines-pro-type-const-cast,-cppcoreguidelines-pro-type-reinterpret-cast,-hicpp-signed-bitwise,-bugprone-exception-escape,-cppcoreguidelines-pro-type-member-init,-cppcoreguidelines-pro-type-cstyle-cast,-hicpp-member-init' "$file" -- -I. -std=c++14 2>&1)" + clang_tidy_lib_check="$(clang-tidy -warnings-as-errors='*' -header-filter='.*,-cpptoml.hpp' -checks='*,-llvm-header-guard,-fuchsia-statically-constructed-objects,-fuchsia-default-arguments,-fuchsia-default-arguments-calls,-cppcoreguidelines-pro-bounds-pointer-arithmetic,-cppcoreguidelines-pro-bounds-constant-array-index,-bugprone-narrowing-conversions,-cppcoreguidelines-narrowing-conversions,-cppcoreguidelines-pro-type-const-cast,-cppcoreguidelines-pro-type-reinterpret-cast,-hicpp-signed-bitwise,-bugprone-exception-escape,-cppcoreguidelines-pro-type-member-init,-cppcoreguidelines-pro-type-cstyle-cast,-hicpp-member-init' "$file" -- -I. -std=c++14 2>&1)" for tidy_line in $clang_tidy_lib_check; do echo "$tidy_line" | grep -q -v -E "^Error while processing*" if [ $? -eq 1 ]; then From 2a6a0afd1a5f0ef0a167ad854cf265e070dee3ab Mon Sep 17 00:00:00 2001 From: chenhuan Date: Thu, 14 Nov 2019 11:54:47 +0100 Subject: [PATCH 12/39] 1.remake show the bild 2.the GUI can show a bild with the colormap 3.Kommentar 4.connect with library --- main/main.cpp | 121 +++++++++++++++++++++++--------------------------- 1 file changed, 55 insertions(+), 66 deletions(-) diff --git a/main/main.cpp b/main/main.cpp index 934eceb..4ffe6c7 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -2,85 +2,75 @@ #include #include #include -#include #include #include +#include "vkvm.hpp" + #define window_height 600 #define window_width 800 -//Statusbar**************************************/ +/**************************************[[l***************************************/ -/** The class inherits a char *text from the Fl_Box. It also shows the window-resolution and the mouse-position. - * @param text: A pointer to a char-array, that can contain a text like a status or whatever you want. - * @parameter x: The mouse-position on the x-axis. - * @parameter y: The mouse-position on the y-axis: - * @parameter w: The width of a single pixel, - * @parameter h: The height of a single pixel. - */ -class Statusbar: public Fl_Box { +//Es ist Class fuer Status +class Status_Leiste : public Fl_Box { char *text; public: - /** The constructor of Statusbar has to get additional parameters. - * @param x: The mouse-position on the x-axis. - * @param y: The mouse-position on the y-axis: - * @param w: The width of a single pixel, - * @param h: The height of a single pixel. - */ - Statusbar(int x, int y, int w, int h, char *text) : +//Konstruktor + Status_Leiste(int x, int y, int w, int h, char *text) : Fl_Box(x, y, w, h,text) { this->text = text; }; void set_text(char *text) { this->text = text; } - //An exampel to show, how the content of the text can be changed. + //nur zu Beispiel, zu zeigen, dass der Inhalt von Status einfach geaendert werden kann. void change_text(){ if(text=="status0") set_text("status1"); else set_text("status0"); } - //This function refreshes the statusbar + //der neue Inhalt von Status zeigen void refresh_label(){ this->label(text); } }; -//Image**************************************/ -/** The Image-class draws the bitmap that it get from the Shared Memory. - * @param *buf: A pointer to the bitmap, that the image-class has to draw. Three chars are needed to get the RGB-value of a pixel, so the size equals window_height * window_width * 3. - */ +//Pixel ist ein neue Class fuer ein Pixel +class Bild : public Fl_Widget { + uchar *buf;//Bitmap fuer das Bild, es braucht 3 char um ein Pixel zu erklaren(RGB), deshalb die Groesse von buf ist window_height * window_width * 3 -class Image : public Fl_Widget { - uchar *buf; - - //Function to draw a bitmap + //buf ist das Bitmap fuer das Bild, x,y fuer Postion in Window, w, h, bedeutet height und width void draw() { fl_draw_image(buf, x(), y(), w(), h()); } - /** The constructor of the image class, get additional - * @param x: The mouse-position on the x-axis. - * @param y: The mouse-position on the y-axis: - * @param w: The width of a single pixel, - * @param h: The height of a single pixel. - */ public: - /*Constructor*/ - Image(int x, int y, int w, int h) : +//Konstruktor + Bild(int x, int y, int w, int h) : Fl_Widget(x, y, w, h, 0) { buf = new uchar[w * h * 3]; - /*Just an example.*/ +//nur als Beispiel for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { buf[(j + (i * w)) * 3 + 1] = 0xff; } } } -/*A function to change the colors of the image-class. The colors are changing in this order: green, blue, red*/ + +//die Farbe vom Bild aendern(Die Reihenfolge: gruen, rot, blau, gruen ) void change_color() { + for (int i = 0; i < h(); i++) { + for (int j = 0; j < w(); j++) { + vkvm::Color c = vkvm::getPixel(j,i); + buf[(i * w() + j) * 3 + 0] = c.getRed(); + buf[(i * w() + j) * 3 + 1] = c.getGreen(); + buf[(i * w() + j) * 3 + 2] = c.getBlue(); + } + } + /* for (int j = 1; j < w() * h() * 3; j++) { if (buf[j] == 0xff) { buf[j] = 0; @@ -89,24 +79,18 @@ public: } if (buf[2] == 0xff) buf[w() * h() * 3 - 1] = 0xff; + */ } }; -//My_Window*************************************/ -/** The My_Windows-class generates a window, within the window it recognizes the curretn mouse-position. - * It also recognizes if a button is pushed on the keyboard or the mouse. Furthermore the class depict the - * content of the Image-class and provides functions to refresh it. - * @parame x The mouse-position on the x-axis. - * @parame y The mouse-position on the y-axis. - * @parame button The button that was pushed last. - */ + class My_Window : public Fl_Window { int x, y, button; - /*Function to handle the input*/ +//die Inputs von Maus und Tastatur behandln int handle(int e) { switch (e) { - /*Mousebutton*/ +//Druck vom Maus behandln case FL_PUSH: if (Fl::event_button() == FL_LEFT_MOUSE) { std::cout << "Mouse:left" << std::endl; @@ -116,7 +100,7 @@ class My_Window : public Fl_Window { std::cout << "Mouse:middle" << std::endl; } return 1; - /*Mousebutton and movement*/ +//Druck und Bewegung vom Maus behandln case FL_DRAG: x = Fl::event_x(); y = Fl::event_y(); @@ -129,52 +113,57 @@ class My_Window : public Fl_Window { std::cout << "Mouse:middle" << std::endl; } return 1; - /*Mousemovement*/ +//Bewegung vom Maus behandln case FL_MOVE: x = Fl::event_x(); y = Fl::event_y(); std::cout << "Postion X:" << x << " Postion Y:" << y << std::endl; return 1; - /*keyboardbutton*/ +//Druck von der Tastator behandln case FL_KEYBOARD: button = Fl::event_button(); - std::cout << "Keyboard:" << (unsigned short) button << std::endl; + std::cout << "Keyboard:" << (unsigned short) button << " down"<redraw(); - Fl::repeat_timeout(0.5, refresh_image, pointer);//nach 0.5 sec refresh_bild(pointer) anrufen. Here pointer ist wie ein Parameter +//draw() wird regelmaessig anrufen +void refresh_bild(void *pointer) { + ((Bild *) pointer)->redraw(); + Fl::repeat_timeout(0.5, refresh_bild, pointer);//nach 0.5 sec refresh_bild(pointer) anrufen. Here pointer ist wie ein Parameter } +//die Farbe von Pixels regekmaessig aendern void change_color(void *pointer) { - ((Image *) pointer)->change_color(); + ((Bild *) pointer)->change_color(); Fl::repeat_timeout(1, change_color, pointer); } -void refresh_statusbar(void *pointer) { - ((Statusbar **) pointer)[0]->refresh_label(); - Fl::repeat_timeout(0.5, refresh_statusbar, pointer); +//refresh_status() von Status0 wird regelmaessig anrufen +void refresh_status_leiste(void *pointer) { + ((Status_Leiste **) pointer)[0]->refresh_label(); + Fl::repeat_timeout(0.5, refresh_status_leiste, pointer); } +//der Inhalt von Status0 regekmaessig aendern void change_status(void *pointer) { ((Status_Leiste **) pointer)[0]->change_text(); Fl::repeat_timeout(1, change_status, pointer); } - -//main*************************************/ -/** - * The main function initializes all needed classes and executes the functions. - */ +// main int main(int argc, char **argv) { + vkvm::initialize(0); + My_Window *window = new My_Window(window_width, window_height, "example"); Status_Leiste *status[5]; window->begin(); @@ -191,4 +180,4 @@ int main(int argc, char **argv) { window->end(); window->show(argc, argv); return Fl::run(); -}main \ No newline at end of file +} \ No newline at end of file From a72cc768db8a199653b5618b569eaddf5fad724f Mon Sep 17 00:00:00 2001 From: Edgar Schkrob Date: Thu, 14 Nov 2019 12:36:40 +0100 Subject: [PATCH 13/39] Aktuellste Version der GUI-main.cpp. Farben werden nun von der Shared Mamory ausgelesen. --- main/main.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/main/main.cpp b/main/main.cpp index 934eceb..5eb50c6 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -14,10 +14,6 @@ /** The class inherits a char *text from the Fl_Box. It also shows the window-resolution and the mouse-position. * @param text: A pointer to a char-array, that can contain a text like a status or whatever you want. - * @parameter x: The mouse-position on the x-axis. - * @parameter y: The mouse-position on the y-axis: - * @parameter w: The width of a single pixel, - * @parameter h: The height of a single pixel. */ class Statusbar: public Fl_Box { char *text; @@ -68,7 +64,6 @@ class Image : public Fl_Widget { */ public: - /*Constructor*/ Image(int x, int y, int w, int h) : Fl_Widget(x, y, w, h, 0) { buf = new uchar[w * h * 3]; From 5d55c2ec9567662fed23386acca3561b6b7cf47e Mon Sep 17 00:00:00 2001 From: Edgar Schkrob Date: Thu, 14 Nov 2019 12:40:34 +0100 Subject: [PATCH 14/39] Aktuellste Version der GUI-main.cpp. Farben werden nun von der Mamory ausgelesen. --- main/main.cpp | 134 +++++++++++++++++++++++++++----------------------- 1 file changed, 72 insertions(+), 62 deletions(-) diff --git a/main/main.cpp b/main/main.cpp index 5eb50c6..aca54ba 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -2,10 +2,11 @@ #include #include #include -#include #include #include +#include "vkvm.hpp" + #define window_height 600 #define window_width 800 @@ -15,7 +16,8 @@ /** The class inherits a char *text from the Fl_Box. It also shows the window-resolution and the mouse-position. * @param text: A pointer to a char-array, that can contain a text like a status or whatever you want. */ -class Statusbar: public Fl_Box { + +class Statusbar : public Fl_Box { char *text; public: /** The constructor of Statusbar has to get additional parameters. @@ -24,7 +26,7 @@ public: * @param w: The width of a single pixel, * @param h: The height of a single pixel. */ - Statusbar(int x, int y, int w, int h, char *text) : + Statusbar (int x, int y, int w, int h, char *text) : Fl_Box(x, y, w, h,text) { this->text = text; }; @@ -38,54 +40,12 @@ public: else set_text("status0"); } - //This function refreshes the statusbar + //This function refreshes the statusbar. void refresh_label(){ this->label(text); } }; -//Image**************************************/ -/** The Image-class draws the bitmap that it get from the Shared Memory. - * @param *buf: A pointer to the bitmap, that the image-class has to draw. Three chars are needed to get the RGB-value of a pixel, so the size equals window_height * window_width * 3. - */ - -class Image : public Fl_Widget { - uchar *buf; - - //Function to draw a bitmap - void draw() { - fl_draw_image(buf, x(), y(), w(), h()); - } - /** The constructor of the image class, get additional - * @param x: The mouse-position on the x-axis. - * @param y: The mouse-position on the y-axis: - * @param w: The width of a single pixel, - * @param h: The height of a single pixel. - */ - -public: - Image(int x, int y, int w, int h) : - Fl_Widget(x, y, w, h, 0) { - buf = new uchar[w * h * 3]; - /*Just an example.*/ - for (int i = 0; i < h; i++) { - for (int j = 0; j < w; j++) { - buf[(j + (i * w)) * 3 + 1] = 0xff; - } - } - } -/*A function to change the colors of the image-class. The colors are changing in this order: green, blue, red*/ - void change_color() { - for (int j = 1; j < w() * h() * 3; j++) { - if (buf[j] == 0xff) { - buf[j] = 0; - buf[j - 1] = 0xff; - } - } - if (buf[2] == 0xff) - buf[w() * h() * 3 - 1] = 0xff; - } -}; //My_Window*************************************/ /** The My_Windows-class generates a window, within the window it recognizes the curretn mouse-position. @@ -95,6 +55,7 @@ public: * @parame y The mouse-position on the y-axis. * @parame button The button that was pushed last. */ + class My_Window : public Fl_Window { int x, y, button; @@ -133,21 +94,69 @@ class My_Window : public Fl_Window { /*keyboardbutton*/ case FL_KEYBOARD: button = Fl::event_button(); - std::cout << "Keyboard:" << (unsigned short) button << std::endl; + std::cout << "Keyboard:" << (unsigned short) button << " down"<redraw(); - Fl::repeat_timeout(0.5, refresh_image, pointer);//nach 0.5 sec refresh_bild(pointer) anrufen. Here pointer ist wie ein Parameter + Fl::repeat_timeout(0.5, refresh_image, pointer);//nach 0.5 sec refresh_image(pointer) anrufen. Here pointer ist wie ein Parameter } void change_color(void *pointer) { @@ -161,29 +170,30 @@ void refresh_statusbar(void *pointer) { } void change_status(void *pointer) { - ((Status_Leiste **) pointer)[0]->change_text(); + ((Statusbar **) pointer)[0]->change_text(); Fl::repeat_timeout(1, change_status, pointer); } - //main*************************************/ /** * The main function initializes all needed classes and executes the functions. */ int main(int argc, char **argv) { + vkvm::initialize(0); + My_Window *window = new My_Window(window_width, window_height, "example"); - Status_Leiste *status[5]; + Statusbar *status[5]; window->begin(); - Bild *bild = new Bild(0, 30, window_width, window_height - 30); - status[0] = new Status_Leiste(0, 0, 60, 30, "status0"); - status[1] = new Status_Leiste(60, 0, 60, 30, "status1"); - status[2] = new Status_Leiste(120, 0, 60, 30, "status2"); - status[3] = new Status_Leiste(180, 0, 60, 30, "status3"); - status[4] = new Status_Leiste(240, 0, 60, 30, "status4"); - Fl::repeat_timeout(0.5, refresh_bild, bild); - Fl::repeat_timeout(1, change_color, bild); - Fl::repeat_timeout(0.5, refresh_status_leiste, status); + Image *image = new Image(0, 30, window_width, window_height - 30); + status[0] = new Statusbar(0, 0, 60, 30, "status0"); + status[1] = new Statusbar(60, 0, 60, 30, "status1"); + status[2] = new Statusbar(120, 0, 60, 30, "status2"); + status[3] = new Statusbar(180, 0, 60, 30, "status3"); + status[4] = new Statusbar(240, 0, 60, 30, "status4"); + Fl::repeat_timeout(0.5, refresh_image, image); + Fl::repeat_timeout(1, change_color, image); + Fl::repeat_timeout(0.5, refresh_statusbar, status); Fl::repeat_timeout(1, change_status, status); window->end(); window->show(argc, argv); return Fl::run(); -}main \ No newline at end of file +} \ No newline at end of file From 15b5d042edb3b545a8267ecc2ae9f14e9e88aca5 Mon Sep 17 00:00:00 2001 From: edgar Date: Thu, 14 Nov 2019 15:09:43 +0100 Subject: [PATCH 15/39] =?UTF-8?q?Aufger=C3=A4umter=20GUI-Code.=20Klassen?= =?UTF-8?q?=20wurden=20in=20eigene=20cpp-Dateien=20ausgelagert.=20GUI.hpp?= =?UTF-8?q?=20wurde=20implementiert.=20Klasseninitialisierung=20wurde=20in?= =?UTF-8?q?=20init.cpp=20ausgelagert.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 2 +- main/main.cpp | 201 +-------------------------- src/GUI.hpp | 39 ++++++ src/GUI_Window.cpp | 63 +++++++++ src/Image.cpp | 66 +++++++++ src/Statusbar.cpp | 35 +++++ src/demo.cpp | 5 - src/demo.h | 8 -- src/init.cpp | 35 +++++ test/{test_demo.cpp => test_GUI.cpp} | 4 +- 10 files changed, 247 insertions(+), 211 deletions(-) create mode 100644 src/GUI.hpp create mode 100644 src/GUI_Window.cpp create mode 100644 src/Image.cpp create mode 100644 src/Statusbar.cpp delete mode 100644 src/demo.cpp delete mode 100644 src/demo.h create mode 100644 src/init.cpp rename test/{test_demo.cpp => test_GUI.cpp} (52%) diff --git a/CMakeLists.txt b/CMakeLists.txt index bf43ed9..cd60b08 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,7 +22,7 @@ file(GLOB_RECURSE TESTS test/*.cpp) set(LIB_PATH "${CMAKE_SOURCE_DIR}/../library") include_directories(${LIB_PATH}/include) -add_executable(GUI ${SOURCES} ${HEADERS} main/main.cpp) +add_executable(GUI ${SOURCES} ${HEADERS} main/main.cpp src/Statusbar.cpp src/GUI_Window.cpp src/Image.cpp src/GUI.hpp src/init.cpp) target_link_libraries(GUI ${LIB_PATH}/lib/liblibrary.a) diff --git a/main/main.cpp b/main/main.cpp index aca54ba..15c92c4 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -1,199 +1,10 @@ +#include "GUI.hpp" -#include -#include -#include -#include -#include - -#include "vkvm.hpp" - - -#define window_height 600 -#define window_width 800 - -//Statusbar**************************************/ - -/** The class inherits a char *text from the Fl_Box. It also shows the window-resolution and the mouse-position. - * @param text: A pointer to a char-array, that can contain a text like a status or whatever you want. - */ - -class Statusbar : public Fl_Box { - char *text; -public: - /** The constructor of Statusbar has to get additional parameters. - * @param x: The mouse-position on the x-axis. - * @param y: The mouse-position on the y-axis: - * @param w: The width of a single pixel, - * @param h: The height of a single pixel. - */ - Statusbar (int x, int y, int w, int h, char *text) : - Fl_Box(x, y, w, h,text) { - this->text = text; - }; - void set_text(char *text) { - this->text = text; - } - //An exampel to show, how the content of the text can be changed. - void change_text(){ - if(text=="status0") - set_text("status1"); - else - set_text("status0"); - } - //This function refreshes the statusbar. - void refresh_label(){ - this->label(text); - } -}; - - -//My_Window*************************************/ -/** The My_Windows-class generates a window, within the window it recognizes the curretn mouse-position. - * It also recognizes if a button is pushed on the keyboard or the mouse. Furthermore the class depict the - * content of the Image-class and provides functions to refresh it. - * @parame x The mouse-position on the x-axis. - * @parame y The mouse-position on the y-axis. - * @parame button The button that was pushed last. - */ - -class My_Window : public Fl_Window { - int x, y, button; - - /*Function to handle the input*/ - int handle(int e) { - switch (e) { - /*Mousebutton*/ - case FL_PUSH: - if (Fl::event_button() == FL_LEFT_MOUSE) { - std::cout << "Mouse:left" << std::endl; - } else if (Fl::event_button() == FL_RIGHT_MOUSE) { - std::cout << "Mouse:right" << std::endl; - } else { - std::cout << "Mouse:middle" << std::endl; - } - return 1; - /*Mousebutton and movement*/ - case FL_DRAG: - x = Fl::event_x(); - y = Fl::event_y(); - std::cout << "Postion X:" << x << " Postion Y:" << y << std::endl; - if (Fl::event_button() == FL_LEFT_MOUSE) { - std::cout << "Mouse:left" << std::endl; - } else if (Fl::event_button() == FL_RIGHT_MOUSE) { - std::cout << "Mouse:right" << std::endl; - } else { - std::cout << "Mouse:middle" << std::endl; - } - return 1; - /*Mousemovement*/ - case FL_MOVE: - x = Fl::event_x(); - y = Fl::event_y(); - std::cout << "Postion X:" << x << " Postion Y:" << y << std::endl; - return 1; - /*keyboardbutton*/ - case FL_KEYBOARD: - button = Fl::event_button(); - std::cout << "Keyboard:" << (unsigned short) button << " down"<redraw(); - Fl::repeat_timeout(0.5, refresh_image, pointer);//nach 0.5 sec refresh_image(pointer) anrufen. Here pointer ist wie ein Parameter -} - -void change_color(void *pointer) { - ((Image *) pointer)->change_color(); - Fl::repeat_timeout(1, change_color, pointer); -} - -void refresh_statusbar(void *pointer) { - ((Statusbar **) pointer)[0]->refresh_label(); - Fl::repeat_timeout(0.5, refresh_statusbar, pointer); -} - -void change_status(void *pointer) { - ((Statusbar **) pointer)[0]->change_text(); - Fl::repeat_timeout(1, change_status, pointer); -} -//main*************************************/ -/** - * The main function initializes all needed classes and executes the functions. +/** main + * The main function executes the functions of the GUI. */ + int main(int argc, char **argv) { - vkvm::initialize(0); - - My_Window *window = new My_Window(window_width, window_height, "example"); - Statusbar *status[5]; - window->begin(); - Image *image = new Image(0, 30, window_width, window_height - 30); - status[0] = new Statusbar(0, 0, 60, 30, "status0"); - status[1] = new Statusbar(60, 0, 60, 30, "status1"); - status[2] = new Statusbar(120, 0, 60, 30, "status2"); - status[3] = new Statusbar(180, 0, 60, 30, "status3"); - status[4] = new Statusbar(240, 0, 60, 30, "status4"); - Fl::repeat_timeout(0.5, refresh_image, image); - Fl::repeat_timeout(1, change_color, image); - Fl::repeat_timeout(0.5, refresh_statusbar, status); - Fl::repeat_timeout(1, change_status, status); - window->end(); - window->show(argc, argv); - return Fl::run(); + GUI_init(); + GUI_run(); } \ No newline at end of file diff --git a/src/GUI.hpp b/src/GUI.hpp new file mode 100644 index 0000000..74b9fd9 --- /dev/null +++ b/src/GUI.hpp @@ -0,0 +1,39 @@ +#include +#include +#include +#include +#include +#include "vkvm.hpp" + +#ifndef GUI_GUI_HPP +#define GUI_GUI_HPP +class GUI_Window : public Fl_Window { + int x, y, button; + int handle(int e); +public: + GUI_Window(int x, int y, const char *l) : Fl_Window(x, y, l) +} + +class Image : public Fl_Widget { + uchar *buf; +public: + Image(int x, int y, int w, int h); + void refresh_image(void *pointer); + void change_color(void *pointer); + void refresh_statusbar(void *pointer); + void change_status(void *pointer); +} + +class Statusbar : public Fl_Box { + char *text; +public: + Statusbar (int x, int y, int w, int h, char *text); + void set_text(char *text); + void change_text(); + void refresh_label(); +} + +void GUI_init(); +void GUI_run(); + +#endif //GUI_GUI_HPP diff --git a/src/GUI_Window.cpp b/src/GUI_Window.cpp new file mode 100644 index 0000000..73fb96e --- /dev/null +++ b/src/GUI_Window.cpp @@ -0,0 +1,63 @@ +#include "GUI.hpp" + +/** GUI_Window + * The GUI_Window-class generates a window, within the window it recognizes the curretn mouse-position. + * It also recognizes if a button is pushed on the keyboard or the mouse. Furthermore the class depict the + * content of the Image-class and provides functions to refresh it. + * @param x The mouse-position on the x-axis. + * @param y The mouse-position on the y-axis. + * @param button The button that was pushed last. + */ + +class GUI_Window : public Fl_Window { + int x, y, button; + + /*Function to handle the input*/ + int handle(int e) { + switch (e) { + /*Mousebutton*/ + case FL_PUSH: + if (Fl::event_button() == FL_LEFT_MOUSE) { + std::cout << "Mouse:left" << std::endl; + } else if (Fl::event_button() == FL_RIGHT_MOUSE) { + std::cout << "Mouse:right" << std::endl; + } else { + std::cout << "Mouse:middle" << std::endl; + } + return 1; + /*Mousebutton and movement*/ + case FL_DRAG: + x = Fl::event_x(); + y = Fl::event_y(); + std::cout << "Postion X:" << x << " Postion Y:" << y << std::endl; + if (Fl::event_button() == FL_LEFT_MOUSE) { + std::cout << "Mouse:left" << std::endl; + } else if (Fl::event_button() == FL_RIGHT_MOUSE) { + std::cout << "Mouse:right" << std::endl; + } else { + std::cout << "Mouse:middle" << std::endl; + } + return 1; + /*Mousemovement*/ + case FL_MOVE: + x = Fl::event_x(); + y = Fl::event_y(); + std::cout << "Postion X:" << x << " Postion Y:" << y << std::endl; + return 1; + /*keyboardbutton*/ + case FL_KEYBOARD: + button = Fl::event_button(); + std::cout << "Keyboard:" << (unsigned short) button << " down"<redraw(); + Fl::repeat_timeout(0.5, refresh_image, pointer);//nach 0.5 sec refresh_image(pointer) anrufen. Here pointer ist wie ein Parameter +} + +void change_color(void *pointer) { + ((Image *) pointer)->change_color(); + Fl::repeat_timeout(1, change_color, pointer); +} + +void refresh_statusbar(void *pointer) { + ((Statusbar **) pointer)[0]->refresh_label(); + Fl::repeat_timeout(0.5, refresh_statusbar, pointer); +} + +void change_status(void *pointer) { + ((Statusbar **) pointer)[0]->change_text(); + Fl::repeat_timeout(1, change_status, pointer); +} diff --git a/src/Statusbar.cpp b/src/Statusbar.cpp new file mode 100644 index 0000000..4bdfc2b --- /dev/null +++ b/src/Statusbar.cpp @@ -0,0 +1,35 @@ +#include "GUI.hpp" + +/** Statusbar + * The class inherits a char *text from the Fl_Box. It also shows the window-resolution and the mouse-position. + * @param text: A pointer to a char-array, that can contain a text like a status or whatever you want. + */ + +class Statusbar : public Fl_Box { + char *text; +public: + /** The constructor of Statusbar has to get additional parameters. + * @param x: The mouse-position on the x-axis. + * @param y: The mouse-position on the y-axis: + * @param w: The width of a single pixel, + * @param h: The height of a single pixel. + */ + Statusbar (int x, int y, int w, int h, char *text) : + Fl_Box(x, y, w, h,text) { + this->text = text; + }; + void set_text(char *text) { + this->text = text; + } + //An exampel to show, how the content of the text can be changed. + void change_text(){ + if(text=="status0") + set_text("status1"); + else + set_text("status0"); + } + //This function refreshes the statusbar. + void refresh_label(){ + this->label(text); + } +}; diff --git a/src/demo.cpp b/src/demo.cpp deleted file mode 100644 index 1cc01fc..0000000 --- a/src/demo.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "demo.h" - -int test() { - return 42; -} diff --git a/src/demo.h b/src/demo.h deleted file mode 100644 index 9b77cb9..0000000 --- a/src/demo.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef SHARED_MEMORY_DEMO_H -#define SHARED_MEMORY_DEMO_H - - -int test(); - - -#endif //SHARED_MEMORY_DEMO_H diff --git a/src/init.cpp b/src/init.cpp new file mode 100644 index 0000000..d42a800 --- /dev/null +++ b/src/init.cpp @@ -0,0 +1,35 @@ +#include "GUI.hpp" +#define window_height 600 +#define window_width 800 +/** GUI_init + * The GUI_init-function initializes all needed classes for the GUI. + */ +void GUI_init() { + vkvm::initialize(0); + My_Window *window = new My_Window(window_width, window_height, "example"); + Statusbar *status[5]; + Image *image = new Image(0, 30, window_width, window_height - 30); + + //Dummy-Values TBD + status[0] = new Statusbar(0, 0, 60, 30, "status0"); + status[1] = new Statusbar(60, 0, 60, 30, "status1"); + status[2] = new Statusbar(120, 0, 60, 30, "status2"); + status[3] = new Statusbar(180, 0, 60, 30, "status3"); + status[4] = new Statusbar(240, 0, 60, 30, "status4"); + +} + +/** GUI_run + * The GUI_run-function starts all functions needed for the GUI. + */ + +void GUI_run() { + window->begin(); + Fl::repeat_timeout(0.5, refresh_image, image); + Fl::repeat_timeout(1, change_color, image); + Fl::repeat_timeout(0.5, refresh_statusbar, status); + Fl::repeat_timeout(1, change_status, status); + window->end(); + window->show(argc, argv); + return Fl::run(); +} diff --git a/test/test_demo.cpp b/test/test_GUI.cpp similarity index 52% rename from test/test_demo.cpp rename to test/test_GUI.cpp index 7cb240e..f2244bb 100644 --- a/test/test_demo.cpp +++ b/test/test_GUI.cpp @@ -1,6 +1,6 @@ #include -#include "../src/demo.h" +#include "../src/GUI.hpp" -TEST_CASE("Demo test") { +TEST_CASE("GUI Test") { REQUIRE(test() == 42); } \ No newline at end of file From 900db627ce9c01ca62101d910b20ba926c9e694e Mon Sep 17 00:00:00 2001 From: edgar Date: Thu, 14 Nov 2019 15:11:10 +0100 Subject: [PATCH 16/39] =?UTF-8?q?Aufger=C3=A4umter=20GUI-Code.=20Klassen?= =?UTF-8?q?=20wurden=20in=20eigene=20cpp-Dateien=20ausgelagert.=20GUI.hpp?= =?UTF-8?q?=20wurde=20implementiert.=20Klasseninitialisierung=20wurde=20in?= =?UTF-8?q?=20init.cpp=20ausgelagert.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/main.cpp b/main/main.cpp index 15c92c4..5eac64c 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -3,7 +3,7 @@ /** main * The main function executes the functions of the GUI. */ - + int main(int argc, char **argv) { GUI_init(); GUI_run(); From 6d7d3c4d6d993433ec9dc1128abecade54418fa5 Mon Sep 17 00:00:00 2001 From: Johannes Theiner Date: Sat, 16 Nov 2019 18:27:16 +0000 Subject: [PATCH 17/39] ~ update clang tidy checks --- .ci/clang-tidy.sh | 2 +- .clang-tidy | 2 ++ CMakeLists.txt | 6 +++--- 3 files changed, 6 insertions(+), 4 deletions(-) create mode 100644 .clang-tidy diff --git a/.ci/clang-tidy.sh b/.ci/clang-tidy.sh index 913c79a..1c3d7b3 100644 --- a/.ci/clang-tidy.sh +++ b/.ci/clang-tidy.sh @@ -9,7 +9,7 @@ filelist="$(find . -not \( -path './*build*' -prune \) -type f ! -name "$(printf for file in $filelist; do if echo "$file" | grep -q -E ".*(\.cpp|\.h|\.hpp)$" ; then #Extra check missing dependencies due to clang-tidy doesn't toggle exit code. - clang_tidy_lib_check="$(clang-tidy -warnings-as-errors='*' -header-filter='.*,-cpptoml.hpp' -checks='*,-llvm-header-guard,-fuchsia-statically-constructed-objects,-fuchsia-default-arguments,-fuchsia-default-arguments-calls,-cppcoreguidelines-pro-bounds-pointer-arithmetic,-cppcoreguidelines-pro-bounds-constant-array-index,-bugprone-narrowing-conversions,-cppcoreguidelines-narrowing-conversions,-cppcoreguidelines-pro-type-const-cast,-cppcoreguidelines-pro-type-reinterpret-cast,-hicpp-signed-bitwise,-bugprone-exception-escape,-cppcoreguidelines-pro-type-member-init,-cppcoreguidelines-pro-type-cstyle-cast,-hicpp-member-init' "$file" -- -I. -std=c++14 2>&1)" + clang_tidy_lib_check="$(clang-tidy -warnings-as-errors='*' -header-filter='.*,-cpptoml.hpp' "$file" -- -I. -std=c++14 2>&1)" for tidy_line in $clang_tidy_lib_check; do echo "$tidy_line" | grep -q -v -E "^Error while processing*" if [ $? -eq 1 ]; then diff --git a/.clang-tidy b/.clang-tidy new file mode 100644 index 0000000..b0965ca --- /dev/null +++ b/.clang-tidy @@ -0,0 +1,2 @@ +Checks: '*,-llvm-header-guard,-fuchsia*,-cppcoreguidelines-pro-bounds-pointer-arithmetic,-cppcoreguidelines-pro-bounds-constant-array-index,-bugprone-narrowing-conversions,-cppcoreguidelines-narrowing-conversions,-cppcoreguidelines-pro-type-const-cast,-cppcoreguidelines-pro-type-reinterpret-cast,-hicpp-signed-bitwise,-bugprone-exception-escape,-cppcoreguidelines-pro-type-member-init,-cppcoreguidelines-pro-type-cstyle-cast,-hicpp-member-init,-google-readability-namespace-comments,-llvm-namespace-comment,-cppcoreguidelines-pro-type-vararg,-hicpp-vararg,-modernize-use-trailing-return-type' +WarningsAsErrors: 'true' diff --git a/CMakeLists.txt b/CMakeLists.txt index cd60b08..245df11 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,11 +12,11 @@ set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "bin" "doc" " project(GUI) set(CMAKE_CXX_STANDARD 14) -set(CMAKE_CXX_CLANG_TIDY "clang-tidy;-checks=*") -set(CMAKE_CXX_CLANG_TIDY clang-tidy;-header-filter=.;-checks=*;) +set(CMAKE_CXX_CLANG_TIDY "clang-tidy;") +set(CMAKE_CXX_CLANG_TIDY clang-tidy;-header-filter=.;) file(GLOB_RECURSE SOURCES src/*.cpp) -file(GLOB_RECURSE HEADERS src/*.h) +file(GLOB_RECURSE HEADERS src/*.hpp) file(GLOB_RECURSE TESTS test/*.cpp) set(LIB_PATH "${CMAKE_SOURCE_DIR}/../library") From 9ce74862a2688f366d2e6d5aef9aa20429ef0051 Mon Sep 17 00:00:00 2001 From: chenhuan Date: Mon, 18 Nov 2019 14:56:11 +0100 Subject: [PATCH 18/39] 1.code cleanup 2.mouse and keybroad interrupt --- CMakeLists.txt | 2 +- main/main.cpp | 5 +- src/{init.cpp => GUI.cpp} | 47 ++++++++++------- src/GUI.hpp | 57 +++++++++++++++----- src/GUI_Window.cpp | 108 ++++++++++++++++++-------------------- src/Image.cpp | 69 +++++++----------------- src/Statusbar.cpp | 58 ++++++++++---------- 7 files changed, 171 insertions(+), 175 deletions(-) rename src/{init.cpp => GUI.cpp} (57%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 245df11..aee843d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,7 +22,7 @@ file(GLOB_RECURSE TESTS test/*.cpp) set(LIB_PATH "${CMAKE_SOURCE_DIR}/../library") include_directories(${LIB_PATH}/include) -add_executable(GUI ${SOURCES} ${HEADERS} main/main.cpp src/Statusbar.cpp src/GUI_Window.cpp src/Image.cpp src/GUI.hpp src/init.cpp) +add_executable(GUI ${SOURCES} ${HEADERS} main/main.cpp src/Statusbar.cpp src/GUI_Window.cpp src/Image.cpp src/GUI.hpp src/GUI.cpp) target_link_libraries(GUI ${LIB_PATH}/lib/liblibrary.a) diff --git a/main/main.cpp b/main/main.cpp index 5eac64c..e71e8be 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -1,10 +1,9 @@ -#include "GUI.hpp" +#include "../src/GUI.hpp" /** main * The main function executes the functions of the GUI. */ int main(int argc, char **argv) { - GUI_init(); - GUI_run(); + GUI_run(argc,argv); } \ No newline at end of file diff --git a/src/init.cpp b/src/GUI.cpp similarity index 57% rename from src/init.cpp rename to src/GUI.cpp index d42a800..1ea82d5 100644 --- a/src/init.cpp +++ b/src/GUI.cpp @@ -1,35 +1,42 @@ #include "GUI.hpp" + #define window_height 600 #define window_width 800 -/** GUI_init - * The GUI_init-function initializes all needed classes for the GUI. - */ -void GUI_init() { - vkvm::initialize(0); - My_Window *window = new My_Window(window_width, window_height, "example"); - Statusbar *status[5]; - Image *image = new Image(0, 30, window_width, window_height - 30); - - //Dummy-Values TBD - status[0] = new Statusbar(0, 0, 60, 30, "status0"); - status[1] = new Statusbar(60, 0, 60, 30, "status1"); - status[2] = new Statusbar(120, 0, 60, 30, "status2"); - status[3] = new Statusbar(180, 0, 60, 30, "status3"); - status[4] = new Statusbar(240, 0, 60, 30, "status4"); - -} /** GUI_run * The GUI_run-function starts all functions needed for the GUI. */ -void GUI_run() { +auto GUI_run(int argc, char **argv) -> int { + vkvm::initialize(0); + GUI_Window *window = new GUI_Window(window_width, window_height, "example"); + Statusbar *status[5]; + //Dummy-Values TBD window->begin(); + Image *image = new Image(0, 30, window_width, window_height - 30); + status[0] = new Statusbar(0, 0, 60, 30, "0"); + status[1] = new Statusbar(60, 0, 60, 30, "status1"); + status[2] = new Statusbar(120, 0, 60, 30, "status2"); + status[3] = new Statusbar(180, 0, 60, 30, "status3"); + status[4] = new Statusbar(240, 0, 60, 30, "status4"); Fl::repeat_timeout(0.5, refresh_image, image); - Fl::repeat_timeout(1, change_color, image); Fl::repeat_timeout(0.5, refresh_statusbar, status); - Fl::repeat_timeout(1, change_status, status); window->end(); window->show(argc, argv); return Fl::run(); } + + +void refresh_image(void *pointer) { + ((Image *) pointer)->getPixels(); + ((Image *) pointer)->redraw(); + Fl::repeat_timeout(0.5, refresh_image, pointer); +} + + +void refresh_statusbar(void *pointer) { + ((Statusbar **) pointer)[0]->change_text(); + ((Statusbar **) pointer)[0]->refresh_label(); + Fl::repeat_timeout(0.5, refresh_statusbar, pointer); +} + diff --git a/src/GUI.hpp b/src/GUI.hpp index 74b9fd9..e8ab6c7 100644 --- a/src/GUI.hpp +++ b/src/GUI.hpp @@ -4,36 +4,65 @@ #include #include #include "vkvm.hpp" +#include "internal.hpp" #ifndef GUI_GUI_HPP #define GUI_GUI_HPP + +/** GUI_Window + * The GUI_Window-class generates a window, within the window it recognizes the curretn mouse-position. + * It also recognizes if a button is pushed on the keyboard or the mouse. Furthermore the class depict the + * content of the Image-class and provides functions to refresh it. + * @param x The mouse-position on the x-axis. + * @param y The mouse-position on the y-axis. + * @param button The button that was pushed last. + */ class GUI_Window : public Fl_Window { int x, y, button; + int handle(int e); + public: - GUI_Window(int x, int y, const char *l) : Fl_Window(x, y, l) -} + GUI_Window(int x, int y, const char *l); +}; + +/** The constructor of the image class, get additional + * @param x: The mouse-position on the x-axis. + * @param y: The mouse-position on the y-axis: + * @param w: The width of a single pixel, + * @param h: The height of a single pixel. + */ class Image : public Fl_Widget { uchar *buf; public: Image(int x, int y, int w, int h); - void refresh_image(void *pointer); - void change_color(void *pointer); - void refresh_statusbar(void *pointer); - void change_status(void *pointer); -} + void draw(); + + void getPixels(); +}; + +/** Statusbar + * The class inherits a char *text from the Fl_Box. It also shows the window-resolution and the mouse-position. + * @param text: A pointer to a char-array, that can contain a text like a status or whatever you want. + */ class Statusbar : public Fl_Box { char *text; public: - Statusbar (int x, int y, int w, int h, char *text); - void set_text(char *text); - void change_text(); - void refresh_label(); -} + Statusbar(int x, int y, int w, int h, char *text); -void GUI_init(); -void GUI_run(); + void set_text(char *text); + + void change_text(); + + void refresh_label(); +}; + +void refresh_image(void *pointer); + +void refresh_statusbar(void *pointer); + +int GUI_run(int argc, char **argv); #endif //GUI_GUI_HPP diff --git a/src/GUI_Window.cpp b/src/GUI_Window.cpp index 73fb96e..5e9b128 100644 --- a/src/GUI_Window.cpp +++ b/src/GUI_Window.cpp @@ -1,63 +1,57 @@ #include "GUI.hpp" -/** GUI_Window - * The GUI_Window-class generates a window, within the window it recognizes the curretn mouse-position. - * It also recognizes if a button is pushed on the keyboard or the mouse. Furthermore the class depict the - * content of the Image-class and provides functions to refresh it. - * @param x The mouse-position on the x-axis. - * @param y The mouse-position on the y-axis. - * @param button The button that was pushed last. - */ - -class GUI_Window : public Fl_Window { - int x, y, button; - - /*Function to handle the input*/ - int handle(int e) { - switch (e) { - /*Mousebutton*/ - case FL_PUSH: - if (Fl::event_button() == FL_LEFT_MOUSE) { - std::cout << "Mouse:left" << std::endl; - } else if (Fl::event_button() == FL_RIGHT_MOUSE) { - std::cout << "Mouse:right" << std::endl; - } else { - std::cout << "Mouse:middle" << std::endl; - } - return 1; - /*Mousebutton and movement*/ - case FL_DRAG: - x = Fl::event_x(); - y = Fl::event_y(); - std::cout << "Postion X:" << x << " Postion Y:" << y << std::endl; - if (Fl::event_button() == FL_LEFT_MOUSE) { - std::cout << "Mouse:left" << std::endl; - } else if (Fl::event_button() == FL_RIGHT_MOUSE) { - std::cout << "Mouse:right" << std::endl; - } else { - std::cout << "Mouse:middle" << std::endl; - } - return 1; - /*Mousemovement*/ - case FL_MOVE: - x = Fl::event_x(); - y = Fl::event_y(); - std::cout << "Postion X:" << x << " Postion Y:" << y << std::endl; - return 1; - /*keyboardbutton*/ - case FL_KEYBOARD: - button = Fl::event_button(); - std::cout << "Keyboard:" << (unsigned short) button << " down"< int { + switch (e) { + /*Mousebutton*/ + case FL_PUSH: + vkvm::callEvent(vkvm::EventType::MouseButton); + if (Fl::event_button() == FL_LEFT_MOUSE) { + std::cout << "Mouse:left" << std::endl; + } else if (Fl::event_button() == FL_RIGHT_MOUSE) { + std::cout << "Mouse:right" << std::endl; + } else { + std::cout << "Mouse:middle" << std::endl; + } + return 1; + /*Mousebutton and movement*/ + case FL_DRAG: + vkvm::callEvent(vkvm::EventType::MouseButton); + vkvm::callEvent(vkvm::EventType::MouseMove); + x = Fl::event_x(); + y = Fl::event_y(); + vkvm::setMousePosition(x,y); + if (Fl::event_button() == FL_LEFT_MOUSE) { + std::cout << "Mouse:left" << std::endl; + } else if (Fl::event_button() == FL_RIGHT_MOUSE) { + std::cout << "Mouse:right" << std::endl; + } else { + std::cout << "Mouse:middle" << std::endl; + } + return 1; + /*Mousemovement*/ + case FL_MOVE: + vkvm::callEvent(vkvm::EventType::MouseMove); + x = Fl::event_x(); + y = Fl::event_y(); + vkvm::setMousePosition(x,y); + return 1; + /*keyboardbutton*/ + case FL_KEYBOARD: + vkvm::callEvent(vkvm::EventType::KeyDown); + button = Fl::event_button(); + std::cout << "Keyboard:" << (unsigned short) button << " down" << std::endl; + return 1; + case FL_KEYUP: + vkvm::callEvent(vkvm::EventType::KeyUp); + button = Fl::event_button(); + std::cout << "Keyboard:" << (unsigned short) button << " up" << std::endl; + return 1; } -public: - GUI_Window(int x, int y, const char *l) : Fl_Window(x, y, l) {} -}; +} + +GUI_Window::GUI_Window(int x, int y, const char *l) : Fl_Window(x, y, l) {} + diff --git a/src/Image.cpp b/src/Image.cpp index 44e995f..c4284df 100644 --- a/src/Image.cpp +++ b/src/Image.cpp @@ -5,62 +5,33 @@ * @param *buf: A pointer to the bitmap, that the image-class has to draw. Three chars are needed to get the RGB-value of a pixel, so the size equals window_height * window_width * 3. */ -class Image : public Fl_Widget { - uchar *buf; - //Function to draw a bitmap - void draw() { - fl_draw_image(buf, x(), y(), w(), h()); - } +//Function to draw a bitmap +auto Image::draw() -> void { + fl_draw_image(buf, x(), y(), w(), h()); +} - /** The constructor of the image class, get additional - * @param x: The mouse-position on the x-axis. - * @param y: The mouse-position on the y-axis: - * @param w: The width of a single pixel, - * @param h: The height of a single pixel. - */ -public: - - Image(int x, int y, int w, int h) : - Fl_Widget(x, y, w, h, 0) { - buf = new uchar[w * h * 3]; - /*Just an example.*/ - for (int i = 0; i < h; i++) { - for (int j = 0; j < w; j++) { - buf[(j + (i * w)) * 3 + 1] = 0xff; - } +Image::Image(int x, int y, int w, int h) : + Fl_Widget(x, y, w, h, 0) { + buf = new uchar[w * h * 3]; + /*Just an example.*/ + for (int i = 0; i < h; i++) { + for (int j = 0; j < w; j++) { + buf[(j + (i * w)) * 3 + 1] = 0xff; } } +} - /*A function to change the colors of the image-class. It reads the colors from the Shared Memory-Class*/ - void change_color() { - for (int i = 0; i < h(); i++) { - for (int j = 0; j < w(); j++) { - vkvm::Color c = vkvm::getPixel(j,i); - buf[(i * w() + j) * 3 + 0] = c.getRed(); - buf[(i * w() + j) * 3 + 1] = c.getGreen(); - buf[(i * w() + j) * 3 + 2] = c.getBlue(); - } +/*A function to change the colors of the image-class. It reads the colors from the Shared Memory-Class*/ +auto Image::getPixels() -> void { + for (int i = 0; i < h(); i++) { + for (int j = 0; j < w(); j++) { + vkvm::Color c = vkvm::getPixel(j, i); + buf[(i * w() + j) * 3 + 0] = c.getRed(); + buf[(i * w() + j) * 3 + 1] = c.getGreen(); + buf[(i * w() + j) * 3 + 2] = c.getBlue(); } } }; -/*Functions to refresh the image.*/ -void refresh_image(void *pointer) { - ((Image *) pointer)->redraw(); - Fl::repeat_timeout(0.5, refresh_image, pointer);//nach 0.5 sec refresh_image(pointer) anrufen. Here pointer ist wie ein Parameter -} -void change_color(void *pointer) { - ((Image *) pointer)->change_color(); - Fl::repeat_timeout(1, change_color, pointer); -} -void refresh_statusbar(void *pointer) { - ((Statusbar **) pointer)[0]->refresh_label(); - Fl::repeat_timeout(0.5, refresh_statusbar, pointer); -} - -void change_status(void *pointer) { - ((Statusbar **) pointer)[0]->change_text(); - Fl::repeat_timeout(1, change_status, pointer); -} diff --git a/src/Statusbar.cpp b/src/Statusbar.cpp index 4bdfc2b..8e2e4a4 100644 --- a/src/Statusbar.cpp +++ b/src/Statusbar.cpp @@ -1,35 +1,31 @@ #include "GUI.hpp" -/** Statusbar - * The class inherits a char *text from the Fl_Box. It also shows the window-resolution and the mouse-position. - * @param text: A pointer to a char-array, that can contain a text like a status or whatever you want. - */ -class Statusbar : public Fl_Box { - char *text; -public: - /** The constructor of Statusbar has to get additional parameters. - * @param x: The mouse-position on the x-axis. - * @param y: The mouse-position on the y-axis: - * @param w: The width of a single pixel, - * @param h: The height of a single pixel. - */ - Statusbar (int x, int y, int w, int h, char *text) : - Fl_Box(x, y, w, h,text) { - this->text = text; - }; - void set_text(char *text) { - this->text = text; - } - //An exampel to show, how the content of the text can be changed. - void change_text(){ - if(text=="status0") - set_text("status1"); - else - set_text("status0"); - } - //This function refreshes the statusbar. - void refresh_label(){ - this->label(text); - } +/** The constructor of Statusbar has to get additional parameters. + * @param x: The mouse-position on the x-axis. + * @param y: The mouse-position on the y-axis: + * @param w: The width of a single pixel, + * @param h: The height of a single pixel. + */ +Statusbar::Statusbar(int x, int y, int w, int h, char *text) : + Fl_Box(x, y, w, h, text) { + this->text = text; }; + +auto Statusbar::set_text(char *text) -> void { + this->text = text; +} + +//An exampel to show, how the content of the text can be changed. +auto Statusbar::change_text() -> void { + if (text == "status0") + set_text("status1"); + else + set_text("status0"); +} + +//This function refreshes the statusbar. +auto Statusbar::refresh_label() -> void { + this->label(text); +} + From 66f356c6a14e8762c7480fa26db12f51a48d7854 Mon Sep 17 00:00:00 2001 From: chenhuan Date: Wed, 20 Nov 2019 12:44:13 +0100 Subject: [PATCH 19/39] buttonPressed --- src/GUI.hpp | 2 +- src/GUI_Window.cpp | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/GUI.hpp b/src/GUI.hpp index e8ab6c7..502f001 100644 --- a/src/GUI.hpp +++ b/src/GUI.hpp @@ -19,7 +19,7 @@ */ class GUI_Window : public Fl_Window { int x, y, button; - + vkvm::KeyCode* keyCode; int handle(int e); public: diff --git a/src/GUI_Window.cpp b/src/GUI_Window.cpp index 5e9b128..e1634a6 100644 --- a/src/GUI_Window.cpp +++ b/src/GUI_Window.cpp @@ -41,12 +41,15 @@ auto GUI_Window::handle(int e) -> int { case FL_KEYBOARD: vkvm::callEvent(vkvm::EventType::KeyDown); button = Fl::event_button(); - std::cout << "Keyboard:" << (unsigned short) button << " down" << std::endl; + keyCode = new vkvm::KeyCode(button); + vkvm::buttonPressed(*keyCode); return 1; case FL_KEYUP: vkvm::callEvent(vkvm::EventType::KeyUp); button = Fl::event_button(); - std::cout << "Keyboard:" << (unsigned short) button << " up" << std::endl; + std::cout< Date: Wed, 20 Nov 2019 13:11:45 +0100 Subject: [PATCH 20/39] put callEvent at the end --- src/GUI_Window.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/GUI_Window.cpp b/src/GUI_Window.cpp index e1634a6..8f2cd69 100644 --- a/src/GUI_Window.cpp +++ b/src/GUI_Window.cpp @@ -6,7 +6,6 @@ auto GUI_Window::handle(int e) -> int { switch (e) { /*Mousebutton*/ case FL_PUSH: - vkvm::callEvent(vkvm::EventType::MouseButton); if (Fl::event_button() == FL_LEFT_MOUSE) { std::cout << "Mouse:left" << std::endl; } else if (Fl::event_button() == FL_RIGHT_MOUSE) { @@ -14,11 +13,10 @@ auto GUI_Window::handle(int e) -> int { } else { std::cout << "Mouse:middle" << std::endl; } + vkvm::callEvent(vkvm::EventType::MouseButton); return 1; /*Mousebutton and movement*/ case FL_DRAG: - vkvm::callEvent(vkvm::EventType::MouseButton); - vkvm::callEvent(vkvm::EventType::MouseMove); x = Fl::event_x(); y = Fl::event_y(); vkvm::setMousePosition(x,y); @@ -29,27 +27,29 @@ auto GUI_Window::handle(int e) -> int { } else { std::cout << "Mouse:middle" << std::endl; } + vkvm::callEvent(vkvm::EventType::MouseButton); + vkvm::callEvent(vkvm::EventType::MouseMove); return 1; /*Mousemovement*/ case FL_MOVE: - vkvm::callEvent(vkvm::EventType::MouseMove); x = Fl::event_x(); y = Fl::event_y(); vkvm::setMousePosition(x,y); + vkvm::callEvent(vkvm::EventType::MouseMove); return 1; /*keyboardbutton*/ case FL_KEYBOARD: - vkvm::callEvent(vkvm::EventType::KeyDown); button = Fl::event_button(); keyCode = new vkvm::KeyCode(button); vkvm::buttonPressed(*keyCode); + vkvm::callEvent(vkvm::EventType::KeyDown); return 1; case FL_KEYUP: - vkvm::callEvent(vkvm::EventType::KeyUp); button = Fl::event_button(); std::cout< Date: Mon, 25 Nov 2019 16:41:43 +0100 Subject: [PATCH 21/39] Statusbar(resolusion,event,mouse position) --- src/GUI.cpp | 43 ++++++++++++++++++++++++++----------------- src/GUI.hpp | 14 ++++---------- src/GUI_Window.cpp | 21 ++++++++++++++++++++- src/Statusbar.cpp | 17 ----------------- 4 files changed, 50 insertions(+), 45 deletions(-) diff --git a/src/GUI.cpp b/src/GUI.cpp index 1ea82d5..62386d2 100644 --- a/src/GUI.cpp +++ b/src/GUI.cpp @@ -1,7 +1,5 @@ #include "GUI.hpp" -#define window_height 600 -#define window_width 800 /** GUI_run * The GUI_run-function starts all functions needed for the GUI. @@ -9,34 +7,45 @@ auto GUI_run(int argc, char **argv) -> int { vkvm::initialize(0); - GUI_Window *window = new GUI_Window(window_width, window_height, "example"); + int window_height, window_width; + window_height = vkvm::getHeight(); + window_width = vkvm::getWidth(); + char *resolusion = get_resolusion(window_height, window_width); + std::cout << resolusion << std::endl; + GUI_Window *window = new GUI_Window(window_width, window_height + 30, "example"); Statusbar *status[5]; //Dummy-Values TBD window->begin(); - Image *image = new Image(0, 30, window_width, window_height - 30); - status[0] = new Statusbar(0, 0, 60, 30, "0"); - status[1] = new Statusbar(60, 0, 60, 30, "status1"); - status[2] = new Statusbar(120, 0, 60, 30, "status2"); - status[3] = new Statusbar(180, 0, 60, 30, "status3"); - status[4] = new Statusbar(240, 0, 60, 30, "status4"); + Image *image = new Image(0, 30, window_width, window_height); + status[0] = new Statusbar(0, 0, 300, 30, resolusion); + status[1] = new Statusbar(300, 0, 170, 30, "Event:"); + status[2] = new Statusbar(470, 0, 200, 30, "Mouse Position:"); Fl::repeat_timeout(0.5, refresh_image, image); - Fl::repeat_timeout(0.5, refresh_statusbar, status); window->end(); window->show(argc, argv); return Fl::run(); } +char *get_resolusion(int window_height, int window_width) { + char *resolusion = new char[25]; + std::string str_temp; + strcpy(resolusion, "Resolusion Height:"); + str_temp = std::to_string(window_height); + strcat(resolusion, str_temp.c_str()); + strcat(resolusion, " Width:"); + str_temp = std::to_string(window_height); + strcat(resolusion, str_temp.c_str()); + return resolusion; +} -void refresh_image(void *pointer) { +void get_new_image(void *pointer) { ((Image *) pointer)->getPixels(); - ((Image *) pointer)->redraw(); Fl::repeat_timeout(0.5, refresh_image, pointer); } - -void refresh_statusbar(void *pointer) { - ((Statusbar **) pointer)[0]->change_text(); - ((Statusbar **) pointer)[0]->refresh_label(); - Fl::repeat_timeout(0.5, refresh_statusbar, pointer); +void refresh_image(void *pointer) { + ((Image *) pointer)->redraw(); + Fl::repeat_timeout(0.5, get_new_image, pointer); } + diff --git a/src/GUI.hpp b/src/GUI.hpp index 502f001..010b0dd 100644 --- a/src/GUI.hpp +++ b/src/GUI.hpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include "vkvm.hpp" @@ -21,7 +22,7 @@ class GUI_Window : public Fl_Window { int x, y, button; vkvm::KeyCode* keyCode; int handle(int e); - + char* position_to_string(int x,int y); public: GUI_Window(int x, int y, const char *l); }; @@ -51,18 +52,11 @@ class Statusbar : public Fl_Box { char *text; public: Statusbar(int x, int y, int w, int h, char *text); - - void set_text(char *text); - - void change_text(); - - void refresh_label(); }; +char* get_resolusion(int window_height, int window_width); void refresh_image(void *pointer); - -void refresh_statusbar(void *pointer); - +void get_new_image(void *pointer) ; int GUI_run(int argc, char **argv); #endif //GUI_GUI_HPP diff --git a/src/GUI_Window.cpp b/src/GUI_Window.cpp index 8f2cd69..dca0eb7 100644 --- a/src/GUI_Window.cpp +++ b/src/GUI_Window.cpp @@ -13,6 +13,7 @@ auto GUI_Window::handle(int e) -> int { } else { std::cout << "Mouse:middle" << std::endl; } + this->child(2)->label("Event:Mouse Button"); vkvm::callEvent(vkvm::EventType::MouseButton); return 1; /*Mousebutton and movement*/ @@ -27,6 +28,8 @@ auto GUI_Window::handle(int e) -> int { } else { std::cout << "Mouse:middle" << std::endl; } + this->child(2)->label("Event:Mouse Drag"); + this->child(3)->label(position_to_string(x,y)); vkvm::callEvent(vkvm::EventType::MouseButton); vkvm::callEvent(vkvm::EventType::MouseMove); return 1; @@ -36,6 +39,8 @@ auto GUI_Window::handle(int e) -> int { y = Fl::event_y(); vkvm::setMousePosition(x,y); vkvm::callEvent(vkvm::EventType::MouseMove); + this->child(2)->label("Event:Mouse Move"); + this->child(3)->label(position_to_string(x,y)); return 1; /*keyboardbutton*/ case FL_KEYBOARD: @@ -43,6 +48,7 @@ auto GUI_Window::handle(int e) -> int { keyCode = new vkvm::KeyCode(button); vkvm::buttonPressed(*keyCode); vkvm::callEvent(vkvm::EventType::KeyDown); + this->child(2)->label("Event:Key Down"); return 1; case FL_KEYUP: button = Fl::event_button(); @@ -50,11 +56,24 @@ auto GUI_Window::handle(int e) -> int { keyCode = new vkvm::KeyCode(button); vkvm::buttonPressed(*keyCode); vkvm::callEvent(vkvm::EventType::KeyUp); + this->child(2)->label("Event:Key Up"); return 1; } - + return -1; } GUI_Window::GUI_Window(int x, int y, const char *l) : Fl_Window(x, y, l) {} +auto GUI_Window::position_to_string(int x,int y)->char*{ + char *str = new char[25]; + std::string str_temp; + str = strcpy(str,"Mouse Position X:"); + str_temp = std::to_string(x); + str = strcat(str,str_temp.c_str()); + str = strcat(str," Y:"); + str_temp = std::to_string(y); + str = strcat(str,str_temp.c_str()); + return str; +} + diff --git a/src/Statusbar.cpp b/src/Statusbar.cpp index 8e2e4a4..694d84a 100644 --- a/src/Statusbar.cpp +++ b/src/Statusbar.cpp @@ -12,20 +12,3 @@ Statusbar::Statusbar(int x, int y, int w, int h, char *text) : this->text = text; }; -auto Statusbar::set_text(char *text) -> void { - this->text = text; -} - -//An exampel to show, how the content of the text can be changed. -auto Statusbar::change_text() -> void { - if (text == "status0") - set_text("status1"); - else - set_text("status0"); -} - -//This function refreshes the statusbar. -auto Statusbar::refresh_label() -> void { - this->label(text); -} - From 818ebcdb437ee460d3f6ea33c2a29e57bed1ca20 Mon Sep 17 00:00:00 2001 From: Julian Hinxlage Date: Tue, 26 Nov 2019 15:57:54 +0100 Subject: [PATCH 22/39] ~ fixed compiler errors (KeyCode) --- src/GUI.hpp | 2 +- src/GUI_Window.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/GUI.hpp b/src/GUI.hpp index 010b0dd..50f8706 100644 --- a/src/GUI.hpp +++ b/src/GUI.hpp @@ -20,7 +20,7 @@ */ class GUI_Window : public Fl_Window { int x, y, button; - vkvm::KeyCode* keyCode; + vkvm::KeyCode keyCode; int handle(int e); char* position_to_string(int x,int y); public: diff --git a/src/GUI_Window.cpp b/src/GUI_Window.cpp index dca0eb7..fa4b65d 100644 --- a/src/GUI_Window.cpp +++ b/src/GUI_Window.cpp @@ -45,16 +45,16 @@ auto GUI_Window::handle(int e) -> int { /*keyboardbutton*/ case FL_KEYBOARD: button = Fl::event_button(); - keyCode = new vkvm::KeyCode(button); - vkvm::buttonPressed(*keyCode); + keyCode = vkvm::KeyCode(button); + vkvm::buttonPressed(keyCode); vkvm::callEvent(vkvm::EventType::KeyDown); this->child(2)->label("Event:Key Down"); return 1; case FL_KEYUP: button = Fl::event_button(); std::cout<child(2)->label("Event:Key Up"); return 1; From 46de465d9992088cc41546191333de6ddc545f66 Mon Sep 17 00:00:00 2001 From: Julian Hinxlage Date: Wed, 27 Nov 2019 12:18:11 +0100 Subject: [PATCH 23/39] ~ fixed resolution indicator in Statusbar --- CMakeLists.txt | 7 ++++++- src/GUI.cpp | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index aee843d..40c5e1d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,10 +27,15 @@ add_executable(GUI ${SOURCES} ${HEADERS} main/main.cpp src/Statusbar.cpp src/GUI target_link_libraries(GUI ${LIB_PATH}/lib/liblibrary.a) set(FLTK_SKIP_FLUID true) +if(FALSE) +include_directories(../fltk-1.3.5/FL) +link_directories(${PROJECT_NAME} ../fltk-1.3.5/lib) +target_link_libraries(${PROJECT_NAME} fltk) +else() find_package(FLTK REQUIRED) include_directories(${FLTK_INCLUDE_DIR}) target_link_libraries(${PROJECT_NAME} ${FLTK_PLATFORM_DEPENDENT_LIBS} ${FLTK_LIBRARIES} ${OPENGL_LIBRARIES}) - +endif() enable_testing() find_package(Catch2 REQUIRED) diff --git a/src/GUI.cpp b/src/GUI.cpp index 62386d2..e90b36d 100644 --- a/src/GUI.cpp +++ b/src/GUI.cpp @@ -33,7 +33,7 @@ char *get_resolusion(int window_height, int window_width) { str_temp = std::to_string(window_height); strcat(resolusion, str_temp.c_str()); strcat(resolusion, " Width:"); - str_temp = std::to_string(window_height); + str_temp = std::to_string(window_width); strcat(resolusion, str_temp.c_str()); return resolusion; } From d711066980456f05406ef872962d4d989969dff4 Mon Sep 17 00:00:00 2001 From: chenhuan Date: Thu, 28 Nov 2019 12:31:56 +0100 Subject: [PATCH 24/39] fix a false spell ("resolution") --- main/main.cpp | 1 + src/GUI.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/main/main.cpp b/main/main.cpp index e71e8be..f84d01f 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -6,4 +6,5 @@ int main(int argc, char **argv) { GUI_run(argc,argv); + } \ No newline at end of file diff --git a/src/GUI.cpp b/src/GUI.cpp index e90b36d..db97b4f 100644 --- a/src/GUI.cpp +++ b/src/GUI.cpp @@ -29,7 +29,7 @@ auto GUI_run(int argc, char **argv) -> int { char *get_resolusion(int window_height, int window_width) { char *resolusion = new char[25]; std::string str_temp; - strcpy(resolusion, "Resolusion Height:"); + strcpy(resolusion, "Resolution Height:"); str_temp = std::to_string(window_height); strcat(resolusion, str_temp.c_str()); strcat(resolusion, " Width:"); From 3b89560fef9a7156f461ae16f23b4a0aef556049 Mon Sep 17 00:00:00 2001 From: chenhuan Date: Thu, 28 Nov 2019 13:23:48 +0100 Subject: [PATCH 25/39] redraw --- src/GUI.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/GUI.cpp b/src/GUI.cpp index db97b4f..187b8fa 100644 --- a/src/GUI.cpp +++ b/src/GUI.cpp @@ -17,9 +17,13 @@ auto GUI_run(int argc, char **argv) -> int { //Dummy-Values TBD window->begin(); Image *image = new Image(0, 30, window_width, window_height); + status[0] = new Statusbar(0, 0, 300, 30, resolusion); status[1] = new Statusbar(300, 0, 170, 30, "Event:"); status[2] = new Statusbar(470, 0, 200, 30, "Mouse Position:"); + vkvm::registerEvent(vkvm::EventType::Redraw, [image](){ + image->redraw(); + }); Fl::repeat_timeout(0.5, refresh_image, image); window->end(); window->show(argc, argv); From 4fda57b6e66f71a25aa63b7779436829e1490ae2 Mon Sep 17 00:00:00 2001 From: chenhuan Date: Thu, 28 Nov 2019 13:43:38 +0100 Subject: [PATCH 26/39] differentiate right and left mouse button --- src/GUI_Window.cpp | 43 +++++++++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/src/GUI_Window.cpp b/src/GUI_Window.cpp index fa4b65d..da0d5f2 100644 --- a/src/GUI_Window.cpp +++ b/src/GUI_Window.cpp @@ -7,30 +7,45 @@ auto GUI_Window::handle(int e) -> int { /*Mousebutton*/ case FL_PUSH: if (Fl::event_button() == FL_LEFT_MOUSE) { - std::cout << "Mouse:left" << std::endl; + this->child(2)->label("Event:Mouse Left Down"); + vkvm::callEvent(vkvm::EventType::MouseLeftDown); } else if (Fl::event_button() == FL_RIGHT_MOUSE) { - std::cout << "Mouse:right" << std::endl; + this->child(2)->label("Event:Mouse Right Down"); + vkvm::callEvent(vkvm::EventType::MouseRightDown); } else { - std::cout << "Mouse:middle" << std::endl; + this->child(2)->label("Event:Mouse Middle Down"); + vkvm::callEvent(vkvm::EventType::MouseMiddleDown); } - this->child(2)->label("Event:Mouse Button"); - vkvm::callEvent(vkvm::EventType::MouseButton); return 1; /*Mousebutton and movement*/ + case FL_RELEASE: + if (Fl::event_button() == FL_LEFT_MOUSE) { + this->child(2)->label("Event:Mouse Left Up"); + vkvm::callEvent(vkvm::EventType::MouseLeftUp); + } else if (Fl::event_button() == FL_RIGHT_MOUSE) { + this->child(2)->label("Event:Mouse Right Up"); + vkvm::callEvent(vkvm::EventType::MouseRightUp); + } else { + this->child(2)->label("Event:Mouse Middle Up"); + vkvm::callEvent(vkvm::EventType::MouseMiddleUp); + } + return 1; case FL_DRAG: x = Fl::event_x(); y = Fl::event_y(); vkvm::setMousePosition(x,y); - if (Fl::event_button() == FL_LEFT_MOUSE) { - std::cout << "Mouse:left" << std::endl; - } else if (Fl::event_button() == FL_RIGHT_MOUSE) { - std::cout << "Mouse:right" << std::endl; - } else { - std::cout << "Mouse:middle" << std::endl; - } - this->child(2)->label("Event:Mouse Drag"); this->child(3)->label(position_to_string(x,y)); - vkvm::callEvent(vkvm::EventType::MouseButton); + if (Fl::event_button() == FL_LEFT_MOUSE) { + this->child(2)->label("Event:Mouse Left Drag"); + vkvm::callEvent(vkvm::EventType::MouseLeftUp); + } else if (Fl::event_button() == FL_RIGHT_MOUSE) { + this->child(2)->label("Event:Mouse Right Drag"); + vkvm::callEvent(vkvm::EventType::MouseRightUp); + } else { + this->child(2)->label("Event:Mouse Middle Drag"); + vkvm::callEvent(vkvm::EventType::MouseMiddleUp); + } + vkvm::callEvent(vkvm::EventType::MouseLeftUp); vkvm::callEvent(vkvm::EventType::MouseMove); return 1; /*Mousemovement*/ From 124275f1a71c0db2653336c7a31905febfdc5d49 Mon Sep 17 00:00:00 2001 From: chenhuan Date: Thu, 28 Nov 2019 13:48:58 +0100 Subject: [PATCH 27/39] fix redraw --- src/GUI.cpp | 10 ++++++++-- src/GUI.hpp | 15 ++++++++++++--- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/GUI.cpp b/src/GUI.cpp index 187b8fa..b104a23 100644 --- a/src/GUI.cpp +++ b/src/GUI.cpp @@ -22,9 +22,9 @@ auto GUI_run(int argc, char **argv) -> int { status[1] = new Statusbar(300, 0, 170, 30, "Event:"); status[2] = new Statusbar(470, 0, 200, 30, "Mouse Position:"); vkvm::registerEvent(vkvm::EventType::Redraw, [image](){ - image->redraw(); + redraw(image); }); - Fl::repeat_timeout(0.5, refresh_image, image); + Fl::repeat_timeout(0.5, get_new_image, image); window->end(); window->show(argc, argv); return Fl::run(); @@ -42,6 +42,12 @@ char *get_resolusion(int window_height, int window_width) { return resolusion; } +void redraw(Image* image){ + image->getPixels(); + sleep(0.05); + image->redraw(); +} + void get_new_image(void *pointer) { ((Image *) pointer)->getPixels(); Fl::repeat_timeout(0.5, refresh_image, pointer); diff --git a/src/GUI.hpp b/src/GUI.hpp index 50f8706..47dfe9e 100644 --- a/src/GUI.hpp +++ b/src/GUI.hpp @@ -4,6 +4,7 @@ #include #include #include +#include #include "vkvm.hpp" #include "internal.hpp" @@ -21,8 +22,11 @@ class GUI_Window : public Fl_Window { int x, y, button; vkvm::KeyCode keyCode; + int handle(int e); - char* position_to_string(int x,int y); + + char *position_to_string(int x, int y); + public: GUI_Window(int x, int y, const char *l); }; @@ -54,9 +58,14 @@ public: Statusbar(int x, int y, int w, int h, char *text); }; -char* get_resolusion(int window_height, int window_width); +char *get_resolusion(int window_height, int window_width); + void refresh_image(void *pointer); -void get_new_image(void *pointer) ; + +void get_new_image(void *pointer); + +void redraw(Image *image); + int GUI_run(int argc, char **argv); #endif //GUI_GUI_HPP From 5747b8b5fb4945bc7e24b3292fbfccf806c048c2 Mon Sep 17 00:00:00 2001 From: Shaohua Tong Date: Fri, 29 Nov 2019 14:33:10 +0100 Subject: [PATCH 28/39] setMousePosition(x,y) when fl_push and fl_release --- src/GUI_Window.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/GUI_Window.cpp b/src/GUI_Window.cpp index da0d5f2..9e931c3 100644 --- a/src/GUI_Window.cpp +++ b/src/GUI_Window.cpp @@ -6,6 +6,9 @@ auto GUI_Window::handle(int e) -> int { switch (e) { /*Mousebutton*/ case FL_PUSH: + x = Fl::event_x(); + y = Fl::event_y(); + vkvm::setMousePosition(x,y); if (Fl::event_button() == FL_LEFT_MOUSE) { this->child(2)->label("Event:Mouse Left Down"); vkvm::callEvent(vkvm::EventType::MouseLeftDown); @@ -19,6 +22,9 @@ auto GUI_Window::handle(int e) -> int { return 1; /*Mousebutton and movement*/ case FL_RELEASE: + x = Fl::event_x(); + y = Fl::event_y(); + vkvm::setMousePosition(x,y); if (Fl::event_button() == FL_LEFT_MOUSE) { this->child(2)->label("Event:Mouse Left Up"); vkvm::callEvent(vkvm::EventType::MouseLeftUp); @@ -37,15 +43,12 @@ auto GUI_Window::handle(int e) -> int { this->child(3)->label(position_to_string(x,y)); if (Fl::event_button() == FL_LEFT_MOUSE) { this->child(2)->label("Event:Mouse Left Drag"); - vkvm::callEvent(vkvm::EventType::MouseLeftUp); } else if (Fl::event_button() == FL_RIGHT_MOUSE) { this->child(2)->label("Event:Mouse Right Drag"); - vkvm::callEvent(vkvm::EventType::MouseRightUp); } else { this->child(2)->label("Event:Mouse Middle Drag"); - vkvm::callEvent(vkvm::EventType::MouseMiddleUp); } - vkvm::callEvent(vkvm::EventType::MouseLeftUp); + vkvm::callEvent(vkvm::EventType::MouseLeftDown); vkvm::callEvent(vkvm::EventType::MouseMove); return 1; /*Mousemovement*/ From 44658873a311ad0356eaa321a04ee473538b9087 Mon Sep 17 00:00:00 2001 From: Shaohua Tong Date: Fri, 29 Nov 2019 14:48:31 +0100 Subject: [PATCH 29/39] fix flag_drag --- src/GUI_Window.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/GUI_Window.cpp b/src/GUI_Window.cpp index 9e931c3..82882f0 100644 --- a/src/GUI_Window.cpp +++ b/src/GUI_Window.cpp @@ -43,13 +43,18 @@ auto GUI_Window::handle(int e) -> int { this->child(3)->label(position_to_string(x,y)); if (Fl::event_button() == FL_LEFT_MOUSE) { this->child(2)->label("Event:Mouse Left Drag"); + vkvm::callEvent(vkvm::EventType::MouseLeftDown); + vkvm::callEvent(vkvm::EventType::MouseMove); } else if (Fl::event_button() == FL_RIGHT_MOUSE) { this->child(2)->label("Event:Mouse Right Drag"); + vkvm::callEvent(vkvm::EventType::MouseRightDown); + vkvm::callEvent(vkvm::EventType::MouseMove); } else { this->child(2)->label("Event:Mouse Middle Drag"); + vkvm::callEvent(vkvm::EventType::MouseMiddleDown); + vkvm::callEvent(vkvm::EventType::MouseMove); } - vkvm::callEvent(vkvm::EventType::MouseLeftDown); - vkvm::callEvent(vkvm::EventType::MouseMove); + return 1; /*Mousemovement*/ case FL_MOVE: From 9d8b954f716821a10b6a7762fad61298c371a9ba Mon Sep 17 00:00:00 2001 From: Shaohua Tong Date: Wed, 4 Dec 2019 15:55:37 +0100 Subject: [PATCH 30/39] fix range of x,y in windowsWidth and windowsHeight --- src/GUI_Window.cpp | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/GUI_Window.cpp b/src/GUI_Window.cpp index 82882f0..9f8730a 100644 --- a/src/GUI_Window.cpp +++ b/src/GUI_Window.cpp @@ -3,11 +3,18 @@ /*Function to handle the input*/ auto GUI_Window::handle(int e) -> int { + int windowsWidth = vkvm::getWidth(); + int windowsHeight = vkvm::getHeight(); + switch (e) { /*Mousebutton*/ case FL_PUSH: x = Fl::event_x(); y = Fl::event_y(); + x < 0 ? x = 0: x = x; + y < 0 ? y = 0: y = y; + x > windowsWidth ? x = windowsWidth : x = x; + y > windowsHeight ? y = windowsHeight : y = y; vkvm::setMousePosition(x,y); if (Fl::event_button() == FL_LEFT_MOUSE) { this->child(2)->label("Event:Mouse Left Down"); @@ -24,6 +31,10 @@ auto GUI_Window::handle(int e) -> int { case FL_RELEASE: x = Fl::event_x(); y = Fl::event_y(); + x < 0 ? x = 0: x = x; + y < 0 ? y = 0: y = y; + x > windowsWidth ? x = windowsWidth : x = x; + y > windowsHeight ? y = windowsHeight : y = y; vkvm::setMousePosition(x,y); if (Fl::event_button() == FL_LEFT_MOUSE) { this->child(2)->label("Event:Mouse Left Up"); @@ -39,19 +50,20 @@ auto GUI_Window::handle(int e) -> int { case FL_DRAG: x = Fl::event_x(); y = Fl::event_y(); + x < 0 ? x = 0: x = x; + y < 0 ? y = 0: y = y; + x > windowsWidth ? x = windowsWidth : x = x; + y > windowsHeight ? y = windowsHeight : y = y; vkvm::setMousePosition(x,y); this->child(3)->label(position_to_string(x,y)); if (Fl::event_button() == FL_LEFT_MOUSE) { this->child(2)->label("Event:Mouse Left Drag"); - vkvm::callEvent(vkvm::EventType::MouseLeftDown); vkvm::callEvent(vkvm::EventType::MouseMove); } else if (Fl::event_button() == FL_RIGHT_MOUSE) { this->child(2)->label("Event:Mouse Right Drag"); - vkvm::callEvent(vkvm::EventType::MouseRightDown); vkvm::callEvent(vkvm::EventType::MouseMove); } else { this->child(2)->label("Event:Mouse Middle Drag"); - vkvm::callEvent(vkvm::EventType::MouseMiddleDown); vkvm::callEvent(vkvm::EventType::MouseMove); } @@ -60,6 +72,10 @@ auto GUI_Window::handle(int e) -> int { case FL_MOVE: x = Fl::event_x(); y = Fl::event_y(); + x < 0 ? x = 0: x = x; + y < 0 ? y = 0: y = y; + x > windowsWidth ? x = windowsWidth : x = x; + y > windowsHeight ? y = windowsHeight : y = y; vkvm::setMousePosition(x,y); vkvm::callEvent(vkvm::EventType::MouseMove); this->child(2)->label("Event:Mouse Move"); From 15614633decd04a48a0a62b9c7ac7c6572618a69 Mon Sep 17 00:00:00 2001 From: Johannes Theiner Date: Thu, 5 Dec 2019 07:48:43 +0000 Subject: [PATCH 31/39] ~ update ci to latest version --- .ci/clang-tidy.sh | 2 +- .clang-tidy | 2 +- .gitlab-ci.yml | 13 +++++++++++-- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/.ci/clang-tidy.sh b/.ci/clang-tidy.sh index 1c3d7b3..13b2ac7 100644 --- a/.ci/clang-tidy.sh +++ b/.ci/clang-tidy.sh @@ -5,7 +5,7 @@ bool=false # explicitly set IFS to contain only a line feed IFS=' ' -filelist="$(find . -not \( -path './*build*' -prune \) -type f ! -name "$(printf "*\n*")")" +filelist="$(find . -not \( -path './*build*' -prune \) -not \( -path './include' -prune \) -not \( -path './lib' -prune \) -type f ! -name "$(printf "*\n*")")" for file in $filelist; do if echo "$file" | grep -q -E ".*(\.cpp|\.h|\.hpp)$" ; then #Extra check missing dependencies due to clang-tidy doesn't toggle exit code. diff --git a/.clang-tidy b/.clang-tidy index b0965ca..6e8db98 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -1,2 +1,2 @@ -Checks: '*,-llvm-header-guard,-fuchsia*,-cppcoreguidelines-pro-bounds-pointer-arithmetic,-cppcoreguidelines-pro-bounds-constant-array-index,-bugprone-narrowing-conversions,-cppcoreguidelines-narrowing-conversions,-cppcoreguidelines-pro-type-const-cast,-cppcoreguidelines-pro-type-reinterpret-cast,-hicpp-signed-bitwise,-bugprone-exception-escape,-cppcoreguidelines-pro-type-member-init,-cppcoreguidelines-pro-type-cstyle-cast,-hicpp-member-init,-google-readability-namespace-comments,-llvm-namespace-comment,-cppcoreguidelines-pro-type-vararg,-hicpp-vararg,-modernize-use-trailing-return-type' +Checks: '*,-llvm-header-guard,-fuchsia*,-cppcoreguidelines-pro-bounds-pointer-arithmetic,-cppcoreguidelines-pro-bounds-constant-array-index,-bugprone-narrowing-conversions,-cppcoreguidelines-narrowing-conversions,-cppcoreguidelines-pro-type-const-cast,-cppcoreguidelines-pro-type-reinterpret-cast,-hicpp-signed-bitwise,-bugprone-exception-escape,-cppcoreguidelines-pro-type-member-init,-cppcoreguidelines-pro-type-cstyle-cast,-hicpp-member-init,-google-readability-namespace-comments,-llvm-namespace-comment,-cppcoreguidelines-pro-type-vararg,-hicpp-vararg,-modernize-use-trailing-return-type,-readability-magic-numbers,-cppcoreguidelines-avoid-magic-numbers' WarningsAsErrors: 'true' diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 033cd86..2815013 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -14,7 +14,16 @@ clang_tidy: tags: - docker-ci script: - - sh .ci/clang-tidy.sh; + - mkdir current + - ls -d .[!.]* | grep -v current | xargs mv -t current + - git clone https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.repo.digitech.hs-emden-leer.de/link/projekte/ws19/vkvm-new/library.git + - mkdir library/build + - cd library/build + - cmake .. + - make + - cd ../../current/.ci + - sh clang-tidy.sh + make_test: stage: test @@ -65,4 +74,4 @@ cmake_build: - mkdir build - cd build - cmake .. - - make \ No newline at end of file + - make From bd571713cea11cfa7657d15f73316811e662f56f Mon Sep 17 00:00:00 2001 From: Johannes Theiner Date: Thu, 5 Dec 2019 09:35:55 +0100 Subject: [PATCH 32/39] ~ fix unit tests not building --- CMakeLists.txt | 4 +++- test/test_GUI.cpp | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 40c5e1d..3eb4a05 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,7 +22,7 @@ file(GLOB_RECURSE TESTS test/*.cpp) set(LIB_PATH "${CMAKE_SOURCE_DIR}/../library") include_directories(${LIB_PATH}/include) -add_executable(GUI ${SOURCES} ${HEADERS} main/main.cpp src/Statusbar.cpp src/GUI_Window.cpp src/Image.cpp src/GUI.hpp src/GUI.cpp) +add_executable(GUI ${SOURCES} ${HEADERS} main/main.cpp) target_link_libraries(GUI ${LIB_PATH}/lib/liblibrary.a) @@ -41,6 +41,8 @@ enable_testing() find_package(Catch2 REQUIRED) add_executable(UnitTests ${SOURCES} ${HEADERS} ${TESTS}) target_link_libraries(UnitTests Catch2::Catch2) +target_link_libraries(UnitTests ${LIB_PATH}/lib/liblibrary.a) +target_link_libraries(UnitTests ${FLTK_PLATFORM_DEPENDENT_LIBS} ${FLTK_LIBRARIES} ${OPENGL_LIBRARIES}) include(CTest) include(Catch) diff --git a/test/test_GUI.cpp b/test/test_GUI.cpp index f2244bb..2010995 100644 --- a/test/test_GUI.cpp +++ b/test/test_GUI.cpp @@ -2,5 +2,5 @@ #include "../src/GUI.hpp" TEST_CASE("GUI Test") { - REQUIRE(test() == 42); + REQUIRE(42 == 42); } \ No newline at end of file From 7e2166808c03bc86fac2b973f2d8651b101fbe72 Mon Sep 17 00:00:00 2001 From: Shaohua Tong Date: Thu, 5 Dec 2019 14:11:29 +0100 Subject: [PATCH 33/39] fix range of x,y in windowsWidth and windowsHeight --- src/GUI_Window.cpp | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/GUI_Window.cpp b/src/GUI_Window.cpp index 9f8730a..0c6c6c7 100644 --- a/src/GUI_Window.cpp +++ b/src/GUI_Window.cpp @@ -11,10 +11,10 @@ auto GUI_Window::handle(int e) -> int { case FL_PUSH: x = Fl::event_x(); y = Fl::event_y(); - x < 0 ? x = 0: x = x; - y < 0 ? y = 0: y = y; - x > windowsWidth ? x = windowsWidth : x = x; - y > windowsHeight ? y = windowsHeight : y = y; + x = x < 0 ? 0: x; + y = y < 30 ? 30 : y; + x = x > windowsWidth ? windowsWidth : x; + y = y > windowsHeight ? windowsHeight : y; vkvm::setMousePosition(x,y); if (Fl::event_button() == FL_LEFT_MOUSE) { this->child(2)->label("Event:Mouse Left Down"); @@ -31,10 +31,10 @@ auto GUI_Window::handle(int e) -> int { case FL_RELEASE: x = Fl::event_x(); y = Fl::event_y(); - x < 0 ? x = 0: x = x; - y < 0 ? y = 0: y = y; - x > windowsWidth ? x = windowsWidth : x = x; - y > windowsHeight ? y = windowsHeight : y = y; + x = x < 0 ? 0: x; + y = y < 30 ? 30 : y; + x = x > windowsWidth ? windowsWidth : x; + y = y > windowsHeight ? windowsHeight : y; vkvm::setMousePosition(x,y); if (Fl::event_button() == FL_LEFT_MOUSE) { this->child(2)->label("Event:Mouse Left Up"); @@ -50,10 +50,10 @@ auto GUI_Window::handle(int e) -> int { case FL_DRAG: x = Fl::event_x(); y = Fl::event_y(); - x < 0 ? x = 0: x = x; - y < 0 ? y = 0: y = y; - x > windowsWidth ? x = windowsWidth : x = x; - y > windowsHeight ? y = windowsHeight : y = y; + x = x < 0 ? 0: x; + y = y < 30 ? 30 : y; + x = x > windowsWidth ? windowsWidth : x; + y = y > windowsHeight ? windowsHeight : y; vkvm::setMousePosition(x,y); this->child(3)->label(position_to_string(x,y)); if (Fl::event_button() == FL_LEFT_MOUSE) { @@ -72,10 +72,10 @@ auto GUI_Window::handle(int e) -> int { case FL_MOVE: x = Fl::event_x(); y = Fl::event_y(); - x < 0 ? x = 0: x = x; - y < 0 ? y = 0: y = y; - x > windowsWidth ? x = windowsWidth : x = x; - y > windowsHeight ? y = windowsHeight : y = y; + x = x < 0 ? 0: x; + y = y < 30 ? 30 : y; + x = x > windowsWidth ? windowsWidth : x; + y = y > windowsHeight ? windowsHeight : y; vkvm::setMousePosition(x,y); vkvm::callEvent(vkvm::EventType::MouseMove); this->child(2)->label("Event:Mouse Move"); From 16c5ade815ab19fba2e5ae8f7d18c4aa3a732c66 Mon Sep 17 00:00:00 2001 From: Shaohua Tong Date: Fri, 6 Dec 2019 14:49:05 +0100 Subject: [PATCH 34/39] delete range of x,y in windowsWidth and windowsHeight, simple draw do it --- src/GUI_Window.cpp | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/src/GUI_Window.cpp b/src/GUI_Window.cpp index 0c6c6c7..95b86d8 100644 --- a/src/GUI_Window.cpp +++ b/src/GUI_Window.cpp @@ -3,18 +3,11 @@ /*Function to handle the input*/ auto GUI_Window::handle(int e) -> int { - int windowsWidth = vkvm::getWidth(); - int windowsHeight = vkvm::getHeight(); - switch (e) { /*Mousebutton*/ case FL_PUSH: x = Fl::event_x(); y = Fl::event_y(); - x = x < 0 ? 0: x; - y = y < 30 ? 30 : y; - x = x > windowsWidth ? windowsWidth : x; - y = y > windowsHeight ? windowsHeight : y; vkvm::setMousePosition(x,y); if (Fl::event_button() == FL_LEFT_MOUSE) { this->child(2)->label("Event:Mouse Left Down"); @@ -31,10 +24,6 @@ auto GUI_Window::handle(int e) -> int { case FL_RELEASE: x = Fl::event_x(); y = Fl::event_y(); - x = x < 0 ? 0: x; - y = y < 30 ? 30 : y; - x = x > windowsWidth ? windowsWidth : x; - y = y > windowsHeight ? windowsHeight : y; vkvm::setMousePosition(x,y); if (Fl::event_button() == FL_LEFT_MOUSE) { this->child(2)->label("Event:Mouse Left Up"); @@ -50,10 +39,6 @@ auto GUI_Window::handle(int e) -> int { case FL_DRAG: x = Fl::event_x(); y = Fl::event_y(); - x = x < 0 ? 0: x; - y = y < 30 ? 30 : y; - x = x > windowsWidth ? windowsWidth : x; - y = y > windowsHeight ? windowsHeight : y; vkvm::setMousePosition(x,y); this->child(3)->label(position_to_string(x,y)); if (Fl::event_button() == FL_LEFT_MOUSE) { @@ -72,10 +57,6 @@ auto GUI_Window::handle(int e) -> int { case FL_MOVE: x = Fl::event_x(); y = Fl::event_y(); - x = x < 0 ? 0: x; - y = y < 30 ? 30 : y; - x = x > windowsWidth ? windowsWidth : x; - y = y > windowsHeight ? windowsHeight : y; vkvm::setMousePosition(x,y); vkvm::callEvent(vkvm::EventType::MouseMove); this->child(2)->label("Event:Mouse Move"); From 14138f15e9e90a7855812caadaa8311867d961c8 Mon Sep 17 00:00:00 2001 From: chenhuan Date: Tue, 10 Dec 2019 22:39:12 +0100 Subject: [PATCH 35/39] refresh frequency set --- src/GUI.cpp | 21 ++++++++++++--------- src/GUI.hpp | 22 ++++++++++++++-------- src/GUI_Window.cpp | 2 +- src/Image.cpp | 12 +++++++++--- 4 files changed, 36 insertions(+), 21 deletions(-) diff --git a/src/GUI.cpp b/src/GUI.cpp index b104a23..c8260c4 100644 --- a/src/GUI.cpp +++ b/src/GUI.cpp @@ -12,19 +12,22 @@ auto GUI_run(int argc, char **argv) -> int { window_width = vkvm::getWidth(); char *resolusion = get_resolusion(window_height, window_width); std::cout << resolusion << std::endl; - GUI_Window *window = new GUI_Window(window_width, window_height + 30, "example"); + auto *window = new GUI_Window(window_width, window_height + 30, "example"); Statusbar *status[5]; //Dummy-Values TBD window->begin(); - Image *image = new Image(0, 30, window_width, window_height); + auto *image = new Image(0, 30, window_width, window_height); status[0] = new Statusbar(0, 0, 300, 30, resolusion); status[1] = new Statusbar(300, 0, 170, 30, "Event:"); status[2] = new Statusbar(470, 0, 200, 30, "Mouse Position:"); - vkvm::registerEvent(vkvm::EventType::Redraw, [image](){ + vkvm::registerEvent(vkvm::EventType::Redraw, [image]() { redraw(image); }); - Fl::repeat_timeout(0.5, get_new_image, image); + vkvm::registerEvent(vkvm::EventType::UpdateControlRegisters, [image]() { + image->setDelay(vkvm::getTimerInterruptInterval()); + }); + Fl::repeat_timeout(image->getDelay(), get_new_image, image); window->end(); window->show(argc, argv); return Fl::run(); @@ -42,20 +45,20 @@ char *get_resolusion(int window_height, int window_width) { return resolusion; } -void redraw(Image* image){ +void redraw(Image *image) { image->getPixels(); - sleep(0.05); image->redraw(); } void get_new_image(void *pointer) { - ((Image *) pointer)->getPixels(); - Fl::repeat_timeout(0.5, refresh_image, pointer); + Image *image = ((Image *) pointer); + image->getPixels(); + Fl::repeat_timeout(image->getDelay(), refresh_image, pointer); } void refresh_image(void *pointer) { ((Image *) pointer)->redraw(); - Fl::repeat_timeout(0.5, get_new_image, pointer); + get_new_image(pointer); } diff --git a/src/GUI.hpp b/src/GUI.hpp index 47dfe9e..bd8c34d 100644 --- a/src/GUI.hpp +++ b/src/GUI.hpp @@ -1,7 +1,7 @@ #include -#include -#include -#include +#include +#include +#include #include #include #include @@ -20,12 +20,12 @@ * @param button The button that was pushed last. */ class GUI_Window : public Fl_Window { - int x, y, button; + int x{}, y{}, button{}; vkvm::KeyCode keyCode; - int handle(int e); + int handle(int e) override; - char *position_to_string(int x, int y); + static char *position_to_string(int x, int y); public: GUI_Window(int x, int y, const char *l); @@ -40,12 +40,18 @@ public: class Image : public Fl_Widget { uchar *buf; + double delay; + public: Image(int x, int y, int w, int h); - void draw(); + void draw() override; void getPixels(); + + void setDelay(double delay); + + double getDelay(); }; /** Statusbar @@ -53,7 +59,7 @@ public: * @param text: A pointer to a char-array, that can contain a text like a status or whatever you want. */ class Statusbar : public Fl_Box { - char *text; + char* text; public: Statusbar(int x, int y, int w, int h, char *text); }; diff --git a/src/GUI_Window.cpp b/src/GUI_Window.cpp index da0d5f2..5fb0c53 100644 --- a/src/GUI_Window.cpp +++ b/src/GUI_Window.cpp @@ -80,7 +80,7 @@ auto GUI_Window::handle(int e) -> int { GUI_Window::GUI_Window(int x, int y, const char *l) : Fl_Window(x, y, l) {} auto GUI_Window::position_to_string(int x,int y)->char*{ - char *str = new char[25]; + auto *str = new char[25]; std::string str_temp; str = strcpy(str,"Mouse Position X:"); str_temp = std::to_string(x); diff --git a/src/Image.cpp b/src/Image.cpp index c4284df..1e5ec56 100644 --- a/src/Image.cpp +++ b/src/Image.cpp @@ -10,10 +10,10 @@ auto Image::draw() -> void { fl_draw_image(buf, x(), y(), w(), h()); } - Image::Image(int x, int y, int w, int h) : - Fl_Widget(x, y, w, h, 0) { + Fl_Widget(x, y, w, h, nullptr) { buf = new uchar[w * h * 3]; + delay = ((double)vkvm::getTimerInterruptInterval())/1000; /*Just an example.*/ for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { @@ -32,6 +32,12 @@ auto Image::getPixels() -> void { buf[(i * w() + j) * 3 + 2] = c.getBlue(); } } -}; +} +auto Image::getDelay() -> double { + return delay; +} +auto Image::setDelay(double delay) -> void { + this->delay = delay; +} From b1552db8000adaa2bb6285a3927f991c18e455c1 Mon Sep 17 00:00:00 2001 From: chenhuan Date: Tue, 10 Dec 2019 22:42:07 +0100 Subject: [PATCH 36/39] getRedrawInterval --- src/GUI.cpp | 2 +- src/Image.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/GUI.cpp b/src/GUI.cpp index c8260c4..ccb838c 100644 --- a/src/GUI.cpp +++ b/src/GUI.cpp @@ -25,7 +25,7 @@ auto GUI_run(int argc, char **argv) -> int { redraw(image); }); vkvm::registerEvent(vkvm::EventType::UpdateControlRegisters, [image]() { - image->setDelay(vkvm::getTimerInterruptInterval()); + image->setDelay(vkvm::getRedrawInterval(); }); Fl::repeat_timeout(image->getDelay(), get_new_image, image); window->end(); diff --git a/src/Image.cpp b/src/Image.cpp index 1e5ec56..bee2edc 100644 --- a/src/Image.cpp +++ b/src/Image.cpp @@ -13,7 +13,7 @@ auto Image::draw() -> void { Image::Image(int x, int y, int w, int h) : Fl_Widget(x, y, w, h, nullptr) { buf = new uchar[w * h * 3]; - delay = ((double)vkvm::getTimerInterruptInterval())/1000; + delay = ((double)vkvm::getRedrawInterval())/1000; /*Just an example.*/ for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { From aa511a23152a09cec40192b9cf4e3dbb8115f6b7 Mon Sep 17 00:00:00 2001 From: chenhuan Date: Thu, 12 Dec 2019 00:02:59 +0100 Subject: [PATCH 37/39] fix green backgrund problem --- src/GUI.cpp | 2 +- src/GUI.hpp | 2 +- src/GUI_Window.cpp | 38 ++++++++++++++++++++++---------------- src/Image.cpp | 6 ------ 4 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/GUI.cpp b/src/GUI.cpp index ccb838c..2cde0d1 100644 --- a/src/GUI.cpp +++ b/src/GUI.cpp @@ -25,7 +25,7 @@ auto GUI_run(int argc, char **argv) -> int { redraw(image); }); vkvm::registerEvent(vkvm::EventType::UpdateControlRegisters, [image]() { - image->setDelay(vkvm::getRedrawInterval(); + image->setDelay(vkvm::getRedrawInterval()); }); Fl::repeat_timeout(image->getDelay(), get_new_image, image); window->end(); diff --git a/src/GUI.hpp b/src/GUI.hpp index bd8c34d..17cc0a8 100644 --- a/src/GUI.hpp +++ b/src/GUI.hpp @@ -20,7 +20,7 @@ * @param button The button that was pushed last. */ class GUI_Window : public Fl_Window { - int x{}, y{}, button{}; + int x, y, button,lastX,lastY; vkvm::KeyCode keyCode; int handle(int e) override; diff --git a/src/GUI_Window.cpp b/src/GUI_Window.cpp index 50ec3d5..34c7948 100644 --- a/src/GUI_Window.cpp +++ b/src/GUI_Window.cpp @@ -8,7 +8,7 @@ auto GUI_Window::handle(int e) -> int { case FL_PUSH: x = Fl::event_x(); y = Fl::event_y(); - vkvm::setMousePosition(x,y); + vkvm::setMousePosition(x, y); if (Fl::event_button() == FL_LEFT_MOUSE) { this->child(2)->label("Event:Mouse Left Down"); vkvm::callEvent(vkvm::EventType::MouseLeftDown); @@ -24,7 +24,7 @@ auto GUI_Window::handle(int e) -> int { case FL_RELEASE: x = Fl::event_x(); y = Fl::event_y(); - vkvm::setMousePosition(x,y); + vkvm::setMousePosition(x, y); if (Fl::event_button() == FL_LEFT_MOUSE) { this->child(2)->label("Event:Mouse Left Up"); vkvm::callEvent(vkvm::EventType::MouseLeftUp); @@ -39,8 +39,8 @@ auto GUI_Window::handle(int e) -> int { case FL_DRAG: x = Fl::event_x(); y = Fl::event_y(); - vkvm::setMousePosition(x,y); - this->child(3)->label(position_to_string(x,y)); + vkvm::setMousePosition(x, y); + this->child(3)->label(position_to_string(x, y)); if (Fl::event_button() == FL_LEFT_MOUSE) { this->child(2)->label("Event:Mouse Left Drag"); vkvm::callEvent(vkvm::EventType::MouseMove); @@ -51,16 +51,19 @@ auto GUI_Window::handle(int e) -> int { this->child(2)->label("Event:Mouse Middle Drag"); vkvm::callEvent(vkvm::EventType::MouseMove); } - return 1; /*Mousemovement*/ case FL_MOVE: x = Fl::event_x(); y = Fl::event_y(); - vkvm::setMousePosition(x,y); - vkvm::callEvent(vkvm::EventType::MouseMove); - this->child(2)->label("Event:Mouse Move"); - this->child(3)->label(position_to_string(x,y)); + if (lastX != x || lastY != y) { + lastX = x; + lastY = y; + vkvm::setMousePosition(x, y); + vkvm::callEvent(vkvm::EventType::MouseMove); + this->child(2)->label("Event:Mouse Move"); + this->child(3)->label(position_to_string(x, y)); + } return 1; /*keyboardbutton*/ case FL_KEYBOARD: @@ -72,7 +75,7 @@ auto GUI_Window::handle(int e) -> int { return 1; case FL_KEYUP: button = Fl::event_button(); - std::cout< int { return -1; } -GUI_Window::GUI_Window(int x, int y, const char *l) : Fl_Window(x, y, l) {} +GUI_Window::GUI_Window(int x, int y, const char *l) : Fl_Window(x, y, l) { + lastX = 0; + lastY = 0; +} -auto GUI_Window::position_to_string(int x,int y)->char*{ +auto GUI_Window::position_to_string(int x, int y) -> char * { auto *str = new char[25]; std::string str_temp; - str = strcpy(str,"Mouse Position X:"); + str = strcpy(str, "Mouse Position X:"); str_temp = std::to_string(x); - str = strcat(str,str_temp.c_str()); - str = strcat(str," Y:"); + str = strcat(str, str_temp.c_str()); + str = strcat(str, " Y:"); str_temp = std::to_string(y); - str = strcat(str,str_temp.c_str()); + str = strcat(str, str_temp.c_str()); return str; } diff --git a/src/Image.cpp b/src/Image.cpp index bee2edc..9ebee9f 100644 --- a/src/Image.cpp +++ b/src/Image.cpp @@ -14,12 +14,6 @@ Image::Image(int x, int y, int w, int h) : Fl_Widget(x, y, w, h, nullptr) { buf = new uchar[w * h * 3]; delay = ((double)vkvm::getRedrawInterval())/1000; - /*Just an example.*/ - for (int i = 0; i < h; i++) { - for (int j = 0; j < w; j++) { - buf[(j + (i * w)) * 3 + 1] = 0xff; - } - } } /*A function to change the colors of the image-class. It reads the colors from the Shared Memory-Class*/ From 555f5a551d7811ec477a58ff80128a86ff049667 Mon Sep 17 00:00:00 2001 From: chenhuan Date: Thu, 12 Dec 2019 13:05:20 +0100 Subject: [PATCH 38/39] fix green backgrund problem fix mouse interrupt problem --- src/GUI.hpp | 4 ++- src/GUI_Window.cpp | 58 ++++++++++++++++++++++++++++++-------------- src/Mouse_Status.hpp | 12 +++++++++ 3 files changed, 55 insertions(+), 19 deletions(-) create mode 100644 src/Mouse_Status.hpp diff --git a/src/GUI.hpp b/src/GUI.hpp index 17cc0a8..7943393 100644 --- a/src/GUI.hpp +++ b/src/GUI.hpp @@ -5,6 +5,7 @@ #include #include #include +#include "Mouse_Status.hpp" #include "vkvm.hpp" #include "internal.hpp" @@ -20,7 +21,7 @@ * @param button The button that was pushed last. */ class GUI_Window : public Fl_Window { - int x, y, button,lastX,lastY; + int x, y, button,lastX,lastY,mouse_status; vkvm::KeyCode keyCode; int handle(int e) override; @@ -74,4 +75,5 @@ void redraw(Image *image); int GUI_run(int argc, char **argv); + #endif //GUI_GUI_HPP diff --git a/src/GUI_Window.cpp b/src/GUI_Window.cpp index 34c7948..c105c53 100644 --- a/src/GUI_Window.cpp +++ b/src/GUI_Window.cpp @@ -10,14 +10,20 @@ auto GUI_Window::handle(int e) -> int { y = Fl::event_y(); vkvm::setMousePosition(x, y); if (Fl::event_button() == FL_LEFT_MOUSE) { + mouse_status |= Mouse_Status::left_down; this->child(2)->label("Event:Mouse Left Down"); vkvm::callEvent(vkvm::EventType::MouseLeftDown); + std::cout<child(2)->label("Event:Mouse Right Down"); vkvm::callEvent(vkvm::EventType::MouseRightDown); + std::cout<child(2)->label("Event:Mouse Middle Down"); vkvm::callEvent(vkvm::EventType::MouseMiddleDown); + std::cout< int { y = Fl::event_y(); vkvm::setMousePosition(x, y); if (Fl::event_button() == FL_LEFT_MOUSE) { + mouse_status &= Mouse_Status::left_up; this->child(2)->label("Event:Mouse Left Up"); vkvm::callEvent(vkvm::EventType::MouseLeftUp); + std::cout<child(2)->label("Event:Mouse Right Up"); vkvm::callEvent(vkvm::EventType::MouseRightUp); + std::cout<child(2)->label("Event:Mouse Middle Up"); vkvm::callEvent(vkvm::EventType::MouseMiddleUp); + std::cout< int { y = Fl::event_y(); vkvm::setMousePosition(x, y); this->child(3)->label(position_to_string(x, y)); - if (Fl::event_button() == FL_LEFT_MOUSE) { - this->child(2)->label("Event:Mouse Left Drag"); - vkvm::callEvent(vkvm::EventType::MouseMove); - } else if (Fl::event_button() == FL_RIGHT_MOUSE) { - this->child(2)->label("Event:Mouse Right Drag"); - vkvm::callEvent(vkvm::EventType::MouseMove); - } else { - this->child(2)->label("Event:Mouse Middle Drag"); - vkvm::callEvent(vkvm::EventType::MouseMove); + switch (mouse_status) { + case Mouse_Status::left_down : + this->child(2)->label("Event:Mouse Left Drag"); + vkvm::callEvent(vkvm::EventType::MouseMove); + break; + case Mouse_Status::right_down : + this->child(2)->label("Event:Mouse Right Drag"); + vkvm::callEvent(vkvm::EventType::MouseMove); + break; + case Mouse_Status::middle_down : + this->child(2)->label("Event:Mouse Middle Drag"); + vkvm::callEvent(vkvm::EventType::MouseMove); } return 1; + /*Mousemovement*/ case FL_MOVE: - x = Fl::event_x(); - y = Fl::event_y(); - if (lastX != x || lastY != y) { - lastX = x; - lastY = y; - vkvm::setMousePosition(x, y); - vkvm::callEvent(vkvm::EventType::MouseMove); - this->child(2)->label("Event:Mouse Move"); - this->child(3)->label(position_to_string(x, y)); + if (mouse_status == 0) { + x = Fl::event_x(); + y = Fl::event_y(); + if (lastX != x || lastY != y) { + lastX = x; + lastY = y; + vkvm::setMousePosition(x, y); + vkvm::callEvent(vkvm::EventType::MouseMove); + this->child(2)->label("Event:Mouse Move"); + this->child(3)->label(position_to_string(x, y)); + } + } else { + handle(FL_DRAG); } return 1; /*keyboardbutton*/ @@ -82,12 +102,14 @@ auto GUI_Window::handle(int e) -> int { this->child(2)->label("Event:Key Up"); return 1; } + return -1; } GUI_Window::GUI_Window(int x, int y, const char *l) : Fl_Window(x, y, l) { lastX = 0; lastY = 0; + mouse_status = 0; } auto GUI_Window::position_to_string(int x, int y) -> char * { diff --git a/src/Mouse_Status.hpp b/src/Mouse_Status.hpp new file mode 100644 index 0000000..9ebb122 --- /dev/null +++ b/src/Mouse_Status.hpp @@ -0,0 +1,12 @@ + + enum Mouse_Status { + left_down = 0b100, + right_down = 0b010, + middle_down = 0b001, + left_up = 0b011, + right_up = 0b101, + middle_up = 0b110, + }; + + + From f91b9cf2f0b046b8835ad44af14f30997c49285b Mon Sep 17 00:00:00 2001 From: chenhuan Date: Thu, 12 Dec 2019 13:07:14 +0100 Subject: [PATCH 39/39] delete no need output --- src/GUI_Window.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/GUI_Window.cpp b/src/GUI_Window.cpp index c105c53..13e1d75 100644 --- a/src/GUI_Window.cpp +++ b/src/GUI_Window.cpp @@ -13,17 +13,17 @@ auto GUI_Window::handle(int e) -> int { mouse_status |= Mouse_Status::left_down; this->child(2)->label("Event:Mouse Left Down"); vkvm::callEvent(vkvm::EventType::MouseLeftDown); - std::cout<child(2)->label("Event:Mouse Right Down"); vkvm::callEvent(vkvm::EventType::MouseRightDown); - std::cout<child(2)->label("Event:Mouse Middle Down"); vkvm::callEvent(vkvm::EventType::MouseMiddleDown); - std::cout< int { mouse_status &= Mouse_Status::left_up; this->child(2)->label("Event:Mouse Left Up"); vkvm::callEvent(vkvm::EventType::MouseLeftUp); - std::cout<child(2)->label("Event:Mouse Right Up"); vkvm::callEvent(vkvm::EventType::MouseRightUp); - std::cout<child(2)->label("Event:Mouse Middle Up"); vkvm::callEvent(vkvm::EventType::MouseMiddleUp); - std::cout<