From 1945f456f14aa58edaa0403d3a170c01b2df5a5f Mon Sep 17 00:00:00 2001 From: Jake Coxon Date: Mon, 20 Jul 2020 20:54:35 +0100 Subject: [PATCH] Windows 98 style --- MS Sans Serif Bold.ttf | Bin 0 -> 12256 bytes MS Sans Serif.ttf | Bin 0 -> 14280 bytes imconfig.h | 2 + imgui.cpp | 111 +++++++++++++++++++++++++++++++- imgui.h | 5 ++ imgui_draw.cpp | 141 +++++++++++++++++++++++++++++++++++++++++ imgui_widgets.cpp | 78 +++++++++++++++++++++++ 7 files changed, 336 insertions(+), 1 deletion(-) create mode 100644 MS Sans Serif Bold.ttf create mode 100644 MS Sans Serif.ttf diff --git a/MS Sans Serif Bold.ttf b/MS Sans Serif Bold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..b91b8faf8eca387935c1012f4309f1749e047aaa GIT binary patch literal 12256 zcmeHNOKhCg6+ZKD#<623PDo-x0zVKTD77cA0^%VNLQJwijp8VZR2-ObCiW29V`j!A zp_GDDRfu?jDpXOGZbGH9U{O_Fv|-UMP{o1;Nhw8rskBH<3k!r2h!X7S_nmvs{CCDP zj#0a*)QPU|{qMc!obP<++{Zr|Nr*_7JS!=QzCN7Y)_c?XLn7TTqW7`U$=vjnzs~JI z`*o4z#<7W$M=$kX`LoE1RU$V%JzmHid303`bCYjj&K=|E=s7j_oIn{qo5v@sCw}ts z{MYcjStPM zZ4P)o;W$bXh03qNUm#EPOFEI(=T+!Q%Z+l2+$IBZk9H|6Y^b34z(W1MeeVQse9$2ssvYqnVo zC+D$k^TRsqH=jAqHg$w^+2(v=3*|VEeVu3KXIYaE7UEKd56HdJp|mFTZ{wdR@!fhH zR(lD`t;RnWx1?lbvu~$llicpxY1trqe7i%sCGXqIAUWyV8QA`|Z+FT%dBeAtV-Gp& z+g*~CcYS+>Jebh^21t73*2F`;zgGqmCEs2nwE)2voH*y(3A8`+ z?WFW3H~4l+?oQt7+iBU6%=>nStV@31x0lK0f2p% zIQ5iouaM_c@B4O->`Oo9+r9Eg`lr6VM)r5CaBbl4?>M}xG<~vM92>7j6Q!AG+m@|& zK0F)^=cX#raG_j08a+^&II_PmHZzec50$2>!`1T4Xf;|mXJJp|#SRwAm11cs+B&%9 z;o$+Q9#GW-R2}FnR-#-~E$5CDCUfOuQR!$jG`u&`3FD>dXzx_DP@c+Fp(-~KJv5o$ zGhVGu-<{1K1+0p~8XPT6X5q%UgT0bgRtt-jY-PN3 zJiB%KT|4f&V_SBzGEku(6;d>ihabDj1webU5bY{WPGWwvvsx_|^D~4S4Ugx_g=ptQ z@mRsz8uilwn6n2<<+1EUakMa1DO9rglhB^sKDZ@2M2-34SoFk9ZuD4jYAkxHFg<>< zT!|hp!I8<6@ajaAFC5u(9S2{|JBr2zREv~w66LhlrG4WpFNJF0q@qGu^{q9$tx zVY>`uMYS3M^B|B@(?A_HTZVd|j=D9@qI#KwcSN6qcLnSd^y?V055@u&zG@^}5i9)mq zHjcw8qm&2lMMyKE$I+_7Dsda$I5J&d3QsGvj`<4ER-mf{ds#$byWAx^Q0_n`W#LN& z@u&bDvxu!Y9(l+xi*|vvf@keXv?9&VNyrj4z1j&sh`gx&8N1BRamZ1cb0#o;4DCjq zN1L=ehE4Y%Y?P71WV{IW3u>_dt6A7O>9J?w6|*Y~CX3=Q=Fu91-6z0!4wA?4Jf%HP zLCZ8yaD5T|CSJtJnC`?SMFgj( z)@Z+-+Kvufa_gT&y@kfm@PYkuKlDG-v!3^v-cw1O{q98SJj3%CWBzK6?jOk8cv|?; zGr4Cy=BIGNcH`7shuMuEDAkT-xJu1^1V~>Ix$+)v=WFBVxsPf$*N)cm7Cc8WFK*0_Gs;v&;CHDpZ=3QdNW9#_gLyEbO^rDOZ8C_xIxX&CeL?e zMJ}Foa$SQecf$hojlSTC_m+9Qk<7s`Yp2cCNdV!q)#13!Pml0sbmi46uM$mS#@&=m zinAzfv#-1gDt|jM~ss zgS)qNpH_ZX${MVXdtm23`0$1pS|u`a%9<80Bd*3-9X*hS?U0L5SJ-aWo2WVqy!p3c zs%y}Ve?Fw+O%_eYvD)Z?vzl>o)ZN6Z%TbMaO0LCt+YfnY_JI~@-J-^4n@3BDs>?X% z7f1MP*-358K8vZ<%)`0<^a$eG-Gs=;!E90k?acMFr-wU)_wUnxxrnvb#nnqGVs1p# zURR=;9_cuXb&7X?B?|KNDm`MF8u(o4X9b*cjhmmw9{UWpduzLR&N0Tf8XLKIPO*X; zzTtqIOst*wZ5@+g_ijW?l-5m5{qnHJa%@zMt^h(rev#$1{P z%?F<+=8Ntxu|g#pgrt4O-ww%*Wc+77?@-OppQYWS9NBa%=AyMY52I?WtYe<7OND zh-cKo{3aH9V~qPc=Af@73P>o=(9fFan|E=Cz;eZA8#=ND zTUgPQ)UzZbSIIx~+H#NB4ZqdlDzONd_Z?>)3zyy?8s*1o&r=f%NT2}UmxzaXZTe_0 zM3&hdBH<|Uw?gFiAAc7D$Gn%-^MdGTi)^xX(U_mb_fXCw$j#5DMSQR`ENa6mG~3y4s{^&~4d4q_z{&Z(8IxL#$~B_qTdXL&k{3*tGM9 z@?1yh5y!#htZD=g+!NVn89=LCmwdKC(niHy3D@N{J_XEV!9i_X-1SDP8!Fk9xDW(Q;cvnKa?#GE#1?52uE{a+i(2Melx z2GLjZjyzC{t|s&|`s9f$_}huw7u09=8S^G_$$uNFwp;MPT(n#@Yt93*Lsoe2p-r9% z&JX_%r%@yp>Tojg9VxRLTsGOWDB6l;%~&~aY^8L=-wRkhIui4?gm)=wGTpSLd5Spr zd{EBV&o#rE{@NJh<$PeT&9Z%zv+A?kXk?s%Ji(i{i!SvNRh(hoJM~TXp*AbRB*R^f znwSMdW_66480j?&W5LK;UyN_DwIAA47Ceu2@42?>Tp0?EGG}R%Qnb%nb0%Kzg*;Qv^4~pkhgsw(XBS8K}YV)z)Jb~r6M4zKQYx3}jl#aq5RSmXIUOJcq3C zU7G*XYrHqJz_l0i5K4w^kzlN_y6JLMa{ z+xmp-7^Q2l^9+7L(Bf30T|;l{L+vA`^u&FaXz{RoU~N{Ne*OL}z-6PBHL)J!#okfD zYD!w}_uOCWYmGm+Vx}$45j|V{`}%^j)9hH5(}qbWsvNzXb+>Qb zqoLEzJ+}rr&%lQ^cN^n@wPB`DEJVvfl#WlEVH{D4woD6oH{P%(rttszO}n%CqLB(X zbIh18AsTwC_gT-8#$#=>UfZWy={MB8YlJ>^oOQU}`>oBQZ)BPbH29@wPOI;6jUD64 zV$*mAQfCZ*s#$qY|hr~VU^P%q3o)gH;^*9W80=40Ma zhF*m^rtEOvg1q+EJ!Do`#7x5So6p88BjLDQ%6nJ$X?Wg}Z@pb2UX~A5$KUiB*Fo+5 zhtBRs|LL=xNR7UcdCRvTa`p9z@s{ra%%8d@@4w|#n04+u&v3-=IvQi2+Y1;l?eyAk zQ!Dc<&SyR4&};jca=#?KT!YPPCDyCEJ-9d2@x4^P%j+<1$tu?bku}6c(_1<8IWv4(%GM*d~8{srlFk zQWt#8lGThbW%;ZHx#DhQ=|^02=oP(X%^8Zxe}|`buHqa0pcSq`+jYzm^F8)lXZqRn z%Vuc}%gmAa*^aZg7q+n(dScqhnrR{q_6Iu^p6H$HjlB$Wd~ur=L(@Q87R!2{u0THN zKC=XyooBiRu|`|01+!;+h52Xaa_1S^G0RpHm9?n>A2J%2H{FaRem9;PNBIK#(H@kS zP<{dA$n1`NC>QXXar_oNgCEFbp2c3+i83v+96tnJ{xZrtxPx!RP3IbvSMU=})GMAx zfxaH->p{C0vc3CIswlq}Sqb@-n7ax(R(%KML;PCzUX(ZS%i1j{Z;Pyf%o@n7c^^MZ zhmN(7T??J-UPr1TMLcyGk vXm6ZFL3yZp4vo#WqsAwV;Tx7e-yvP=La+Go(f$Ba*{# zhL)5zsS6Z=U~%DP0%Q?b2AYKzMUh1zCqNfQk%bqLToic$RUZLp$BWdkT0siQe&0R! z`~QDlq-+!|P;`XL`#z8FoO|y1{~1}q%m(dM>#^jICdv;F-@WJ8W?Ro;^s7^Im4&^3 zf7b-sZ{=L(4 zjWe&^XV0PkgjwO-Y;CGyHu(~kvcEi6IkRAs>pwRuy@U11d}Xfs?e~`6L;v5*`rcTm z)f-k^Uxhp?oJT35^q|~=zmU9euaycr(BFZ79RGcL(q6VdwQnW2C41M`F_K{953OR~ zOh%JC*Votob^Tw~|9Sn&`afM6zw#y0_&@gfe>|EEN(-ZufBntxyuAI1t8^89{^8my zQ>xdNS4Vf)@OktH;9>3)_&a=l6@I+4v9?@j>}<68%4F#nDZnY=ohtoDaGb_K=pwxK z4X-)JwJg1td`x}LaSzvPj_qzmv^2jRJ}y4wE8d(}UpzF&^_t7qqRBC?fzF|3n}sq{ zR@S1gJ^5Pm93yWQwMi$xmhD!$9OF9j>OZo!%$nG+P&U!@c^H5eo3tlvJFO97L}=vx zB!zFM_S=PV*?7oy#dgv9?XKAFu~EA}wo7)a{XuN^+E$y0?LHf_mtwmgyidjUfbFrr zitR0kNk5M5L3_~tF1EKJB7G3sL-x7CzSthNvBDq6_HNr(_;YVV*lmR$FyfWAK=ykJ zKaA~y-Cp=vY!_{~@KJ2{*nuMBB-fYh!Qz3~?zKI|KZ)%=yS=y&+x>Q?_*!fa*ynqS zvAxCmdd6aV&|c^{7~9+ITRrDud&r(E^~LtEy;wRL+q>=g(%*O+@{jhG4%ZgWF3y~s zZX~m{rR3oQ4?XtmL^4sCuO}1L#hDY&S5Gd@Ru;!=^Noqd;?h(jX_{{8BysW4>SBGS zHlI8+cHr5G{iL-&(8>{+sV9}Bu~<1?ovSRKN@^#P@rh@Wuwc5jkUTTrs4mV|8lX~{ zO};!g`Sf(7vGB!m`2^&s2RX*3YI9|Xe7Q-4_mb0fpGxH~t zZ&Vki&o0)JuhpQ#+*v4eCYh`rKXkfwXzJ(}PJZRklTX@VtJ#8`wMCn;lQwM)OKcWn zOQ;{V1NM+TX3yeGBq$Y|w|Zz*!}=5Uyj8Jl2|Fqn8OOePP?$hj#OPF@)_r&PnWTmC zQSey=@0q|MfmCCVjr;efavap#3EN;nwPVpzyl&T4?}Dh}qh* z*J!`n^9TkI$o=!GZm-xMpLpSUd&-hz@6ZVImErTeAN}SSxHvR|c7np}7@xv-?OkuR z{Ox6bXawtfa1(CDy|@Rfn?E2L2KtaHt^Nig;ZfkmKSK6fv;OLD*6&$Au|A2J*GLdV ze(CeYh2kw(_hE51*0thJGR5kt_51(h7hL<%`y9dLg>8)}ODctr5*yBDz2eGX+3e~i z?i;w+d#T&LB8YR}z(r;pH!gVQfjaODSoI(WNclA@pY@oBtU_4IAz4(DzW5ZDFb}9y za}D>EjyeAu7icNYvag+7K?>qPIZ1`K<$Bbx6|)QT0UiMtTsnCEtbV>z97+lbu(d);FX zK!2Xv$MF2OsrB+Ww6?5?ep~5c5Zym zaGcavjqxU55}sPGd5!1xb+nY$gYh7_H~CT?*PBN(rxkUex3VS@tV4;OlONYQ&C}*= z``^sB3Jv1KS$Ymm&ih=|K3{x4o{@M~iYpO0`24`d7*m2);*muI#>myt;!5gc&DuvT zB(e6dj=ChEjfnZt2Sa;gtBvVtziQFlfF90$|B=!$JR5n8-fp{rQ-_aewxTK?8t*?M zS-qD3$geUh@IEOt`j6n*Y-=;mJl>?DzFUl(WI0-k7G%6#TZUyCL61}eNv)dafh$vK zAVcX`aRsLomZI8RNq(hcz7pLq7Ix&;aF+7B$M{v6-V=znGPlkR#JS6n;z zUGUH1`|h94qv>3=@t{0htuvyS$UfVWxX|EJ@72rx^n3O4;8?U;(6w|7{@R~uApBW# zo$n$q_QC~=)$z>t+7>*=?!+_hZMHX~ArzWx?jjvVNy!|>a=2)`T^Gtj4+xgWj0{o6l`11F5uPz&wC&RXFZ82=)!q zWO%s!OUL?iyeR{%%iJWzpdTlTw@G(9fin5{nmT*hmfwdcaxPux{GuF!JgPp)zPXe4{QKkj` zLbOm_T;UGRa-6pc^(R(dE017?lk=x8c^)w%H~BTalVggVsuc%x4zIlpzXCjFMf!u5D7A&e+~Bad6zJ|KRlc17OQi-H_=+0i5_{hYA=q+TVb_p z7yHLulB<`cJ$)J2g*+;p-45}CKCe?qv|J}qXu~g~wFOe8AIjQF$zP8!0*DIugt#0r zP-d2+lM++|dMj4Q3+P=O+sq=48Zn{oIfBYH+pH7x3UYP8hO;I-JDv-kSDt*X z2s43Jr)M$W6LQqx|G6B!8G|S@am&l^Jw_3os;yY@F|Y_P)ev(+Jd|ILgtrIHl!a?c zP217S z=Qtz_%IV~7luc1Xr-yF<7%|#ocsN_IHQpU(e$FSm4Ln?&gdu5AH-3b3^tf<#9a~4b z^rFwKExV3>dvlIBdTdSoHJs;EuAQA^k}UG5PTDJqY>2}DQV#B@IBwbVqV8U0iaPNC zI6K3+j92*r(V&0&cj2ebMfJ(G9r0LYmATw zg?XGloiAlhp7}5z^V67RKJM2Ue$Dd)f@tjEmkQbYulzgU4g6duE2|~H>L4fNC4Ql_ zv>8h|F1@tx-{U&Q6k198sczL%`l?Rf7zN5ahosz|8G9zl*zxZ=qx}##-4cj0GQbWV9wf&b5r!ZUf$v`Dd&Y?qvaXD;`{Pk z{K``%wbfDnMv1oj=mYY?e7Ik8x!rb_m%Xp0Yb8xKx2!0Kg#h5nfC@l5lZb_=RM@m8O7!UBa7ORwxY~;(tlXo`=C#?5<&73@2 zSzBgQWK5&|iBPaVFlJr@%{IZ9@{le+E?dTneNyy!_5!w{R+f-uetsT7W<#CChjp_) z^W`EE=Y+My7qQHUt1l`>C;3l=n+nUW8$>(h|%Vp)3;fr7k#Do^9UkOj6NOj^$yV> zpbgwemA;yuwPqdiNr?w|qUbgP*(ROhu5zLHv0d zx$X#zef2L{tFrC+`0{A0p%xVd%lYDuGt9uX5=jt&=`e$x1rqrQ?onHnB9301+?x& ze=m6L1+Tq7F#F6cC>a0DirHOHp}b?3>_GW56!84)D9UpvADi8c_TA@DJ~X=rWA|YH yy@v966zsnbJns9B+5Mn-|BuWbcpL?5K9`_;&uky|?*rX^-$wzTeZS-X#rrSWussO? literal 0 HcmV?d00001 diff --git a/imconfig.h b/imconfig.h index c6817de7c..b54d05ce7 100644 --- a/imconfig.h +++ b/imconfig.h @@ -13,6 +13,8 @@ #pragma once +#define WIN98 + //---- Define assertion handler. Defaults to calling assert(). // If your macro uses multiple statements, make sure is enclosed in a 'do { .. } while (0)' block so it can be used as a single statement. //#define IM_ASSERT(_EXPR) MyAssert(_EXPR) diff --git a/imgui.cpp b/imgui.cpp index b17e2ee87..650a1124c 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2664,8 +2664,12 @@ void ImGui::RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool border, const float border_size = g.Style.FrameBorderSize; if (border && border_size > 0.0f) { +#ifdef WIN98 + WinAddRect(p_min, p_max, true); +#else window->DrawList->AddRect(p_min + ImVec2(1, 1), p_max + ImVec2(1, 1), GetColorU32(ImGuiCol_BorderShadow), rounding, ImDrawCornerFlags_All, border_size); window->DrawList->AddRect(p_min, p_max, GetColorU32(ImGuiCol_Border), rounding, ImDrawCornerFlags_All, border_size); +#endif } } @@ -5165,11 +5169,57 @@ static inline void ClampWindowRect(ImGuiWindow* window, const ImRect& visibility window->Pos = ImClamp(window->Pos, visibility_rect.Min - size_for_clamping, visibility_rect.Max); } +void ImGui::WinAddRect(const ImVec2& min, const ImVec2& max, bool inset) +{ + ImU32 top_left = IM_COL32(255,255,255,255); + ImU32 bottom_right = IM_COL32(0,0,0,255); + ImU32 top_left_inner = IM_COL32(223,223,223,255); + ImU32 bottom_right_inner = IM_COL32(128,128,128,255); + + if (inset) { + ImU32 tmp = top_left; top_left = bottom_right; bottom_right = tmp; + tmp = top_left_inner; top_left_inner = bottom_right_inner; bottom_right_inner = tmp; + } + + // ImU32 fill_col = IM_COL32(192,192,192,255); + + ImDrawList* draw_list = ImGui::GetWindowDrawList(); + ImVec2 a = min + ImVec2(0.5f, 0.5f); + ImVec2 b = max - ImVec2(0.5f, 0.5f); + + draw_list->PathLineTo(ImVec2(a.x, b.y)); + draw_list->PathLineTo(a); + draw_list->PathLineTo(ImVec2(b.x, a.y)); + draw_list->PathStroke(top_left, false, 1.0f); + + draw_list->PathLineTo(ImVec2(a.x, b.y)); + draw_list->PathLineTo(b); + draw_list->PathLineTo(ImVec2(b.x, a.y)); + draw_list->PathStroke(bottom_right, false, 1.0f); + + + draw_list->PathLineTo(ImVec2(a.x, b.y) + ImVec2(1, -1)); + draw_list->PathLineTo(a + ImVec2(1, 1)); + draw_list->PathLineTo(ImVec2(b.x, a.y) + ImVec2(-1, 1)); + draw_list->PathStroke(top_left_inner, false, 1.0f); + + draw_list->PathLineTo(ImVec2(a.x, b.y) + ImVec2(1, -1)); + draw_list->PathLineTo(b + ImVec2(-1, -1)); + draw_list->PathLineTo(ImVec2(b.x, a.y) + ImVec2(-1, 1)); + draw_list->PathStroke(bottom_right_inner, false, 1.0f); +} + + static void ImGui::RenderWindowOuterBorders(ImGuiWindow* window) { ImGuiContext& g = *GImGui; float rounding = window->WindowRounding; float border_size = window->WindowBorderSize; + +#ifdef WIN98 // window borders + if (border_size > 0.0f && !(window->Flags & ImGuiWindowFlags_NoBackground)) + WinAddRect(window->Pos, window->Pos + window->Size, false); +#else if (border_size > 0.0f && !(window->Flags & ImGuiWindowFlags_NoBackground)) window->DrawList->AddRect(window->Pos, window->Pos + window->Size, GetColorU32(ImGuiCol_Border), rounding, ImDrawCornerFlags_All, border_size); @@ -5187,6 +5237,7 @@ static void ImGui::RenderWindowOuterBorders(ImGuiWindow* window) float y = window->Pos.y + window->TitleBarHeight() - 1; window->DrawList->AddLine(ImVec2(window->Pos.x + border_size, y), ImVec2(window->Pos.x + window->Size.x - border_size, y), GetColorU32(ImGuiCol_Border), g.Style.FrameBorderSize); } +#endif } // Draw background and borders @@ -5294,6 +5345,11 @@ void ImGui::RenderWindowTitleBarContents(ImGuiWindow* window, const ImRect& titl float pad_l = style.FramePadding.x; float pad_r = style.FramePadding.x; float button_sz = g.FontSize; +#ifdef WIN98 // draw title bar + button_sz = 16.0f; + // pad_l = 0.0f; + pad_r = 0.0f; +#endif ImVec2 close_button_pos; ImVec2 collapse_button_pos; if (has_close_button) @@ -5312,6 +5368,38 @@ void ImGui::RenderWindowTitleBarContents(ImGuiWindow* window, const ImRect& titl pad_l += button_sz; } +#ifdef WIN98 // windows style title bar + + close_button_pos += ImVec2(0.0f, 2.0f); + collapse_button_pos += ImVec2(0.0f, 2.0f); + + ImU32 col_left = IM_COL32(128,128,128,255); + ImU32 col_right = IM_COL32(181,181,181,255); + + bool focused = IsWindowFocused(ImGuiFocusedFlags_ChildWindows); + if (focused) { + + // Windows98 colors are (0,0,128), (16,132,208) + // This code generates the secondary color from the primary while + // keeping the original windows colors + col_left = GetColorU32(ImGuiCol_TitleBgActive); + + ImVec4 secondary = GetStyleColorVec4(ImGuiCol_TitleBgActive); + ImVec4 secondary_hsv; + ColorConvertRGBtoHSV(secondary.x, secondary.y, secondary.z, secondary_hsv.x, secondary_hsv.y, secondary_hsv.z); + secondary_hsv.x -= 0.1f; + if (secondary_hsv.x < 0.0f) secondary_hsv.x += 1.0f; + secondary_hsv.y *= 0.92f; + secondary_hsv.z *= 1.625f; + ColorConvertHSVtoRGB(secondary_hsv.x, secondary_hsv.y, secondary_hsv.z, secondary.x, secondary.y, secondary.z); + + col_right = ColorConvertFloat4ToU32(secondary); + } + + + window->DrawList->AddRectFilledMultiColor(title_bar_rect.Min, title_bar_rect.Max, col_left, col_right, col_right, col_left); +#endif + // Collapse button (submitting first so it gets priority when choosing a navigation init fallback) if (has_collapse_button) if (CollapseButton(window->GetID("#COLLAPSE"), collapse_button_pos)) @@ -5346,6 +5434,14 @@ void ImGui::RenderWindowTitleBarContents(ImGuiWindow* window, const ImRect& titl pad_r = ImMax(pad_r, pad_extend * centerness); } +#ifdef WIN98 // windows title font + if (focused) PushStyleColor(ImGuiCol_Text, IM_COL32(255,255,255,255)); + else PushStyleColor(ImGuiCol_Text, IM_COL32(192,192,192,255)); + ImGuiIO& io = ImGui::GetIO(); + ImFont* font = io.Fonts->Fonts[1]; // Assume the icon font is here. pretty bad + PushFont(font); +#endif + ImRect layout_r(title_bar_rect.Min.x + pad_l, title_bar_rect.Min.y, title_bar_rect.Max.x - pad_r, title_bar_rect.Max.y); ImRect clip_r(layout_r.Min.x, layout_r.Min.y, layout_r.Max.x + g.Style.ItemInnerSpacing.x, layout_r.Max.y); //if (g.IO.KeyCtrl) window->DrawList->AddRect(layout_r.Min, layout_r.Max, IM_COL32(255, 128, 0, 255)); // [DEBUG] @@ -5356,6 +5452,11 @@ void ImGui::RenderWindowTitleBarContents(ImGuiWindow* window, const ImRect& titl ImVec2 off = ImVec2(0.0f, IM_FLOOR(-g.FontSize * 0.25f)); RenderTextClipped(marker_pos + off, layout_r.Max + off, UNSAVED_DOCUMENT_MARKER, NULL, NULL, ImVec2(0, style.WindowTitleAlign.y), &clip_r); } + +#ifdef WIN98 + PopFont(); + PopStyleColor(); +#endif } void ImGui::UpdateWindowParentAndRootLinks(ImGuiWindow* window, ImGuiWindowFlags flags, ImGuiWindow* parent_window) @@ -5937,8 +6038,16 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) } // Title bar - if (!(flags & ImGuiWindowFlags_NoTitleBar)) + if (!(flags & ImGuiWindowFlags_NoTitleBar)) { +#ifdef WIN98 // title bar sizing + ImRect inset_title_rect = title_bar_rect; + inset_title_rect.Min += ImVec2(2.0f, 2.0f); + inset_title_rect.Max -= ImVec2(2.0f, 0.0f); + RenderWindowTitleBarContents(window, inset_title_rect, name, p_open); +#else RenderWindowTitleBarContents(window, title_bar_rect, name, p_open); +#endif + } // Pressing CTRL+C while holding on a window copy its content to the clipboard // This works but 1. doesn't handle multiple Begin/End pairs, 2. recursing into another Begin/End pair - so we need to work that out and add better logging scope. diff --git a/imgui.h b/imgui.h index 4517aabcd..15e91a718 100644 --- a/imgui.h +++ b/imgui.h @@ -776,6 +776,11 @@ namespace ImGui IMGUI_API void* MemAlloc(size_t size); IMGUI_API void MemFree(void* ptr); + // Windows98 functions + IMGUI_API void WinAddRect(const ImVec2& min, const ImVec2& max, bool inset); + IMGUI_API void StyleWin98(ImGuiStyle* dst = NULL); + + } // namespace ImGui //----------------------------------------------------------------------------- diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 09b5a413e..dacd97694 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -174,6 +174,12 @@ using namespace IMGUI_STB_NAMESPACE; void ImGui::StyleColorsDark(ImGuiStyle* dst) { +#ifdef WIN98 + // These colors don't make sense with win98 so just call this anyway + // also means I don't have to change all the examples + StyleWin98(dst); + return; +#endif ImGuiStyle* style = dst ? dst : &ImGui::GetStyle(); ImVec4* colors = style->Colors; @@ -229,6 +235,12 @@ void ImGui::StyleColorsDark(ImGuiStyle* dst) void ImGui::StyleColorsClassic(ImGuiStyle* dst) { +#ifdef WIN98 + // These colors don't make sense with win98 so just call this anyway + // also means I don't have to change all the examples + StyleWin98(dst); + return; +#endif ImGuiStyle* style = dst ? dst : &ImGui::GetStyle(); ImVec4* colors = style->Colors; @@ -285,6 +297,13 @@ void ImGui::StyleColorsClassic(ImGuiStyle* dst) // Those light colors are better suited with a thicker font than the default one + FrameBorder void ImGui::StyleColorsLight(ImGuiStyle* dst) { +#ifdef WIN98 + // These colors don't make sense with win98 so just call this anyway + // also means I don't have to change all the examples + StyleWin98(dst); + return; +#endif + ImGuiStyle* style = dst ? dst : &ImGui::GetStyle(); ImVec4* colors = style->Colors; @@ -338,6 +357,128 @@ void ImGui::StyleColorsLight(ImGuiStyle* dst) colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.20f, 0.20f, 0.20f, 0.35f); } +// Windows style config +#ifdef WIN98 +void ImGui::StyleWin98(ImGuiStyle* dst) +{ + ImGuiStyle* style = dst ? dst : &ImGui::GetStyle(); + style->FrameBorderSize = 1.0f; + style->FramePadding = ImVec2(4.0f, 4.0f); + style->WindowMenuButtonPosition = ImGuiDir_Right; + style->ScrollbarSize = 16.0f; + + ImVec4* colors = style->Colors; + + colors[ImGuiCol_Text] = ImVec4(0.00f, 0.00f, 0.00f, 1.00f); + colors[ImGuiCol_TextDisabled] = ImVec4(0.60f, 0.60f, 0.60f, 1.00f); + colors[ImGuiCol_WindowBg] = ImVec4(0.75f, 0.75f, 0.75f, 1.00f); + colors[ImGuiCol_ChildBg] = ImVec4(0.75f, 0.75f, 0.75f, 1.00f); + colors[ImGuiCol_PopupBg] = ImVec4(0.75f, 0.75f, 0.75f, 1.00f); + colors[ImGuiCol_Border] = ImVec4(0.00f, 0.00f, 0.00f, 0.30f); + colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); + colors[ImGuiCol_FrameBg] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f); + colors[ImGuiCol_FrameBgHovered] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f); + colors[ImGuiCol_FrameBgActive] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f); + colors[ImGuiCol_TitleBg] = ImVec4(0.96f, 0.96f, 0.96f, 1.00f); + colors[ImGuiCol_TitleBgActive] = ImVec4(0.00f, 0.00f, 0.50f, 1.00f); + colors[ImGuiCol_TitleBgCollapsed] = ImVec4(1.00f, 1.00f, 1.00f, 0.51f); + colors[ImGuiCol_MenuBarBg] = ImVec4(0.86f, 0.86f, 0.86f, 1.00f); + colors[ImGuiCol_ScrollbarBg] = ImVec4(0.98f, 0.98f, 0.98f, 0.53f); + colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.69f, 0.69f, 0.69f, 0.80f); + colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.49f, 0.49f, 0.49f, 0.80f); + colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.49f, 0.49f, 0.49f, 1.00f); + colors[ImGuiCol_CheckMark] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); + colors[ImGuiCol_SliderGrab] = ImVec4(0.26f, 0.59f, 0.98f, 0.78f); + colors[ImGuiCol_SliderGrabActive] = ImVec4(0.46f, 0.54f, 0.80f, 0.60f); + colors[ImGuiCol_Button] = ImVec4(0.26f, 0.59f, 0.98f, 0.40f); + colors[ImGuiCol_ButtonHovered] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); + colors[ImGuiCol_ButtonActive] = ImVec4(0.06f, 0.53f, 0.98f, 1.00f); + colors[ImGuiCol_Header] = ImVec4(0.26f, 0.59f, 0.98f, 0.31f); + colors[ImGuiCol_HeaderHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.80f); + colors[ImGuiCol_HeaderActive] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); + colors[ImGuiCol_Separator] = ImVec4(0.39f, 0.39f, 0.39f, 0.62f); + colors[ImGuiCol_SeparatorHovered] = ImVec4(0.14f, 0.44f, 0.80f, 0.78f); + colors[ImGuiCol_SeparatorActive] = ImVec4(0.14f, 0.44f, 0.80f, 1.00f); + colors[ImGuiCol_ResizeGrip] = ImVec4(0.80f, 0.80f, 0.80f, 0.56f); + colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.67f); + colors[ImGuiCol_ResizeGripActive] = ImVec4(0.26f, 0.59f, 0.98f, 0.95f); + colors[ImGuiCol_Tab] = ImVec4(0.76f, 0.80f, 0.84f, 0.95f); + colors[ImGuiCol_TabHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.95f); + colors[ImGuiCol_TabActive] = ImVec4(0.60f, 0.73f, 0.88f, 0.95f); + colors[ImGuiCol_TabUnfocused] = ImVec4(0.92f, 0.92f, 0.94f, 0.95f); + colors[ImGuiCol_TabUnfocusedActive] = ImVec4(0.74f, 0.82f, 0.91f, 1.00f); + colors[ImGuiCol_PlotLines] = ImVec4(0.39f, 0.39f, 0.39f, 1.00f); + colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.43f, 0.35f, 1.00f); + colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f); + colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.45f, 0.00f, 1.00f); + colors[ImGuiCol_TextSelectedBg] = ImVec4(0.26f, 0.59f, 0.98f, 0.35f); + colors[ImGuiCol_DragDropTarget] = ImVec4(0.26f, 0.59f, 0.98f, 0.95f); + colors[ImGuiCol_NavHighlight] = colors[ImGuiCol_HeaderHovered]; + colors[ImGuiCol_NavWindowingHighlight] = ImVec4(0.70f, 0.70f, 0.70f, 0.70f); + colors[ImGuiCol_NavWindowingDimBg] = ImVec4(0.20f, 0.20f, 0.20f, 0.20f); + colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.20f, 0.20f, 0.20f, 0.35f); + + + if (dst != NULL) return; + + // Fonts + Icons + ImGuiIO& io = ImGui::GetIO(); + for (int i = 0; i < io.Fonts->ConfigData.size(); i++) { + if (strcmp(io.Fonts->ConfigData[i].Name, "MS Sans Serif")) { + return; + } + } + ImFont *font = io.Fonts->AddFontFromFileTTF("../../MS Sans Serif.ttf", 12.0f, NULL, io.Fonts->GetGlyphRangesDefault()); + io.Fonts->AddFontFromFileTTF("../../MS Sans Serif Bold.ttf", 12.0f, NULL, io.Fonts->GetGlyphRangesDefault()); + + // Run-length encoding of some icons + // In retrorespect I should have used an icon map like FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS + unsigned char minimize[] = {86,6,6,6,0}; + unsigned char close[] = {14,2,4,2,5,2,2,2,7,4,9,2,9,4,7,2,2,2,5,2,4,2,0}; + unsigned char *run_length[] = {minimize, close}; + + int rect_ids[IM_ARRAYSIZE(run_length)]; + for (int i = 0; i < IM_ARRAYSIZE(run_length); i++) { + rect_ids[i] = io.Fonts->AddCustomRectFontGlyph(font, 214 + i, 12, 9, 13+1); + } + + io.Fonts->Build(); + + unsigned char* tex_pixels = NULL; + int tex_width, tex_height; + io.Fonts->GetTexDataAsRGBA32(&tex_pixels, &tex_width, &tex_height); + + for (int i = 0; i < IM_ARRAYSIZE(run_length); i++) { + + int rect_id = rect_ids[i]; + if (const ImFontAtlas::CustomRect* rect = io.Fonts->GetCustomRectByIndex(rect_id)) { + bool black = false; + unsigned char* run = run_length[i]; + int run_size = 0; + + for (int y = 0; y < rect->Height; y++) + { + ImU32* p = (ImU32*)tex_pixels + (rect->Y + y) * tex_width + (rect->X); + for (int x = rect->Width; x > 0; x--) { + if (black) *p = IM_COL32(255, 0, 0, 255); + p ++; + run_size ++; + if (run_size == *run) { + run_size = 0; + run ++; + black = !black; + if (*run == 0) goto done; + } + } + } + done:; + } + } + + +} +#endif + //----------------------------------------------------------------------------- // ImDrawList //----------------------------------------------------------------------------- diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 86295bcd1..1c5a0ce51 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -668,9 +668,19 @@ bool ImGui::ButtonEx(const char* label, const ImVec2& size_arg, ImGuiButtonFlags // Render const ImU32 col = GetColorU32((held && hovered) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button); +#ifdef WIN98 + const ImU32 fill_col = GetColorU32(ImGuiCol_WindowBg); + window->DrawList->AddRectFilled(bb.Min, bb.Max, fill_col, 0.0f); + + WinAddRect(bb.Min, bb.Max, (held && hovered)); + PushStyleColor(ImGuiCol_Text, ImVec4(0.0f, 0.0f, 0.0f, 1.0f)); + RenderTextClipped(bb.Min + style.FramePadding, bb.Max - style.FramePadding, label, NULL, &label_size, style.ButtonTextAlign, &bb); + PopStyleColor(); +#else RenderNavHighlight(bb, id); RenderFrame(bb.Min, bb.Max, col, true, style.FrameRounding); RenderTextClipped(bb.Min + style.FramePadding, bb.Max - style.FramePadding, label, NULL, &label_size, style.ButtonTextAlign, &bb); +#endif // Automatically close popups //if (pressed && !(flags & ImGuiButtonFlags_DontClosePopups) && (window->Flags & ImGuiWindowFlags_Popup)) @@ -762,9 +772,13 @@ bool ImGui::CloseButton(ImGuiID id, const ImVec2& pos)//, float size) ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; +#ifdef WIN98 // close button size + const ImRect bb(pos, pos + ImVec2(16.0f, 14.0f)); +#else // We intentionally allow interaction when clipped so that a mechanical Alt,Right,Validate sequence close a window. // (this isn't the regular behavior of buttons, but it doesn't affect the user much because navigation tends to keep items visible). const ImRect bb(pos, pos + ImVec2(g.FontSize, g.FontSize) + g.Style.FramePadding * 2.0f); +#endif bool is_clipped = !ItemAdd(bb, id); bool hovered, held; @@ -775,14 +789,25 @@ bool ImGui::CloseButton(ImGuiID id, const ImVec2& pos)//, float size) // Render ImU32 col = GetColorU32(held ? ImGuiCol_ButtonActive : ImGuiCol_ButtonHovered); ImVec2 center = bb.GetCenter(); + +#ifdef WIN98 // close button + const ImU32 fill_col = GetColorU32(ImGuiCol_WindowBg); + window->DrawList->AddRectFilled(bb.Min, bb.Max, fill_col, 0.0f); + WinAddRect(bb.Min, bb.Max, hovered && held); +#else if (hovered) window->DrawList->AddCircleFilled(center, ImMax(2.0f, g.FontSize * 0.5f + 1.0f), col, 12); +#endif float cross_extent = g.FontSize * 0.5f * 0.7071f - 1.0f; ImU32 cross_col = GetColorU32(ImGuiCol_Text); center -= ImVec2(0.5f, 0.5f); +#ifdef WIN98 // close button icon + RenderText(bb.Min + ImVec2(2.0f, 2.0f), "\u00D7"); +#else window->DrawList->AddLine(center + ImVec2(+cross_extent, +cross_extent), center + ImVec2(-cross_extent, -cross_extent), cross_col, 1.0f); window->DrawList->AddLine(center + ImVec2(+cross_extent, -cross_extent), center + ImVec2(-cross_extent, +cross_extent), cross_col, 1.0f); +#endif return pressed; } @@ -792,7 +817,11 @@ bool ImGui::CollapseButton(ImGuiID id, const ImVec2& pos) ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; +#ifdef WIN98 // collapse button size + ImRect bb(pos, pos + ImVec2(16.0f, 14.0f)); +#else ImRect bb(pos, pos + ImVec2(g.FontSize, g.FontSize) + g.Style.FramePadding * 2.0f); +#endif ItemAdd(bb, id); bool hovered, held; bool pressed = ButtonBehavior(bb, id, &hovered, &held, ImGuiButtonFlags_None); @@ -801,9 +830,19 @@ bool ImGui::CollapseButton(ImGuiID id, const ImVec2& pos) ImU32 bg_col = GetColorU32((held && hovered) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button); ImU32 text_col = GetColorU32(ImGuiCol_Text); ImVec2 center = bb.GetCenter(); + +#ifdef WIN98 // collapse button + const ImU32 fill_col = GetColorU32(ImGuiCol_WindowBg); + window->DrawList->AddRectFilled(bb.Min, bb.Max, fill_col, 0.0f); + WinAddRect(bb.Min, bb.Max, hovered && held); + + // collapse icon + RenderText(bb.Min + ImVec2(2.0f, 2.0f), "\u00D6"); +#else if (hovered || held) window->DrawList->AddCircleFilled(center/*+ ImVec2(0.0f, -0.5f)*/, g.FontSize * 0.5f + 1.0f, bg_col, 12); RenderArrow(window->DrawList, bb.Min + g.Style.FramePadding, text_col, window->Collapsed ? ImGuiDir_Right : ImGuiDir_Down, 1.0f); +#endif // Switch to moving the window after mouse is moved beyond the initial drag threshold if (IsItemActive() && IsMouseDragging(0)) @@ -888,8 +927,19 @@ bool ImGui::ScrollbarEx(const ImRect& bb_frame, ImGuiID id, ImGuiAxis axis, floa const ImGuiStyle& style = g.Style; const bool allow_interaction = (alpha >= 1.0f); +#ifdef WIN98 + + ImRect bb = bb_frame; + float button_size = (axis == ImGuiAxis_X) ? bb.GetHeight() : bb.GetWidth(); + ImVec2 button_size_rect(button_size, button_size); + ImVec2 main_axis((axis == ImGuiAxis_X) ? 1.0f : 0.0f, (axis == ImGuiAxis_X) ? 0.0f : 1.0f); + ImVec2 main_axis_button_size = main_axis * button_size; + + bb.Expand(main_axis * -button_size); +#else ImRect bb = bb_frame; bb.Expand(ImVec2(-ImClamp(IM_FLOOR((bb_frame_width - 2.0f) * 0.5f), 0.0f, 3.0f), -ImClamp(IM_FLOOR((bb_frame_height - 2.0f) * 0.5f), 0.0f, 3.0f))); +#endif // V denote the main, longer axis of the scrollbar (= height for a vertical scrollbar) const float scrollbar_size_v = (axis == ImGuiAxis_X) ? bb.GetWidth() : bb.GetHeight(); @@ -944,6 +994,33 @@ bool ImGui::ScrollbarEx(const ImRect& bb_frame, ImGuiID id, ImGuiAxis axis, floa } // Render +#ifdef WIN98 // scrollbar + + ImRect grab_rect; + if (axis == ImGuiAxis_X) { + grab_rect = ImRect(ImLerp(bb.Min.x, bb.Max.x, grab_v_norm), bb.Min.y, ImLerp(bb.Min.x, bb.Max.x, grab_v_norm) + grab_h_pixels, bb.Max.y); + } else { + grab_rect = ImRect(bb.Min.x, ImLerp(bb.Min.y, bb.Max.y, grab_v_norm), bb.Max.x, ImLerp(bb.Min.y, bb.Max.y, grab_v_norm) + grab_h_pixels); + } + WinAddRect(grab_rect.Min, grab_rect.Max, false); + { + const ImGuiID up_id = window->GetID("##scrollup"); + ImRect button_bounds(bb_frame.Min, bb_frame.Min + button_size_rect); + bool held_up = false; + bool hovered_up = false; + bool pressed_up = ButtonBehavior(button_bounds, up_id, &hovered_up, &held_up, 0); + WinAddRect(button_bounds.Min, button_bounds.Max, (held_up && hovered_up)); + } + { + const ImGuiID down_id = window->GetID("##scrolldown"); + ImVec2 pos = bb_frame.Min + main_axis * (((axis == ImGuiAxis_X) ? bb_frame.GetWidth() : bb_frame.GetHeight()) - button_size); + ImRect button_bounds(pos, pos + button_size_rect); + bool held_down = false; + bool hovered_down = false; + bool pressed_down = ButtonBehavior(button_bounds, down_id, &hovered_down, &held_down, 0); + WinAddRect(button_bounds.Min, button_bounds.Max, (held_down && hovered_down)); + } +#else const ImU32 bg_col = GetColorU32(ImGuiCol_ScrollbarBg); const ImU32 grab_col = GetColorU32(held ? ImGuiCol_ScrollbarGrabActive : hovered ? ImGuiCol_ScrollbarGrabHovered : ImGuiCol_ScrollbarGrab, alpha); window->DrawList->AddRectFilled(bb_frame.Min, bb_frame.Max, bg_col, window->WindowRounding, rounding_corners); @@ -953,6 +1030,7 @@ bool ImGui::ScrollbarEx(const ImRect& bb_frame, ImGuiID id, ImGuiAxis axis, floa else grab_rect = ImRect(bb.Min.x, ImLerp(bb.Min.y, bb.Max.y, grab_v_norm), bb.Max.x, ImLerp(bb.Min.y, bb.Max.y, grab_v_norm) + grab_h_pixels); window->DrawList->AddRectFilled(grab_rect.Min, grab_rect.Max, grab_col, style.ScrollbarRounding); +#endif return held; }