r2850 - in trunk/data/qcsrc: . menu-div0test menu-div0test/item menu-div0test/nexuiz menu-div0test/oo

DONOTREPLY at icculus.org DONOTREPLY at icculus.org
Fri Oct 26 06:53:56 EDT 2007


Author: div0
Date: 2007-10-26 06:53:56 -0400 (Fri, 26 Oct 2007)
New Revision: 2850

Added:
   trunk/data/qcsrc/menu-div0test/
   trunk/data/qcsrc/menu-div0test/basebutton_cl.tga
   trunk/data/qcsrc/menu-div0test/basebutton_cm.tga
   trunk/data/qcsrc/menu-div0test/basebutton_cr.tga
   trunk/data/qcsrc/menu-div0test/basebutton_fl.tga
   trunk/data/qcsrc/menu-div0test/basebutton_fm.tga
   trunk/data/qcsrc/menu-div0test/basebutton_fr.tga
   trunk/data/qcsrc/menu-div0test/basebutton_nl.tga
   trunk/data/qcsrc/menu-div0test/basebutton_nm.tga
   trunk/data/qcsrc/menu-div0test/basebutton_nr.tga
   trunk/data/qcsrc/menu-div0test/classes.c
   trunk/data/qcsrc/menu-div0test/draw.qc
   trunk/data/qcsrc/menu-div0test/draw.qh
   trunk/data/qcsrc/menu-div0test/gamecommand.qc
   trunk/data/qcsrc/menu-div0test/gamecommand.qh
   trunk/data/qcsrc/menu-div0test/item.c
   trunk/data/qcsrc/menu-div0test/item/
   trunk/data/qcsrc/menu-div0test/item/button.c
   trunk/data/qcsrc/menu-div0test/item/container.c
   trunk/data/qcsrc/menu-div0test/item/image.c
   trunk/data/qcsrc/menu-div0test/item/inputcontainer.c
   trunk/data/qcsrc/menu-div0test/item/label.c
   trunk/data/qcsrc/menu-div0test/item/modalcontroller.c
   trunk/data/qcsrc/menu-div0test/item/nexposee.c
   trunk/data/qcsrc/menu-div0test/mbuiltin.qh
   trunk/data/qcsrc/menu-div0test/menu.qc
   trunk/data/qcsrc/menu-div0test/menu.qh
   trunk/data/qcsrc/menu-div0test/msys.qh
   trunk/data/qcsrc/menu-div0test/nexuiz/
   trunk/data/qcsrc/menu-div0test/nexuiz/mainwindow.c
   trunk/data/qcsrc/menu-div0test/oo/
   trunk/data/qcsrc/menu-div0test/oo/base.h
   trunk/data/qcsrc/menu-div0test/oo/classdefs.h
   trunk/data/qcsrc/menu-div0test/oo/constructors.h
   trunk/data/qcsrc/menu-div0test/oo/implementation.h
   trunk/data/qcsrc/menu-div0test/progs.src
   trunk/data/qcsrc/menu-div0test/todo
Log:
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


Added: trunk/data/qcsrc/menu-div0test/basebutton_cl.tga
===================================================================
(Binary files differ)


Property changes on: trunk/data/qcsrc/menu-div0test/basebutton_cl.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/data/qcsrc/menu-div0test/basebutton_cm.tga
===================================================================
(Binary files differ)


Property changes on: trunk/data/qcsrc/menu-div0test/basebutton_cm.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/data/qcsrc/menu-div0test/basebutton_cr.tga
===================================================================
(Binary files differ)


Property changes on: trunk/data/qcsrc/menu-div0test/basebutton_cr.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/data/qcsrc/menu-div0test/basebutton_fl.tga
===================================================================
(Binary files differ)


Property changes on: trunk/data/qcsrc/menu-div0test/basebutton_fl.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/data/qcsrc/menu-div0test/basebutton_fm.tga
===================================================================
(Binary files differ)


Property changes on: trunk/data/qcsrc/menu-div0test/basebutton_fm.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/data/qcsrc/menu-div0test/basebutton_fr.tga
===================================================================
(Binary files differ)


Property changes on: trunk/data/qcsrc/menu-div0test/basebutton_fr.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/data/qcsrc/menu-div0test/basebutton_nl.tga
===================================================================
(Binary files differ)


