From 0424d4e993e8c53dad2b49bf7a3ad4e432cb6a7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Ker=C3=A4nen?= Date: Mon, 1 Feb 2016 21:13:04 +0200 Subject: [PATCH] UI|Home|Client: Working on the new Home UI Added GameDrawerButton as a concrete DrawerButton that shows the information of a single game. Work in progress. --- .../client/include/ui/home/columnwidget.h | 2 + .../include/ui/home/drawerbuttonwidget.h | 8 +- .../client/include/ui/home/gamecolumnwidget.h | 5 +- .../client/include/ui/home/gamedrawerbutton.h | 38 ++++ .../client/include/ui/home/headerwidget.h | 1 + .../graphics/doom/background.jpg | Bin 0 -> 4147 bytes .../{game-libdoom.png => doom/icon-small.png} | Bin .../graphics/{logo-doom.png => doom/logo.png} | Bin .../graphics/heretic/background.jpg | Bin 0 -> 3961 bytes .../icon-small.png} | Bin .../{logo-heretic.png => heretic/logo.png} | Bin .../graphics/hexen/background.jpg | Bin 0 -> 4181 bytes .../icon-small.png} | Bin .../{logo-hexen.png => hexen/logo.png} | Bin .../defaultstyle.pack/images.dei | 21 +- .../apps/client/src/ui/home/columnwidget.cpp | 25 ++- .../client/src/ui/home/drawerbuttonwidget.cpp | 55 ++++- .../client/src/ui/home/gamecolumnwidget.cpp | 197 ++++++++++++++++-- .../client/src/ui/home/gamedrawerbutton.cpp | 37 ++++ .../apps/client/src/ui/home/headerwidget.cpp | 25 ++- .../apps/client/src/ui/home/homewidget.cpp | 11 +- 21 files changed, 370 insertions(+), 55 deletions(-) create mode 100644 doomsday/apps/client/include/ui/home/gamedrawerbutton.h create mode 100644 doomsday/apps/client/net.dengine.client.pack/defaultstyle.pack/graphics/doom/background.jpg rename doomsday/apps/client/net.dengine.client.pack/defaultstyle.pack/graphics/{game-libdoom.png => doom/icon-small.png} (100%) rename doomsday/apps/client/net.dengine.client.pack/defaultstyle.pack/graphics/{logo-doom.png => doom/logo.png} (100%) create mode 100644 doomsday/apps/client/net.dengine.client.pack/defaultstyle.pack/graphics/heretic/background.jpg rename doomsday/apps/client/net.dengine.client.pack/defaultstyle.pack/graphics/{game-libheretic.png => heretic/icon-small.png} (100%) rename doomsday/apps/client/net.dengine.client.pack/defaultstyle.pack/graphics/{logo-heretic.png => heretic/logo.png} (100%) create mode 100644 doomsday/apps/client/net.dengine.client.pack/defaultstyle.pack/graphics/hexen/background.jpg rename doomsday/apps/client/net.dengine.client.pack/defaultstyle.pack/graphics/{game-libhexen.png => hexen/icon-small.png} (100%) rename doomsday/apps/client/net.dengine.client.pack/defaultstyle.pack/graphics/{logo-hexen.png => hexen/logo.png} (100%) create mode 100644 doomsday/apps/client/src/ui/home/gamedrawerbutton.cpp diff --git a/doomsday/apps/client/include/ui/home/columnwidget.h b/doomsday/apps/client/include/ui/home/columnwidget.h index 8951f2c461..ca86c484db 100644 --- a/doomsday/apps/client/include/ui/home/columnwidget.h +++ b/doomsday/apps/client/include/ui/home/columnwidget.h @@ -34,6 +34,8 @@ class ColumnWidget : public de::GuiWidget public: ColumnWidget(de::String const &name = ""); + void setBackgroundImage(de::Image const &image); + de::ScrollAreaWidget &scrollArea(); de::Rule const &maximumContentWidth() const; diff --git a/doomsday/apps/client/include/ui/home/drawerbuttonwidget.h b/doomsday/apps/client/include/ui/home/drawerbuttonwidget.h index 470dd29f4d..8a2be14244 100644 --- a/doomsday/apps/client/include/ui/home/drawerbuttonwidget.h +++ b/doomsday/apps/client/include/ui/home/drawerbuttonwidget.h @@ -19,7 +19,9 @@ #ifndef DENG_CLIENT_UI_DRAWERBUTTONWIDGET_H #define DENG_CLIENT_UI_DRAWERBUTTONWIDGET_H -#include +#include +#include +#include /** * Button with an extensible drawer. @@ -29,6 +31,10 @@ class DrawerButtonWidget : public de::GuiWidget public: DrawerButtonWidget(); + de::LabelWidget &icon(); + de::LabelWidget &label(); + de::PanelWidget &drawer(); + private: DENG2_PRIVATE(d) }; diff --git a/doomsday/apps/client/include/ui/home/gamecolumnwidget.h b/doomsday/apps/client/include/ui/home/gamecolumnwidget.h index 7cecb3725b..7eff4fd8b8 100644 --- a/doomsday/apps/client/include/ui/home/gamecolumnwidget.h +++ b/doomsday/apps/client/include/ui/home/gamecolumnwidget.h @@ -24,10 +24,7 @@ class GameColumnWidget : public ColumnWidget { public: - GameColumnWidget(de::String const &name, - de::String const &author, - de::String const &gameTitle, - de::DotPath const &logoId); + GameColumnWidget(de::String const &gameFamily); void setHighlighted(bool highlighted) override; diff --git a/doomsday/apps/client/include/ui/home/gamedrawerbutton.h b/doomsday/apps/client/include/ui/home/gamedrawerbutton.h new file mode 100644 index 0000000000..e02103d55f --- /dev/null +++ b/doomsday/apps/client/include/ui/home/gamedrawerbutton.h @@ -0,0 +1,38 @@ +/** @file gamedrawerbutton.h Drawer button for games. + * + * @authors Copyright (c) 2016 Jaakko Keränen + * + * @par License + * GPL: http://www.gnu.org/licenses/gpl.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. This program is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. You should have received a copy of the GNU + * General Public License along with this program; if not, see: + * http://www.gnu.org/licenses + */ + +#ifndef DENG_CLIENT_UI_HOME_GAMEDRAWERBUTTON_H +#define DENG_CLIENT_UI_HOME_GAMEDRAWERBUTTON_H + +#include "drawerbuttonwidget.h" + +#include + +/** + * Drawer button for a particular game. Also shows the list of saved games. + */ +class GameDrawerButton : public DrawerButtonWidget +{ +public: + GameDrawerButton(Game const &game); + +private: + DENG2_PRIVATE(d) +}; + +#endif // DENG_CLIENT_UI_HOME_GAMEDRAWERBUTTON_H diff --git a/doomsday/apps/client/include/ui/home/headerwidget.h b/doomsday/apps/client/include/ui/home/headerwidget.h index 4ad8f638fb..784aa00638 100644 --- a/doomsday/apps/client/include/ui/home/headerwidget.h +++ b/doomsday/apps/client/include/ui/home/headerwidget.h @@ -34,6 +34,7 @@ class HeaderWidget : public de::GuiWidget de::LabelWidget &info(); void setLogoImage(de::DotPath const &imageId); + void setLogoBackground(de::DotPath const &imageId); private: DENG2_PRIVATE(d) diff --git a/doomsday/apps/client/net.dengine.client.pack/defaultstyle.pack/graphics/doom/background.jpg b/doomsday/apps/client/net.dengine.client.pack/defaultstyle.pack/graphics/doom/background.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e6345e7a675717441c8a4a119357fcb8eaa019d0 GIT binary patch literal 4147 zcmeHKX;c$e6n>LQfItU@QQ@0oWsh016ob4}iDCCIyYN@#sPLrc(ioN{h$WWG!x2#tu#Rq1>rGIbK}BULN8 zq(sBz`|!9RD1_8VqzatiB;m<&RWSDK#3_s;mjz=9{xQ55O*oz+kJfAPsro7LQoTYN zD8oX;oFGy}Dm6-+kZ?$4no1`kgE5~s*5*I;LYR5zpYD;QMeYT>KCt8rv+nwuO}6|Oe)f)C#B+2qBj*` zl4LHV+`mk4DM^2lNEuMCVBRR&R{$}mAN?8V&p>|$`ZLg0E}0F8y9EW~;ad<1(`24aJ485|HAN@v*FJ1`xcph39{pdlzqqoWK4wGFZu&I3A& zG01~I!EW$p5_@dH5J9eCyTgdE!)MrWHEkn(le9~jjziyf9p>gaYV??o$NKpPj1vZm z!XqX|MnzAWJT-pW^n@9SGo>m+Elz_ z=dRs*_U_w%ptS5r`O#w)mB*{jo~u58;o_ysH*eM6Hr4%X{-yC=)BWZLmWM5mp1)}C z`0eGZ&aT&#F4#x+$bw^!vcKtKL0vRD9i`h-x)53hC7eZPc<}88P58`SvS2VK$aNSJ zX4roC40D8UTpK${TjMx%q+g@wb4r>`*}oIE^gk)<6ZTG5JqU-tGZbj>L}@fwDinea zB|tFj7&h4T!rlf43d}xOp%a@28jTK5rX9nsZ|+|c>#y*4gl_!>yoVz2V?tRV1av!N zZM#;zDob$wVnwV*@z9}TNciR3WjmsdA@cZpW6n>HGBtL7ZX9m89^1*iy2wSLch0}s zQh|0Q95p{YAp6K$@1CDuQ}U+#Y>~xFXTJEt^Xk2t=RaCOu56iRfGoR;({+Bp;@t1a z1%X`(gZRT(bN#G&?c~^uD}y(*{@yER@1y27dEZ& znwi)zs#wS$9@OHOZN1SQb*hx9VvK(??1W>-WA_o)9#tO9UF845qFmy>(pY=I?E5-_ zxiKqf{P7^w^+<7w@X(Z7esLa`*f-3b8fIwy9K&8R%SBUOU-V$Zp4D5f6i;&#XPbyQ z&R1qHJMIC)YZ;I{;c0+PsLSQB_?zYs#CBpUNBFu=tMeT%Gg4OjDeeUe!rG{_>qxhV zN~6*1hg(5B>6a?6JN{co8S6d?bv+bPVItln2AwQ;U9`Y|^5IgkD${d(L;HYPRUs*X zPLZqc9-Aa?&SI>(me)RTOI=Be-m|PRhiz#R?)Xl6(RflkZHnld1bJf|=5%!XwkpH& pE8k~bH3gUs-)|~t|8$VzWq?Pn#4tCYY-}Ok`c3n&^ToAR^B;`c`#k^v literal 0 HcmV?d00001 diff --git a/doomsday/apps/client/net.dengine.client.pack/defaultstyle.pack/graphics/game-libdoom.png b/doomsday/apps/client/net.dengine.client.pack/defaultstyle.pack/graphics/doom/icon-small.png similarity index 100% rename from doomsday/apps/client/net.dengine.client.pack/defaultstyle.pack/graphics/game-libdoom.png rename to doomsday/apps/client/net.dengine.client.pack/defaultstyle.pack/graphics/doom/icon-small.png diff --git a/doomsday/apps/client/net.dengine.client.pack/defaultstyle.pack/graphics/logo-doom.png b/doomsday/apps/client/net.dengine.client.pack/defaultstyle.pack/graphics/doom/logo.png similarity index 100% rename from doomsday/apps/client/net.dengine.client.pack/defaultstyle.pack/graphics/logo-doom.png rename to doomsday/apps/client/net.dengine.client.pack/defaultstyle.pack/graphics/doom/logo.png diff --git a/doomsday/apps/client/net.dengine.client.pack/defaultstyle.pack/graphics/heretic/background.jpg b/doomsday/apps/client/net.dengine.client.pack/defaultstyle.pack/graphics/heretic/background.jpg new file mode 100644 index 0000000000000000000000000000000000000000..99a51a63446ad7572a8076b91d5f22f662f725a5 GIT binary patch literal 3961 zcmeHKX;c$e6n>LQ2*ITUiCDxM2cv?L4X`8M%#G` zGO6E&1Z{W#_J9s=9m2P9SIF0GPy%xQ+Cumw0Cyz3_C2GNCOl0gF=%v5U$!5c4*;Lb zn=0h;gNFP|Byzbk!|#4YjnvRoB%z7Lld`z|kiMq(XKPT}M0u8F10SQ4-5*ejXh;5LSa2}B96qj+l znGPeOB~&ckmA_`&UPsU1qqU5f%g@LAN_A^#P9xn$eeBMfFmaNXx1ayiPXh!(aY$&` ztnk?p^J3@6#V<%ml*#d=WQ8(CZ^&3?G-YOewJv-8hK-wY^0yc4*tx6l>!NS>?JqfS zu(YiF*zprp-~UiubF!|!;pa1F&z--}eC6u3mg_fKZ?;?Rbo_Sr-u(v;J72u~y{r3= zSAX^px?mmMCkys{%HGpOhq_2)GD@Zrx)73)5Kbpk#_=3nW=2yb=_4@y8b{aQZF`T_ z(mZ`*o-?Gn%T6Q5`?a$=328QEA0}+=e^O=_HlXVk5X0XY0wj2$Boa&&3PFYvASezL z8yxyUwZV}9%?>McV)H;Ek>N#ipg7p)KA2eB;O_|8dJ_yq5%@8obT9+-E?ycmwB65pkuQhpl3JZHS z)@>1Q_Hf#&NJpDbj>DQa#g{U2_1=|b&Q0F_HS3Co%5Nj_SLzk@qYj^A#e}7%czNDh zJ6VvFvAnR6TfW8mYp)WIBORM~DfRMGza;c&i)+uc( zVU4-;g>v($fP>TX51EaJm$;?xd^kDoW_X8(rKYp`yr2FKPj|GoO|g4bVxxQ5nFmXb z`=-`UVBB z`g#-nQPaX_ac$;}ZRzVPJsI`8r(~Lrj4_KJytF79Rut8mJB9iaInNJvitiv5F83Pp zTI*x#v{xSHK0iJ6^(R#;Eg^#Xc;Bh!>aI%8u7yc~MWq@1tfH>f*G?HktGiaUePnI@ E3*ai1X8-^I literal 0 HcmV?d00001 diff --git a/doomsday/apps/client/net.dengine.client.pack/defaultstyle.pack/graphics/game-libheretic.png b/doomsday/apps/client/net.dengine.client.pack/defaultstyle.pack/graphics/heretic/icon-small.png similarity index 100% rename from doomsday/apps/client/net.dengine.client.pack/defaultstyle.pack/graphics/game-libheretic.png rename to doomsday/apps/client/net.dengine.client.pack/defaultstyle.pack/graphics/heretic/icon-small.png diff --git a/doomsday/apps/client/net.dengine.client.pack/defaultstyle.pack/graphics/logo-heretic.png b/doomsday/apps/client/net.dengine.client.pack/defaultstyle.pack/graphics/heretic/logo.png similarity index 100% rename from doomsday/apps/client/net.dengine.client.pack/defaultstyle.pack/graphics/logo-heretic.png rename to doomsday/apps/client/net.dengine.client.pack/defaultstyle.pack/graphics/heretic/logo.png diff --git a/doomsday/apps/client/net.dengine.client.pack/defaultstyle.pack/graphics/hexen/background.jpg b/doomsday/apps/client/net.dengine.client.pack/defaultstyle.pack/graphics/hexen/background.jpg new file mode 100644 index 0000000000000000000000000000000000000000..09e9f7b1396201ad800dcf2379199443c899cde3 GIT binary patch literal 4181 zcmeHKYg7~08a%EE%TMW|HL+9KRy)hZ8Bi^U=osV;(|Ql&}@2uMxO1jKv0`lG9V%bv;1o;lz7 z&e{9Rk8kYX+q;4D>Xnfz0fGRq3Le021Ls#*R7wD%qJSR&fCiip7eIy#fd@c50L8%p zkRhH^d=s*GGKK_WcmQ4j1OD^~-@#`?zCBk3(8;-l@J;}(NMxP3N2@G&np$eq>X`y| z0Gkg0pUVppa`{3okICl|Bp?U?aw+n3Kc%FpoXbkdPdSm?Zle#U7>zn1hodpDr3$SK zXUnx}jzy~D@Yq}q5QSQFQh6$FWXkZ3DvcPsUv~;)suW@@J}`@(=|Ux|Auh2rX)z8aGOr7Im7&Ahd`vM{*(L#A^=5bc7gF#aKdAG&4-A$C-gp z5f_8A^$MjhCVb`OT=*o$CO2s|o7rXoTdUv5;e~{RaJYO9pU;93EJLQoD7COO2CpX> z!f}IKuhJP+S`CxPD3xh5jA9I~Jh3IUZYu2`YJU=_kWayJ7?321o1cm8wqJFVjZJHSSeLac2E962$hHMiq zH%?k1k#6Kb%K5(m4k77(BoYC{E9e_RrwXu?IgM!trX84eVA_Fc2c{kP`#JEmg~K(l zZ!^ON4cPlZaCC~+s5PW$b+DD>f?!Ex6iW1-5DxC+pw4a2=XdS_$I!kl^ul{1k{tVK zz@UL;U>O;~0EvN+8Hl|e%!fTH1#!SJ4PFou8KqF2X!IG+z<_FJKtjl55=y2}h-HvB z;5a}T6qg0OljI6qxiLkx$zaSdnJt-FZ*G5UNAAvDdGGDrSFry; z;rm7Z`S7E%!{rqpA365<7uCmWYXAG?nX~l`jZNp8&tLwo?Mi#c_nlX5JvVOl-nxCK z@5h0ke;FJaemF8ZM(Bcl^n@&Uoly2WT@0v;gra2BiO_|R%!F_TN?E|8x-4JkBu#h4 z_*-eSCGQ^k>}$H0Am+gwnZ9+#bKU_qp8-OeL)o7bw(Tz|n-ca^R~HC_pECqV@FbH+ zuvBCS6iR@gP$>>jC*kA(jR1WLc9_JGfkZ;#NvBe%Q)7Rc*ssCQ5!8Ma%p@c5&qQW` zP%zZ2Y3C)>2rs7V5|k&p5(c&hje1r#j4vPXTWrX+{_^;PWZ$&Su`xxOrZ!biaN@R~ zj$U{*a-n-mYWME7c@-MT==-_pYW#^ZPC3+{e1#M$|&cfGcv{6KTzCxX@Y#!Rer-gi=yLJAsFdw-qV^l8g!t#$q7 z@hJ5CtRJst{=4;dyw$C4zWv*gTF&b|AJ#hDLxWyiDX-`-(mpJ?kX z?tOdnVth1Bt=ue$nB(IkZ|fg_Lu6i1Q#5>PW_Hq}fMo$CN3;DmR|MAn^B)GjS7m0Bj z3dTR2r(Zw+O6S5A{YiR}|0}h!PbxR8&s1fkbI#GNrSWGvJhneFxfTr`BzF%!%yX+> zlk$OBeCZ0eu;MkjBD==+D|O(e=T>XE$lc~!Mbab<9sE~!SC@06*9KenrQE}GhACEb znHwK*E`8RLyRR4L=H@)#?6=M3s{^YZpsm2$?4Y*Y%nYYM~7fSv6l;6pv=PLHTn7?HCD_ZW}V6V7h)0>CNzC>!u e%-<#+$=mOV=chNk8a`f`SEjtyx$oX3d*^Srhz?5t literal 0 HcmV?d00001 diff --git a/doomsday/apps/client/net.dengine.client.pack/defaultstyle.pack/graphics/game-libhexen.png b/doomsday/apps/client/net.dengine.client.pack/defaultstyle.pack/graphics/hexen/icon-small.png similarity index 100% rename from doomsday/apps/client/net.dengine.client.pack/defaultstyle.pack/graphics/game-libhexen.png rename to doomsday/apps/client/net.dengine.client.pack/defaultstyle.pack/graphics/hexen/icon-small.png diff --git a/doomsday/apps/client/net.dengine.client.pack/defaultstyle.pack/graphics/logo-hexen.png b/doomsday/apps/client/net.dengine.client.pack/defaultstyle.pack/graphics/hexen/logo.png similarity index 100% rename from doomsday/apps/client/net.dengine.client.pack/defaultstyle.pack/graphics/logo-hexen.png rename to doomsday/apps/client/net.dengine.client.pack/defaultstyle.pack/graphics/hexen/logo.png diff --git a/doomsday/apps/client/net.dengine.client.pack/defaultstyle.pack/images.dei b/doomsday/apps/client/net.dengine.client.pack/defaultstyle.pack/images.dei index 502618c061..1d0e508184 100644 --- a/doomsday/apps/client/net.dengine.client.pack/defaultstyle.pack/images.dei +++ b/doomsday/apps/client/net.dengine.client.pack/defaultstyle.pack/images.dei @@ -21,13 +21,13 @@ logo { } game { - image libdoom { path = "graphics/game-libdoom.png" } - image libheretic { path = "graphics/game-libheretic.png" } - image libhexen { path = "graphics/game-libhexen.png" } + image libdoom { path = "graphics/doom/icon-small.png" } + image libheretic { path = "graphics/heretic/icon-small.png" } + image libhexen { path = "graphics/hexen/icon-small.png" } - image doom { path = "graphics/logo-doom.png" } - image heretic { path = "graphics/logo-heretic.png" } - image hexen { path = "graphics/logo-hexen.png" } + image doom { path = "graphics/doom/logo.png" } + image heretic { path = "graphics/heretic/logo.png" } + image hexen { path = "graphics/hexen/logo.png" } } } @@ -63,3 +63,12 @@ progress { image gear { path = "graphics/progress-gear.png" } image mini { path = "graphics/progress-mini.png" } } + +# Home: +home { + background { + image doom { path = "graphics/doom/background.jpg" } + image heretic { path = "graphics/heretic/background.jpg" } + image hexen { path = "graphics/hexen/background.jpg" } + } +} diff --git a/doomsday/apps/client/src/ui/home/columnwidget.cpp b/doomsday/apps/client/src/ui/home/columnwidget.cpp index f6a25252c6..57ffa20e4d 100644 --- a/doomsday/apps/client/src/ui/home/columnwidget.cpp +++ b/doomsday/apps/client/src/ui/home/columnwidget.cpp @@ -31,17 +31,19 @@ DENG_GUI_PIMPL(ColumnWidget) bool highlighted; LabelWidget *back; ScrollAreaWidget *scrollArea; - Vector4f bgColor; + //Vector4f bgColor; Rule const *maxContentWidth = nullptr; Instance(Public *i) : Base(i) { back = new LabelWidget; + back->margins().setZero(); + scrollArea = new ScrollAreaWidget; - QColor bg; - bg.setHsvF(de::frand(), .9, .5); - bgColor = Vector4f(bg.redF(), bg.greenF(), bg.blueF(), 1); + //QColor bg; + //bg.setHsvF(de::frand(), .9, .5); + //bgColor = Vector4f(bg.redF(), bg.greenF(), bg.blueF(), 1); } ~Instance() @@ -61,11 +63,20 @@ ColumnWidget::ColumnWidget(String const &name) .setLeft(contentMargin) .setRight(contentMargin); - d->scrollArea->rule().setRect(rule()); d->back->rule().setRect(rule()); + d->scrollArea->rule().setRect(rule()); add(d->back); add(d->scrollArea); + + setBackgroundImage(style().images().image("window.background")); +} + +void ColumnWidget::setBackgroundImage(Image const &image) +{ + d->back->setImage(image); + d->back->setImageFit(ui::FitToSize); + d->back->setSizePolicy(ui::Filled, ui::Filled); } ScrollAreaWidget &ColumnWidget::scrollArea() @@ -82,8 +93,8 @@ void ColumnWidget::setHighlighted(bool highlighted) { d->highlighted = highlighted; - d->back->set(Background(highlighted? d->bgColor : - (d->bgColor * Vector4f(.5f, .5f, .5f, 1.f)))); +/* d->back->set(Background(highlighted? d->bgColor : + (d->bgColor * Vector4f(.5f, .5f, .5f, 1.f))));*/ } bool ColumnWidget::dispatchEvent(Event const &event, bool (Widget::*memberFunc)(Event const &)) diff --git a/doomsday/apps/client/src/ui/home/drawerbuttonwidget.cpp b/doomsday/apps/client/src/ui/home/drawerbuttonwidget.cpp index 06c877c536..17a8c8bb43 100644 --- a/doomsday/apps/client/src/ui/home/drawerbuttonwidget.cpp +++ b/doomsday/apps/client/src/ui/home/drawerbuttonwidget.cpp @@ -18,14 +18,65 @@ #include "ui/home/drawerbuttonwidget.h" +#include +#include + using namespace de; DENG_GUI_PIMPL(DrawerButtonWidget) { + LabelWidget *icon; + LabelWidget *label; + PanelWidget *drawer; + QList buttons; + Instance(Public *i) : Base(i) - {} + { + self.add(icon = new LabelWidget); + self.add(label = new LabelWidget); + self.add(drawer = new PanelWidget); + + label->setSizePolicy(ui::Fixed, ui::Expand); + label->setTextLineAlignment(ui::AlignLeft); + label->setAlignment(ui::AlignLeft); + + icon->set(Background(style().colors().colorf("text"))); + } }; DrawerButtonWidget::DrawerButtonWidget() : d(new Instance(this)) -{} +{ + AutoRef iconSize(new ConstantRule(2 * 50)); + + d->icon->rule() + .setSize(iconSize, iconSize) + .setInput(Rule::Left, rule().left()) + .setInput(Rule::Top, rule().top()); + + d->label->rule() + .setInput(Rule::Top, rule().top()) + .setInput(Rule::Left, d->icon->rule().right()) + .setInput(Rule::Right, rule().right()); // adjust when buttons added + + d->drawer->rule() + .setInput(Rule::Top, d->label->rule().bottom()) + .setInput(Rule::Left, rule().left()); + + rule().setInput(Rule::Height, d->label->rule().height()); +} + +LabelWidget &DrawerButtonWidget::icon() +{ + return *d->icon; +} + +LabelWidget &DrawerButtonWidget::label() +{ + return *d->label; +} + +PanelWidget &DrawerButtonWidget::drawer() +{ + return *d->drawer; +} diff --git a/doomsday/apps/client/src/ui/home/gamecolumnwidget.cpp b/doomsday/apps/client/src/ui/home/gamecolumnwidget.cpp index 65acd70519..6284ed2e0c 100644 --- a/doomsday/apps/client/src/ui/home/gamecolumnwidget.cpp +++ b/doomsday/apps/client/src/ui/home/gamecolumnwidget.cpp @@ -18,59 +18,201 @@ #include "ui/home/gamecolumnwidget.h" #include "ui/home/headerwidget.h" +#include "ui/home/gamedrawerbutton.h" + +#include +#include + +#include +#include using namespace de; -DENG2_PIMPL(GameColumnWidget) +DENG_GUI_PIMPL(GameColumnWidget) +, DENG2_OBSERVES(Games, Readiness) +, public ChildWidgetOrganizer::IWidgetFactory { + // Item for a particular loadable game. + struct MenuItem : public ui::Item + { + Game const &game; + + MenuItem(Game const &game) : game(game) + { + setData(game.id()); + } + + String gameId() const { return data().toString(); } + + void update() const { notifyChange(); } + + DENG2_AS_IS_METHODS() + }; + + String gameFamily; HeaderWidget *header; + MenuWidget *menu; + Image bgImage; - Instance(Public *i) : Base(i) + Instance(Public *i, String const &gameFamily) + : Base(i) + , gameFamily(gameFamily) { ScrollAreaWidget &area = self.scrollArea(); area.add(header = new HeaderWidget); + header->rule() .setInput(Rule::Left, area.contentRule().left()) .setInput(Rule::Top, area.contentRule().top()) .setInput(Rule::Width, area.contentRule().width()); + + area.add(menu = new MenuWidget); + menu->enableScrolling(false); + menu->enablePageKeys(false); + menu->setGridSize(1, ui::Filled, 0, ui::Expand); + menu->organizer().setWidgetFactory(*this); + + menu->rule() + .setInput(Rule::Width, area.rule().width()) + .setInput(Rule::Left, area.contentRule().left()) + .setInput(Rule::Top, header->rule().bottom() + + style().rules().rule("gap")*2); + + DoomsdayApp::games().audienceForReadiness() += this; + } + + ~Instance() + { + DoomsdayApp::games().audienceForReadiness() -= this; + } + + ui::Item const *findItem(String const &id) const + { + auto const pos = menu->items().findData(id); + if(pos == ui::Data::InvalidPos) return nullptr; + return &menu->items().at(pos); + } + + GameDrawerButton &widgetForItem(ui::Item const &item) const + { + DENG2_ASSERT(menu->items().find(item) != ui::Data::InvalidPos); + return menu->itemWidget(item); + } + + void populateItems() + { + Games const &games = DoomsdayApp::games(); + + // Add games not already in the list. + for(int i = 0; i < games.count(); ++i) + { + Game const &game = games.byIndex(i); + if(game.family() == gameFamily) + { + if(auto const *item = findItem(game.id())) + { + item->as().update(); + } + else + { + menu->items() << new MenuItem(game); + } + } + } + + // Remove items no longer available. + for(ui::DataPos i = menu->items().size() - 1; i < menu->items().size(); --i) + { + MenuItem const &item = menu->items().at(i).as(); + if(!games.contains(item.gameId())) + { + // Time to remove this one. + menu->items().remove(i); + } + } + } + + void gameReadinessUpdated() + { + populateItems(); + } + +//- ChildWidgetOrganizer::IWidgetFactory -------------------------------------- + + GuiWidget *makeItemWidget(ui::Item const &item, GuiWidget const *) + { + return new GameDrawerButton(item.as().game); + } + + void updateItemWidget(GuiWidget &widget, ui::Item const &item) + { + MenuItem const &menuItem = item.as(); + auto &drawer = widget.as(); + drawer.enable(menuItem.game.isPlayable()); + drawer.label().setText(String("%1\n" _E(l) "%2") + .arg(menuItem.game.title()) + .arg(menuItem.game.releaseDate().year())); } }; -GameColumnWidget::GameColumnWidget(String const &name, - String const &author, - String const &gameTitle, - DotPath const &logoId) - : ColumnWidget(name) - , d(new Instance(this)) +GameColumnWidget::GameColumnWidget(String const &gameFamily) + : ColumnWidget(gameFamily.toLower() + "-column") + , d(new Instance(this, gameFamily.toLower())) { scrollArea().setContentSize(maximumContentWidth(), - d->header->rule().height()); + d->header->rule().height() + + style().rules().rule("gap") + + d->menu->rule().height()); d->header->title().setText(String(_E(s) "%1\n" _E(.)_E(w) "%2") - .arg(author) - .arg(gameTitle)); - if(!logoId.isEmpty()) + .arg( gameFamily == "DOOM"? "id Software" : + !gameFamily.isEmpty()? "Raven Software" : "") + .arg(!gameFamily.isEmpty()? QString(gameFamily) : tr("Other Games"))); + if(!gameFamily.isEmpty()) { - d->header->setLogoImage(logoId); + d->header->setLogoImage("logo.game." + gameFamily.toLower()); + d->header->setLogoBackground("home.background." + d->gameFamily); + d->bgImage = style().images().image("home.background." + d->gameFamily); } - /// @todo Get these from the games def. - if(name == "doom-column") + /// @todo Get these from the game family defs. + if(name() == "doom-column") { - d->header->info().setText("id Software released DOOM for MS-DOS in 1993. It soon became a massive hit and is regarded as the game that popularized the first-person shooter genre. Since then the franchise has been continued in several sequels, starting with DOOM II: Hell on Earth in 1994. DOOM and many of its follow-ups have been ported to numerous other platforms, and to this day remains a favorite among gamers."); + d->header->info().setText("id Software released DOOM for MS-DOS in 1993. " + "It soon became a massive hit and is regarded as " + "the game that popularized the first-person shooter " + "genre. Since then the franchise has been continued " + "in several sequels, starting with DOOM II: Hell on " + "Earth in 1994. DOOM and many of its follow-ups " + "have been ported to numerous other platforms, and " + "to this day remains a favorite among gamers."); } - else if(name == "heretic-column") + else if(name() == "heretic-column") { - d->header->info().setText("Raven Software released Heretic in 1994. It used a modified version of id Software's DOOM engine. The game featured such enhancements as inventory management and the ability to look up and down. Ambient sound effects were used to improve the atmosphere of the game world."); + d->header->info().setText("Raven Software released Heretic in 1994. It used " + "a modified version of id Software's DOOM engine. " + "The game featured such enhancements as inventory " + "management and the ability to look up and down. " + "Ambient sound effects were used to improve the " + "atmosphere of the game world."); } - else if(name == "hexen-column") + else if(name() == "hexen-column") { - d->header->info().setText("Raven Software released Hexen in 1996. The company had continued making heavy modifications to the DOOM engine, and Hexen introduced such sophisticated features as a scripting language for game events. The maps were well-designed and interconnected with each other, resulting in a more intriguing game world and more complex puzzles to solve."); + d->header->info().setText("Raven Software released Hexen in 1996. The " + "company had continued making heavy modifications " + "to the DOOM engine, and Hexen introduced such " + "sophisticated features as a scripting language " + "for game events. The maps were well-designed and " + "interconnected with each other, resulting in a " + "more intriguing game world and more complex " + "puzzles to solve."); } else { - d->header->info().setText("Thanks to its excellent modding support, DOOM was used as a basis for many games and community projects."); + d->header->info().setText("Thanks to its excellent modding support, DOOM has " + "been used as a basis for many games and community " + "projects."); } } @@ -78,5 +220,16 @@ void GameColumnWidget::setHighlighted(bool highlighted) { ColumnWidget::setHighlighted(highlighted); - d->header->setOpacity(highlighted? 1 : .7, .5); + if(highlighted) + { + setBackgroundImage(d->bgImage); + } + else + { + setBackgroundImage(Image::solidColor(Image::Color(0, 0, 0, 255), + Image::Size(4, 4))); + } + + //d->header->setOpacity(highlighted? 1 : .7, .5); + //d->menu->setOpacity (highlighted? 1 : .7, .5); } diff --git a/doomsday/apps/client/src/ui/home/gamedrawerbutton.cpp b/doomsday/apps/client/src/ui/home/gamedrawerbutton.cpp new file mode 100644 index 0000000000..e557f87095 --- /dev/null +++ b/doomsday/apps/client/src/ui/home/gamedrawerbutton.cpp @@ -0,0 +1,37 @@ +/** @file gamedrawerbutton.cpp Button for + * + * @authors Copyright (c) 2016 Jaakko Keränen + * + * @par License + * GPL: http://www.gnu.org/licenses/gpl.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. This program is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. You should have received a copy of the GNU + * General Public License along with this program; if not, see: + * http://www.gnu.org/licenses + */ + +#include "ui/home/gamedrawerbutton.h" + +using namespace de; + +DENG2_PIMPL(GameDrawerButton) +{ + Game const &game; + + Instance(Public *i, Game const &game) + : Base(i) + , game(game) + {} +}; + +GameDrawerButton::GameDrawerButton(Game const &game) + : d(new Instance(this, game)) +{ + +} diff --git a/doomsday/apps/client/src/ui/home/headerwidget.cpp b/doomsday/apps/client/src/ui/home/headerwidget.cpp index 65a447486f..987c8e31e9 100644 --- a/doomsday/apps/client/src/ui/home/headerwidget.cpp +++ b/doomsday/apps/client/src/ui/home/headerwidget.cpp @@ -22,12 +22,14 @@ #include #include #include +#include using namespace de; DENG_GUI_PIMPL(HeaderWidget) { LabelWidget *logo; + LabelWidget *logoBg; /// @todo Backgrounds should support ProceduralImages. -jk LabelWidget *title; PanelWidget *infoPanel; LabelWidget *info; @@ -35,8 +37,9 @@ DENG_GUI_PIMPL(HeaderWidget) Instance(Public *i) : Base(i) { - self.add(logo = new LabelWidget); - self.add(title = new LabelWidget); + self.add(logoBg = new LabelWidget); + self.add(logo = new LabelWidget); + self.add(title = new LabelWidget); self.add(infoPanel = new PanelWidget); info = new LabelWidget; infoPanel->setContent(info); @@ -59,14 +62,18 @@ HeaderWidget::HeaderWidget() d->logo->setSizePolicy(ui::Filled, ui::Filled); d->logo->setImageFit(ui::FitToSize | ui::OriginalAspectRatio); - d->logo->set(Background(Vector4f(0, 0, 0, 1))); + //d->logo->set(Background(Vector4f(0, 0, 0, 1))); - d->info->setFont("small"); + d->logoBg->setSizePolicy(ui::Filled, ui::Filled); + d->logoBg->setImageFit(ui::FitToSize); + d->logoBg->margins().setZero(); + + //d->info->setFont("small"); d->info->setAlignment(ui::AlignLeft); d->info->setTextLineAlignment(ui::AlignLeft); d->info->setMaximumTextWidth(rule().width()); d->info->setSizePolicy(ui::Fixed, ui::Expand); - d->info->margins().setLeft("").setRight(""); + d->info->margins().setZero().setTop("gap"); d->menuButton->setSizePolicy(ui::Expand, ui::Expand); d->menuButton->setFont("small"); @@ -84,6 +91,7 @@ HeaderWidget::HeaderWidget() } })); + d->logoBg->rule().setRect(d->logo->rule()); d->logo->rule() .setInput(Rule::Height, logoHeight) .setInput(Rule::Width, Const(0)) @@ -124,7 +132,12 @@ LabelWidget &HeaderWidget::info() void HeaderWidget::setLogoImage(const DotPath &imageId) { - d->logo->setImage(style().images().image(imageId)); + d->logo->setImage(new StyleProceduralImage(imageId, *d->logo)); d->logo->rule().setInput(Rule::Width, Const(2 * 160)); d->title->margins().setLeft("gap"); } + +void HeaderWidget::setLogoBackground(const DotPath &imageId) +{ + d->logoBg->setImage(new StyleProceduralImage(imageId, *d->logoBg)); +} diff --git a/doomsday/apps/client/src/ui/home/homewidget.cpp b/doomsday/apps/client/src/ui/home/homewidget.cpp index 29d36cc891..1106f8f374 100644 --- a/doomsday/apps/client/src/ui/home/homewidget.cpp +++ b/doomsday/apps/client/src/ui/home/homewidget.cpp @@ -194,19 +194,16 @@ HomeWidget::HomeWidget() column = new NoGamesColumnWidget(); d->addColumn(column); - column = new GameColumnWidget("doom-column", "id Software", "DOOM", - "logo.game.doom"); + column = new GameColumnWidget("DOOM"); d->addColumn(column); - column = new GameColumnWidget("heretic-column", "Raven Software", "Heretic", - "logo.game.heretic"); + column = new GameColumnWidget("Heretic"); d->addColumn(column); - column = new GameColumnWidget("hexen-column", "Raven Software", "Hexen", - "logo.game.hexen"); + column = new GameColumnWidget("Hexen"); d->addColumn(column); - column = new GameColumnWidget("other-column", "", "Other Games", ""); + column = new GameColumnWidget(""); d->addColumn(column); column = new ColumnWidget("multiplayer-column");