From c2146cda883371c22424bf09de9279eae061243e Mon Sep 17 00:00:00 2001 From: div0 Date: Fri, 26 Oct 2007 10:53:56 +0000 Subject: [PATCH] adding qcsrc/menu-div0test with a test menu.dat source... may or may not replace the current menu eventually, very incomplete, can't do anything useful yet, still not done making controls for it git-svn-id: svn://svn.icculus.org/nexuiz/trunk@2850 f962a42d-fe04-0410-a3ab-8c8b0445ebaa --- data/qcsrc/menu-div0test/basebutton_cl.tga | Bin 0 -> 556 bytes data/qcsrc/menu-div0test/basebutton_cm.tga | Bin 0 -> 204 bytes data/qcsrc/menu-div0test/basebutton_cr.tga | Bin 0 -> 560 bytes data/qcsrc/menu-div0test/basebutton_fl.tga | Bin 0 -> 560 bytes data/qcsrc/menu-div0test/basebutton_fm.tga | Bin 0 -> 204 bytes data/qcsrc/menu-div0test/basebutton_fr.tga | Bin 0 -> 560 bytes data/qcsrc/menu-div0test/basebutton_nl.tga | Bin 0 -> 2066 bytes data/qcsrc/menu-div0test/basebutton_nm.tga | Bin 0 -> 204 bytes data/qcsrc/menu-div0test/basebutton_nr.tga | Bin 0 -> 2066 bytes data/qcsrc/menu-div0test/classes.c | 9 + data/qcsrc/menu-div0test/draw.qc | 63 ++++ data/qcsrc/menu-div0test/draw.qh | 18 + data/qcsrc/menu-div0test/gamecommand.qc | 37 ++ data/qcsrc/menu-div0test/gamecommand.qh | 2 + data/qcsrc/menu-div0test/item.c | 73 ++++ data/qcsrc/menu-div0test/item/button.c | 97 +++++ data/qcsrc/menu-div0test/item/container.c | 223 ++++++++++++ data/qcsrc/menu-div0test/item/image.c | 18 + .../qcsrc/menu-div0test/item/inputcontainer.c | 163 +++++++++ data/qcsrc/menu-div0test/item/label.c | 39 ++ .../menu-div0test/item/modalcontroller.c | 264 ++++++++++++++ data/qcsrc/menu-div0test/item/nexposee.c | 338 ++++++++++++++++++ data/qcsrc/menu-div0test/mbuiltin.qh | 252 +++++++++++++ data/qcsrc/menu-div0test/menu.qc | 155 ++++++++ data/qcsrc/menu-div0test/menu.qh | 24 ++ data/qcsrc/menu-div0test/msys.qh | 281 +++++++++++++++ data/qcsrc/menu-div0test/nexuiz/mainwindow.c | 105 ++++++ data/qcsrc/menu-div0test/oo/base.h | 8 + data/qcsrc/menu-div0test/oo/classdefs.h | 21 ++ data/qcsrc/menu-div0test/oo/constructors.h | 21 ++ data/qcsrc/menu-div0test/oo/implementation.h | 15 + data/qcsrc/menu-div0test/progs.src | 25 ++ data/qcsrc/menu-div0test/todo | 26 ++ 33 files changed, 2277 insertions(+) create mode 100644 data/qcsrc/menu-div0test/basebutton_cl.tga create mode 100644 data/qcsrc/menu-div0test/basebutton_cm.tga create mode 100644 data/qcsrc/menu-div0test/basebutton_cr.tga create mode 100644 data/qcsrc/menu-div0test/basebutton_fl.tga create mode 100644 data/qcsrc/menu-div0test/basebutton_fm.tga create mode 100644 data/qcsrc/menu-div0test/basebutton_fr.tga create mode 100644 data/qcsrc/menu-div0test/basebutton_nl.tga create mode 100644 data/qcsrc/menu-div0test/basebutton_nm.tga create mode 100644 data/qcsrc/menu-div0test/basebutton_nr.tga create mode 100644 data/qcsrc/menu-div0test/classes.c create mode 100644 data/qcsrc/menu-div0test/draw.qc create mode 100644 data/qcsrc/menu-div0test/draw.qh create mode 100644 data/qcsrc/menu-div0test/gamecommand.qc create mode 100644 data/qcsrc/menu-div0test/gamecommand.qh create mode 100644 data/qcsrc/menu-div0test/item.c create mode 100644 data/qcsrc/menu-div0test/item/button.c create mode 100644 data/qcsrc/menu-div0test/item/container.c create mode 100644 data/qcsrc/menu-div0test/item/image.c create mode 100644 data/qcsrc/menu-div0test/item/inputcontainer.c create mode 100644 data/qcsrc/menu-div0test/item/label.c create mode 100644 data/qcsrc/menu-div0test/item/modalcontroller.c create mode 100644 data/qcsrc/menu-div0test/item/nexposee.c create mode 100644 data/qcsrc/menu-div0test/mbuiltin.qh create mode 100644 data/qcsrc/menu-div0test/menu.qc create mode 100644 data/qcsrc/menu-div0test/menu.qh create mode 100644 data/qcsrc/menu-div0test/msys.qh create mode 100644 data/qcsrc/menu-div0test/nexuiz/mainwindow.c create mode 100644 data/qcsrc/menu-div0test/oo/base.h create mode 100644 data/qcsrc/menu-div0test/oo/classdefs.h create mode 100644 data/qcsrc/menu-div0test/oo/constructors.h create mode 100644 data/qcsrc/menu-div0test/oo/implementation.h create mode 100644 data/qcsrc/menu-div0test/progs.src create mode 100644 data/qcsrc/menu-div0test/todo diff --git a/data/qcsrc/menu-div0test/basebutton_cl.tga b/data/qcsrc/menu-div0test/basebutton_cl.tga new file mode 100644 index 0000000000000000000000000000000000000000..bdc3ea037275a940359a77176f9458a3e2103658 GIT binary patch literal 556 zcmZwFK?;IE6b9heE?RX2FHpBI5TYO}I!`SETXX@lBaMT|C@Kmr1VOoI-ViOQ|CXeYHh;cso5tbBk=~ATx4yIX%5lb#lT}sKpE!D+*IGgdB-eG3q?8>I zFMROIZtGzm-}jM}Qb<7%AcbLw6h#qIk|aoJnj&RchSW3-QeD?bWmzH>MS+y(Inu-- q;yA{?CayhEuc63e!?@7U(y`aSS^pZ2hm(FbOk=-WT{gy6U(*L4e^6oo literal 0 HcmV?d00001 diff --git a/data/qcsrc/menu-div0test/basebutton_cm.tga b/data/qcsrc/menu-div0test/basebutton_cm.tga new file mode 100644 index 0000000000000000000000000000000000000000..12810352350ba61b3d1e4ffdc4b6b2807d242906 GIT binary patch literal 204 zcmY+8O$viB7(~Bi>8eNY0_`m<2&IMo(Ob<0?3px(Xow+!ECj)TCzzI^6ld{P!{do; zW!X*=Nj7-rxvW8q<46=mL6l`lD5Z$1s))L-iKc0YwrvTmHDQb)thI!5j_}?S(=-t= sMq(HSqVIbmgfL&auA2ov-(UZ2;kspsmHYLPKC@ePIqzS`?35nl19EwNr2qf` literal 0 HcmV?d00001 diff --git a/data/qcsrc/menu-div0test/basebutton_cr.tga b/data/qcsrc/menu-div0test/basebutton_cr.tga new file mode 100644 index 0000000000000000000000000000000000000000..f38e5e8150e0e0bd3c3084058d3e1ab272b56c27 GIT binary patch literal 560 zcmZ|N-wJ{-6bA6)U3AqW_yYA720|3{kDjM40&jW&vqw@HLuC^MF9cx&pTL?S(ueJ0 z?EJQi?R+De(=ZlflRbMpeV@k3`;;BMg5Z8L8=g|Cvy2(K_7sL;XBjvAr6`J!;y6ZP zj3IH(k&+}qO4Af6%Q7S(1X7;oNJUW~m1T+4wk?v@8mVa-q`Iz=s;WYoxP+7vPfa{~ jqF?_S{TrI8##qO^`_=Fxj{B2yb`S1uyS%L3jkBURAQf7U literal 0 HcmV?d00001 diff --git a/data/qcsrc/menu-div0test/basebutton_fl.tga b/data/qcsrc/menu-div0test/basebutton_fl.tga new file mode 100644 index 0000000000000000000000000000000000000000..30e1dfe376df57046f1ae5b8ad4ca18b4844a9bb GIT binary patch literal 560 zcmZQz;9`IQ0R{yI1&;o?bLKE0h-MI%0Z24-0g3-jATA?_3*vPht@1|*{Ri>7F3zq+ z5(4qM{`~xjB=jE$x_*BBiYfFNUFgT>Pv}D5K7K?O`uzSKy3nULZ_tH4zJ7%+^zOxT zbfGuTpP~!Be)+i2$NX8$p3H;v$ s5{F0H0dS;&#Np9;035A|_y)6JDIz2&)HTdA*wf!nH^R-+$5oF30AdMT{{R30 literal 0 HcmV?d00001 diff --git a/data/qcsrc/menu-div0test/basebutton_fm.tga b/data/qcsrc/menu-div0test/basebutton_fm.tga new file mode 100644 index 0000000000000000000000000000000000000000..cb1e5784ed1ffcb0d87a43d9a60142210713b864 GIT binary patch literal 204 zcmY+;O$vfg6vgp7j7BZN4b(0S9z@b7ttD#K{45}ww3le?s0}1WilGn7C&@_#A@AS^ zcXIfP^rgLlSYq{Xa$V^{T(%D39rwi77{X*(jV5xP67M7-^eZOPC?b;ZNyLwUhytGo y{X0?SpDuaznucnxtVheDp&)MO199EWSZ6f+1+}%y`O03ag>t6D%~(zBk^BH{kAM;Y literal 0 HcmV?d00001 diff --git a/data/qcsrc/menu-div0test/basebutton_fr.tga b/data/qcsrc/menu-div0test/basebutton_fr.tga new file mode 100644 index 0000000000000000000000000000000000000000..07b7d15e118ed391ad1a8d031fc0fdd26a377b92 GIT binary patch literal 560 zcmZQz;9`IQ0R{yI1&;o?bLKE0h%O-aKLe0xXa-4i9j)^J&j=C&2{nO*F3zs~&j=C+ z2}6Yb{QUW!5hRWf`uX+if5!hnfGqSGUFgT>Pv}D5K7K?O`uzSKy3nULZ_tH4zJ7%+ z^zOxTbfGuTpP~!Be)!M6Uz`VVv14WB3XEaV4s#1(#n{d z`NqRkrnpG|~zinHnFyC4W73Mch0~O}0cQ55#;m`976;^*)7N}g|t8YK$ ovHIJ#LFEcxoqZ{f)sHbkCG+3=x?p-Eub=*cV~@0tNOFFb5Ad${nE(I) literal 0 HcmV?d00001 diff --git a/data/qcsrc/menu-div0test/basebutton_nm.tga b/data/qcsrc/menu-div0test/basebutton_nm.tga new file mode 100644 index 0000000000000000000000000000000000000000..2829422714d6ec8ae2a0c42857127756f970858d GIT binary patch literal 204 zcmY+8Jqp4=7(~BPtUN+4ptpz+5Cx6mt)_{0TaqG>Vqpn{-Rw_0h9xO7#p`C~i5z9i zNeU?r_%)5}L2wCTjD+`|u+|dOG!f%C62=%pYfTKpK=gf2bX`ZZZA&Pn)<&*5=ZJZp lSLD4A0+EqFQcCOP;=;YlCM)&xU4E)p^|+tE*XmYY&hXXQm+Dx4j1el#|1}j4>+F4Jd%!l6m2>Xyb3E&Lnd=|L2ltr( literal 0 HcmV?d00001 diff --git a/data/qcsrc/menu-div0test/classes.c b/data/qcsrc/menu-div0test/classes.c new file mode 100644 index 000000000..45db05ae6 --- /dev/null +++ b/data/qcsrc/menu-div0test/classes.c @@ -0,0 +1,9 @@ +#include "item.c" +#include "item/container.c" +#include "item/inputcontainer.c" +#include "item/nexposee.c" +#include "item/modalcontroller.c" +#include "item/image.c" +#include "item/label.c" +#include "item/button.c" +#include "nexuiz/mainwindow.c" diff --git a/data/qcsrc/menu-div0test/draw.qc b/data/qcsrc/menu-div0test/draw.qc new file mode 100644 index 000000000..fc5791d36 --- /dev/null +++ b/data/qcsrc/menu-div0test/draw.qc @@ -0,0 +1,63 @@ +string draw_mousepointer; + +void draw_setMousePointer(string pic) +{ + draw_mousepointer = pic; +} + +void draw_drawMousePointer(vector where) +{ + drawpic(boxToGlobal(where, draw_shift, draw_scale), draw_mousepointer, '32 32 0', '1 1 1', draw_alpha, 0); +} + +void draw_reset() +{ + draw_shift = '0 0 0'; + draw_scale = '1 0 0' * cvar("vid_conwidth") + '0 1 0' * cvar("vid_conheight"); + draw_alpha = 1; +} + +vector globalToBox(vector v, vector theOrigin, vector theScale) +{ + v -= theOrigin; + v_x /= theScale_x; + v_y /= theScale_y; + return v; +} + +vector globalToBoxSize(vector v, vector theScale) +{ + v_x /= theScale_x; + v_y /= theScale_y; + return v; +} + +vector boxToGlobal(vector v, vector theOrigin, vector theScale) +{ + v_x *= theScale_x; + v_y *= theScale_y; + v += theOrigin; + return v; +} + +vector boxToGlobalSize(vector v, vector theScale) +{ + v_x *= theScale_x; + v_y *= theScale_y; + return v; +} + +void draw_Picture(vector theOrigin, string pic, vector theSize, vector theColor, float theAlpha) +{ + drawpic(boxToGlobal(theOrigin, draw_shift, draw_scale), pic, boxToGlobalSize(theSize, draw_scale), theColor, theAlpha * draw_alpha, 0); +} + +void draw_Text(vector theOrigin, string theText, vector theSize, vector theColor, float theAlpha) +{ + drawstring(boxToGlobal(theOrigin, draw_shift, draw_scale), theText, boxToGlobalSize(theSize, draw_scale), theColor, theAlpha * draw_alpha, 0); +} + +float draw_TextWidth(string theText) +{ + return strlen(theText); +} diff --git a/data/qcsrc/menu-div0test/draw.qh b/data/qcsrc/menu-div0test/draw.qh new file mode 100644 index 000000000..256b9b182 --- /dev/null +++ b/data/qcsrc/menu-div0test/draw.qh @@ -0,0 +1,18 @@ +vector draw_shift; +vector draw_scale; +float draw_alpha; + +void draw_reset(); +void draw_setMousePointer(string pic); +void draw_drawMousePointer(vector where); + +void draw_Picture(vector origin, string pic, vector size, vector color, float alpha); +void draw_Text(vector origin, string text, vector size, vector color, float alpha); +float draw_TextWidth(string text); + +vector boxToGlobal(vector v, vector shift, vector scale); +vector boxToGlobalSize(vector v, vector scale); +vector globalToBox(vector v, vector shift, vector scale); +vector globalToBoxSize(vector v, vector scale); + +float draw_NeedResizeNotify; diff --git a/data/qcsrc/menu-div0test/gamecommand.qc b/data/qcsrc/menu-div0test/gamecommand.qc new file mode 100644 index 000000000..72acf5d00 --- /dev/null +++ b/data/qcsrc/menu-div0test/gamecommand.qc @@ -0,0 +1,37 @@ +void GameCommand_Init() +{ + // make gg call menu QC commands + localcmd("alias qc_cmd \"menu_cmd $*\"\n"); +} + +void GameCommand(string command) +{ + float argc; + argc = tokenize(command); + + if(argv(0) == "help" || argc == 0) + { + print("Usage: menu_cmd COMMAND..., where possible commands are:\n"); + print(" sync - reloads all cvars on the current menu page\n"); + print(" directmenu ITEM - select a menu item as main item\n"); + GameCommand_Generic("help"); + return; + } + + if(GameCommand_Generic(command)) + return; + + if(argv(0) == "sync") + { + // make changes in cvars known to the system + return; + } + + if(argv(0) == "directmenu") if(argc == 2) + { + // switch to a menu item + return; + } + + print("Invalid command. For a list of supported commands, try menu_cmd help.\n"); +} diff --git a/data/qcsrc/menu-div0test/gamecommand.qh b/data/qcsrc/menu-div0test/gamecommand.qh new file mode 100644 index 000000000..33eb05371 --- /dev/null +++ b/data/qcsrc/menu-div0test/gamecommand.qh @@ -0,0 +1,2 @@ +void GameCommand_Init(); +void GameCommand(string command); diff --git a/data/qcsrc/menu-div0test/item.c b/data/qcsrc/menu-div0test/item.c new file mode 100644 index 000000000..5a7e3ec79 --- /dev/null +++ b/data/qcsrc/menu-div0test/item.c @@ -0,0 +1,73 @@ +#ifdef INTERFACE +CLASS(Item) EXTENDS(Object) + METHOD(Item, draw, void(entity)) + METHOD(Item, keyDown, float(entity, float, float, float)) + METHOD(Item, keyUp, float(entity, float, float, float)) + METHOD(Item, mouseMove, float(entity, vector)) + METHOD(Item, mousePress, float(entity, vector)) + METHOD(Item, mouseDrag, float(entity, vector)) + METHOD(Item, mouseRelease, float(entity, vector)) + METHOD(Item, focusEnter, void(entity)) + METHOD(Item, focusLeave, void(entity)) + METHOD(Item, resizeNotify, void(entity, vector, vector, vector, vector)) + METHOD(Item, relinquishFocus, void(entity)) + ATTRIB(Item, focused, float, 0) + ATTRIB(Item, focusable, float, 0) + ATTRIB(Item, parent, entity, NULL) +ENDCLASS(Item) +#endif + +#ifdef IMPLEMENTATION +void relinquishFocusItem(entity me) +{ + if(me.parent) + if(me.parent.instanceOfContainer) + me.parent.setFocus(me.parent, NULL); +} + +void resizeNotifyItem(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) +{ +} + +void drawItem(entity me) +{ +} + +float keyDownItem(entity me, float scan, float ascii, float shift) +{ + return 0; // unhandled +} + +float keyUpItem(entity me, float scan, float ascii, float shift) +{ + return 0; // unhandled +} + +float mouseMoveItem(entity me, vector pos) +{ + return 0; // unhandled +} + +float mousePressItem(entity me, vector pos) +{ + return 0; // unhandled +} + +float mouseDragItem(entity me, vector pos) +{ + return 0; // unhandled +} + +float mouseReleaseItem(entity me, vector pos) +{ + return 0; // unhandled +} + +void focusEnterItem(entity me) +{ +} + +void focusLeaveItem(entity me) +{ +} +#endif diff --git a/data/qcsrc/menu-div0test/item/button.c b/data/qcsrc/menu-div0test/item/button.c new file mode 100644 index 000000000..8e5ccf925 --- /dev/null +++ b/data/qcsrc/menu-div0test/item/button.c @@ -0,0 +1,97 @@ +#ifdef INTERFACE +CLASS(Button) EXTENDS(Label) + METHOD(Button, configureButton, void(entity, string, float, string)) + METHOD(Button, draw, void(entity)) + METHOD(Button, resizeNotify, void(entity, vector, vector, vector, vector)) + METHOD(Button, keyDown, float(entity, float, float, float)) + METHOD(Button, mousePress, float(entity, vector)) + METHOD(Button, mouseDrag, float(entity, vector)) + METHOD(Button, mouseRelease, float(entity, vector)) + ATTRIB(Button, onClick, void(entity, entity), SUB_Null) + ATTRIB(Button, onClickEntity, entity, NULL) + ATTRIB(Button, src, string, "") + ATTRIB(Button, focusable, float, 1) + ATTRIB(Button, pressed, float, 0) + ATTRIB(Button, clickTime, float, 0) + ATTRIB(Button, forcePressed, float, 0) + + ATTRIB(Button, origin, vector, '0 0 0') + ATTRIB(Button, size, vector, '0 0 0') +ENDCLASS(Button) +#endif + +#ifdef IMPLEMENTATION +void resizeNotifyButton(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) +{ + resizeNotifyLabel(me, relOrigin, relSize, absOrigin, absSize); + me.origin = absOrigin; + me.size = absSize; +} +void configureButtonButton(entity me, string txt, float sz, string gfx) +{ + configureLabelLabel(me, txt, sz, 0.5); + me.src = gfx; +} +float keyDownButton(entity me, float key, float ascii, float shift) +{ + if(key == K_ENTER || key == K_SPACE) + { + me.onClick(me, me.onClickEntity); + me.clickTime = 0.1; + return 1; + } + return 0; +} +float mouseDragButton(entity me, vector pos) +{ + me.pressed = 1; + if(pos_x < 0) me.pressed = 0; + if(pos_y < 0) me.pressed = 0; + if(pos_x >= 1) me.pressed = 0; + if(pos_y >= 1) me.pressed = 0; + return 1; +} +float mousePressButton(entity me, vector pos) +{ + me.mouseDrag(me, pos); // verify coordinates + return 1; +} +float mouseReleaseButton(entity me, vector pos) +{ + me.mouseDrag(me, pos); // verify coordinates + if(me.pressed) + { + me.onClick(me, me.onClickEntity); + me.pressed = 0; + } + return 1; +} +void drawButton(entity me) +{ + float division; + division = min(0.5, 0.5 * me.size_y / me.size_x); + if(me.forcePressed || me.pressed || me.clickTime > 0) + { + draw_Picture('0 0 0', strcat(me.src, "_cl"), eX * division + eY, '1 1 1', 1); + if(division < 0.5) + draw_Picture('0 0 0' + eX * division, strcat(me.src, "_cm"), eX * (1 - 2 * division) + eY, '1 1 1', 1); + draw_Picture(eX * (1 - division), strcat(me.src, "_cr"), eX * division + eY, '1 1 1', 1); + } + else if(me.focused) + { + draw_Picture('0 0 0', strcat(me.src, "_fl"), eX * division + eY, '1 1 1', 1); + if(division < 0.5) + draw_Picture('0 0 0' + eX * division, strcat(me.src, "_fm"), eX * (1 - 2 * division) + eY, '1 1 1', 1); + draw_Picture(eX * (1 - division), strcat(me.src, "_fr"), eX * division + eY, '1 1 1', 1); + } + else + { + draw_Picture('0 0 0', strcat(me.src, "_nl"), eX * division + eY, '1 1 1', 1); + if(division < 0.5) + draw_Picture('0 0 0' + eX * division, strcat(me.src, "_nm"), eX * (1 - 2 * division) + eY, '1 1 1', 1); + draw_Picture(eX * (1 - division), strcat(me.src, "_nr"), eX * division + eY, '1 1 1', 1); + } + me.clickTime -= frametime; + drawLabel(me); +} +#endif diff --git a/data/qcsrc/menu-div0test/item/container.c b/data/qcsrc/menu-div0test/item/container.c new file mode 100644 index 000000000..de48c7c1a --- /dev/null +++ b/data/qcsrc/menu-div0test/item/container.c @@ -0,0 +1,223 @@ +#ifdef INTERFACE +CLASS(Container) EXTENDS(Item) + METHOD(Container, draw, void(entity)) + METHOD(Container, keyUp, float(entity, float, float, float)) + METHOD(Container, keyDown, float(entity, float, float, float)) + METHOD(Container, mouseMove, float(entity, vector)) + METHOD(Container, mousePress, float(entity, vector)) + METHOD(Container, mouseDrag, float(entity, vector)) + METHOD(Container, mouseRelease, float(entity, vector)) + METHOD(Container, focusLeave, void(entity)) + METHOD(Container, resizeNotify, void(entity, vector, vector, vector, vector)) + METHOD(Container, resizeNotifyLie, void(entity, vector, vector, vector, vector, .vector, .vector)) + METHOD(Container, addItem, void(entity, entity, vector, vector, float)) + METHOD(Container, removeItem, void(entity, entity)) + METHOD(Container, setFocus, void(entity, entity)) + METHOD(Container, itemFromPoint, entity(entity, vector)) + ATTRIB(Container, focusable, float, 0) + ATTRIB(Container, firstChild, entity, NULL) + ATTRIB(Container, lastChild, entity, NULL) + ATTRIB(Container, focusedChild, entity, NULL) +ENDCLASS(Container) +#endif + +#ifdef IMPLEMENTATION +.vector Container_origin; +.vector Container_size; +.float Container_alpha; +.entity Container_nextSibling; +.entity Container_prevSibling; + +void resizeNotifyLieContainer(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize, .vector originField, .vector sizeField) +{ + entity e; + vector o, s; + for(e = me.lastChild; e; e = e.Container_prevSibling) + { + o = e.originField; + s = e.sizeField; + e.resizeNotify(e, o, s, boxToGlobal(o, absOrigin, absSize), boxToGlobalSize(s, absSize)); + } + resizeNotifyItem(me, relOrigin, relSize, absOrigin, absSize); +} + +void resizeNotifyContainer(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) +{ + me.resizeNotifyLie(me, relOrigin, relSize, absOrigin, absSize, Container_origin, Container_size); +} + +entity itemFromPointContainer(entity me, vector pos) +{ + entity e; + vector o, s; + for(e = me.lastChild; e; e = e.Container_prevSibling) + { + o = e.Container_origin; + s = e.Container_size; + if(pos_x < o_x) continue; + if(pos_y < o_y) continue; + if(pos_x >= o_x + s_x) continue; + if(pos_y >= o_y + s_y) continue; + return e; + } + return NULL; +} + +void drawContainer(entity me) +{ + vector oldshift; + vector oldscale; + float oldalpha; + entity e; + + oldshift = draw_shift; + oldscale = draw_scale; + oldalpha = draw_alpha; + me.focusable = 0; + for(e = me.firstChild; e; e = e.Container_nextSibling) + { + if(e.focusable) + me.focusable += 1; + if(!e.Container_alpha) + continue; + draw_shift = boxToGlobal(e.Container_origin, oldshift, oldscale); + draw_scale = boxToGlobalSize(e.Container_size, oldscale); + draw_alpha *= e.Container_alpha; + e.draw(e); + draw_shift = oldshift; + draw_scale = oldscale; + draw_alpha = oldalpha; + } +}; + +void focusLeaveContainer(entity me) +{ + if(me.focusedChild) + me.focusedChild.focused = 0; + me.focusedChild = NULL; +} + +float keyUpContainer(entity me, float scan, float ascii, float shift) +{ + entity f; + f = me.focusedChild; + if(f) + return f.keyUp(f, scan, ascii, shift); + return 0; +} + +float keyDownContainer(entity me, float scan, float ascii, float shift) +{ + entity f; + f = me.focusedChild; + if(f) + return f.keyDown(f, scan, ascii, shift); + return 0; +} + +float mouseMoveContainer(entity me, vector pos) +{ + entity f; + f = me.focusedChild; + if(f) + return f.mouseMove(f, globalToBox(pos, f.Container_origin, f.Container_size)); + return 0; +} +float mousePressContainer(entity me, vector pos) +{ + entity f; + f = me.focusedChild; + if(f) + return f.mousePress(f, globalToBox(pos, f.Container_origin, f.Container_size)); + return 0; +} +float mouseDragContainer(entity me, vector pos) +{ + entity f; + f = me.focusedChild; + if(f) + return f.mouseDrag(f, globalToBox(pos, f.Container_origin, f.Container_size)); + return 0; +} +float mouseReleaseContainer(entity me, vector pos) +{ + entity f; + f = me.focusedChild; + if(f) + return f.mouseRelease(f, globalToBox(pos, f.Container_origin, f.Container_size)); + return 0; +} + +void addItemContainer(entity me, entity other, vector theOrigin, vector theSize, float theAlpha) +{ + if(other.parent) + error("Can't add already added item!"); + + if(other.focusable) + me.focusable += 1; + + other.parent = me; + other.Container_origin = theOrigin; + other.Container_size = theSize; + other.Container_alpha = theAlpha; + + entity f, l; + f = me.firstChild; + l = me.lastChild; + + if(l) + l.Container_nextSibling = other; + else + me.firstChild = other; + + other.Container_prevSibling = l; + other.Container_nextSibling = NULL; + me.lastChild = other; + + draw_NeedResizeNotify = 1; +} + +void removeItemContainer(entity me, entity other) +{ + if(other.parent != me) + error("Can't remove from wrong container!"); + + if(other.focusable) + me.focusable -= 1; + + other.parent = NULL; + + entity n, p, f, l; + f = me.firstChild; + l = me.lastChild; + n = other.Container_nextSibling; + p = other.Container_prevSibling; + + if(p) + p.Container_nextSibling = n; + else + me.firstChild = n; + + if(n) + n.Container_prevSibling = p; + else + me.lastChild = p; +} + +void setFocusContainer(entity me, entity other) +{ + if(me.focusedChild == other) + return; + if(me.focusedChild) + { + me.focusedChild.focused = 0; + me.focusedChild.focusLeave(me.focusedChild); + } + if(other) + { + other.focused = 1; + other.focusEnter(other); + } + me.focusedChild = other; +} +#endif diff --git a/data/qcsrc/menu-div0test/item/image.c b/data/qcsrc/menu-div0test/item/image.c new file mode 100644 index 000000000..6db185133 --- /dev/null +++ b/data/qcsrc/menu-div0test/item/image.c @@ -0,0 +1,18 @@ +#ifdef INTERFACE +CLASS(Image) EXTENDS(Item) + METHOD(Image, configureImage, void(entity, string)) + METHOD(Image, draw, void(entity)) + ATTRIB(Image, src, string, "") +ENDCLASS(Image) +#endif + +#ifdef IMPLEMENTATION +void configureImageImage(entity me, string path) +{ + me.src = path; +} +void drawImage(entity me) +{ + draw_Picture('0 0 0', me.src, '1 1 0', '1 1 1', 1); +}; +#endif diff --git a/data/qcsrc/menu-div0test/item/inputcontainer.c b/data/qcsrc/menu-div0test/item/inputcontainer.c new file mode 100644 index 000000000..b64c24d42 --- /dev/null +++ b/data/qcsrc/menu-div0test/item/inputcontainer.c @@ -0,0 +1,163 @@ +#ifdef INTERFACE +CLASS(InputContainer) EXTENDS(Container) + METHOD(InputContainer, keyDown, float(entity, float, float, float)) + METHOD(InputContainer, mouseMove, float(entity, vector)) + METHOD(InputContainer, mousePress, float(entity, vector)) + METHOD(InputContainer, mouseRelease, float(entity, vector)) + METHOD(InputContainer, mouseDrag, float(entity, vector)) + METHOD(InputContainer, focusLeave, void(entity)) + METHOD(InputContainer, resizeNotify, void(entity, vector, vector, vector, vector)) + + METHOD(InputContainer, _changeFocusXY, float(entity, vector)) + ATTRIB(InputContainer, mouseFocusedChild, entity, NULL) + ATTRIB(InputContainer, isTabRoot, float, 0) +ENDCLASS(InputContainer) +#endif + +#ifdef IMPLEMENTATION +void resizeNotifyInputContainer(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) +{ + resizeNotifyContainer(me, relOrigin, relSize, absOrigin, absSize); + if(me.parent.instanceOfInputContainer) + me.isTabRoot = 0; + else + me.isTabRoot = 1; +} + +void focusLeaveInputContainer(entity me) +{ + focusLeaveContainer(me); + me.mouseFocusedChild = NULL; +} + +float keyDownInputContainer(entity me, float scan, float ascii, float shift) +{ + entity f, ff; + if(keyDownContainer(me, scan, ascii, shift)) + return 1; + if(scan == K_ESCAPE) + { + f = me.focusedChild; + if(f) + { + me.setFocus(me, NULL); + return 1; + } + return 0; + } + if(scan == K_TAB) + { + f = me.focusedChild; + if(shift & S_SHIFT) + { + if(f) + { + for(ff = f.Container_prevSibling; ff; ff = ff.Container_prevSibling) + { + if(!ff.focusable) + continue; + me.setFocus(me, ff); + return 1; + } + } + if(!f || me.isTabRoot) + { + for(ff = me.lastChild; ff; ff = ff.Container_prevSibling) + { + if(!ff.focusable) + continue; + me.setFocus(me, ff); + return 1; + } + return 0; // AIIIIEEEEE! + } + } + else + { + if(f) + { + for(ff = f.Container_nextSibling; ff; ff = ff.Container_nextSibling) + { + if(!ff.focusable) + continue; + me.setFocus(me, ff); + return 1; + } + } + if(!f || me.isTabRoot) + { + for(ff = me.firstChild; ff; ff = ff.Container_nextSibling) + { + if(!ff.focusable) + continue; + me.setFocus(me, ff); + return 1; + } + return 0; // AIIIIEEEEE! + } + } + } + return 0; +} + +float _changeFocusXYInputContainer(entity me, vector pos) +{ + entity e, ne; + e = me.mouseFocusedChild; + ne = me.itemFromPoint(me, pos); + if(ne) + if(!ne.focusable) + ne = NULL; + me.mouseFocusedChild = ne; + if(ne) + if(ne != e) + { + me.setFocus(me, ne); + if(ne.instanceOfInputContainer) + { + ne.focusedChild = NULL; + ne._changeFocusXY(e, globalToBox(pos, ne.Container_origin, ne.Container_size)); + } + } + return (ne != NULL); +} + +float mouseDragInputContainer(entity me, vector pos) +{ + if(mouseDragContainer(me, pos)) + return 1; + if(pos_x >= 0 && pos_y >= 0 && pos_x < 1 && pos_y < 1) + return 1; + return 0; +} +float mouseMoveInputContainer(entity me, vector pos) +{ + if(me._changeFocusXY(me, pos)) + if(mouseMoveContainer(me, pos)) + return 1; + if(pos_x >= 0 && pos_y >= 0 && pos_x < 1 && pos_y < 1) + return 1; + return 0; +} +float mousePressInputContainer(entity me, vector pos) +{ + me.mouseFocusedChild = NULL; // force focusing + if(me._changeFocusXY(me, pos)) + if(mousePressContainer(me, pos)) + return 1; + if(pos_x >= 0 && pos_y >= 0 && pos_x < 1 && pos_y < 1) + return 1; + return 0; +} +float mouseReleaseInputContainer(entity me, vector pos) +{ + float r; + r = mouseReleaseContainer(me, pos); + me._changeFocusXY(me, pos); + if(r) + return 1; + if(pos_x >= 0 && pos_y >= 0 && pos_x < 1 && pos_y < 1) + return 1; + return 0; +} +#endif diff --git a/data/qcsrc/menu-div0test/item/label.c b/data/qcsrc/menu-div0test/item/label.c new file mode 100644 index 000000000..04a5cf776 --- /dev/null +++ b/data/qcsrc/menu-div0test/item/label.c @@ -0,0 +1,39 @@ +#ifdef INTERFACE +CLASS(Label) EXTENDS(Item) + METHOD(Label, configureLabel, void(entity, string, float, float)) + METHOD(Label, draw, void(entity)) + METHOD(Label, resizeNotify, void(entity, vector, vector, vector, vector)) + METHOD(Label, setText, void(entity, string)) + ATTRIB(Label, text, string, "Big Red Button") + ATTRIB(Label, fontSize, float, 8) + ATTRIB(Label, align, float, 0.5) + ATTRIB(Label, realFontSize, vector, '0 0 0') + ATTRIB(Label, realOrigin, vector, '0 0 0') +ENDCLASS(Label) +#endif + +#ifdef IMPLEMENTATION +void setTextLabel(entity me, string txt) +{ + me.text = txt; + me.realOrigin_x = me.align * (1 - me.realFontSize_x * draw_TextWidth(me.text)); +} +void resizeNotifyLabel(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) +{ + // absSize_y is height of label + me.realFontSize_y = me.fontSize / absSize_y; + me.realFontSize_x = me.fontSize / absSize_x; + me.realOrigin_x = me.align * (1 - me.realFontSize_x * draw_TextWidth(me.text)); + me.realOrigin_y = 0.5 * (1 - me.realFontSize_y); +} +void configureLabelLabel(entity me, string txt, float sz, float algn) +{ + me.fontSize = sz; + me.align = algn; + me.setText(me, txt); +} +void drawLabel(entity me) +{ + draw_Text(me.realOrigin, me.text, me.realFontSize, '0 0 0', 1); +} +#endif diff --git a/data/qcsrc/menu-div0test/item/modalcontroller.c b/data/qcsrc/menu-div0test/item/modalcontroller.c new file mode 100644 index 000000000..8f405797f --- /dev/null +++ b/data/qcsrc/menu-div0test/item/modalcontroller.c @@ -0,0 +1,264 @@ +#ifdef INTERFACE +CLASS(ModalController) EXTENDS(Container) + METHOD(ModalController, resizeNotify, void(entity, vector, vector, vector, vector)) + METHOD(ModalController, draw, void(entity)) + METHOD(ModalController, addItem, void(entity, entity, vector, vector, float)) + METHOD(ModalController, setFocus, void(entity, entity)) + METHOD(ModalController, showChild, void(entity, entity, vector, vector, float)) + METHOD(ModalController, hideChild, void(entity, entity, float)) + METHOD(ModalController, hideAll, void(entity, float)) + METHOD(ModalController, addItem, void(entity, entity, vector, vector, float)) + METHOD(ModalController, addTab, void(entity, entity, entity)) + + METHOD(ModalController, initializeDialog, void(entity, entity)) + + METHOD(ModalController, switchState, void(entity, entity, float, float)) + ATTRIB(ModalController, origin, vector, '0 0 0') + ATTRIB(ModalController, size, vector, '0 0 0') + ATTRIB(ModalController, previousButton, entity, NULL) + ATTRIB(ModalController, fadedAlpha, float, 0.3) +ENDCLASS(ModalController) + +.vector origin; +.vector size; +void TabButton_Click(entity button, entity tab); // assumes a button has set the above fields to its own absolute origin, its size, and the tab to activate +void DialogOpenButton_Click(entity button, entity tab); // assumes a button has set the above fields to its own absolute origin, its size, and the tab to activate +void DialogCloseButton_Click(entity button, entity tab); // assumes a button has set the above fields to the tab to close +#endif + +#ifdef IMPLEMENTATION + +// modal dialog controller +// handles a stack of dialog elements +// each element can have one of the following states: +// 0: hidden (fading out) +// 1: visible (zooming in) +// 2: greyed out (inactive) +// While an animation is running, no item has focus. When an animation is done, +// the topmost item gets focus. +// The items are assumed to be added in overlapping order, that is, the lowest +// window must get added first. +// +// Possible uses: +// - to control a modal dialog: +// - show modal dialog: me.showChild(me, childItem, buttonAbsOrigin, buttonAbsSize, 0) // childItem also gets focus +// - dismiss modal dialog: me.hideChild(me, childItem, 0) // childItem fades out and relinquishes focus +// - show first screen in m_show: me.hideAll(me, 1); me.showChild(me, me.firstChild, '0 0 0', '0 0 0', 1); +// - to show a temporary dialog instead of the menu (teamselect): me.hideAll(me, 1); me.showChild(me, teamSelectDialog, '0 0 0', '0 0 0', 1); +// - as a tabbed dialog control: +// - to initialize: me.hideAll(me, 1); me.showChild(me, me.firstChild, '0 0 0', '0 0 0', 1); +// - to show a tab: me.hideChild(me, currentTab, 0); me.showChild(me, newTab, buttonAbsOrigin, buttonAbsSize, 0); + +.vector ModalController_initialSize; +.vector ModalController_initialOrigin; +.float ModalController_initialAlpha; +.vector ModalController_buttonSize; +.vector ModalController_buttonOrigin; +.float ModalController_state; +.float ModalController_factor; +.entity ModalController_controllingButton; + +void initializeDialogModalController(entity me, entity root) +{ + me.hideAll(me, 1); + me.showChild(me, root, '0 0 0', '0 0 0', 1); // someone else animates for us +} + +void TabButton_Click(entity button, entity tab) +{ + if(tab.ModalController_state == 1) + return; + tab.parent.hideAll(tab.parent, 0); + button.forcePressed = 1; + tab.ModalController_controllingButton = button; + tab.parent.showChild(tab.parent, tab, button.origin, button.size, 0); +} + +void DialogOpenButton_Click(entity button, entity tab) +{ + if(tab.ModalController_state) + return; + button.forcePressed = 1; + tab.ModalController_controllingButton = button; + tab.parent.showChild(tab.parent, tab, button.origin, button.size, 0); +} + +void DialogCloseButton_Click(entity button, entity tab) +{ + tab.parent.hideChild(tab.parent, tab, 0); +} + +void resizeNotifyModalController(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) +{ + me.origin = absOrigin; + me.size = absSize; + me.resizeNotifyLie(me, relOrigin, relSize, absOrigin, absSize, ModalController_initialOrigin, ModalController_initialSize); +} + +void switchStateModalController(entity me, entity other, float state, float skipAnimation) +{ + float previousState; + previousState = other.ModalController_state; + if(state == previousState) + return; + other.ModalController_state = state; + switch(state) + { + case 0: + other.ModalController_factor = 1 - other.Container_alpha / other.ModalController_initialAlpha; + // fading out + break; + case 1: + other.ModalController_factor = other.Container_alpha / other.ModalController_initialAlpha; + if(previousState == 0 && !skipAnimation) + { + other.Container_origin = other.ModalController_buttonOrigin; + other.Container_size = other.ModalController_buttonSize; + } + // zooming in + break; + case 2: + other.ModalController_factor = bound(0, (1 - other.Container_alpha / other.ModalController_initialAlpha) / me.fadedAlpha, 1); + // fading out halfway + break; + } + if(skipAnimation) + other.ModalController_factor = 1; +} + +void drawModalController(entity me) +{ + // TODO set up alpha, sizes and focus + entity e; + entity front; + float animating; + float f0, f, fd; + vector to, ts; float ta; + animating = 0; + + for(e = me.firstChild; e; e = e.Container_nextSibling) + if(e.ModalController_state) + { + if(front) + me.switchState(me, front, 2, 0); + front = e; + } + if(front) + me.switchState(me, front, 1, 0); + + for(e = me.firstChild; e; e = e.Container_nextSibling) + { + f0 = e.ModalController_factor; + f = e.ModalController_factor = min(1, f0 + frametime * 3); + if(e.ModalController_state) + if(f < 1) + animating = 1; + if(e.ModalController_state == 2) + { + // fading out partially + to = e.Container_origin; // stay as is + ts = e.Container_size; // stay as is + ta = me.fadedAlpha * e.ModalController_initialAlpha; + } + else if(e.ModalController_state == 1) + { + // zooming in + to = e.ModalController_initialOrigin; + ts = e.ModalController_initialSize; + ta = e.ModalController_initialAlpha; + } + else + { + // fading out + if(f < 1) + animating = 1; + to = e.Container_origin; // stay as is + ts = e.Container_size; // stay as is + ta = 0; + } + + if(f == 1) + { + e.Container_origin = to; + e.Container_size = ts; + e.Container_alpha = ta; + } + else + { + e.Container_origin = (e.Container_origin * (1 - f) + to * (f - f0)) * (1 / (1 - f0)); + e.Container_size = (e.Container_size * (1 - f) + ts * (f - f0)) * (1 / (1 - f0)); + e.Container_alpha = (e.Container_alpha * (1 - f) + ta * (f - f0)) * (1 / (1 - f0)); + } + // assume: o == to * f0 + X * (1 - f0) + // make: o' = to * f + X * (1 - f) + // --> + // X == (o - to * f0) / (1 - f0) + // o' = to * f + (o - to * f0) / (1 - f0) * (1 - f) + } + if(animating) + me.focusedChild = NULL; + else + me.focusedChild = front; + drawContainer(me); +}; + +void addTabModalController(entity me, entity other, entity tabButton) +{ + me.addItem(me, other, '0 0 0', '1 1 1', 1); + tabButton.onClick = TabButton_Click; + tabButton.onClickEntity = other; + if(other == me.firstChild) + { + tabButton.forcePressed = 1; + other.ModalController_controllingButton = tabButton; + me.showChild(me, other, '0 0 0', '0 0 0', 1); + } +} + +void addItemModalController(entity me, entity other, vector theOrigin, vector theSize, float theAlpha) +{ + other.ModalController_initialSize = theSize; + other.ModalController_initialOrigin = theOrigin; + other.ModalController_initialAlpha = theAlpha; + addItemContainer(me, other, theOrigin, theSize, theAlpha); + if(other != me.firstChild) + other.Container_alpha = 0; +} + +void setFocusModalController(entity me, entity other) +{ + error("Sorry, modal controllers can't handle setFocus"); +} + +void showChildModalController(entity me, entity other, vector theOrigin, vector theSize, float skipAnimation) +{ + if(other.ModalController_state == 0) + { + me.focusedChild = NULL; + other.ModalController_buttonOrigin = globalToBox(theOrigin, me.origin, me.size); + other.ModalController_buttonSize = globalToBoxSize(theSize, me.size); + me.switchState(me, other, 1, skipAnimation); + } // zoom in from button (factor increases) +} + +void hideAllModalController(entity me, float skipAnimation) +{ + entity e; + for(e = me.firstChild; e; e = e.Container_nextSibling) + me.hideChild(me, e, skipAnimation); +} + +void hideChildModalController(entity me, entity other, float skipAnimation) +{ + if(other.ModalController_state) + { + me.focusedChild = NULL; + me.switchState(me, other, 0, skipAnimation); + if(other.ModalController_controllingButton) + { + other.ModalController_controllingButton.forcePressed = 0; + other.ModalController_controllingButton = NULL; + } + } // just alpha fade out (factor increases and decreases alpha) +} +#endif diff --git a/data/qcsrc/menu-div0test/item/nexposee.c b/data/qcsrc/menu-div0test/item/nexposee.c new file mode 100644 index 000000000..02d56d87c --- /dev/null +++ b/data/qcsrc/menu-div0test/item/nexposee.c @@ -0,0 +1,338 @@ +#ifdef INTERFACE +CLASS(Nexposee) EXTENDS(Container) + METHOD(Nexposee, draw, void(entity)) + METHOD(Nexposee, keyDown, float(entity, float, float, float)) + METHOD(Nexposee, keyUp, float(entity, float, float, float)) + METHOD(Nexposee, mousePress, float(entity, vector)) + METHOD(Nexposee, mouseMove, float(entity, vector)) + METHOD(Nexposee, mouseRelease, float(entity, vector)) + METHOD(Nexposee, mouseDrag, float(entity, vector)) + METHOD(Nexposee, resizeNotify, void(entity, vector, vector, vector, vector)) + METHOD(Nexposee, setFocus, void(entity, entity)) + + ATTRIB(Nexposee, animationState, float, -1) + ATTRIB(Nexposee, animationFactor, float, 0) + ATTRIB(Nexposee, selectedChild, entity, NULL) + ATTRIB(Nexposee, mouseFocusedChild, entity, NULL) + METHOD(Nexposee, addItem, void(entity, entity, vector, vector, float)) + METHOD(Nexposee, calc, void(entity)) + METHOD(Nexposee, setNexposee, void(entity, entity, vector, float, float)) + ATTRIB(Nexposee, mousePosition, vector, '0 0 0') +ENDCLASS(Nexposee) + +void ExposeeCloseButton_Click(entity button, entity other); // un-exposees the current state +#endif + +// animation states: +// 0 = thumbnails seen +// 1 = zooming in +// 2 = zoomed in +// 3 = zooming out +// animation factor: 0 = minimum theSize, 1 = maximum theSize + +#ifdef IMPLEMENTATION + +.vector Nexposee_initialSize; +.vector Nexposee_initialOrigin; +.float Nexposee_initialAlpha; + +.vector Nexposee_smallSize; +.vector Nexposee_smallOrigin; +.float Nexposee_smallAlpha; +.float Nexposee_mediumAlpha; +.vector Nexposee_scaleCenter; + +void ExposeeCloseButton_Click(entity button, entity other) +{ + other.setFocus(other, NULL); +} + +void resizeNotifyNexposee(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize) +{ + me.resizeNotifyLie(me, relOrigin, relSize, absOrigin, absSize, Nexposee_initialOrigin, Nexposee_initialSize); +} + +void calcNexposee(entity me) +{ + /* + * patented by Apple + * can't put that here ;) + */ + float scale; + entity e, e2; + vector emins, emaxs, e2mins, e2maxs; + + for(scale = 0.7;; scale *= 0.9) + { + for(e = me.firstChild; e; e = e.Container_nextSibling) + { + e.Nexposee_smallOrigin = (e.Nexposee_initialOrigin - e.Nexposee_scaleCenter) * scale + e.Nexposee_scaleCenter; + e.Nexposee_smallSize = e.Nexposee_initialSize * scale; + } + + for(e = me.firstChild; e; e = e.Container_nextSibling) + { + emins = e.Nexposee_smallOrigin; + emaxs = emins + e.Nexposee_smallSize; + for(e2 = e.Container_nextSibling; e2; e2 = e2.Container_nextSibling) + { + e2mins = e2.Nexposee_smallOrigin; + e2maxs = e2mins + e2.Nexposee_smallSize; + + // two intervals [amins, amaxs] and [bmins, bmaxs] overlap if: + // amins < bmins < amaxs < bmaxs + // for which suffices + // bmins < amaxs + // amins < bmaxs + if((e2mins_x - emaxs_x) * (emins_x - e2maxs_x) > 0) // x overlap + if((e2mins_y - emaxs_y) * (emins_y - e2maxs_y) > 0) // y overlap + { + goto have_overlap; + } + } + } + + break; +:have_overlap + } + + scale *= 0.9; + for(e = me.firstChild; e; e = e.Container_nextSibling) + { + e.Nexposee_smallOrigin = (e.Nexposee_initialOrigin - e.Nexposee_scaleCenter) * scale + e.Nexposee_scaleCenter; + e.Nexposee_smallSize = e.Nexposee_initialSize * scale; + } +} + +void setNexposeeNexposee(entity me, entity other, vector scalecenter, float a0, float a1) +{ + other.Nexposee_scaleCenter = scalecenter; + other.Nexposee_smallAlpha = other.Container_alpha = a0; + other.Nexposee_mediumAlpha = a1; +} + +void drawNexposee(entity me) +{ + entity e; + float f; + + if(me.animationState == -1) + { + me.animationState = 0; + me.calc(me); + } + + //print(ftos(me.animationState), "\n"); + + f = min(1, frametime * 5); + switch(me.animationState) + { + case 0: + me.animationFactor = 0; + break; + case 1: + me.animationFactor += f; + if(me.animationFactor >= 1) + { + me.animationFactor = 1; + me.animationState = 2; + setFocusContainer(me, me.selectedChild); + } + break; + case 2: + me.animationFactor = 1; + break; + case 3: + me.animationFactor -= f; + me.mouseFocusedChild = me.itemFromPoint(me, me.mousePosition); + if(me.animationFactor <= 0) + { + me.animationFactor = 0; + me.animationState = 0; + me.selectedChild = me.mouseFocusedChild; + } + break; + } + + f = min(1, frametime * 10); + for(e = me.firstChild; e; e = e.Container_nextSibling) + { + float a; + float a0; + if(e == me.selectedChild) + { + e.Container_origin = e.Nexposee_smallOrigin * (1 - me.animationFactor) + e.Nexposee_initialOrigin * me.animationFactor; + e.Container_size = e.Nexposee_smallSize * (1 - me.animationFactor) + e.Nexposee_initialSize * me.animationFactor; + a0 = e.Nexposee_mediumAlpha; + if(me.animationState == 3) + if(e != me.mouseFocusedChild) + a0 = e.Nexposee_smallAlpha; + a = a0 * (1 - me.animationFactor) + me.animationFactor; + } + else + { + // minimum theSize counts + e.Container_origin = e.Nexposee_smallOrigin; + e.Container_size = e.Nexposee_smallSize; + a = e.Nexposee_smallAlpha * (1 - me.animationFactor); + } + e.Container_alpha = e.Container_alpha * (1 - f) + a * f; + } + + drawContainer(me); +}; + +float mousePressNexposee(entity me, vector pos) +{ + if(me.animationState == 0) + { + me.mouseFocusedChild = NULL; + mouseMoveNexposee(me, pos); + if(me.selectedChild) + { + me.animationState = 1; + setFocusContainer(me, NULL); + } + return 1; + } + else if(me.animationState == 2) + { + if(!mousePressContainer(me, pos)) + { + me.animationState = 3; + setFocusContainer(me, NULL); + } + return 1; + } + return 0; +} + +float mouseReleaseNexposee(entity me, vector pos) +{ + if(me.animationState == 2) + return mouseReleaseContainer(me, pos); + return 0; +} + +float mouseDragNexposee(entity me, vector pos) +{ + if(me.animationState == 2) + return mouseDragContainer(me, pos); + return 0; +} + +float mouseMoveNexposee(entity me, vector pos) +{ + entity e; + me.mousePosition = pos; + e = me.mouseFocusedChild; + me.mouseFocusedChild = me.itemFromPoint(me, pos); + if(me.animationState == 2) + return mouseMoveContainer(me, pos); + if(me.animationState == 0) + { + if(me.mouseFocusedChild) + if(me.mouseFocusedChild != e) + me.selectedChild = me.mouseFocusedChild; + return 1; + } + return 0; +} + +float keyUpNexposee(entity me, float scan, float ascii, float shift) +{ + if(me.animationState == 2) + return keyUpContainer(me, scan, ascii, shift); + return 0; +} + +float keyDownNexposee(entity me, float scan, float ascii, float shift) +{ + float nexposeeKey; + if(me.animationState == 2) + if(keyDownContainer(me, scan, ascii, shift)) + return 1; + if(scan == K_TAB) + { + if(me.animationState == 0) + { + if(shift & S_SHIFT) + { + if(me.selectedChild) + me.selectedChild = me.selectedChild.Container_prevSibling; + if(!me.selectedChild) + me.selectedChild = me.lastChild; + } + else + { + if(me.selectedChild) + me.selectedChild = me.selectedChild.Container_nextSibling; + if(!me.selectedChild) + me.selectedChild = me.firstChild; + } + } + } + switch(me.animationState) + { + case 0: + case 3: + nexposeeKey = ((scan == K_SPACE) || (scan == K_ENTER)); + break; + case 1: + case 2: + nexposeeKey = (scan == K_ESCAPE); + break; + } + if(nexposeeKey) + { + switch(me.animationState) + { + case 0: + case 3: + me.animationState = 1; + break; + case 1: + case 2: + me.animationState = 3; + break; + } + if(me.focusedChild) + me.selectedChild = me.focusedChild; + if(!me.selectedChild) + me.animationState = 0; + setFocusContainer(me, NULL); + return 1; + } + return 0; +} + +void addItemNexposee(entity me, entity other, vector theOrigin, vector theSize, float theAlpha) +{ + other.Nexposee_initialSize = theSize; + other.Nexposee_initialOrigin = theOrigin; + other.Nexposee_initialAlpha = theAlpha; + addItemContainer(me, other, theOrigin, theSize, theAlpha); +} + +void setFocusNexposee(entity me, entity other) +{ + if(me.animationState == 0) + { + if(other != NULL) + { + me.focusedChild = other; + me.selectedChild = other; + me.animationState = 1; + } + } + else if(me.animationState == 2) + { + if(other == NULL) + { + me.selectedChild = me.focusedChild; + me.focusedChild = NULL; + me.animationState = 3; + } + } +} +#endif diff --git a/data/qcsrc/menu-div0test/mbuiltin.qh b/data/qcsrc/menu-div0test/mbuiltin.qh new file mode 100644 index 000000000..0a3daa4d0 --- /dev/null +++ b/data/qcsrc/menu-div0test/mbuiltin.qh @@ -0,0 +1,252 @@ +////////////////////////////////////////////////// +// common cmd +////////////////////////////////////////////////// +// AK FIXME: Create perhaps a special builtin file for the common cmds + +//#define PROFILESTRZONE +#define FIXEDFOPEN + +void checkextension(string ext) = #1; + +// error cmds +void error(string err,...) = #2; +void objerror(string err,...) = #3; + +// print + +void print(string text,...) = #4; +void bprint(string text,...) = #5; +void sprint(float clientnum, string text,...) = #6; +void centerprint(string text,...) = #7; + +// vector stuff + +vector normalize(vector v) = #8; +float vlen(vector v) = #9; +float vectoyaw(vector v) = #10; +vector vectoangles(vector v) = #11; + +float random(void) = #12; + +void cmd(string command, ...) = #13; + +// cvar cmds + +float cvar(string name) = #14; +const string cvar_string(string name) = #71; +const string cvar_defstring(string name) = #89; +void cvar_set(string name, string value) = #15; + +//void dprint(string text,...) = #16; + +// conversion functions + +string ftos(float f) = #17; +float fabs(float f) = #18; +string vtos(vector v) = #19; +string etos(entity e) = #20; + +float stof(string val,...) = #21; + +entity spawn(void) = #22; +void remove(entity e) = #23; + +entity findstring(entity start, .string _field, string match) = #24; +entity findfloat(entity start, .float _field, float match) = #25; +entity findentity(entity start, .entity _field, entity match) = #25; + +entity findchainstring(.string _field, string match) = #26; +entity findchainfloat(.float _field, float match) = #27; +entity findchainentity(.entity _field, entity match) = #27; + +entity findflags(entity start, .float field, float match) = #87; +entity findchainflags(.float field, float match) = #88; + +string precache_file(string file) = #28; +string precache_sound(string sample) = #29; + +void crash(void) = #72; +void coredump(void) = #30; +void stackdump(void) = #73; +void traceon(void) = #31; +void traceoff(void) = #32; + +void eprint(entity e) = #33; +float rint(float f) = #34; +float floor(float f) = #35; +float ceil(float f) = #36; +entity nextent(entity e) = #37; +float sin(float f) = #38; +float cos(float f) = #39; +float sqrt(float f) = #40; +vector randomvec(void) = #41; + +float registercvar(string name, string value, float flags) = #42; // returns 1 if success +float min(float f,...) = #43; +float max(float f,...) = #44; +float bound(float min,float value, float max) = #45; +float pow(float a, float b) = #46; +void copyentity(entity src, entity dst) = #47; + +#ifdef FIXEDFOPEN +float _fopen( string filename, float mode ) = #48; +#else +float fopen(string filename, float mode) = #48; +#endif +void fclose(float fhandle) = #49; +string fgets(float fhandle) = #50; +void fputs(float fhandle, string s) = #51; + +float strlen(string s) = #52; +//string strcat(string s1,string s2,...) = #53; +string strcat(string s1, ...) = #53; +string substring(string s, float start, float length) = #54; + +vector stov(string s) = #55; + +#ifdef PROFILESTRZONE +string _strzone(string s) = #56; +void _strunzone(string s) = #57; + +string( string s ) strzone = +{ + return _strzone( s ); +}; + +void( string s ) strunzone = +{ + return _strunzone( s ); +}; +#else +string strzone(string s) = #56; +void strunzone(string s) = #57; +#endif + +float tokenize(string s) = #58; +float(string s, string separator1, ...) tokenizebyseparator = #479; +string argv(float n) = #59; + +float isserver(void) = #60; +float clientcount(void) = #61; +float clientstate(void) = #62; +void clientcommand(float client, string s) = #63; +void changelevel(string map) = #64; +void localsound(string sample) = #65; +vector getmousepos(void) = #66; +float gettime(void) = #67; +void loadfromdata(string data) = #68; +void loadfromfile(string file) = #69; + +float mod(float val, float m) = #70; + +float search_begin(string pattern, float caseinsensitive, float quiet) = #74; +void search_end(float handle) = #75; +float search_getsize(float handle) = #76; +string search_getfilename(float handle, float num) = #77; + +string chr(float ascii) = #78; + +float etof(entity ent) = #79; +entity ftoe(float num) = #80; + +float validstring(string str) = #81; + +float altstr_count(string str) = #82; +string altstr_prepare(string str) = #83; +string altstr_get(string str, float num) = #84; +string altstr_set(string str, float num, string set) = #85; +string altstr_ins(string str, float num, string set) = #86; + +///////////////////////////////////////////////// +// Write* Functions +///////////////////////////////////////////////// +void WriteByte(float data, float dest, float desto) = #401; +void WriteChar(float data, float dest, float desto) = #402; +void WriteShort(float data, float dest, float desto) = #403; +void WriteLong(float data, float dest, float desto) = #404; +void WriteAngle(float data, float dest, float desto) = #405; +void WriteCoord(float data, float dest, float desto) = #406; +void WriteString(string data, float dest, float desto)= #407; +void WriteEntity(entity data, float dest, float desto) = #408; + +////////////////////////////////////////////////// +// Draw funtions +////////////////////////////////////////////////// + +float iscachedpic(string name) = #451; +string precache_pic(string name) = #452; +void freepic(string name) = #453; + +float drawcharacter(vector position, float character, vector scale, vector rgb, float alpha, float flag) = #454; + +float drawstring(vector position, string text, vector scale, vector rgb, float alpha, float flag) = #455; + +float drawpic(vector position, string pic, vector size, vector rgb, float alpha, float flag) = #456; + +float drawfill(vector position, vector size, vector rgb, float alpha, float flag) = #457; + +void drawsetcliparea(float x, float y, float width, float height) = #458; + +void drawresetcliparea(void) = #459; + +vector drawgetimagesize(string pic) = #460; + +float cin_open(string file, string name) = #461; +void cin_close(string name) = #462; +void cin_setstate(string name, float type) = #463; +float cin_getstate(string name) = #464; + +//////////////////////////////////////////////// +// Menu functions +//////////////////////////////////////////////// + +void setkeydest(float dest) = #601; +float getkeydest(void) = #602; + +void setmousetarget(float trg) = #603; +float getmousetarget(void) = #604; + +float isfunction(string function_name) = #607; +void callfunction(...) = #605; +void writetofile(float fhandle, entity ent) = #606; +vector getresolution(float number) = #608; +string keynumtostring(float keynum) = #609; +string findkeysforcommand(string command) = #610; + +float gethostcachevalue(float type) = #611; +string gethostcachestring(float type, float hostnr) = #612; + +void parseentitydata(entity ent, string data) = #613; + +float stringtokeynum(string key) = #614; + +void resethostcachemasks(void) = #615; +void sethostcachemaskstring(float mask, float fld, string str, float op) = #616; +void sethostcachemasknumber(float mask, float fld, float num, float op) = #617; +void resorthostcache(void) = #618; +void sethostcachesort(float fld, float descending) = #619; +void refreshhostcache(void) = #620; +float gethostcachenumber(float fld, float hostnr) = #621; +float gethostcacheindexforkey(string key) = #622; +void addwantedhostcachekey(string key) = #623; +string getextresponse(void) = #624; + +#ifdef FIXEDFOPEN +float fopen( string filename, float mode ) = +{ + local float handle; + if( mode == FILE_READ ) { + return _fopen( filename, mode ); + } + + // check for data/ + filename = strzone( filename ); + if( substring( filename, 0, 5 ) != "data/" ) { + print( "menu: fopen: all output must go into data/!\n" ); + return -1; + } + handle = _fopen( substring( filename, 5, 10000 ), mode ); + strunzone( filename ); + return handle; +}; +#endif diff --git a/data/qcsrc/menu-div0test/menu.qc b/data/qcsrc/menu-div0test/menu.qc new file mode 100644 index 000000000..1b1332ada --- /dev/null +++ b/data/qcsrc/menu-div0test/menu.qc @@ -0,0 +1,155 @@ +/////////////////////////////////////////////// +// Menu Source File +/////////////////////// +// This file belongs to dpmod/darkplaces +// AK contains all menu functions (especially the required ones) +/////////////////////////////////////////////// + +entity main; +float mouseButtonsPressed; +vector mousePos; +float shiftState; +float prevTime; +float menuAlpha; + +void SUB_Null() { }; + +void() m_init = +{ + dprint_load(); + GameCommand_Init(); + + draw_setMousePointer("gfx/cursor"); + + main = spawnMainWindow(); main.configureMainWindow(main); + draw_reset(); + main.resizeNotify(main, draw_shift, draw_scale, draw_shift, draw_scale); + shiftState = 0; +}; + +void(float key, float ascii) m_keyup = +{ + if(!Menu_Active) + return; + draw_reset(); + main.keyUp(main, key, ascii, shiftState); + if(key >= K_MOUSE1 && key <= K_MOUSE10) + { + --mouseButtonsPressed; + if(!mouseButtonsPressed) + main.mouseRelease(main, mousePos); + if(mouseButtonsPressed < 0) + { + mouseButtonsPressed = 0; + print("Warning: released an already released button\n"); + } + } + if(key == K_ALT) shiftState -= (shiftState & S_ALT); + if(key == K_CTRL) shiftState -= (shiftState & S_CTRL); + if(key == K_SHIFT) shiftState -= (shiftState & S_SHIFT); +}; + +void(float key, float ascii) m_keydown = +{ + if(!Menu_Active) + return; + draw_reset(); + if(!main.keyDown(main, key, ascii, shiftState)) + if(key == K_ESCAPE) + if(gamestatus & (GAME_ISSERVER | GAME_CONNECTED)) // don't back out to console only + m_hide(); // disable menu on unhandled ESC + if(key >= K_MOUSE1 && key <= K_MOUSE10) + { + if(!mouseButtonsPressed) + main.mousePress(main, mousePos); + ++mouseButtonsPressed; + if(mouseButtonsPressed > 10) + { + mouseButtonsPressed = 10; + print("Warning: pressed an already pressed button\n"); + } + } + if(key == K_ALT) shiftState |= S_ALT; + if(key == K_CTRL) shiftState |= S_CTRL; + if(key == K_SHIFT) shiftState |= S_SHIFT; +}; + +void() m_draw = +{ + float t; + float realFrametime; + t = gettime(); + realFrametime = frametime = min(0.2, t - prevTime); + prevTime = t; + + if(cvar("cl_capturevideo")) + frametime = 1 / cvar("cl_capturevideo_fps"); // make capturevideo work smoothly + + if(Menu_Active) + menuAlpha = min(1, menuAlpha + frametime * 5); + else + menuAlpha = max(0, menuAlpha - frametime * 5); + + if(menuAlpha <= 0) + return; + + dprint_load(); + gamestatus = 0; + if(isserver()) + gamestatus = gamestatus | GAME_ISSERVER; + if(clientstate() == CS_CONNECTED) + gamestatus = gamestatus | GAME_CONNECTED; + if(cvar("developer")) + gamestatus = gamestatus | GAME_DEVELOPER; + + draw_reset(); + draw_alpha *= menuAlpha; + + vector dMouse; + dMouse = getmousepos(); + dMouse *= frametime / realFrametime; // for capturevideo + if(dMouse != '0 0 0') + { + dMouse = globalToBoxSize(dMouse, draw_scale); + mousePos += dMouse * 1; // TODO use a cvar here + mousePos_x = bound(0, mousePos_x, 1); + mousePos_y = bound(0, mousePos_y, 1); + if(mouseButtonsPressed) + main.mouseDrag(main, mousePos); + else + main.mouseMove(main, mousePos); + } + main.draw(main); + draw_drawMousePointer(mousePos); +}; + +void() m_display = +{ + Menu_Active = true; + setkeydest(KEY_MENU); + setmousetarget(MT_MENU); + + main.focusEnter(main); +}; + +void() m_hide = +{ + Menu_Active = false; + setkeydest(KEY_GAME); + setmousetarget(MT_CLIENT); + + main.focusLeave(main); +}; + +void() m_toggle = +{ + if(Menu_Active) + m_hide(); + else + m_display(); +}; + +void() m_shutdown = +{ + m_hide(); +}; diff --git a/data/qcsrc/menu-div0test/menu.qh b/data/qcsrc/menu-div0test/menu.qh new file mode 100644 index 000000000..de9b2c5e4 --- /dev/null +++ b/data/qcsrc/menu-div0test/menu.qh @@ -0,0 +1,24 @@ +#define localcmd cmd + +#define NULL (null_entity) + +// constants + +const vector eX = '1 0 0'; +const vector eY = '0 1 0'; +const vector eZ = '0 0 1'; + +const float GAME_ISSERVER = 1; +const float GAME_CONNECTED = 2; +const float GAME_DEVELOPER = 4; + +// prototypes + +float Menu_Active; +float gamestatus; + +const float S_SHIFT = 1; +const float S_CTRL = 2; +const float S_ALT = 4; + +float frametime; diff --git a/data/qcsrc/menu-div0test/msys.qh b/data/qcsrc/menu-div0test/msys.qh new file mode 100644 index 000000000..4e93acc48 --- /dev/null +++ b/data/qcsrc/menu-div0test/msys.qh @@ -0,0 +1,281 @@ +#pragma flag off fastarrays // make dp behave with new fteqcc versions. remove when dp bug with fteqcc fastarrays is fixed +#define MENUQC // so common/*.qc can check for menu QC or game QC + +////////////////////////////////////////////////////////// +// sys globals + +entity self; + +///////////////////////////////////////////////////////// +void end_sys_globals; +///////////////////////////////////////////////////////// +// sys fields + +///////////////////////////////////////////////////////// +void end_sys_fields; +///////////////////////////////////////////////////////// +// sys functions + +void() m_init; +void(float keynr, float ascii) m_keydown; +void() m_draw; +void() m_display; // old NG Menu +void() m_toggle; +void() m_hide; // old NG Menu +void() m_shutdown; + +///////////////////////////////////////////////////////// +// sys constants +/////////////////////////// +// key constants + +// +// these are the key numbers that should be passed to Key_Event +// +float K_TAB = 9; +float K_ENTER = 13; +float K_ESCAPE = 27; +float K_SPACE = 32; + +// normal keys should be passed as lowercased ascii + +float K_BACKSPACE = 127; +float K_UPARROW = 128; +float K_DOWNARROW = 129; +float K_LEFTARROW = 130; +float K_RIGHTARROW = 131; + +float K_ALT = 132; +float K_CTRL = 133; +float K_SHIFT = 134; +float K_F1 = 135; +float K_F2 = 136; +float K_F3 = 137; +float K_F4 = 138; +float K_F5 = 139; +float K_F6 = 140; +float K_F7 = 141; +float K_F8 = 142; +float K_F9 = 143; +float K_F10 = 144; +float K_F11 = 145; +float K_F12 = 146; +float K_INS = 147; +float K_DEL = 148; +float K_PGDN = 149; +float K_PGUP = 150; +float K_HOME = 151; +float K_END = 152; + +float K_KP_HOME = 160; +float K_KP_UPARROW = 161; +float K_KP_PGUP = 162; +float K_KP_LEFTARROW = 163; +float K_KP_5 = 164; +float K_KP_RIGHTARROW = 165; +float K_KP_END = 166; +float K_KP_DOWNARROW = 167; +float K_KP_PGDN = 168; +float K_KP_ENTER = 169; +float K_KP_INS = 170; +float K_KP_DEL = 171; +float K_KP_SLASH = 172; +float K_KP_MINUS = 173; +float K_KP_PLUS = 174; + +float K_PAUSE = 255; + +// +// joystick buttons +// +float K_JOY1 = 768; +float K_JOY2 = 769; +float K_JOY3 = 770; +float K_JOY4 = 771; + +// +// aux keys are for multi-buttoned joysticks to generate so they can use +// the normal binding process +// +float K_AUX1 = 772; +float K_AUX2 = 773; +float K_AUX3 = 774; +float K_AUX4 = 775; +float K_AUX5 = 776; +float K_AUX6 = 777; +float K_AUX7 = 778; +float K_AUX8 = 779; +float K_AUX9 = 780; +float K_AUX10 = 781; +float K_AUX11 = 782; +float K_AUX12 = 783; +float K_AUX13 = 784; +float K_AUX14 = 785; +float K_AUX15 = 786; +float K_AUX16 = 787; +float K_AUX17 = 788; +float K_AUX18 = 789; +float K_AUX19 = 790; +float K_AUX20 = 791; +float K_AUX21 = 792; +float K_AUX22 = 793; +float K_AUX23 = 794; +float K_AUX24 = 795; +float K_AUX25 = 796; +float K_AUX26 = 797; +float K_AUX27 = 798; +float K_AUX28 = 799; +float K_AUX29 = 800; +float K_AUX30 = 801; +float K_AUX31 = 802; +float K_AUX32 = 803; + +// +// mouse buttons generate virtual keys +// +float K_MOUSE1 = 512; +float K_MOUSE2 = 513; +float K_MOUSE3 = 514; +float K_MOUSE4 = 515; +float K_MOUSE5 = 516; +float K_MOUSE6 = 517; +float K_MOUSE7 = 518; +float K_MOUSE8 = 519; +float K_MOUSE9 = 520; +float K_MOUSE10 = 521; + +float K_MWHEELDOWN = K_MOUSE4; +float K_MWHEELUP = K_MOUSE5; + +/////////////////////////// +// key dest constants + +float KEY_GAME = 0; +float KEY_MENU = 2; +float KEY_UNKNOWN = 3; + +/////////////////////////// +// file constants + +float FILE_READ = 0; +float FILE_APPEND = 1; +float FILE_WRITE = 2; + +/////////////////////////// +// logical constants (just for completeness) + +float TRUE = 1; +float FALSE = 0; + +/////////////////////////// +// boolean constants + +float true = 1; +float false = 0; + +/////////////////////////// +// msg constants + +float MSG_BROADCAST = 0; // unreliable to all +float MSG_ONE = 1; // reliable to one (msg_entity) +float MSG_ALL = 2; // reliable to all +float MSG_INIT = 3; // write to the init string + +///////////////////////////// +// mouse target constants + +float MT_MENU = 1; +float MT_CLIENT = 2; + +///////////////////////// +// client state constants + +float CS_DEDICATED = 0; +float CS_DISCONNECTED = 1; +float CS_CONNECTED = 2; + +/////////////////////////// +// blend flags + +float DRAWFLAG_NORMAL = 0; +float DRAWFLAG_ADDITIVE = 1; +float DRAWFLAG_MODULATE = 2; +float DRAWFLAG_2XMODULATE = 3; + + +/////////////////////////// +// cvar constants + +float CVAR_SAVE = 1; +float CVAR_NOTIFY = 2; +float CVAR_READONLY = 4; + +/////////////////////////// +// server list constants + +float SLIST_HOSTCACHEVIEWCOUNT = 0; +float SLIST_HOSTCACHETOTALCOUNT = 1; +float SLIST_MASTERQUERYCOUNT = 2; +float SLIST_MASTERREPLYCOUNT = 3; +float SLIST_SERVERQUERYCOUNT = 4; +float SLIST_SERVERREPLYCOUNT = 5; +float SLIST_SORTFIELD = 6; +float SLIST_SORTDESCENDING = 7; + +float SLIST_LEGACY_LINE1 = 1024; +float SLIST_LEGACY_LINE2 = 1025; + +float SLIST_TEST_CONTAINS = 0; +float SLIST_TEST_NOTCONTAIN = 1; +float SLIST_TEST_LESSEQUAL = 2; +float SLIST_TEST_LESS = 3; +float SLIST_TEST_EQUAL = 4; +float SLIST_TEST_GREATER = 5; +float SLIST_TEST_GREATEREQUAL = 6; +float SLIST_TEST_NOTEQUAL = 7; + +float SLIST_MASK_AND = 0; +float SLIST_MASK_OR = 512; + +float NET_CURRENTPROTOCOL = 3; + +//////////////////////////////// +// cinematic action constants + +float CINE_PLAY = 1; +float CINE_LOOP = 2; +float CINE_PAUSE = 3; +float CINE_FIRSTFRAME = 4; +float CINE_RESETONWAKEUP= 5; + +/////////////////////////// +// null entity (actually it is the same like the world entity) + +entity null_entity; + +/////////////////////////// +// error constants + +// file handling +float ERR_CANNOTOPEN = -1; // fopen +float ERR_NOTENOUGHFILEHANDLES = -2; // fopen +float ERR_INVALIDMODE = -3; // fopen +float ERR_BADFILENAME = -4; // fopen + +// drawing functions + +float ERR_NULLSTRING = -1; +float ERR_BADDRAWFLAG = -2; +float ERR_BADSCALE = -3; +//float ERR_BADSIZE = ERR_BADSCALE; +float ERR_NOTCACHED = -4; + +/* not supported at the moment +/////////////////////////// +// os constants + +float OS_WINDOWS = 0; +float OS_LINUX = 1; +float OS_MAC = 2; +*/ + diff --git a/data/qcsrc/menu-div0test/nexuiz/mainwindow.c b/data/qcsrc/menu-div0test/nexuiz/mainwindow.c new file mode 100644 index 000000000..e76511c80 --- /dev/null +++ b/data/qcsrc/menu-div0test/nexuiz/mainwindow.c @@ -0,0 +1,105 @@ +#ifdef INTERFACE +CLASS(MainWindow) EXTENDS(ModalController) + METHOD(MainWindow, configureMainWindow, void(entity)) +ENDCLASS(MainWindow) +#endif + +#ifdef IMPLEMENTATION + +void DemoButton_Click(entity me, entity other) +{ + if(me.text == "Do not press this button again!") + DialogOpenButton_Click(me, other); + else + me.setText(me, "Do not press this button again!"); +} + +void configureMainWindowMainWindow(entity me) +{ + entity dlg, n, i, b, c, mc, t1, t2, t3; + + n = spawnNexposee(); + me.addItem(me, n, '0 0 0', '1 1 0', 1); + + dlg = spawnInputContainer(); + i = spawnImage(); + i.configureImage(i, "gfx/4.tga"); + dlg.addItem(dlg, i, '0 0 0', '1 1 0', 1); + + i = spawnLabel(); + i.configureLabel(i, "I told you...", 24, 0.5); + dlg.addItem(dlg, i, '0 0 0', '1 0.2 0', 1); + + i = spawnLabel(); + i.configureLabel(i, "Swim swim hungry, swim swim hungry...", 12, 0.5); + dlg.addItem(dlg, i, '0 0.3 0', '1 0.2 0', 1); + + i = spawnButton(); + i.configureButton(i, "Close", 12, "qcsrc/menu-div0test/basebutton"); + i.onClick = DialogCloseButton_Click; i.onClickEntity = dlg; + dlg.addItem(dlg, i, '0.3 0.6 0', '0.4 0.3 0', 1); + me.addItem(me, dlg, '0.2 0.3 0', '0.6 0.4 0', 1); + + i = spawnImage(); + i.configureImage(i, "gfx/0.tga"); + n.addItem(n, i, '0.4 0.45 0', '0.2 0.1 0', 1); + n.setNexposee(n, i, '0.5 0.5 0', 0.2, 0.5); + + c = spawnInputContainer(); + + i = spawnImage(); + i.configureImage(i, "gfx/0.tga"); + c.addItem(c, i, '0 0 0', '1 1 0', 1); + + mc = spawnModalController(); + b = spawnButton(); + b.configureButton(b, "1!", 12, "qcsrc/menu-div0test/basebutton"); + c.addItem(c, b, '0 0 0', '0.2 0.2 0', 1); + i = spawnButton(); + i.configureButton(i, "Do not press this button!", 12, "qcsrc/menu-div0test/basebutton"); // click n gently with a chainsaw + i.onClick = DemoButton_Click; i.onClickEntity = dlg; + mc.addTab(mc, i, b); + t1 = i; + + b = spawnButton(); + b.configureButton(b, "2!", 12, "qcsrc/menu-div0test/basebutton"); + c.addItem(c, b, '0.2 0 0', '0.2 0.2 0', 1); + i = spawnButton(); + i.configureButton(i, "Close", 12, "qcsrc/menu-div0test/basebutton"); // click n plenty + i.onClick = ExposeeCloseButton_Click; i.onClickEntity = n; + mc.addTab(mc, i, b); + t2 = i; + + b = spawnButton(); + b.configureButton(b, "3!", 12, "qcsrc/menu-div0test/basebutton"); + c.addItem(c, b, '0.4 0 0', '0.2 0.2 0', 1); + i = spawnButton(); + i.configureButton(i, "Close", 12, "qcsrc/menu-div0test/basebutton"); // click n plenty + i.onClick = ExposeeCloseButton_Click; i.onClickEntity = n; + mc.addTab(mc, i, b); + t3 = i; + c.addItem(c, mc, '0 0.2 0', '1 0.8 0', 1); + + n.addItem(n, c, '0.03 0.06 0', '0.9 0.9 0', 0.5); + n.setNexposee(n, c, '0.1 0.2 0', 0.2, 0.5); + + i = spawnImage(); + i.configureImage(i, "gfx/2.tga"); + n.addItem(n, i, '0.04 0.01 0', '0.9 0.9 0', 1); + n.setNexposee(n, i, '0.95 0.8 0', 0.2, 0.5); + + i = spawnImage(); + i.configureImage(i, "gfx/3.tga"); + n.addItem(n, i, '0.02 0.03 0', '0.9 0.9 0', 1); + n.setNexposee(n, i, '0.99 0.1 0', 0.2, 0.5); + + i = spawnImage(); + i.configureImage(i, "gfx/4.tga"); + n.addItem(n, i, '0.01 0.09 0', '0.9 0.9 0', 1); + n.setNexposee(n, i, '0.1 0.9 0', 0.2, 0.5); + + me.initializeDialog(me, n); +} +#endif + +// click. The C-word so you can grep for it. diff --git a/data/qcsrc/menu-div0test/oo/base.h b/data/qcsrc/menu-div0test/oo/base.h new file mode 100644 index 000000000..65bfbf556 --- /dev/null +++ b/data/qcsrc/menu-div0test/oo/base.h @@ -0,0 +1,8 @@ +.string classname; +entity spawnObject() +{ + entity e; + e = spawn(); + e.classname = "Object"; + return e; +} diff --git a/data/qcsrc/menu-div0test/oo/classdefs.h b/data/qcsrc/menu-div0test/oo/classdefs.h new file mode 100644 index 000000000..4db54b63e --- /dev/null +++ b/data/qcsrc/menu-div0test/oo/classdefs.h @@ -0,0 +1,21 @@ +#ifndef INTERFACE +#define INTERFACE +#endif + +#ifdef IMPLEMENTATION +#undef IMPLEMENTATION +#endif + +#ifdef CLASS +#undef CLASS +#undef EXTENDS +#undef METHOD +#undef ATTRIB +#undef ENDCLASS +#endif + +#define CLASS(cname) entity spawn##cname(); +#define EXTENDS(base) +#define METHOD(cname,name,prototype) prototype name##cname; .prototype name; +#define ATTRIB(cname,name,type,val) .type name; +#define ENDCLASS(cname) .float instanceOf##cname; diff --git a/data/qcsrc/menu-div0test/oo/constructors.h b/data/qcsrc/menu-div0test/oo/constructors.h new file mode 100644 index 000000000..b936307cf --- /dev/null +++ b/data/qcsrc/menu-div0test/oo/constructors.h @@ -0,0 +1,21 @@ +#ifndef INTERFACE +#define INTERFACE +#endif + +#ifdef IMPLEMENTATION +#undef IMPLEMENTATION +#endif + +#ifdef CLASS +#undef CLASS +#undef EXTENDS +#undef METHOD +#undef ATTRIB +#undef ENDCLASS +#endif + +#define CLASS(cname) entity spawn##cname() { entity e; +#define EXTENDS(base) e = spawn##base (); +#define METHOD(cname,name,prototype) e.name = name##cname; +#define ATTRIB(cname,name,type,val) e.name = val; +#define ENDCLASS(cname) e.instanceOf##cname = 1; e.classname = #cname; return e; } diff --git a/data/qcsrc/menu-div0test/oo/implementation.h b/data/qcsrc/menu-div0test/oo/implementation.h new file mode 100644 index 000000000..6b0868349 --- /dev/null +++ b/data/qcsrc/menu-div0test/oo/implementation.h @@ -0,0 +1,15 @@ +#ifdef INTERFACE +#undef INTERFACE +#endif + +#ifndef IMPLEMENTATION +#define IMPLEMENTATION +#endif + +#ifdef CLASS +#undef CLASS +#undef EXTENDS +#undef METHOD +#undef ATTRIB +#undef ENDCLASS +#endif diff --git a/data/qcsrc/menu-div0test/progs.src b/data/qcsrc/menu-div0test/progs.src new file mode 100644 index 000000000..a1b318eba --- /dev/null +++ b/data/qcsrc/menu-div0test/progs.src @@ -0,0 +1,25 @@ +../../menu.dat + +msys.qh +mbuiltin.qh + +oo/base.h + +../common/util.qh +gamecommand.qh +menu.qh +draw.qh + +oo/classdefs.h + classes.c + +../common/util.qc +../common/gamecommand.qc +gamecommand.qc +menu.qc +draw.qc + +oo/constructors.h + classes.c +oo/implementation.h + classes.c diff --git a/data/qcsrc/menu-div0test/todo b/data/qcsrc/menu-div0test/todo new file mode 100644 index 000000000..44b17efc9 --- /dev/null +++ b/data/qcsrc/menu-div0test/todo @@ -0,0 +1,26 @@ +DONE generic container +DONE container that takes input to switch focus +DONE container that does "exposee" + +DONE image displayer +DONE text label +DONE button +TODO radio button +TODO checkbox (+ tristate) +TODO listbox (with draw callback and scroll bar) +TODO value slider +DONE tabbed dialog + +TODO options dialog: + TODO video/effects + TODO preferences + TODO input +TODO singleplayer dialog + TODO campaign + TODO instant action +TODO multiplayer dialog + TODO player setup + TODO server browser + TODO create game +TODO demo viewer +TODO quit dialog -- 2.39.2