Property changes on: trunk/data/qcsrc/menu-div0test/basebutton_nl.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/data/qcsrc/menu-div0test/basebutton_nm.tga
===================================================================
(Binary files differ)


Property changes on: trunk/data/qcsrc/menu-div0test/basebutton_nm.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/data/qcsrc/menu-div0test/basebutton_nr.tga
===================================================================
(Binary files differ)


Property changes on: trunk/data/qcsrc/menu-div0test/basebutton_nr.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/data/qcsrc/menu-div0test/classes.c
===================================================================
--- trunk/data/qcsrc/menu-div0test/classes.c	                        (rev 0)
+++ trunk/data/qcsrc/menu-div0test/classes.c	2007-10-26 10:53:56 UTC (rev 2850)
@@ -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"

Added: trunk/data/qcsrc/menu-div0test/draw.qc
===================================================================
--- trunk/data/qcsrc/menu-div0test/draw.qc	                        (rev 0)
+++ trunk/data/qcsrc/menu-div0test/draw.qc	2007-10-26 10:53:56 UTC (rev 2850)
@@ -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);
+}

Added: trunk/data/qcsrc/menu-div0test/draw.qh
===================================================================
--- trunk/data/qcsrc/menu-div0test/draw.qh	                        (rev 0)
+++ trunk/data/qcsrc/menu-div0test/draw.qh	2007-10-26 10:53:56 UTC (rev 2850)
@@ -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;

Added: trunk/data/qcsrc/menu-div0test/gamecommand.qc
===================================================================
--- trunk/data/qcsrc/menu-div0test/gamecommand.qc	                        (rev 0)
+++ trunk/data/qcsrc/menu-div0test/gamecommand.qc	2007-10-26 10:53:56 UTC (rev 2850)
@@ -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");
+}

Added: trunk/data/qcsrc/menu-div0test/gamecommand.qh
===================================================================
--- trunk/data/qcsrc/menu-div0test/gamecommand.qh	                        (rev 0)
+++ trunk/data/qcsrc/menu-div0test/gamecommand.qh	2007-10-26 10:53:56 UTC (rev 2850)
@@ -0,0 +1,2 @@
+void GameCommand_Init();
+void GameCommand(string command);

Added: trunk/data/qcsrc/menu-div0test/item/button.c
===================================================================
--- trunk/data/qcsrc/menu-div0test/item/button.c	                        (rev 0)
+++ trunk/data/qcsrc/menu-div0test/item/button.c	2007-10-26 10:53:56 UTC (rev 2850)
@@ -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

Added: trunk/data/qcsrc/menu-div0test/item/container.c
===================================================================
--- trunk/data/qcsrc/menu-div0test/item/container.c	                        (rev 0)
+++ trunk/data/qcsrc/menu-div0test/item/container.c	2007-10-26 10:53:56 UTC (rev 2850)
@@ -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

Added: trunk/data/qcsrc/menu-div0test/item/image.c
===================================================================
--- trunk/data/qcsrc/menu-div0test/item/image.c	                        (rev 0)
+++ trunk/data/qcsrc/menu-div0test/item/image.c	2007-10-26 10:53:56 UTC (rev 2850)
@@ -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

Added: trunk/data/qcsrc/menu-div0test/item/inputcontainer.c
===================================================================
--- trunk/data/qcsrc/menu-div0test/item/inputcontainer.c	                        (rev 0)
+++ trunk/data/qcsrc/menu-div0test/item/inputcontainer.c	2007-10-26 10:53:56 UTC (rev 2850)
@@ -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

Added: trunk/data/qcsrc/menu-div0test/item/label.c
===================================================================
--- trunk/data/qcsrc/menu-div0test/item/label.c	                        (rev 0)
+++ trunk/data/qcsrc/menu-div0test/item/label.c	2007-10-26 10:53:56 UTC (rev 2850)
@@ -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

Added: trunk/data/qcsrc/menu-div0test/item/modalcontroller.c
===================================================================
--- trunk/data/qcsrc/menu-div0test/item/modalcontroller.c	                        (rev 0)
+++ trunk/data/qcsrc/menu-div0test/item/modalcontroller.c	2007-10-26 10:53:56 UTC (rev 2850)
@@ -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

Added: trunk/data/qcsrc/menu-div0test/item/nexposee.c
===================================================================
--- trunk/data/qcsrc/menu-div0test/item/nexposee.c	                        (rev 0)
+++ trunk/data/qcsrc/menu-div0test/item/nexposee.c	2007-10-26 10:53:56 UTC (rev 2850)
@@ -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

Added: trunk/data/qcsrc/menu-div0test/item.c
===================================================================
--- trunk/data/qcsrc/menu-div0test/item.c	                        (rev 0)
+++ trunk/data/qcsrc/menu-div0test/item.c	2007-10-26 10:53:56 UTC (rev 2850)
@@ -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

Added: trunk/data/qcsrc/menu-div0test/mbuiltin.qh
===================================================================
--- trunk/data/qcsrc/menu-div0test/mbuiltin.qh	                        (rev 0)
+++ trunk/data/qcsrc/menu-div0test/mbuiltin.qh	2007-10-26 10:53:56 UTC (rev 2850)
@@ -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

Added: trunk/data/qcsrc/menu-div0test/menu.qc
===================================================================
--- trunk/data/qcsrc/menu-div0test/menu.qc	                        (rev 0)
+++ trunk/data/qcsrc/menu-div0test/menu.qc	2007-10-26 10:53:56 UTC (rev 2850)
@@ -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();
+};

Added: trunk/data/qcsrc/menu-div0test/menu.qh
===================================================================
--- trunk/data/qcsrc/menu-div0test/menu.qh	                        (rev 0)
+++ trunk/data/qcsrc/menu-div0test/menu.qh	2007-10-26 10:53:56 UTC (rev 2850)
@@ -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;

Added: trunk/data/qcsrc/menu-div0test/msys.qh
===================================================================
--- trunk/data/qcsrc/menu-div0test/msys.qh	                        (rev 0)
+++ trunk/data/qcsrc/menu-div0test/msys.qh	2007-10-26 10:53:56 UTC (rev 2850)
@@ -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;
+*/
+

Added: trunk/data/qcsrc/menu-div0test/nexuiz/mainwindow.c
===================================================================
--- trunk/data/qcsrc/menu-div0test/nexuiz/mainwindow.c	                        (rev 0)
+++ trunk/data/qcsrc/menu-div0test/nexuiz/mainwindow.c	2007-10-26 10:53:56 UTC (rev 2850)
@@ -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.

Added: trunk/data/qcsrc/menu-div0test/oo/base.h
===================================================================
--- trunk/data/qcsrc/menu-div0test/oo/base.h	                        (rev 0)
+++ trunk/data/qcsrc/menu-div0test/oo/base.h	2007-10-26 10:53:56 UTC (rev 2850)
@@ -0,0 +1,8 @@
+.string classname;
+entity spawnObject()
+{
+	entity e;
+	e = spawn();
+	e.classname = "Object";
+	return e;
+}

Added: trunk/data/qcsrc/menu-div0test/oo/classdefs.h
===================================================================
--- trunk/data/qcsrc/menu-div0test/oo/classdefs.h	                        (rev 0)
+++ trunk/data/qcsrc/menu-div0test/oo/classdefs.h	2007-10-26 10:53:56 UTC (rev 2850)
@@ -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;

Added: trunk/data/qcsrc/menu-div0test/oo/constructors.h
===================================================================
--- trunk/data/qcsrc/menu-div0test/oo/constructors.h	                        (rev 0)
+++ trunk/data/qcsrc/menu-div0test/oo/constructors.h	2007-10-26 10:53:56 UTC (rev 2850)
@@ -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; }

Added: trunk/data/qcsrc/menu-div0test/oo/implementation.h
===================================================================
--- trunk/data/qcsrc/menu-div0test/oo/implementation.h	                        (rev 0)
+++ trunk/data/qcsrc/menu-div0test/oo/implementation.h	2007-10-26 10:53:56 UTC (rev 2850)
@@ -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

Added: trunk/data/qcsrc/menu-div0test/progs.src
===================================================================
--- trunk/data/qcsrc/menu-div0test/progs.src	                        (rev 0)
+++ trunk/data/qcsrc/menu-div0test/progs.src	2007-10-26 10:53:56 UTC (rev 2850)
@@ -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

Added: trunk/data/qcsrc/menu-div0test/todo
===================================================================
--- trunk/data/qcsrc/menu-div0test/todo	                        (rev 0)
+++ trunk/data/qcsrc/menu-div0test/todo	2007-10-26 10:53:56 UTC (rev 2850)
@@ -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




More information about the nexuiz-commits mailing list