From: TimePath <andrew.hardaker1995@gmail.com>
Date: Tue, 15 Mar 2016 04:10:30 +0000 (+1100)
Subject: menu: #undef IMPLEMENTATION
X-Git-Tag: xonotic-v0.8.2~1080
X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=f532317ada52b5363cb0b74bfbdd38f5015e290c;p=xonotic%2Fxonotic-data.pk3dir.git

menu: #undef IMPLEMENTATION
---

diff --git a/qcsrc/common/mutators/mutator/damagetext/damagetext.qc b/qcsrc/common/mutators/mutator/damagetext/damagetext.qc
index 86adda03f..0b44b7346 100644
--- a/qcsrc/common/mutators/mutator/damagetext/damagetext.qc
+++ b/qcsrc/common/mutators/mutator/damagetext/damagetext.qc
@@ -2,7 +2,7 @@
 #define MUTATOR_DAMAGETEXT_H
 
 #ifdef MENUQC
-#include <menu/xonotic/tab.qc>
+#include <menu/xonotic/tab.qh>
 #endif
 
 #endif
diff --git a/qcsrc/menu/_all.qh b/qcsrc/menu/_all.qh
index 33313d637..21f784e32 100644
--- a/qcsrc/menu/_all.qh
+++ b/qcsrc/menu/_all.qh
@@ -2,3 +2,4 @@
 
 #include "draw.qh"
 #include "xonotic/util.qh"
+#include "menu.qh"
diff --git a/qcsrc/menu/anim/animation.qc b/qcsrc/menu/anim/animation.qc
index c20101d87..72bcc5e94 100644
--- a/qcsrc/menu/anim/animation.qc
+++ b/qcsrc/menu/anim/animation.qc
@@ -1,35 +1,7 @@
 #include "animation.qh"
-#ifndef ANIM_ANIMATION_H
-	#define ANIM_ANIMATION_H
-	CLASS(Animation, Object)
-		METHOD(Animation, configureAnimation, void(entity, entity, void(entity, float), float, float, float, float));
-		METHOD(Animation, update, void(entity, float, float, float));
-		METHOD(Animation, setTimeStartEnd, void(entity, float, float));
-		METHOD(Animation, setTimeStartDuration, void(entity, float, float));
-		METHOD(Animation, setValueStartEnd, void(entity, float, float));
-		METHOD(Animation, setValueStartDelta, void(entity, float, float));
-		METHOD(Animation, setObjectSetter, void(entity, entity, void(entity, float)));
-		METHOD(Animation, tick, void(entity, float));
-		METHOD(Animation, calcValue, float(entity, float, float, float, float));
-		METHOD(Animation, isStopped, float(entity));
-		METHOD(Animation, stopAnim, void(entity));
-		METHOD(Animation, resumeAnim, void(entity));
-		METHOD(Animation, isFinished, float(entity));
-		METHOD(Animation, finishAnim, void(entity));
-		ATTRIB(Animation, object, entity, NULL)
-		void setterDummy(entity, float) {}
-		ATTRIB(Animation, setter, void(entity, float), setterDummy)
-		ATTRIB(Animation, value, float, 0)
-		ATTRIB(Animation, startTime, float, 0)
-		ATTRIB(Animation, duration, float, 0)
-		ATTRIB(Animation, startValue, float, 0)
-		ATTRIB(Animation, delta, float, 0)
-		ATTRIB(Animation, stopped, float, false)
-		ATTRIB(Animation, finished, float, false)
-	ENDCLASS(Animation)
-#endif
-
-#ifdef IMPLEMENTATION
+
+#include "../menu.qh"
+
 	METHOD(Animation, configureAnimation, void(entity this, entity obj, void(entity, float) objSetter, float animStartTime, float animDuration, float animStartValue, float animEndValue))
 	{
 		this.setObjectSetter(this, obj, objSetter);
@@ -114,5 +86,3 @@
 		this.finished = true;
 		this.setter(this.object, this.value);
 	}
-
-#endif
diff --git a/qcsrc/menu/anim/animation.qh b/qcsrc/menu/anim/animation.qh
index 6f70f09be..0427f322a 100644
--- a/qcsrc/menu/anim/animation.qh
+++ b/qcsrc/menu/anim/animation.qh
@@ -1 +1,28 @@
 #pragma once
+
+CLASS(Animation, Object)
+	METHOD(Animation, configureAnimation, void(Animation this, entity, void(entity, float), float, float, float, float));
+	METHOD(Animation, update, void(Animation this, float, float, float));
+	METHOD(Animation, setTimeStartEnd, void(Animation this, float, float));
+	METHOD(Animation, setTimeStartDuration, void(Animation this, float, float));
+	METHOD(Animation, setValueStartEnd, void(Animation this, float, float));
+	METHOD(Animation, setValueStartDelta, void(Animation this, float, float));
+	METHOD(Animation, setObjectSetter, void(Animation this, entity, void(entity, float)));
+	METHOD(Animation, tick, void(Animation this, float));
+	METHOD(Animation, calcValue, float(Animation this, float, float, float, float));
+	METHOD(Animation, isStopped, float(Animation this));
+	METHOD(Animation, stopAnim, void(Animation this));
+	METHOD(Animation, resumeAnim, void(Animation this));
+	METHOD(Animation, isFinished, float(Animation this));
+	METHOD(Animation, finishAnim, void(Animation this));
+	ATTRIB(Animation, object, entity, NULL)
+	void setterDummy(Animation this, float) {}
+	ATTRIB(Animation, setter, void(Animation this, float), setterDummy)
+	ATTRIB(Animation, value, float, 0)
+	ATTRIB(Animation, startTime, float, 0)
+	ATTRIB(Animation, duration, float, 0)
+	ATTRIB(Animation, startValue, float, 0)
+	ATTRIB(Animation, delta, float, 0)
+	ATTRIB(Animation, stopped, float, false)
+	ATTRIB(Animation, finished, float, false)
+ENDCLASS(Animation)
diff --git a/qcsrc/menu/anim/animhost.qc b/qcsrc/menu/anim/animhost.qc
index 3ef209414..5e39191dd 100644
--- a/qcsrc/menu/anim/animhost.qc
+++ b/qcsrc/menu/anim/animhost.qc
@@ -1,28 +1,10 @@
 #include "animhost.qh"
+
 #include "../menu.qh"
 
-#ifndef ANIM_ANIMHOST_H
-	#define ANIM_ANIMHOST_H
-	CLASS(AnimHost, Object)
-		METHOD(AnimHost, addAnim, void(entity, entity));
-		METHOD(AnimHost, removeAnim, void(entity, entity));
-		METHOD(AnimHost, removeAllAnim, void(entity));
-		METHOD(AnimHost, removeObjAnim, void(entity, entity));
-		METHOD(AnimHost, stopAllAnim, void(entity));
-		METHOD(AnimHost, stopObjAnim, void(entity, entity));
-		METHOD(AnimHost, resumeAllAnim, void(entity));
-		METHOD(AnimHost, resumeObjAnim, void(entity, entity));
-		METHOD(AnimHost, finishAllAnim, void(entity));
-		METHOD(AnimHost, finishObjAnim, void(entity, entity));
-		METHOD(AnimHost, tickAll, void(entity));
-		ATTRIB(AnimHost, firstChild, entity, NULL)
-		ATTRIB(AnimHost, lastChild, entity, NULL)
-	ENDCLASS(AnimHost)
-	.entity nextSibling;
-	.entity prevSibling;
-#endif
-
-#ifdef IMPLEMENTATION
+#include "animation.qh"
+
+    .entity parent;
 	METHOD(AnimHost, addAnim, void(entity this, entity other))
 	{
 		if (other.parent) error("Can't add already added anim!");
@@ -141,4 +123,3 @@
 			}
 		}
 	}
-#endif
diff --git a/qcsrc/menu/anim/animhost.qh b/qcsrc/menu/anim/animhost.qh
index 6f70f09be..1292b7d8b 100644
--- a/qcsrc/menu/anim/animhost.qh
+++ b/qcsrc/menu/anim/animhost.qh
@@ -1 +1,19 @@
 #pragma once
+
+#include "../item/container.qh"
+
+CLASS(AnimHost, Object)
+	METHOD(AnimHost, addAnim, void(entity, entity));
+	METHOD(AnimHost, removeAnim, void(entity, entity));
+	METHOD(AnimHost, removeAllAnim, void(entity));
+	METHOD(AnimHost, removeObjAnim, void(entity, entity));
+	METHOD(AnimHost, stopAllAnim, void(entity));
+	METHOD(AnimHost, stopObjAnim, void(entity, entity));
+	METHOD(AnimHost, resumeAllAnim, void(entity));
+	METHOD(AnimHost, resumeObjAnim, void(entity, entity));
+	METHOD(AnimHost, finishAllAnim, void(entity));
+	METHOD(AnimHost, finishObjAnim, void(entity, entity));
+	METHOD(AnimHost, tickAll, void(entity));
+	ATTRIB(AnimHost, firstChild, entity, NULL)
+	ATTRIB(AnimHost, lastChild, entity, NULL)
+ENDCLASS(AnimHost)
diff --git a/qcsrc/menu/anim/easing.qc b/qcsrc/menu/anim/easing.qc
index e2b02f136..3014fa808 100644
--- a/qcsrc/menu/anim/easing.qc
+++ b/qcsrc/menu/anim/easing.qc
@@ -1,21 +1,8 @@
 #include "easing.qh"
-#ifndef ANIM_EASING_H
-	#define ANIM_EASING_H
-	#include "animation.qc"
-	entity makeHostedEasing(entity, void(entity, float), float(float, float, float, float), float, float, float);
-	entity makeEasing(entity, void(entity, float), float(float, float, float, float), float, float, float, float);
-	float easingLinear(float, float, float, float);
-	float easingQuadIn(float, float, float, float);
-	float easingQuadOut(float, float, float, float);
-	float easingQuadInOut(float, float, float, float);
-	CLASS(Easing, Animation)
-		METHOD(Easing, calcValue, float(entity, float, float, float, float));
-		METHOD(Easing, setMath, void(entity, float(float, float, float, float)));
-		ATTRIB(Easing, math, float(float, float, float, float), easingLinear)
-	ENDCLASS(Easing)
-#endif
 
-#ifdef IMPLEMENTATION
+#include "../menu.qh"
+#include "keyframe.qh"
+
 	entity makeHostedEasing(entity obj, void(entity, float) objSetter, float(float, float, float, float) func, float animDuration, float animStartValue, float animEnd)
 	{
 		entity this = makeEasing(obj, objSetter, func, time, animDuration, animStartValue, animEnd);
@@ -63,5 +50,3 @@
 		if (tickTime < (animDuration / 2)) return easingQuadIn(tickTime, (animDuration / 2), animStart, (animDelta / 2));
 		else return easingQuadOut((tickTime - (animDuration / 2)), (animDuration / 2), (animStart + (animDelta / 2)), (animDelta / 2));
 	}
-
-#endif
diff --git a/qcsrc/menu/anim/easing.qh b/qcsrc/menu/anim/easing.qh
index 6f70f09be..832a87c73 100644
--- a/qcsrc/menu/anim/easing.qh
+++ b/qcsrc/menu/anim/easing.qh
@@ -1 +1,14 @@
 #pragma once
+
+#include "animation.qh"
+entity makeHostedEasing(entity, void(entity, float), float(float, float, float, float), float, float, float);
+entity makeEasing(entity, void(entity, float), float(float, float, float, float), float, float, float, float);
+float easingLinear(float, float, float, float);
+float easingQuadIn(float, float, float, float);
+float easingQuadOut(float, float, float, float);
+float easingQuadInOut(float, float, float, float);
+CLASS(Easing, Animation)
+	METHOD(Easing, calcValue, float(entity, float, float, float, float));
+	METHOD(Easing, setMath, void(entity, float(float, float, float, float)));
+	ATTRIB(Easing, math, float(float, float, float, float), easingLinear)
+ENDCLASS(Easing)
diff --git a/qcsrc/menu/anim/keyframe.qc b/qcsrc/menu/anim/keyframe.qc
index da74e9f33..12c0c9aca 100644
--- a/qcsrc/menu/anim/keyframe.qc
+++ b/qcsrc/menu/anim/keyframe.qc
@@ -1,23 +1,12 @@
 #include "keyframe.qh"
-#ifndef ANIM_KEYFRAME_H
-	#define ANIM_KEYFRAME_H
-	#include "animation.qc"
-	CLASS(Keyframe, Animation)
-		METHOD(Keyframe, addEasing, entity(entity, float, float, float(float, float, float, float)));
-		METHOD(Keyframe, addAnim, void(entity, entity));
-		METHOD(Keyframe, calcValue, float(entity, float, float, float, float));
-		ATTRIB(Keyframe, currentChild, entity, NULL)
-		ATTRIB(Keyframe, firstChild, entity, NULL)
-		ATTRIB(Keyframe, lastChild, entity, NULL)
-	ENDCLASS(Keyframe)
-	entity makeHostedKeyframe(entity, void(entity, float), float, float, float);
-	entity makeKeyframe(entity, void(entity, float), float, float, float);
-	float getNewChildStart(entity);
-	float getNewChildDuration(entity, float);
-	float getNewChildValue(entity);
-#endif
-
-#ifdef IMPLEMENTATION
+
+#include "../menu.qh"
+#include "easing.qh"
+
+#include "../item/container.qh"
+
+.entity parent;
+
 	entity makeHostedKeyframe(entity obj, void(entity, float) objSetter, float animDuration, float animStart, float animEnd)
 	{
 		entity this = makeKeyframe(obj, objSetter, animDuration, animStart, animEnd);
@@ -98,4 +87,3 @@
 
 		return animStartValue + animDelta;
 	}
-#endif
diff --git a/qcsrc/menu/anim/keyframe.qh b/qcsrc/menu/anim/keyframe.qh
index 6f70f09be..d21db6920 100644
--- a/qcsrc/menu/anim/keyframe.qh
+++ b/qcsrc/menu/anim/keyframe.qh
@@ -1 +1,16 @@
 #pragma once
+
+#include "animation.qh"
+CLASS(Keyframe, Animation)
+	METHOD(Keyframe, addEasing, entity(entity, float, float, float(float, float, float, float)));
+	METHOD(Keyframe, addAnim, void(entity, entity));
+	METHOD(Keyframe, calcValue, float(entity, float, float, float, float));
+	ATTRIB(Keyframe, currentChild, entity, NULL)
+	ATTRIB(Keyframe, firstChild, entity, NULL)
+	ATTRIB(Keyframe, lastChild, entity, NULL)
+ENDCLASS(Keyframe)
+entity makeHostedKeyframe(entity, void(entity, float), float, float, float);
+entity makeKeyframe(entity, void(entity, float), float, float, float);
+float getNewChildStart(entity);
+float getNewChildDuration(entity, float);
+float getNewChildValue(entity);
diff --git a/qcsrc/menu/classes.qc b/qcsrc/menu/classes.qc
deleted file mode 100644
index 90ea3b992..000000000
--- a/qcsrc/menu/classes.qc
+++ /dev/null
@@ -1,10 +0,0 @@
-#include "classes.qh"
-#ifndef CLASSES_H
-#define CLASSES_H
-
-#include "classes.inc"
-#define IMPLEMENTATION
-#include "classes.inc"
-#undef IMPLEMENTATION
-
-#endif
diff --git a/qcsrc/menu/classes.qh b/qcsrc/menu/classes.qh
deleted file mode 100644
index 6f70f09be..000000000
--- a/qcsrc/menu/classes.qh
+++ /dev/null
@@ -1 +0,0 @@
-#pragma once
diff --git a/qcsrc/menu/command/all.qc b/qcsrc/menu/command/all.qc
deleted file mode 100644
index d555b23ba..000000000
--- a/qcsrc/menu/command/all.qc
+++ /dev/null
@@ -1,6 +0,0 @@
-#include "all.qh"
-#include "../menu.qh"
-
-#include <common/command/all.qc>
-
-#include "menu_cmd.qc"
diff --git a/qcsrc/menu/command/all.qh b/qcsrc/menu/command/all.qh
deleted file mode 100644
index 05b4eb2e4..000000000
--- a/qcsrc/menu/command/all.qh
+++ /dev/null
@@ -1,5 +0,0 @@
-#pragma once
-
-#include <common/command/command.qh>
-
-#include "menu_cmd.qh"
diff --git a/qcsrc/menu/command/menu_cmd.qc b/qcsrc/menu/command/menu_cmd.qc
index c76beca04..6b944c90e 100644
--- a/qcsrc/menu/command/menu_cmd.qc
+++ b/qcsrc/menu/command/menu_cmd.qc
@@ -1,7 +1,7 @@
 #include "menu_cmd.qh"
 
 #include "../menu.qh"
-#include "../classes.qc"
+#include "../item.qh"
 
 #include "../mutators/events.qh"
 
diff --git a/qcsrc/menu/gamesettings.qh b/qcsrc/menu/gamesettings.qh
index 868ac0fe3..80133b8b3 100644
--- a/qcsrc/menu/gamesettings.qh
+++ b/qcsrc/menu/gamesettings.qh
@@ -2,7 +2,7 @@
 
 #ifdef MENUQC
 
-#include "xonotic/tab.qc"
+#include "xonotic/tab.qh"
 
 REGISTRY(Settings, BITS(3))
 #define Settings_from(i) _Settings_from(i, NULL)
diff --git a/qcsrc/menu/item.qc b/qcsrc/menu/item.qc
index 3aba726b4..edac51ce7 100644
--- a/qcsrc/menu/item.qc
+++ b/qcsrc/menu/item.qc
@@ -1,35 +1,8 @@
 #include "item.qh"
-#ifndef ITEM_H
-#define ITEM_H
-#include "skin.qh"
-CLASS(Item, Object)
-	METHOD(Item, draw, void(Item));
-	METHOD(Item, keyDown, float(Item, float, float, float));
-	METHOD(Item, keyUp, float(Item, float, float, float));
-	METHOD(Item, mouseMove, float(Item, vector));
-	METHOD(Item, mousePress, float(Item, vector));
-	METHOD(Item, mouseDrag, float(Item, vector));
-	METHOD(Item, mouseRelease, float(Item, vector));
-	METHOD(Item, focusEnter, void(Item));
-	METHOD(Item, focusLeave, void(Item));
-	METHOD(Item, resizeNotify, void(Item, vector, vector, vector, vector));
-	METHOD(Item, relinquishFocus, void(Item));
-	METHOD(Item, showNotify, void(Item));
-	METHOD(Item, hideNotify, void(Item));
-	METHOD(Item, toString, string(Item));
-	METHOD(Item, destroy, void(Item));
-	ATTRIB(Item, focused, float, 0)
-	ATTRIB(Item, focusable, float, 0)
-	ATTRIB(Item, allowFocusSound, float, 0)
-	ATTRIB(Item, parent, entity, NULL)
-	ATTRIB(Item, preferredFocusPriority, float, 0)
-	ATTRIB(Item, origin, vector, '0 0 0')
-	ATTRIB(Item, size, vector, '0 0 0')
-	ATTRIB(Item, tooltip, string, string_null)
-ENDCLASS(Item)
-#endif
-
-#ifdef IMPLEMENTATION
+
+#include "item/container.qh"
+#include "item/borderimage.qh"
+
 	METHOD(Item, destroy, void(Item this))
 	{
 		// free memory associated with this
@@ -128,4 +101,3 @@ ENDCLASS(Item)
 	{
 		return string_null;
 	}
-#endif
diff --git a/qcsrc/menu/item.qh b/qcsrc/menu/item.qh
index 6f70f09be..118a45426 100644
--- a/qcsrc/menu/item.qh
+++ b/qcsrc/menu/item.qh
@@ -1 +1,30 @@
 #pragma once
+
+// convenience
+#include "skin.qh"
+
+CLASS(Item, Object)
+	METHOD(Item, draw, void(Item));
+	METHOD(Item, keyDown, float(Item, float, float, float));
+	METHOD(Item, keyUp, float(Item, float, float, float));
+	METHOD(Item, mouseMove, float(Item, vector));
+	METHOD(Item, mousePress, float(Item, vector));
+	METHOD(Item, mouseDrag, float(Item, vector));
+	METHOD(Item, mouseRelease, float(Item, vector));
+	METHOD(Item, focusEnter, void(Item));
+	METHOD(Item, focusLeave, void(Item));
+	METHOD(Item, resizeNotify, void(Item, vector, vector, vector, vector));
+	METHOD(Item, relinquishFocus, void(Item));
+	METHOD(Item, showNotify, void(Item));
+	METHOD(Item, hideNotify, void(Item));
+	METHOD(Item, toString, string(Item));
+	METHOD(Item, destroy, void(Item));
+	ATTRIB(Item, focused, float, 0)
+	ATTRIB(Item, focusable, float, 0)
+	ATTRIB(Item, allowFocusSound, float, 0)
+	ATTRIB(Item, parent, entity, NULL)
+	ATTRIB(Item, preferredFocusPriority, float, 0)
+	ATTRIB(Item, origin, vector, '0 0 0')
+	ATTRIB(Item, size, vector, '0 0 0')
+	ATTRIB(Item, tooltip, string, string_null)
+ENDCLASS(Item)
diff --git a/qcsrc/menu/item/borderimage.qc b/qcsrc/menu/item/borderimage.qc
index 3c2c8817c..ff37b4b86 100644
--- a/qcsrc/menu/item/borderimage.qc
+++ b/qcsrc/menu/item/borderimage.qc
@@ -1,30 +1,7 @@
 #include "borderimage.qh"
-#ifndef ITEM_BORDERIMAGE_H
-	#define ITEM_BORDERIMAGE_H
-	#include "label.qc"
-	CLASS(BorderImage, Label)
-		METHOD(BorderImage, configureBorderImage, void(entity, string, float, vector, string, float));
-		METHOD(BorderImage, resizeNotify, void(entity, vector, vector, vector, vector));
-		METHOD(BorderImage, recalcPositionWithText, void(entity, string));
-		ATTRIB(BorderImage, isBold, float, 1)
-		METHOD(BorderImage, draw, void(entity));
-		ATTRIB(BorderImage, src, string, string_null)
-		ATTRIB(BorderImage, borderHeight, float, 0)
-		ATTRIB(BorderImage, borderVec, vector, '0 0 0')
-		ATTRIB(BorderImage, color, vector, '1 1 1')
-		ATTRIB(BorderImage, closeButton, entity, NULL)
-		ATTRIB(BorderImage, realFontSize_Nexposeed, vector, '0 0 0')
-		ATTRIB(BorderImage, realOrigin_Nexposeed, vector, '0 0 0')
-		ATTRIB(BorderImage, isNexposeeTitleBar, float, 0)
-		ATTRIB(BorderImage, zoomedOutTitleBarPosition, float, 0)
-		ATTRIB(BorderImage, zoomedOutTitleBar, float, 0)
-		ATTRIB(BorderImage, overrideRealOrigin, vector, '0 1 0')
-		ATTRIB(BorderImage, saveRelOrigin, vector, '0 0 0')
-		ATTRIB(BorderImage, saveRelSize, vector, '0 0 0')
-	ENDCLASS(BorderImage)
-#endif
 
-#ifdef IMPLEMENTATION
+#include "nexposee.qh"
+#include "dialog.qh"
 	void BorderImage_recalcPositionWithText(entity me, string t)
 	{
 		if (me.isNexposeeTitleBar)
@@ -109,4 +86,3 @@
 			SUPER(BorderImage).draw(me);
 		}
 	}
-#endif
diff --git a/qcsrc/menu/item/borderimage.qh b/qcsrc/menu/item/borderimage.qh
index 6f70f09be..c956d362d 100644
--- a/qcsrc/menu/item/borderimage.qh
+++ b/qcsrc/menu/item/borderimage.qh
@@ -1 +1,25 @@
 #pragma once
+
+#include "label.qh"
+CLASS(BorderImage, Label)
+	METHOD(BorderImage, configureBorderImage, void(entity, string, float, vector, string, float));
+	METHOD(BorderImage, resizeNotify, void(entity, vector, vector, vector, vector));
+	METHOD(BorderImage, recalcPositionWithText, void(entity, string));
+	ATTRIB(BorderImage, isBold, float, 1)
+	METHOD(BorderImage, draw, void(entity));
+	ATTRIB(BorderImage, src, string, string_null)
+	ATTRIB(BorderImage, borderHeight, float, 0)
+	ATTRIB(BorderImage, borderVec, vector, '0 0 0')
+	ATTRIB(BorderImage, color, vector, '1 1 1')
+	ATTRIB(BorderImage, closeButton, entity, NULL)
+	ATTRIB(BorderImage, realFontSize_Nexposeed, vector, '0 0 0')
+	ATTRIB(BorderImage, realOrigin_Nexposeed, vector, '0 0 0')
+	ATTRIB(BorderImage, isNexposeeTitleBar, float, 0)
+	ATTRIB(BorderImage, zoomedOutTitleBarPosition, float, 0)
+	ATTRIB(BorderImage, zoomedOutTitleBar, float, 0)
+	ATTRIB(BorderImage, overrideRealOrigin, vector, '0 1 0')
+	ATTRIB(BorderImage, saveRelOrigin, vector, '0 0 0')
+	ATTRIB(BorderImage, saveRelSize, vector, '0 0 0')
+ENDCLASS(BorderImage)
+
+.vector colorC, colorF;
diff --git a/qcsrc/menu/item/button.qc b/qcsrc/menu/item/button.qc
index bec835664..8299a6859 100644
--- a/qcsrc/menu/item/button.qc
+++ b/qcsrc/menu/item/button.qc
@@ -1,47 +1,5 @@
 #include "button.qh"
-#ifndef ITEM_BUTTON_H
-	#define ITEM_BUTTON_H
-	#include "label.qc"
-	CLASS(Button, Label)
-		METHOD(Button, configureButton, void(entity, string, float, string));
-		METHOD(Button, draw, void(entity));
-		METHOD(Button, showNotify, 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));
-		METHOD(Button, playClickSound, void(entity));
-		ATTRIB(Button, onClick, void(entity, entity), func_null)
-		ATTRIB(Button, onClickEntity, entity, NULL)
-		ATTRIB(Button, src, string, string_null)
-		ATTRIB(Button, srcSuffix, string, string_null)
-		ATTRIB(Button, src2, string, string_null) // is centered, same aspect, and stretched to label size
-		ATTRIB(Button, src2scale, float, 1)
-		ATTRIB(Button, srcMulti, float, 1)        // 0: button square left, text right; 1: button stretched, text over it
-		ATTRIB(Button, buttonLeftOfText, float, 0)
-		ATTRIB(Button, focusable, float, 1)
-		ATTRIB(Button, allowFocusSound, float, 1)
-		ATTRIB(Button, pressed, float, 0)
-		ATTRIB(Button, clickTime, float, 0)
-		ATTRIB(Button, applyButton, entity, NULL)
-		ATTRIB(Button, disableOnClick, bool, false)
-		ATTRIB(Button, disabled, float, 0)
-		ATTRIB(Button, disabledAlpha, float, 0.3)
-		ATTRIB(Button, forcePressed, float, 0)
-		ATTRIB(Button, color, vector, '1 1 1')
-		ATTRIB(Button, colorC, vector, '1 1 1')
-		ATTRIB(Button, colorF, vector, '1 1 1')
-		ATTRIB(Button, colorD, vector, '1 1 1')
-		ATTRIB(Button, color2, vector, '1 1 1')
-		ATTRIB(Button, alpha2, float, 1)
 
-		ATTRIB(Button, origin, vector, '0 0 0')
-		ATTRIB(Button, size, vector, '0 0 0')
-	ENDCLASS(Button)
-#endif
-
-#ifdef IMPLEMENTATION
 	void Button_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize)
 	{
 		if (me.srcMulti) me.keepspaceLeft = 0;
@@ -177,4 +135,3 @@
 		else if (me.onClick == Dialog_Close) m_play_click_sound(MENU_SOUND_CLOSE);
 		else m_play_click_sound(MENU_SOUND_EXECUTE);
 	}
-#endif
diff --git a/qcsrc/menu/item/button.qh b/qcsrc/menu/item/button.qh
index 6f70f09be..6fd2bc888 100644
--- a/qcsrc/menu/item/button.qh
+++ b/qcsrc/menu/item/button.qh
@@ -1 +1,42 @@
 #pragma once
+
+#include "modalcontroller.qh"
+
+#include "label.qh"
+CLASS(Button, Label)
+	METHOD(Button, configureButton, void(entity, string, float, string));
+	METHOD(Button, draw, void(entity));
+	METHOD(Button, showNotify, 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));
+	METHOD(Button, playClickSound, void(entity));
+	ATTRIB(Button, onClick, void(entity, entity), func_null)
+	ATTRIB(Button, onClickEntity, entity, NULL)
+	ATTRIB(Button, src, string, string_null)
+	ATTRIB(Button, srcSuffix, string, string_null)
+	ATTRIB(Button, src2, string, string_null) // is centered, same aspect, and stretched to label size
+	ATTRIB(Button, src2scale, float, 1)
+	ATTRIB(Button, srcMulti, float, 1)        // 0: button square left, text right; 1: button stretched, text over it
+	ATTRIB(Button, buttonLeftOfText, float, 0)
+	ATTRIB(Button, focusable, float, 1)
+	ATTRIB(Button, allowFocusSound, float, 1)
+	ATTRIB(Button, pressed, float, 0)
+	ATTRIB(Button, clickTime, float, 0)
+	ATTRIB(Button, applyButton, entity, NULL)
+	ATTRIB(Button, disableOnClick, bool, false)
+	ATTRIB(Button, disabled, float, 0)
+	ATTRIB(Button, disabledAlpha, float, 0.3)
+	ATTRIB(Button, forcePressed, float, 0)
+	ATTRIB(Button, color, vector, '1 1 1')
+	ATTRIB(Button, colorC, vector, '1 1 1')
+	ATTRIB(Button, colorF, vector, '1 1 1')
+	ATTRIB(Button, colorD, vector, '1 1 1')
+	ATTRIB(Button, color2, vector, '1 1 1')
+	ATTRIB(Button, alpha2, float, 1)
+
+	ATTRIB(Button, origin, vector, '0 0 0')
+	ATTRIB(Button, size, vector, '0 0 0')
+ENDCLASS(Button)
diff --git a/qcsrc/menu/item/checkbox.qc b/qcsrc/menu/item/checkbox.qc
index b4b733ce2..79cfe7a99 100644
--- a/qcsrc/menu/item/checkbox.qc
+++ b/qcsrc/menu/item/checkbox.qc
@@ -1,23 +1,5 @@
 #include "checkbox.qh"
-#ifndef ITEM_CHECKBOX_H
-	#define ITEM_CHECKBOX_H
-	#include "button.qc"
-	void CheckBox_Click(entity me, entity other);
-	CLASS(CheckBox, Button)
-		METHOD(CheckBox, configureCheckBox, void(entity, string, float, string));
-		METHOD(CheckBox, draw, void(entity));
-		METHOD(CheckBox, playClickSound, void(entity));
-		METHOD(CheckBox, toString, string(entity));
-		METHOD(CheckBox, setChecked, void(entity, float));
-		ATTRIB(CheckBox, useDownAsChecked, float, 0)
-		ATTRIB(CheckBox, checked, float, 0)
-		ATTRIB(CheckBox, onClick, void(entity, entity), CheckBox_Click)
-		ATTRIB(CheckBox, srcMulti, float, 0)
-		ATTRIB(CheckBox, disabled, float, 0)
-	ENDCLASS(CheckBox)
-#endif
 
-#ifdef IMPLEMENTATION
 	void CheckBox_setChecked(entity me, float val)
 	{
 		me.checked = val;
@@ -55,4 +37,3 @@
 	{
 		m_play_click_sound(MENU_SOUND_SELECT);
 	}
-#endif
diff --git a/qcsrc/menu/item/checkbox.qh b/qcsrc/menu/item/checkbox.qh
index 6f70f09be..32f6b0f50 100644
--- a/qcsrc/menu/item/checkbox.qh
+++ b/qcsrc/menu/item/checkbox.qh
@@ -1 +1,16 @@
 #pragma once
+
+#include "button.qh"
+CLASS(CheckBox, Button)
+	METHOD(CheckBox, configureCheckBox, void(entity, string, float, string));
+	METHOD(CheckBox, draw, void(entity));
+	METHOD(CheckBox, playClickSound, void(entity));
+	METHOD(CheckBox, toString, string(entity));
+	METHOD(CheckBox, setChecked, void(entity, float));
+	ATTRIB(CheckBox, useDownAsChecked, float, 0)
+	ATTRIB(CheckBox, checked, float, 0)
+    void CheckBox_Click(entity me, entity other);
+	ATTRIB(CheckBox, onClick, void(entity, entity), CheckBox_Click)
+	ATTRIB(CheckBox, srcMulti, float, 0)
+	ATTRIB(CheckBox, disabled, float, 0)
+ENDCLASS(CheckBox)
diff --git a/qcsrc/menu/item/container.qc b/qcsrc/menu/item/container.qc
index 63366c0ee..56535bf71 100644
--- a/qcsrc/menu/item/container.qc
+++ b/qcsrc/menu/item/container.qc
@@ -1,55 +1,5 @@
 #include "container.qh"
-#ifndef ITEM_CONTAINER_H
-	#define ITEM_CONTAINER_H
-	#include "../item.qc"
-	CLASS(Container, 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, .vector));
-		METHOD(Container, addItem, void(entity, entity, vector, vector, float));
-		METHOD(Container, addItemCentered, void(entity, entity, vector, float));
-		METHOD(Container, addItemRightCentered, void(entity, entity, vector, float));
-		METHOD(Container, moveItemAfter, void(entity, entity, entity));
-		METHOD(Container, removeItem, void(entity, entity));
-		METHOD(Container, setFocus, void(entity, entity));
-		METHOD(Container, saveFocus, void(entity));
-		METHOD(Container, setAlphaOf, void(entity, entity, float));
-		METHOD(Container, itemFromPoint, entity(entity, vector));
-		METHOD(Container, showNotify, void(entity));
-		METHOD(Container, hideNotify, void(entity));
-		METHOD(Container, preferredFocusedGrandChild, entity(entity));
-		ATTRIB(Container, focusable, float, 0)
-		ATTRIB(Container, firstChild, entity, NULL)
-		ATTRIB(Container, lastChild, entity, NULL)
-		ATTRIB(Container, focusedChild, entity, NULL)
-		ATTRIB(Container, savedFocus, entity, NULL)
-		ATTRIB(Container, shown, float, 0)
-
-		METHOD(Container, enterSubitem, void(entity, entity));
-		METHOD(Container, enterLieSubitem, void(entity, vector, vector, vector, float));
-		METHOD(Container, leaveSubitem, void(entity));
-	ENDCLASS(Container)
-	.entity nextSibling;
-	.entity prevSibling;
-	.float resized;
-	.vector Container_origin;
-	.vector Container_size;
-	.vector Container_fontscale;
-	.float Container_alpha;
-	.vector Container_save_shift;
-	.vector Container_save_scale;
-	.vector Container_save_fontscale;
-	.float Container_save_alpha;
-#endif
-
-#ifdef IMPLEMENTATION
+
 	void Container_enterSubitem(entity me, entity sub)
 	{
 		me.enterLieSubitem(me, sub.Container_origin, sub.Container_size, sub.Container_fontscale, sub.Container_alpha);
@@ -427,4 +377,3 @@
 
 		return best;
 	}
-#endif
diff --git a/qcsrc/menu/item/container.qh b/qcsrc/menu/item/container.qh
index 6f70f09be..dbb4cf221 100644
--- a/qcsrc/menu/item/container.qh
+++ b/qcsrc/menu/item/container.qh
@@ -1 +1,50 @@
 #pragma once
+
+#include <menu/item.qh>
+
+CLASS(Container, 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, .vector));
+	METHOD(Container, addItem, void(entity, entity, vector, vector, float));
+	METHOD(Container, addItemCentered, void(entity, entity, vector, float));
+	METHOD(Container, addItemRightCentered, void(entity, entity, vector, float));
+	METHOD(Container, moveItemAfter, void(entity, entity, entity));
+	METHOD(Container, removeItem, void(entity, entity));
+	METHOD(Container, setFocus, void(entity, entity));
+	METHOD(Container, saveFocus, void(entity));
+	METHOD(Container, setAlphaOf, void(entity, entity, float));
+	METHOD(Container, itemFromPoint, entity(entity, vector));
+	METHOD(Container, showNotify, void(entity));
+	METHOD(Container, hideNotify, void(entity));
+	METHOD(Container, preferredFocusedGrandChild, entity(entity));
+	ATTRIB(Container, focusable, float, 0)
+	ATTRIB(Container, firstChild, entity, NULL)
+	ATTRIB(Container, lastChild, entity, NULL)
+	ATTRIB(Container, focusedChild, entity, NULL)
+	ATTRIB(Container, savedFocus, entity, NULL)
+	ATTRIB(Container, shown, float, 0)
+
+	METHOD(Container, enterSubitem, void(entity, entity));
+	METHOD(Container, enterLieSubitem, void(entity, vector, vector, vector, float));
+	METHOD(Container, leaveSubitem, void(entity));
+ENDCLASS(Container)
+
+.entity nextSibling;
+.entity prevSibling;
+.float resized;
+.vector Container_origin;
+.vector Container_size;
+.vector Container_fontscale;
+.float Container_alpha;
+.vector Container_save_shift;
+.vector Container_save_scale;
+.vector Container_save_fontscale;
+.float Container_save_alpha;
diff --git a/qcsrc/menu/item/dialog.qc b/qcsrc/menu/item/dialog.qc
index 9c5fb385c..c4a78fa56 100644
--- a/qcsrc/menu/item/dialog.qc
+++ b/qcsrc/menu/item/dialog.qc
@@ -1,77 +1,9 @@
 #include "dialog.qh"
-// Note: this class is called Dialog, but it can also handle a tab under the following conditions:
-// - isTabRoot is 0
-// - backgroundImage is the tab's background
-// - closable is 0
-// - rootDialog is 0
-// - title is ""
-// - marginTop is
-// - intendedHeight ends up to be the tab's actual height, or at least close
-// - titleFontSize is 0
-// - marginTop cancels out as much of titleHeight as needed (that is, it should be actualMarginTop - titleHeight)
-// To ensure the latter, you best create all tabs FIRST and insert the tabbed
-// control to your dialog THEN - with the right height
-//
-// a subclass may help with using this as a tab
-
-#ifndef ITEM_DIALOG_H
-	#define ITEM_DIALOG_H
-	#include "inputcontainer.qc"
-	CLASS(Dialog, InputContainer)
-		METHOD(Dialog, configureDialog, void(entity)); // no runtime configuration, all parameters are given in the code!
-		METHOD(Dialog, fill, void(entity));            // to be overridden by user to fill the dialog with controls
-		METHOD(Dialog, keyDown, float(entity, float, float, float));
-		METHOD(Dialog, close, void(entity));
-		METHOD(Dialog, addItemSimple, void(entity, float, float, float, float, entity, vector));
-
-		METHOD(Dialog, TD, void(entity, float, float, entity));
-		METHOD(Dialog, TDNoMargin, void(entity, float, float, entity, vector));
-		METHOD(Dialog, TDempty, void(entity, float));
-		METHOD(Dialog, setFirstColumn, void(entity, float));
-		METHOD(Dialog, TR, void(entity));
-		METHOD(Dialog, gotoRC, void(entity, float, float));
-
-		ATTRIB(Dialog, isTabRoot, float, 1)
-		ATTRIB(Dialog, closeButton, entity, NULL)
-		ATTRIB(Dialog, intendedHeight, float, 0)
-		ATTRIB(Dialog, itemOrigin, vector, '0 0 0')
-		ATTRIB(Dialog, itemSize, vector, '0 0 0')
-		ATTRIB(Dialog, itemSpacing, vector, '0 0 0')
-		ATTRIB(Dialog, currentRow, float, 0)
-		ATTRIB(Dialog, currentColumn, float, 0)
-		ATTRIB(Dialog, firstColumn, float, 0)
-
-		// to be customized
-		ATTRIB(Dialog, closable, float, 1)
-		ATTRIB(Dialog, title, string, "Form1")  // ;)
-		ATTRIB(Dialog, color, vector, '1 0.5 1')
-		ATTRIB(Dialog, intendedWidth, float, 0)
-		ATTRIB(Dialog, rows, float, 3)
-		ATTRIB(Dialog, columns, float, 2)
-
-		ATTRIB(Dialog, marginTop, float, 0)     // pixels
-		ATTRIB(Dialog, marginBottom, float, 0)  // pixels
-		ATTRIB(Dialog, marginLeft, float, 0)    // pixels
-		ATTRIB(Dialog, marginRight, float, 0)   // pixels
-		ATTRIB(Dialog, columnSpacing, float, 0) // pixels
-		ATTRIB(Dialog, rowSpacing, float, 0)    // pixels
-		ATTRIB(Dialog, rowHeight, float, 0)     // pixels
-		ATTRIB(Dialog, titleHeight, float, 0)   // pixels
-		ATTRIB(Dialog, titleFontSize, float, 0) // pixels; if 0, title causes no margin
-		ATTRIB(Dialog, zoomedOutTitleBarPosition, float, 0)
-		ATTRIB(Dialog, zoomedOutTitleBar, float, 0)
-
-		ATTRIB(Dialog, requiresConnection, float, 0)  // set to true if the dialog requires a connection to be opened
-
-		ATTRIB(Dialog, backgroundImage, string, string_null)
-		ATTRIB(Dialog, borderLines, float, 1)
-		ATTRIB(Dialog, closeButtonImage, string, string_null)
-
-		ATTRIB(Dialog, frame, entity, NULL)
-	ENDCLASS(Dialog)
-#endif
-
-#ifdef IMPLEMENTATION
+
+#include "borderimage.qh"
+#include "button.qh"
+#include "nexposee.qh"
+
 	void Dialog_Close(entity button, entity me)
 	{
 		me.close(me);
@@ -188,4 +120,3 @@
 		}
 		return SUPER(Dialog).keyDown(me, key, ascii, shift);
 	}
-#endif
diff --git a/qcsrc/menu/item/dialog.qh b/qcsrc/menu/item/dialog.qh
index 6f70f09be..17343e7cd 100644
--- a/qcsrc/menu/item/dialog.qh
+++ b/qcsrc/menu/item/dialog.qh
@@ -1 +1,72 @@
 #pragma once
+
+// Note: this class is called Dialog, but it can also handle a tab under the following conditions:
+// - isTabRoot is 0
+// - backgroundImage is the tab's background
+// - closable is 0
+// - rootDialog is 0
+// - title is ""
+// - marginTop is
+// - intendedHeight ends up to be the tab's actual height, or at least close
+// - titleFontSize is 0
+// - marginTop cancels out as much of titleHeight as needed (that is, it should be actualMarginTop - titleHeight)
+// To ensure the latter, you best create all tabs FIRST and insert the tabbed
+// control to your dialog THEN - with the right height
+//
+// a subclass may help with using this as a tab
+
+#include "inputcontainer.qh"
+CLASS(Dialog, InputContainer)
+	METHOD(Dialog, configureDialog, void(entity)); // no runtime configuration, all parameters are given in the code!
+	METHOD(Dialog, fill, void(entity));            // to be overridden by user to fill the dialog with controls
+	METHOD(Dialog, keyDown, float(entity, float, float, float));
+	METHOD(Dialog, close, void(entity));
+	METHOD(Dialog, addItemSimple, void(entity, float, float, float, float, entity, vector));
+
+	METHOD(Dialog, TD, void(entity, float, float, entity));
+	METHOD(Dialog, TDNoMargin, void(entity, float, float, entity, vector));
+	METHOD(Dialog, TDempty, void(entity, float));
+	METHOD(Dialog, setFirstColumn, void(entity, float));
+	METHOD(Dialog, TR, void(entity));
+	METHOD(Dialog, gotoRC, void(entity, float, float));
+
+	ATTRIB(Dialog, isTabRoot, float, 1)
+	ATTRIB(Dialog, closeButton, entity, NULL)
+	ATTRIB(Dialog, intendedHeight, float, 0)
+	ATTRIB(Dialog, itemOrigin, vector, '0 0 0')
+	ATTRIB(Dialog, itemSize, vector, '0 0 0')
+	ATTRIB(Dialog, itemSpacing, vector, '0 0 0')
+	ATTRIB(Dialog, currentRow, float, 0)
+	ATTRIB(Dialog, currentColumn, float, 0)
+	ATTRIB(Dialog, firstColumn, float, 0)
+
+	// to be customized
+	ATTRIB(Dialog, closable, float, 1)
+	ATTRIB(Dialog, title, string, "Form1")  // ;)
+	ATTRIB(Dialog, color, vector, '1 0.5 1')
+	ATTRIB(Dialog, intendedWidth, float, 0)
+	ATTRIB(Dialog, rows, float, 3)
+	ATTRIB(Dialog, columns, float, 2)
+
+	ATTRIB(Dialog, marginTop, float, 0)     // pixels
+	ATTRIB(Dialog, marginBottom, float, 0)  // pixels
+	ATTRIB(Dialog, marginLeft, float, 0)    // pixels
+	ATTRIB(Dialog, marginRight, float, 0)   // pixels
+	ATTRIB(Dialog, columnSpacing, float, 0) // pixels
+	ATTRIB(Dialog, rowSpacing, float, 0)    // pixels
+	ATTRIB(Dialog, rowHeight, float, 0)     // pixels
+	ATTRIB(Dialog, titleHeight, float, 0)   // pixels
+	ATTRIB(Dialog, titleFontSize, float, 0) // pixels; if 0, title causes no margin
+	ATTRIB(Dialog, zoomedOutTitleBarPosition, float, 0)
+	ATTRIB(Dialog, zoomedOutTitleBar, float, 0)
+
+	ATTRIB(Dialog, requiresConnection, float, 0)  // set to true if the dialog requires a connection to be opened
+
+	ATTRIB(Dialog, backgroundImage, string, string_null)
+	ATTRIB(Dialog, borderLines, float, 1)
+	ATTRIB(Dialog, closeButtonImage, string, string_null)
+
+	ATTRIB(Dialog, frame, entity, NULL)
+ENDCLASS(Dialog)
+
+void Dialog_Close(entity button, entity me);
diff --git a/qcsrc/menu/item/image.qc b/qcsrc/menu/item/image.qc
index 9141d4df4..06ac91f02 100644
--- a/qcsrc/menu/item/image.qc
+++ b/qcsrc/menu/item/image.qc
@@ -1,35 +1,5 @@
 #include "image.qh"
-#ifndef ITEM_IMAGE_H
-	#define ITEM_IMAGE_H
-	#include "../item.qc"
-	CLASS(Image, Item)
-		METHOD(Image, configureImage, void(entity, string));
-		METHOD(Image, draw, void(entity));
-		METHOD(Image, toString, string(entity));
-		METHOD(Image, resizeNotify, void(entity, vector, vector, vector, vector));
-		METHOD(Image, updateAspect, void(entity));
-		METHOD(Image, initZoom, void(entity));
-		METHOD(Image, setZoom, void(entity, float, float));
-		METHOD(Image, drag_setStartPos, float(entity, vector));
-		METHOD(Image, drag, float(entity, vector));
-		ATTRIB(Image, src, string, string_null)
-		ATTRIB(Image, color, vector, '1 1 1')
-		ATTRIB(Image, forcedAspect, float, 0)        // special values: -1 keep image aspect ratio, -2 keep image size but bound to the containing box, -3 always keep image size
-		ATTRIB(Image, zoomBox, float, 0)             // used by forcedAspect -2 when the image is larger than the containing box
-		ATTRIB(Image, zoomFactor, float, 1)
-		ATTRIB(Image, zoomOffset, vector, '0.5 0.5 0')
-		ATTRIB(Image, zoomSnapToTheBox, float, 1)    // snap the zoomed in image to the box borders when zooming/dragging it
-		ATTRIB(Image, zoomTime, float, 0)
-		ATTRIB(Image, zoomLimitedByTheBox, float, 0) // forbids zoom if image would be larger than the containing box
-		ATTRIB(Image, zoomMax, float, 0)
-		ATTRIB(Image, start_zoomOffset, vector, '0 0 0')
-		ATTRIB(Image, start_coords, vector, '0 0 0')
-		ATTRIB(Image, imgOrigin, vector, '0 0 0')
-		ATTRIB(Image, imgSize, vector, '0 0 0')
-	ENDCLASS(Image)
-#endif
 
-#ifdef IMPLEMENTATION
 	string Image_toString(entity me)
 	{
 		return me.src;
@@ -222,4 +192,3 @@
 		SUPER(Image).resizeNotify(me, relOrigin, relSize, absOrigin, absSize);
 		me.updateAspect(me);
 	}
-#endif
diff --git a/qcsrc/menu/item/image.qh b/qcsrc/menu/item/image.qh
index 6f70f09be..35bca5985 100644
--- a/qcsrc/menu/item/image.qh
+++ b/qcsrc/menu/item/image.qh
@@ -1 +1,28 @@
 #pragma once
+
+#include "../item.qh"
+CLASS(Image, Item)
+	METHOD(Image, configureImage, void(entity, string));
+	METHOD(Image, draw, void(entity));
+	METHOD(Image, toString, string(entity));
+	METHOD(Image, resizeNotify, void(entity, vector, vector, vector, vector));
+	METHOD(Image, updateAspect, void(entity));
+	METHOD(Image, initZoom, void(entity));
+	METHOD(Image, setZoom, void(entity, float, float));
+	METHOD(Image, drag_setStartPos, float(entity, vector));
+	METHOD(Image, drag, float(entity, vector));
+	ATTRIB(Image, src, string, string_null)
+	ATTRIB(Image, color, vector, '1 1 1')
+	ATTRIB(Image, forcedAspect, float, 0)        // special values: -1 keep image aspect ratio, -2 keep image size but bound to the containing box, -3 always keep image size
+	ATTRIB(Image, zoomBox, float, 0)             // used by forcedAspect -2 when the image is larger than the containing box
+	ATTRIB(Image, zoomFactor, float, 1)
+	ATTRIB(Image, zoomOffset, vector, '0.5 0.5 0')
+	ATTRIB(Image, zoomSnapToTheBox, float, 1)    // snap the zoomed in image to the box borders when zooming/dragging it
+	ATTRIB(Image, zoomTime, float, 0)
+	ATTRIB(Image, zoomLimitedByTheBox, float, 0) // forbids zoom if image would be larger than the containing box
+	ATTRIB(Image, zoomMax, float, 0)
+	ATTRIB(Image, start_zoomOffset, vector, '0 0 0')
+	ATTRIB(Image, start_coords, vector, '0 0 0')
+	ATTRIB(Image, imgOrigin, vector, '0 0 0')
+	ATTRIB(Image, imgSize, vector, '0 0 0')
+ENDCLASS(Image)
diff --git a/qcsrc/menu/item/inputbox.qc b/qcsrc/menu/item/inputbox.qc
index 43ef41f81..6f7ed9f24 100644
--- a/qcsrc/menu/item/inputbox.qc
+++ b/qcsrc/menu/item/inputbox.qc
@@ -1,51 +1,8 @@
 #include "inputbox.qh"
-#ifndef ITEM_INPUTBOX_H
-	#define ITEM_INPUTBOX_H
-	#include "label.qc"
-	CLASS(InputBox, Label)
-		METHOD(InputBox, configureInputBox, void(entity, string, float, float, string));
-		METHOD(InputBox, draw, void(entity));
-		METHOD(InputBox, setText, void(entity, string));
-		METHOD(InputBox, enterText, void(entity, string));
-		METHOD(InputBox, keyDown, float(entity, float, float, float));
-		METHOD(InputBox, mouseMove, float(entity, vector));
-		METHOD(InputBox, mouseRelease, float(entity, vector));
-		METHOD(InputBox, mousePress, float(entity, vector));
-		METHOD(InputBox, mouseDrag, float(entity, vector));
-		METHOD(InputBox, showNotify, void(entity));
-		METHOD(InputBox, resizeNotify, void(entity, vector, vector, vector, vector));
 
-		ATTRIB(InputBox, src, string, string_null)
+.float cb_offset;
+.string cb_src;
 
-		ATTRIB(InputBox, cursorPos, float, 0)  // characters
-		ATTRIB(InputBox, scrollPos, float, 0)  // widths
-
-		ATTRIB(InputBox, focusable, float, 1)
-		ATTRIB(InputBox, allowFocusSound, float, 1)
-		ATTRIB(InputBox, disabled, float, 0)
-		ATTRIB(InputBox, lastChangeTime, float, 0)
-		ATTRIB(InputBox, dragScrollTimer, float, 0)
-		ATTRIB(InputBox, dragScrollPos, vector, '0 0 0')
-		ATTRIB(InputBox, pressed, float, 0)
-		ATTRIB(InputBox, editColorCodes, float, 1)
-		ATTRIB(InputBox, forbiddenCharacters, string, "")
-		ATTRIB(InputBox, color, vector, '1 1 1')
-		ATTRIB(InputBox, colorF, vector, '1 1 1')
-		ATTRIB(InputBox, maxLength, float, 255)  // if negative, it counts bytes, not chars
-		ATTRIB(InputBox, applyButton, entity, NULL)
-
-		ATTRIB(InputBox, enableClearButton, float, 1)
-		ATTRIB(InputBox, clearButton, entity, NULL)
-		ATTRIB(InputBox, cb_width, float, 0)
-		ATTRIB(InputBox, cb_pressed, float, 0)
-		ATTRIB(InputBox, cb_focused, float, 0)
-		ATTRIB(InputBox, cb_color, vector, '1 1 1')
-		ATTRIB(InputBox, cb_colorF, vector, '1 1 1')
-		ATTRIB(InputBox, cb_colorC, vector, '1 1 1')
-	ENDCLASS(InputBox)
-#endif
-
-#ifdef IMPLEMENTATION
 	void InputBox_configureInputBox(entity me, string theText, float theCursorPos, float theFontSize, string gfx)
 	{
 		SUPER(InputBox).configureLabel(me, theText, theFontSize, 0.0);
@@ -406,4 +363,3 @@
 	{
 		me.focusable = !me.disabled;
 	}
-#endif
diff --git a/qcsrc/menu/item/inputbox.qh b/qcsrc/menu/item/inputbox.qh
index 6f70f09be..cfb576cfa 100644
--- a/qcsrc/menu/item/inputbox.qh
+++ b/qcsrc/menu/item/inputbox.qh
@@ -1 +1,44 @@
 #pragma once
+
+#include "label.qh"
+CLASS(InputBox, Label)
+	METHOD(InputBox, configureInputBox, void(entity, string, float, float, string));
+	METHOD(InputBox, draw, void(entity));
+	METHOD(InputBox, setText, void(entity, string));
+	METHOD(InputBox, enterText, void(entity, string));
+	METHOD(InputBox, keyDown, float(entity, float, float, float));
+	METHOD(InputBox, mouseMove, float(entity, vector));
+	METHOD(InputBox, mouseRelease, float(entity, vector));
+	METHOD(InputBox, mousePress, float(entity, vector));
+	METHOD(InputBox, mouseDrag, float(entity, vector));
+	METHOD(InputBox, showNotify, void(entity));
+	METHOD(InputBox, resizeNotify, void(entity, vector, vector, vector, vector));
+
+	ATTRIB(InputBox, src, string, string_null)
+
+	ATTRIB(InputBox, cursorPos, float, 0)  // characters
+	ATTRIB(InputBox, scrollPos, float, 0)  // widths
+
+	ATTRIB(InputBox, focusable, float, 1)
+	ATTRIB(InputBox, allowFocusSound, float, 1)
+	ATTRIB(InputBox, disabled, float, 0)
+	ATTRIB(InputBox, lastChangeTime, float, 0)
+	ATTRIB(InputBox, dragScrollTimer, float, 0)
+	ATTRIB(InputBox, dragScrollPos, vector, '0 0 0')
+	ATTRIB(InputBox, pressed, float, 0)
+	ATTRIB(InputBox, editColorCodes, float, 1)
+	ATTRIB(InputBox, forbiddenCharacters, string, "")
+	ATTRIB(InputBox, color, vector, '1 1 1')
+	ATTRIB(InputBox, colorF, vector, '1 1 1')
+	ATTRIB(InputBox, maxLength, float, 255)  // if negative, it counts bytes, not chars
+	ATTRIB(InputBox, applyButton, entity, NULL)
+
+	ATTRIB(InputBox, enableClearButton, float, 1)
+	ATTRIB(InputBox, clearButton, entity, NULL)
+	ATTRIB(InputBox, cb_width, float, 0)
+	ATTRIB(InputBox, cb_pressed, float, 0)
+	ATTRIB(InputBox, cb_focused, float, 0)
+	ATTRIB(InputBox, cb_color, vector, '1 1 1')
+	ATTRIB(InputBox, cb_colorF, vector, '1 1 1')
+	ATTRIB(InputBox, cb_colorC, vector, '1 1 1')
+ENDCLASS(InputBox)
diff --git a/qcsrc/menu/item/inputcontainer.qc b/qcsrc/menu/item/inputcontainer.qc
index ce263889d..3840721e3 100644
--- a/qcsrc/menu/item/inputcontainer.qc
+++ b/qcsrc/menu/item/inputcontainer.qc
@@ -1,23 +1,5 @@
 #include "inputcontainer.qh"
-#ifndef ITEM_INPUTCONTAINER_H
-	#define ITEM_INPUTCONTAINER_H
-	#include "container.qc"
-	CLASS(InputContainer, 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, bool(entity this, vector pos));
-		ATTRIB(InputContainer, mouseFocusedChild, entity, NULL)
-		ATTRIB(InputContainer, isTabRoot, float, 0)
-	ENDCLASS(InputContainer)
-#endif
-
-#ifdef IMPLEMENTATION
 	void InputContainer_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize)
 	{
 		SUPER(InputContainer).resizeNotify(me, relOrigin, relSize, absOrigin, absSize);
@@ -150,4 +132,3 @@
 		if (pos.x >= 0 && pos.y >= 0 && pos.x < 1 && pos.y < 1) return 1;
 		return 0;
 	}
-#endif
diff --git a/qcsrc/menu/item/inputcontainer.qh b/qcsrc/menu/item/inputcontainer.qh
index 6f70f09be..5d84189fa 100644
--- a/qcsrc/menu/item/inputcontainer.qh
+++ b/qcsrc/menu/item/inputcontainer.qh
@@ -1 +1,16 @@
 #pragma once
+
+#include "container.qh"
+CLASS(InputContainer, 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, bool(entity this, vector pos));
+	ATTRIB(InputContainer, mouseFocusedChild, entity, NULL)
+	ATTRIB(InputContainer, isTabRoot, float, 0)
+ENDCLASS(InputContainer)
diff --git a/qcsrc/menu/item/label.qc b/qcsrc/menu/item/label.qc
index 7148b1f0d..ca9ec00b0 100644
--- a/qcsrc/menu/item/label.qc
+++ b/qcsrc/menu/item/label.qc
@@ -1,41 +1,5 @@
 #include "label.qh"
-#ifndef ITEM_LABEL_H
-	#define ITEM_LABEL_H
-	#include "../item.qc"
-	CLASS(Label, 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));
-		METHOD(Label, toString, string(entity));
-		METHOD(Label, recalcPositionWithText, void(entity, string));
-		ATTRIB(Label, isBold, float, 0)
-		ATTRIB(Label, text, string, string_null)
-		ATTRIB(Label, currentText, string, string_null)
-		ATTRIB(Label, fontSize, float, 8)
-		ATTRIB(Label, align, float, 0.5)
-		ATTRIB(Label, allowCut, float, 0)
-		ATTRIB(Label, allowColors, float, 0)
-		ATTRIB(Label, keepspaceLeft, float, 0) // for use by subclasses (radiobuttons for example)
-		ATTRIB(Label, keepspaceRight, float, 0)
-		ATTRIB(Label, marginLeft, float, 0)    // alternate way to specify keepspace* (in characters from the font)
-		ATTRIB(Label, marginRight, float, 0)
-		ATTRIB(Label, realFontSize, vector, '0 0 0')
-		ATTRIB(Label, realOrigin, vector, '0 0 0')
-		ATTRIB(Label, alpha, float, 0.7)
-		ATTRIB(Label, colorL, vector, SKINCOLOR_TEXT)
-		ATTRIB(Label, disabled, float, 0)
-		ATTRIB(Label, disabledAlpha, float, 0.3)
-		ATTRIB(Label, textEntity, entity, NULL)
-		ATTRIB(Label, allowWrap, float, 0)
-		ATTRIB(Label, recalcPos, float, 0)
-		ATTRIB(Label, condenseFactor, float, 1)
-		ATTRIB(Label, overrideRealOrigin, vector, '0 0 0')
-		ATTRIB(Label, overrideCondenseFactor, float, 0)
-	ENDCLASS(Label)
-#endif
-
-#ifdef IMPLEMENTATION
+
 	string Label_toString(entity me)
 	{
 		return me.text;
@@ -203,4 +167,3 @@
 
 		SUPER(Label).draw(me);
 	}
-#endif
diff --git a/qcsrc/menu/item/label.qh b/qcsrc/menu/item/label.qh
index 6f70f09be..428958c20 100644
--- a/qcsrc/menu/item/label.qh
+++ b/qcsrc/menu/item/label.qh
@@ -1 +1,34 @@
 #pragma once
+
+#include "../item.qh"
+CLASS(Label, 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));
+	METHOD(Label, toString, string(entity));
+	METHOD(Label, recalcPositionWithText, void(entity, string));
+	ATTRIB(Label, isBold, float, 0)
+	ATTRIB(Label, text, string, string_null)
+	ATTRIB(Label, currentText, string, string_null)
+	ATTRIB(Label, fontSize, float, 8)
+	ATTRIB(Label, align, float, 0.5)
+	ATTRIB(Label, allowCut, float, 0)
+	ATTRIB(Label, allowColors, float, 0)
+	ATTRIB(Label, keepspaceLeft, float, 0) // for use by subclasses (radiobuttons for example)
+	ATTRIB(Label, keepspaceRight, float, 0)
+	ATTRIB(Label, marginLeft, float, 0)    // alternate way to specify keepspace* (in characters from the font)
+	ATTRIB(Label, marginRight, float, 0)
+	ATTRIB(Label, realFontSize, vector, '0 0 0')
+	ATTRIB(Label, realOrigin, vector, '0 0 0')
+	ATTRIB(Label, alpha, float, 0.7)
+	ATTRIB(Label, colorL, vector, SKINCOLOR_TEXT)
+	ATTRIB(Label, disabled, float, 0)
+	ATTRIB(Label, disabledAlpha, float, 0.3)
+	ATTRIB(Label, textEntity, entity, NULL)
+	ATTRIB(Label, allowWrap, float, 0)
+	ATTRIB(Label, recalcPos, float, 0)
+	ATTRIB(Label, condenseFactor, float, 1)
+	ATTRIB(Label, overrideRealOrigin, vector, '0 0 0')
+	ATTRIB(Label, overrideCondenseFactor, float, 0)
+ENDCLASS(Label)
diff --git a/qcsrc/menu/item/listbox.qc b/qcsrc/menu/item/listbox.qc
index 10cc934bf..d9d63ab8c 100644
--- a/qcsrc/menu/item/listbox.qc
+++ b/qcsrc/menu/item/listbox.qc
@@ -1,93 +1,5 @@
 #include "listbox.qh"
-#ifndef ITEM_LISTBOX_H
-	#define ITEM_LISTBOX_H
-	#include "../item.qc"
-	CLASS(ListBox, Item)
-		METHOD(ListBox, resizeNotify, void(entity, vector, vector, vector, vector));
-		METHOD(ListBox, configureListBox, void(entity, float, float));
-		METHOD(ListBox, draw, void(entity));
-		METHOD(ListBox, keyDown, float(entity, float, float, float));
-		METHOD(ListBox, mouseMove, float(entity, vector));
-		METHOD(ListBox, mousePress, float(entity, vector));
-		METHOD(ListBox, mouseDrag, float(entity, vector));
-		METHOD(ListBox, mouseRelease, float(entity, vector));
-		METHOD(ListBox, focusLeave, void(entity));
-		ATTRIB(ListBox, focusable, float, 1)
-		ATTRIB(ListBox, focusedItem, int, -1)
-		ATTRIB(ListBox, focusedItemAlpha, float, 0.3)
-		METHOD(ListBox, setFocusedItem, void(entity, int));
-		ATTRIB(ListBox, mouseMoveOffset, float, -1)  // let know where the cursor is when the list scrolls without moving the cursor
-		ATTRIB(ListBox, allowFocusSound, float, 1)
-		ATTRIB(ListBox, selectedItem, int, 0)
-		ATTRIB(ListBox, size, vector, '0 0 0')
-		ATTRIB(ListBox, origin, vector, '0 0 0')
-		ATTRIB(ListBox, scrollPos, float, 0)  // measured in window heights, fixed when needed
-		ATTRIB(ListBox, scrollPosTarget, float, 0)
-		METHOD(ListBox, isScrolling, bool(entity));
-		ATTRIB(ListBox, needScrollToItem, float, -1)
-		METHOD(ListBox, scrollToItem, void(entity, int));
-		ATTRIB(ListBox, previousValue, float, 0)
-		ATTRIB(ListBox, pressed, float, 0)  // 0 = normal, 1 = scrollbar dragging, 2 = item dragging, 3 = released
-		ATTRIB(ListBox, pressOffset, float, 0)
 
-		METHOD(ListBox, updateControlTopBottom, void(entity));
-		ATTRIB(ListBox, controlTop, float, 0)
-		ATTRIB(ListBox, controlBottom, float, 0)
-		ATTRIB(ListBox, controlWidth, float, 0)
-		ATTRIB(ListBox, dragScrollPos, vector, '0 0 0')
-		ATTRIB(ListBox, selectionDoesntMatter, bool, false) // improves scrolling by keys for lists that don't need to show an active selection
-
-		ATTRIB(ListBox, src, string, string_null)           // scrollbar
-		ATTRIB(ListBox, color, vector, '1 1 1')
-		ATTRIB(ListBox, color2, vector, '1 1 1')
-		ATTRIB(ListBox, colorC, vector, '1 1 1')
-		ATTRIB(ListBox, colorF, vector, '1 1 1')
-		ATTRIB(ListBox, tolerance, vector, '0 0 0') // drag tolerance
-		ATTRIB(ListBox, scrollbarWidth, float, 0)   // pixels
-		ATTRIB(ListBox, nItems, float, 42) // FIXME: why?!?
-		ATTRIB(ListBox, itemHeight, float, 0)
-		ATTRIB(ListBox, colorBG, vector, '0 0 0')
-		ATTRIB(ListBox, alphaBG, float, 0)
-
-		ATTRIB(ListBox, lastClickedItem, float, -1)
-		ATTRIB(ListBox, lastClickedTime, float, 0)
-
-		METHOD(ListBox, drawListBoxItem, void(entity, int, vector, bool, bool)); // item number, width/height, isSelected, isFocused
-		METHOD(ListBox, clickListBoxItem, void(entity, float, vector));          // item number, relative clickpos
-		METHOD(ListBox, doubleClickListBoxItem, void(entity, float, vector));    // item number, relative clickpos
-		METHOD(ListBox, setSelected, void(entity, float));
-		METHOD(ListBox, focusedItemChangeNotify, void(entity));
-
-		METHOD(ListBox, getLastFullyVisibleItemAtScrollPos, float(entity, float));
-		METHOD(ListBox, getFirstFullyVisibleItemAtScrollPos, float(entity, float));
-
-		// NOTE: override these four methods if you want variable sized list items
-		METHOD(ListBox, getTotalHeight, float(entity));
-		METHOD(ListBox, getItemAtPos, float(entity, float));
-		METHOD(ListBox, getItemStart, float(entity, float));
-		METHOD(ListBox, getItemHeight, float(entity, float));
-		// NOTE: if getItemAt* are overridden, it may make sense to cache the
-		// start and height of the last item returned by getItemAtPos and fast
-		// track returning their properties for getItemStart and getItemHeight.
-		// The "hot" code path calls getItemAtPos first, then will query
-		// getItemStart and getItemHeight on it soon.
-		// When overriding, the following consistency rules must hold:
-		// getTotalHeight() == SUM(getItemHeight(i), i, 0, me.nItems-1)
-		// getItemStart(i+1) == getItemStart(i) + getItemHeight(i)
-		//   for 0 <= i < me.nItems-1
-		// getItemStart(0) == 0
-		// getItemStart(getItemAtPos(p)) <= p
-		//   if p >= 0
-		// getItemAtPos(p) == 0
-		//   if p < 0
-		// getItemStart(getItemAtPos(p)) + getItemHeight(getItemAtPos(p)) > p
-		//   if p < getTotalHeigt()
-		// getItemAtPos(p) == me.nItems - 1
-		//   if p >= getTotalHeight()
-	ENDCLASS(ListBox)
-#endif
-
-#ifdef IMPLEMENTATION
 	bool ListBox_isScrolling(entity me)
 	{
 		return me.scrollPos != me.scrollPosTarget;
@@ -503,4 +415,3 @@
 	{
 		draw_Text('0 0 0', sprintf(_("Item %d"), i), eX * (8 / absSize.x) + eY * (8 / absSize.y), (isSelected ? '0 1 0' : '1 1 1'), 1, 0);
 	}
-#endif
diff --git a/qcsrc/menu/item/listbox.qh b/qcsrc/menu/item/listbox.qh
index 6f70f09be..461125e30 100644
--- a/qcsrc/menu/item/listbox.qh
+++ b/qcsrc/menu/item/listbox.qh
@@ -1 +1,87 @@
 #pragma once
+
+#include "../item.qh"
+CLASS(ListBox, Item)
+	METHOD(ListBox, resizeNotify, void(entity, vector, vector, vector, vector));
+	METHOD(ListBox, configureListBox, void(entity, float, float));
+	METHOD(ListBox, draw, void(entity));
+	METHOD(ListBox, keyDown, float(entity, float, float, float));
+	METHOD(ListBox, mouseMove, float(entity, vector));
+	METHOD(ListBox, mousePress, float(entity, vector));
+	METHOD(ListBox, mouseDrag, float(entity, vector));
+	METHOD(ListBox, mouseRelease, float(entity, vector));
+	METHOD(ListBox, focusLeave, void(entity));
+	ATTRIB(ListBox, focusable, float, 1)
+	ATTRIB(ListBox, focusedItem, int, -1)
+	ATTRIB(ListBox, focusedItemAlpha, float, 0.3)
+	METHOD(ListBox, setFocusedItem, void(entity, int));
+	ATTRIB(ListBox, mouseMoveOffset, float, -1)  // let know where the cursor is when the list scrolls without moving the cursor
+	ATTRIB(ListBox, allowFocusSound, float, 1)
+	ATTRIB(ListBox, selectedItem, int, 0)
+	ATTRIB(ListBox, size, vector, '0 0 0')
+	ATTRIB(ListBox, origin, vector, '0 0 0')
+	ATTRIB(ListBox, scrollPos, float, 0)  // measured in window heights, fixed when needed
+	ATTRIB(ListBox, scrollPosTarget, float, 0)
+	METHOD(ListBox, isScrolling, bool(entity));
+	ATTRIB(ListBox, needScrollToItem, float, -1)
+	METHOD(ListBox, scrollToItem, void(entity, int));
+	ATTRIB(ListBox, previousValue, float, 0)
+	ATTRIB(ListBox, pressed, float, 0)  // 0 = normal, 1 = scrollbar dragging, 2 = item dragging, 3 = released
+	ATTRIB(ListBox, pressOffset, float, 0)
+
+	METHOD(ListBox, updateControlTopBottom, void(entity));
+	ATTRIB(ListBox, controlTop, float, 0)
+	ATTRIB(ListBox, controlBottom, float, 0)
+	ATTRIB(ListBox, controlWidth, float, 0)
+	ATTRIB(ListBox, dragScrollPos, vector, '0 0 0')
+	ATTRIB(ListBox, selectionDoesntMatter, bool, false) // improves scrolling by keys for lists that don't need to show an active selection
+
+	ATTRIB(ListBox, src, string, string_null)           // scrollbar
+	ATTRIB(ListBox, color, vector, '1 1 1')
+	ATTRIB(ListBox, color2, vector, '1 1 1')
+	ATTRIB(ListBox, colorC, vector, '1 1 1')
+	ATTRIB(ListBox, colorF, vector, '1 1 1')
+	ATTRIB(ListBox, tolerance, vector, '0 0 0') // drag tolerance
+	ATTRIB(ListBox, scrollbarWidth, float, 0)   // pixels
+	ATTRIB(ListBox, nItems, float, 42)          // FIXME: why?!?
+	ATTRIB(ListBox, itemHeight, float, 0)
+    ATTRIB(ListBox, itemAbsSize, vector, '0 0 0')
+	ATTRIB(ListBox, colorBG, vector, '0 0 0')
+	ATTRIB(ListBox, alphaBG, float, 0)
+
+	ATTRIB(ListBox, lastClickedItem, float, -1)
+	ATTRIB(ListBox, lastClickedTime, float, 0)
+
+	METHOD(ListBox, drawListBoxItem, void(entity, int, vector, bool, bool)); // item number, width/height, isSelected, isFocused
+	METHOD(ListBox, clickListBoxItem, void(entity, float, vector));          // item number, relative clickpos
+	METHOD(ListBox, doubleClickListBoxItem, void(entity, float, vector));    // item number, relative clickpos
+	METHOD(ListBox, setSelected, void(entity, float));
+	METHOD(ListBox, focusedItemChangeNotify, void(entity));
+
+	METHOD(ListBox, getLastFullyVisibleItemAtScrollPos, float(entity, float));
+	METHOD(ListBox, getFirstFullyVisibleItemAtScrollPos, float(entity, float));
+
+	// NOTE: override these four methods if you want variable sized list items
+	METHOD(ListBox, getTotalHeight, float(entity));
+	METHOD(ListBox, getItemAtPos, float(entity, float));
+	METHOD(ListBox, getItemStart, float(entity, float));
+	METHOD(ListBox, getItemHeight, float(entity, float));
+	// NOTE: if getItemAt* are overridden, it may make sense to cache the
+	// start and height of the last item returned by getItemAtPos and fast
+	// track returning their properties for getItemStart and getItemHeight.
+	// The "hot" code path calls getItemAtPos first, then will query
+	// getItemStart and getItemHeight on it soon.
+	// When overriding, the following consistency rules must hold:
+	// getTotalHeight() == SUM(getItemHeight(i), i, 0, me.nItems-1)
+	// getItemStart(i+1) == getItemStart(i) + getItemHeight(i)
+	//   for 0 <= i < me.nItems-1
+	// getItemStart(0) == 0
+	// getItemStart(getItemAtPos(p)) <= p
+	//   if p >= 0
+	// getItemAtPos(p) == 0
+	//   if p < 0
+	// getItemStart(getItemAtPos(p)) + getItemHeight(getItemAtPos(p)) > p
+	//   if p < getTotalHeigt()
+	// getItemAtPos(p) == me.nItems - 1
+	//   if p >= getTotalHeight()
+ENDCLASS(ListBox)
diff --git a/qcsrc/menu/item/modalcontroller.qc b/qcsrc/menu/item/modalcontroller.qc
index 0dd6fe8ef..660431d60 100644
--- a/qcsrc/menu/item/modalcontroller.qc
+++ b/qcsrc/menu/item/modalcontroller.qc
@@ -1,56 +1,6 @@
 #include "modalcontroller.qh"
-#ifndef ITEM_MODALCONTROLLER_H
-	#define ITEM_MODALCONTROLLER_H
-	#include "container.qc"
-	CLASS(ModalController, Container)
-		METHOD(ModalController, resizeNotify, void(entity, vector, vector, vector, vector));
-		METHOD(ModalController, draw, void(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)
-
-	.entity tabSelectingButton;
-	.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 DialogOpenButton_Click_withCoords(entity button, entity tab, vector theOrigin, vector theSize);
-	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);
+#include "button.qh"
 
 	.vector ModalController_initialSize;
 	.vector ModalController_initialOrigin;
@@ -286,4 +236,3 @@
 			}
 		}  // just alpha fade out (factor increases and decreases alpha)
 	}
-#endif
diff --git a/qcsrc/menu/item/modalcontroller.qh b/qcsrc/menu/item/modalcontroller.qh
index 6f70f09be..27faaa86b 100644
--- a/qcsrc/menu/item/modalcontroller.qh
+++ b/qcsrc/menu/item/modalcontroller.qh
@@ -1 +1,50 @@
 #pragma once
+
+// 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);
+
+#include "container.qh"
+CLASS(ModalController, Container)
+	METHOD(ModalController, resizeNotify, void(entity, vector, vector, vector, vector));
+	METHOD(ModalController, draw, void(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)
+
+.float ModalController_state;
+.entity tabSelectingButton;
+.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 DialogOpenButton_Click_withCoords(entity button, entity tab, vector theOrigin, vector theSize);
+void DialogCloseButton_Click(entity button, entity tab); // assumes a button has set the above fields to the tab to close
diff --git a/qcsrc/menu/item/nexposee.qc b/qcsrc/menu/item/nexposee.qc
index ba786597f..3e3575f4f 100644
--- a/qcsrc/menu/item/nexposee.qc
+++ b/qcsrc/menu/item/nexposee.qc
@@ -1,54 +1,5 @@
 #include "nexposee.qh"
-#ifndef ITEM_NEXPOSEE_H
-	#define ITEM_NEXPOSEE_H
-	#include "container.qc"
-	CLASS(Nexposee, 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, focusEnter, void(entity));
-		METHOD(Nexposee, close, void(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')
-		METHOD(Nexposee, pullNexposee, void(entity, entity, vector));
-	ENDCLASS(Nexposee)
-
-	void ExposeeCloseButton_Click(entity button, entity other);  // un-exposees the current state
-
-// animation states:
-//   0 = thumbnails seen
-//   1 = zooming in
-//   2 = zoomed in
-//   3 = zooming out
-// animation factor: 0 = minimum theSize, 1 = maximum theSize
-	.vector Nexposee_initialSize;
-	.vector Nexposee_initialFontScale;
-	.vector Nexposee_initialOrigin;
-	.float Nexposee_initialAlpha;
-
-	.vector Nexposee_smallSize;
-	.vector Nexposee_smallOrigin;
-	.float Nexposee_smallAlpha;
-	.float Nexposee_mediumAlpha;
-	.vector Nexposee_scaleCenter;
-	.vector Nexposee_align;
-	.float Nexposee_animationFactor;
-
-#endif
-
-#ifdef IMPLEMENTATION
 	void Nexposee_close(entity me)
 	{
 		// user must override this
@@ -344,4 +295,3 @@
 	{
 		other.Nexposee_align = theAlign;
 	}
-#endif
diff --git a/qcsrc/menu/item/nexposee.qh b/qcsrc/menu/item/nexposee.qh
index 6f70f09be..2d8e3ec49 100644
--- a/qcsrc/menu/item/nexposee.qh
+++ b/qcsrc/menu/item/nexposee.qh
@@ -1 +1,46 @@
 #pragma once
+
+#include "container.qh"
+CLASS(Nexposee, 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, focusEnter, void(entity));
+	METHOD(Nexposee, close, void(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')
+	METHOD(Nexposee, pullNexposee, void(entity, entity, vector));
+ENDCLASS(Nexposee)
+
+void ExposeeCloseButton_Click(entity button, entity other);  // un-exposees the current state
+
+// animation states:
+//   0 = thumbnails seen
+//   1 = zooming in
+//   2 = zoomed in
+//   3 = zooming out
+// animation factor: 0 = minimum theSize, 1 = maximum theSize
+.vector Nexposee_initialSize;
+.vector Nexposee_initialFontScale;
+.vector Nexposee_initialOrigin;
+.float Nexposee_initialAlpha;
+
+.vector Nexposee_smallSize;
+.vector Nexposee_smallOrigin;
+.float Nexposee_smallAlpha;
+.float Nexposee_mediumAlpha;
+.vector Nexposee_scaleCenter;
+.vector Nexposee_align;
+.float Nexposee_animationFactor;
diff --git a/qcsrc/menu/item/radiobutton.qc b/qcsrc/menu/item/radiobutton.qc
index e707f773d..00dcb680a 100644
--- a/qcsrc/menu/item/radiobutton.qc
+++ b/qcsrc/menu/item/radiobutton.qc
@@ -1,18 +1,5 @@
 #include "radiobutton.qh"
-#ifndef ITEM_RADIOBUTTON_H
-	#define ITEM_RADIOBUTTON_H
-	#include "checkbox.qc"
-	void RadioButton_Click(entity me, entity other);
-	CLASS(RadioButton, CheckBox)
-		METHOD(RadioButton, configureRadioButton, void(entity, string, float, string, float, float));
-		ATTRIB(RadioButton, checked, float, 0)
-		ATTRIB(RadioButton, group, float, 0)
-		ATTRIB(RadioButton, allowDeselect, float, 0)
-		ATTRIB(RadioButton, onClick, void(entity, entity), RadioButton_Click)
-	ENDCLASS(RadioButton)
-#endif
 
-#ifdef IMPLEMENTATION
 	void RadioButton_configureRadioButton(entity me, string txt, float sz, string gfx, float theGroup, float doAllowDeselect)
 	{
 		me.configureCheckBox(me, txt, sz, gfx);
@@ -35,4 +22,3 @@
 			me.setChecked(me, 1);
 		}
 	}
-#endif
diff --git a/qcsrc/menu/item/radiobutton.qh b/qcsrc/menu/item/radiobutton.qh
index 6f70f09be..53aa7ff2e 100644
--- a/qcsrc/menu/item/radiobutton.qh
+++ b/qcsrc/menu/item/radiobutton.qh
@@ -1 +1,11 @@
 #pragma once
+
+#include "checkbox.qh"
+void RadioButton_Click(entity me, entity other);
+CLASS(RadioButton, CheckBox)
+	METHOD(RadioButton, configureRadioButton, void(entity, string, float, string, float, float));
+	ATTRIB(RadioButton, checked, float, 0)
+	ATTRIB(RadioButton, group, float, 0)
+	ATTRIB(RadioButton, allowDeselect, float, 0)
+	ATTRIB(RadioButton, onClick, void(entity, entity), RadioButton_Click)
+ENDCLASS(RadioButton)
diff --git a/qcsrc/menu/item/slider.qc b/qcsrc/menu/item/slider.qc
index 348addbb8..2e89bb68e 100644
--- a/qcsrc/menu/item/slider.qc
+++ b/qcsrc/menu/item/slider.qc
@@ -1,57 +1,10 @@
 #include "slider.qh"
-// Note:
-//   to use this, you FIRST call configureSliderVisuals, then configureSliderValues
-#ifndef ITEM_SLIDER_H
-	#define ITEM_SLIDER_H
-	#include "label.qc"
-	CLASS(Slider, Label)
-		METHOD(Slider, resizeNotify, void(entity, vector, vector, vector, vector));
-		METHOD(Slider, configureSliderVisuals, void(entity, float, float, float, string));
-		METHOD(Slider, configureSliderValues, void(entity, float, float, float, float, float, float));
-		METHOD(Slider, draw, void(entity));
-		METHOD(Slider, keyDown, float(entity, float, float, float));
-		METHOD(Slider, keyUp, float(entity, float, float, float));
-		METHOD(Slider, mousePress, float(entity, vector));
-		METHOD(Slider, mouseDrag, float(entity, vector));
-		METHOD(Slider, mouseRelease, float(entity, vector));
-		METHOD(Slider, valueToText, string(entity, float));
-		METHOD(Slider, toString, string(entity));
-		METHOD(Slider, setValue_allowAnim, void(entity, float, bool));
-		METHOD(Slider, setValue_noAnim, void(entity, float));
-		METHOD(Slider, setValue, void(entity, float));
-		METHOD(Slider, setSliderValue, void(entity, float));
-		METHOD(Slider, showNotify, void(entity));
-		ATTRIB(Slider, src, string, string_null)
-		ATTRIB(Slider, focusable, float, 1)
-		ATTRIB(Slider, allowFocusSound, float, 1)
-		ATTRIB(Slider, value, float, 0)
-		ATTRIB(Slider, animated, float, 1)
-		ATTRIB(Slider, sliderValue, float, 0)
-		ATTRIB(Slider, sliderAnim, entity, NULL)
-		ATTRIB(Slider, valueMin, float, 0)
-		ATTRIB(Slider, valueMax, float, 0)
-		ATTRIB(Slider, valueStep, float, 0)
-		ATTRIB(Slider, valueDigits, float, 0)
-		ATTRIB(Slider, valueKeyStep, float, 0)
-		ATTRIB(Slider, valuePageStep, float, 0)
-		ATTRIB(Slider, valueDisplayMultiplier, float, 1.0)
-		ATTRIB(Slider, textSpace, float, 0)
-		ATTRIB(Slider, controlWidth, float, 0)
-		ATTRIB(Slider, pressed, float, 0)
-		ATTRIB(Slider, pressOffset, float, 0)
-		ATTRIB(Slider, previousValue, float, 0)
-		ATTRIB(Slider, tolerance, vector, '0 0 0')
-		ATTRIB(Slider, disabled, float, 0)
-		ATTRIB(Slider, color, vector, '1 1 1')
-		ATTRIB(Slider, color2, vector, '1 1 1')
-		ATTRIB(Slider, colorD, vector, '1 1 1')
-		ATTRIB(Slider, colorC, vector, '1 1 1')
-		ATTRIB(Slider, colorF, vector, '1 1 1')
-		ATTRIB(Slider, disabledAlpha, float, 0.3)
-	ENDCLASS(Slider)
-#endif
 
-#ifdef IMPLEMENTATION
+#include "../anim/easing.qh"
+#include "../anim/animhost.qh"
+
+.entity applyButton;
+
 	void Slider_setValue_allowAnim(entity me, float val, bool allowAnim)
 	{
 		if (allowAnim && me.animated)
@@ -309,4 +262,3 @@
 		SUPER(Slider).draw(me);
 		me.text = string_null;  // TEMPSTRING!
 	}
-#endif
diff --git a/qcsrc/menu/item/slider.qh b/qcsrc/menu/item/slider.qh
index 6f70f09be..f5e8fd496 100644
--- a/qcsrc/menu/item/slider.qh
+++ b/qcsrc/menu/item/slider.qh
@@ -1 +1,50 @@
 #pragma once
+
+// Note:
+//   to use this, you FIRST call configureSliderVisuals, then configureSliderValues
+#include "label.qh"
+CLASS(Slider, Label)
+	METHOD(Slider, resizeNotify, void(entity, vector, vector, vector, vector));
+	METHOD(Slider, configureSliderVisuals, void(entity, float, float, float, string));
+	METHOD(Slider, configureSliderValues, void(entity, float, float, float, float, float, float));
+	METHOD(Slider, draw, void(entity));
+	METHOD(Slider, keyDown, float(entity, float, float, float));
+	METHOD(Slider, keyUp, float(entity, float, float, float));
+	METHOD(Slider, mousePress, float(entity, vector));
+	METHOD(Slider, mouseDrag, float(entity, vector));
+	METHOD(Slider, mouseRelease, float(entity, vector));
+	METHOD(Slider, valueToText, string(entity, float));
+	METHOD(Slider, toString, string(entity));
+	METHOD(Slider, setValue_allowAnim, void(entity, float, bool));
+	METHOD(Slider, setValue_noAnim, void(entity, float));
+	METHOD(Slider, setValue, void(entity, float));
+	METHOD(Slider, setSliderValue, void(entity, float));
+	METHOD(Slider, showNotify, void(entity));
+	ATTRIB(Slider, src, string, string_null)
+	ATTRIB(Slider, focusable, float, 1)
+	ATTRIB(Slider, allowFocusSound, float, 1)
+	ATTRIB(Slider, value, float, 0)
+	ATTRIB(Slider, animated, float, 1)
+	ATTRIB(Slider, sliderValue, float, 0)
+	ATTRIB(Slider, sliderAnim, entity, NULL)
+	ATTRIB(Slider, valueMin, float, 0)
+	ATTRIB(Slider, valueMax, float, 0)
+	ATTRIB(Slider, valueStep, float, 0)
+	ATTRIB(Slider, valueDigits, float, 0)
+	ATTRIB(Slider, valueKeyStep, float, 0)
+	ATTRIB(Slider, valuePageStep, float, 0)
+	ATTRIB(Slider, valueDisplayMultiplier, float, 1.0)
+	ATTRIB(Slider, textSpace, float, 0)
+	ATTRIB(Slider, controlWidth, float, 0)
+	ATTRIB(Slider, pressed, float, 0)
+	ATTRIB(Slider, pressOffset, float, 0)
+	ATTRIB(Slider, previousValue, float, 0)
+	ATTRIB(Slider, tolerance, vector, '0 0 0')
+	ATTRIB(Slider, disabled, float, 0)
+	ATTRIB(Slider, color, vector, '1 1 1')
+	ATTRIB(Slider, color2, vector, '1 1 1')
+	ATTRIB(Slider, colorD, vector, '1 1 1')
+	ATTRIB(Slider, colorC, vector, '1 1 1')
+	ATTRIB(Slider, colorF, vector, '1 1 1')
+	ATTRIB(Slider, disabledAlpha, float, 0.3)
+ENDCLASS(Slider)
diff --git a/qcsrc/menu/item/tab.qc b/qcsrc/menu/item/tab.qc
index 28a9c71d4..72bcaadbb 100644
--- a/qcsrc/menu/item/tab.qc
+++ b/qcsrc/menu/item/tab.qc
@@ -1,31 +1 @@
 #include "tab.qh"
-#ifndef ITEM_TAB_H
-	#define ITEM_TAB_H
-	#include "dialog.qc"
-	CLASS(Tab, Dialog)
-		ATTRIB(Tab, isTabRoot, float, 0)
-		ATTRIB(Tab, closable, float, 0)
-		ATTRIB(Tab, rootDialog, float, 0)
-		ATTRIB(Tab, title, string, string_null)
-		ATTRIB(Tab, titleFontSize, float, 0)  // pixels
-
-		// still to be customized
-		ATTRIB(Tab, intendedWidth, float, 0)
-		ATTRIB(Tab, rows, float, 3)
-		ATTRIB(Tab, columns, float, 2)
-
-		ATTRIB(Tab, marginTop, float, 0)     // pixels
-		ATTRIB(Tab, marginBottom, float, 0)  // pixels
-		ATTRIB(Tab, marginLeft, float, 0)    // pixels
-		ATTRIB(Tab, marginRight, float, 0)   // pixels
-		ATTRIB(Tab, columnSpacing, float, 0) // pixels
-		ATTRIB(Tab, rowSpacing, float, 0)    // pixels
-		ATTRIB(Tab, rowHeight, float, 0)     // pixels
-		ATTRIB(Tab, titleHeight, float, 0)   // pixels
-
-		ATTRIB(Tab, backgroundImage, string, string_null)
-	ENDCLASS(Tab)
-#endif
-
-#ifdef IMPLEMENTATION
-#endif
diff --git a/qcsrc/menu/item/tab.qh b/qcsrc/menu/item/tab.qh
index 6f70f09be..e9ba81a90 100644
--- a/qcsrc/menu/item/tab.qh
+++ b/qcsrc/menu/item/tab.qh
@@ -1 +1,26 @@
 #pragma once
+
+#include "dialog.qh"
+CLASS(Tab, Dialog)
+	ATTRIB(Tab, isTabRoot, float, 0)
+	ATTRIB(Tab, closable, float, 0)
+	ATTRIB(Tab, rootDialog, float, 0)
+	ATTRIB(Tab, title, string, string_null)
+	ATTRIB(Tab, titleFontSize, float, 0)  // pixels
+
+	// still to be customized
+	ATTRIB(Tab, intendedWidth, float, 0)
+	ATTRIB(Tab, rows, float, 3)
+	ATTRIB(Tab, columns, float, 2)
+
+	ATTRIB(Tab, marginTop, float, 0)     // pixels
+	ATTRIB(Tab, marginBottom, float, 0)  // pixels
+	ATTRIB(Tab, marginLeft, float, 0)    // pixels
+	ATTRIB(Tab, marginRight, float, 0)   // pixels
+	ATTRIB(Tab, columnSpacing, float, 0) // pixels
+	ATTRIB(Tab, rowSpacing, float, 0)    // pixels
+	ATTRIB(Tab, rowHeight, float, 0)     // pixels
+	ATTRIB(Tab, titleHeight, float, 0)   // pixels
+
+	ATTRIB(Tab, backgroundImage, string, string_null)
+ENDCLASS(Tab)
diff --git a/qcsrc/menu/item/textslider.qc b/qcsrc/menu/item/textslider.qc
index 5d9d6b886..01f89fc4d 100644
--- a/qcsrc/menu/item/textslider.qc
+++ b/qcsrc/menu/item/textslider.qc
@@ -1,27 +1,5 @@
 #include "textslider.qh"
-// Note:
-//   to use this, you FIRST call configureSliderVisuals, then multiple times addValue, then configureTextSlider
-#ifndef ITEM_TEXTSLIDER_H
-	#define ITEM_TEXTSLIDER_H
-	#include "slider.qc"
-	CLASS(TextSlider, Slider)
-		METHOD(TextSlider, valueToText, string(entity, float));
-		METHOD(TextSlider, valueToIdentifier, string(entity, float));
-		METHOD(TextSlider, setValueFromIdentifier_allowAnim, void(entity, string, bool));
-		METHOD(TextSlider, setValueFromIdentifier_noAnim, void(entity, string));
-		METHOD(TextSlider, setValueFromIdentifier, void(entity, string));
-		METHOD(TextSlider, getIdentifier, string(entity));
-		METHOD(TextSlider, clearValues, void(entity));
-		METHOD(TextSlider, addValue, void(entity, string, string));
-		METHOD(TextSlider, insertValue, void(entity, float, string, string));
-		METHOD(TextSlider, configureTextSliderValues, void(entity, string));
-		ATTRIBARRAY(TextSlider, valueStrings, string, 256)
-		ATTRIBARRAY(TextSlider, valueIdentifiers, string, 256)
-		ATTRIB(TextSlider, nValues, int, 0)
-	ENDCLASS(TextSlider)
-#endif
 
-#ifdef IMPLEMENTATION
 	string TextSlider_valueToIdentifier(entity me, int val)
 	{
 		if (val >= me.nValues) return "custom";
@@ -84,4 +62,3 @@
 		me.configureSliderValues(me, 0, 0, me.nValues - 1, 1, 1, 1);
 		me.setValueFromIdentifier_noAnim(me, theDefault);
 	}
-#endif
diff --git a/qcsrc/menu/item/textslider.qh b/qcsrc/menu/item/textslider.qh
index 6f70f09be..0703942f9 100644
--- a/qcsrc/menu/item/textslider.qh
+++ b/qcsrc/menu/item/textslider.qh
@@ -1 +1,20 @@
 #pragma once
+
+// Note:
+//   to use this, you FIRST call configureSliderVisuals, then multiple times addValue, then configureTextSlider
+#include "slider.qh"
+CLASS(TextSlider, Slider)
+	METHOD(TextSlider, valueToText, string(entity, float));
+	METHOD(TextSlider, valueToIdentifier, string(entity, float));
+	METHOD(TextSlider, setValueFromIdentifier_allowAnim, void(entity, string, bool));
+	METHOD(TextSlider, setValueFromIdentifier_noAnim, void(entity, string));
+	METHOD(TextSlider, setValueFromIdentifier, void(entity, string));
+	METHOD(TextSlider, getIdentifier, string(entity));
+	METHOD(TextSlider, clearValues, void(entity));
+	METHOD(TextSlider, addValue, void(entity, string, string));
+	METHOD(TextSlider, insertValue, void(entity, float, string, string));
+	METHOD(TextSlider, configureTextSliderValues, void(entity, string));
+	ATTRIBARRAY(TextSlider, valueStrings, string, 256)
+	ATTRIBARRAY(TextSlider, valueIdentifiers, string, 256)
+	ATTRIB(TextSlider, nValues, int, 0)
+ENDCLASS(TextSlider)
diff --git a/qcsrc/menu/menu.qc b/qcsrc/menu/menu.qc
index 2617634af..70c8aedc4 100644
--- a/qcsrc/menu/menu.qc
+++ b/qcsrc/menu/menu.qc
@@ -1,9 +1,24 @@
 #include "menu.qh"
-#include "classes.qc"
+
+#include "item.qh"
+
+#include "anim/animhost.qh"
+
+#include "item/dialog.qh"
+#include "item/listbox.qh"
+#include "item/nexposee.qh"
+
+#include "xonotic/commandbutton.qh"
+#include "xonotic/mainwindow.qh"
+#include "xonotic/serverlist.qh"
+#include "xonotic/slider_resolution.qh"
+
+.string cvarName;
+
 #include "xonotic/util.qh"
 
 #include "../common/items/all.qh"
-#include "../common/weapons/all.qh"
+#include <common/weapons/all.qh>
 #include "../common/mapinfo.qh"
 #include "../common/mutators/base.qh"
 
diff --git a/qcsrc/menu/progs.inc b/qcsrc/menu/progs.inc
index 621c1a489..b032f6e90 100644
--- a/qcsrc/menu/progs.inc
+++ b/qcsrc/menu/progs.inc
@@ -2,16 +2,17 @@
 
 #define world NULL
 
-#include "classes.qc"
+#include "classes.inc"
 
 #include "draw.qc"
 #include "menu.qc"
 
-#include "command/all.qc"
+#include <common/command/all.qc>
+#include "command/menu_cmd.qc"
 
 #include "xonotic/util.qc"
 
-#include "../common/_all.inc"
+#include <common/_all.inc>
 
 #if BUILD_MOD
 #include "../../mod/menu/progs.inc"
diff --git a/qcsrc/menu/xonotic/bigbutton.qc b/qcsrc/menu/xonotic/bigbutton.qc
index 45990118b..0022aad5a 100644
--- a/qcsrc/menu/xonotic/bigbutton.qc
+++ b/qcsrc/menu/xonotic/bigbutton.qc
@@ -1,16 +1,5 @@
 #include "bigbutton.qh"
-#ifndef BIGBUTTON_H
-#define BIGBUTTON_H
-#include "button.qc"
-CLASS(XonoticBigButton, XonoticButton)
-	METHOD(XonoticBigButton, configureXonoticBigButton, void(entity, string, vector));
-	ATTRIB(XonoticBigButton, image, string, SKINGFX_BUTTON_BIG)
-	ATTRIB(XonoticBigButton, grayImage, string, SKINGFX_BUTTON_BIG_GRAY)
-ENDCLASS(XonoticBigButton)
-entity makeXonoticBigButton(string theText, vector theColor);
-#endif
 
-#ifdef IMPLEMENTATION
 entity makeXonoticBigButton(string theText, vector theColor)
 {
 	entity me;
@@ -23,4 +12,3 @@ void XonoticBigButton_configureXonoticBigButton(entity me, string theText, vecto
 {
 	me.configureXonoticButton(me, theText, theColor, string_null);
 }
-#endif
diff --git a/qcsrc/menu/xonotic/bigbutton.qh b/qcsrc/menu/xonotic/bigbutton.qh
index 6f70f09be..14b6893a7 100644
--- a/qcsrc/menu/xonotic/bigbutton.qh
+++ b/qcsrc/menu/xonotic/bigbutton.qh
@@ -1 +1,9 @@
 #pragma once
+
+#include "button.qh"
+CLASS(XonoticBigButton, XonoticButton)
+	METHOD(XonoticBigButton, configureXonoticBigButton, void(entity, string, vector));
+	ATTRIB(XonoticBigButton, image, string, SKINGFX_BUTTON_BIG)
+	ATTRIB(XonoticBigButton, grayImage, string, SKINGFX_BUTTON_BIG_GRAY)
+ENDCLASS(XonoticBigButton)
+entity makeXonoticBigButton(string theText, vector theColor);
diff --git a/qcsrc/menu/xonotic/bigcommandbutton.qc b/qcsrc/menu/xonotic/bigcommandbutton.qc
index d453cb119..a6f8615de 100644
--- a/qcsrc/menu/xonotic/bigcommandbutton.qc
+++ b/qcsrc/menu/xonotic/bigcommandbutton.qc
@@ -1,17 +1,5 @@
 #include "bigcommandbutton.qh"
-#ifndef BIGCOMMANDBUTTON_H
-#define BIGCOMMANDBUTTON_H
-#include "commandbutton.qc"
-CLASS(XonoticBigCommandButton, XonoticCommandButton)
-	METHOD(XonoticBigCommandButton, configureXonoticBigCommandButton, void(entity, string, vector, string, float, string));
-	ATTRIB(XonoticBigCommandButton, image, string, SKINGFX_BUTTON_BIG)
-	ATTRIB(XonoticBigCommandButton, grayImage, string, SKINGFX_BUTTON_BIG_GRAY)
-ENDCLASS(XonoticBigCommandButton)
-entity makeXonoticBigCommandButton_T(string theText, vector theColor, string theCommand, float closesMenu, string theTooltip);
-entity makeXonoticBigCommandButton(string theText, vector theColor, string theCommand, float closesMenu);
-#endif
 
-#ifdef IMPLEMENTATION
 entity makeXonoticBigCommandButton_T(string theText, vector theColor, string theCommand, float theFlags, string theTooltip)
 {
 	entity me;
@@ -28,4 +16,3 @@ void XonoticBigCommandButton_configureXonoticBigCommandButton(entity me, string
 {
 	me.configureXonoticCommandButton(me, theText, theColor, theCommand, theFlags, theTooltip);
 }
-#endif
diff --git a/qcsrc/menu/xonotic/bigcommandbutton.qh b/qcsrc/menu/xonotic/bigcommandbutton.qh
index 6f70f09be..4713fa370 100644
--- a/qcsrc/menu/xonotic/bigcommandbutton.qh
+++ b/qcsrc/menu/xonotic/bigcommandbutton.qh
@@ -1 +1,10 @@
 #pragma once
+
+#include "commandbutton.qh"
+CLASS(XonoticBigCommandButton, XonoticCommandButton)
+	METHOD(XonoticBigCommandButton, configureXonoticBigCommandButton, void(entity, string, vector, string, float, string));
+	ATTRIB(XonoticBigCommandButton, image, string, SKINGFX_BUTTON_BIG)
+	ATTRIB(XonoticBigCommandButton, grayImage, string, SKINGFX_BUTTON_BIG_GRAY)
+ENDCLASS(XonoticBigCommandButton)
+entity makeXonoticBigCommandButton_T(string theText, vector theColor, string theCommand, float closesMenu, string theTooltip);
+entity makeXonoticBigCommandButton(string theText, vector theColor, string theCommand, float closesMenu);
diff --git a/qcsrc/menu/xonotic/button.qc b/qcsrc/menu/xonotic/button.qc
index 6c84c48a4..d86c4a453 100644
--- a/qcsrc/menu/xonotic/button.qc
+++ b/qcsrc/menu/xonotic/button.qc
@@ -1,26 +1,5 @@
 #include "button.qh"
-#ifndef BUTTON_H
-#define BUTTON_H
-#include "../item/button.qc"
-CLASS(XonoticButton, Button)
-	METHOD(XonoticButton, configureXonoticButton, void(entity, string, vector, string));
-	ATTRIB(XonoticButton, fontSize, float, SKINFONTSIZE_NORMAL)
-	ATTRIB(XonoticButton, image, string, SKINGFX_BUTTON)
-	ATTRIB(XonoticButton, grayImage, string, SKINGFX_BUTTON_GRAY)
-	ATTRIB(XonoticButton, color, vector, SKINCOLOR_BUTTON_N)
-	ATTRIB(XonoticButton, colorC, vector, SKINCOLOR_BUTTON_C)
-	ATTRIB(XonoticButton, colorF, vector, SKINCOLOR_BUTTON_F)
-	ATTRIB(XonoticButton, colorD, vector, SKINCOLOR_BUTTON_D)
-	ATTRIB(XonoticButton, alpha, float, SKINALPHA_TEXT)
-	ATTRIB(XonoticButton, disabledAlpha, float, SKINALPHA_DISABLED)
-	ATTRIB(XonoticButton, marginLeft, float, SKINMARGIN_BUTTON) // chars
-	ATTRIB(XonoticButton, marginRight, float, SKINMARGIN_BUTTON) // chars
-ENDCLASS(XonoticButton)
-entity makeXonoticButton_T(string theText, vector theColor, string theTooltip);
-entity makeXonoticButton(string theText, vector theColor);
-#endif
 
-#ifdef IMPLEMENTATION
 entity makeXonoticButton_T(string theText, vector theColor, string theTooltip)
 {
 	entity me;
@@ -48,4 +27,3 @@ void XonoticButton_configureXonoticButton(entity me, string theText, vector theC
 	}
 	setZonedTooltip(me, theTooltip, string_null);
 }
-#endif
diff --git a/qcsrc/menu/xonotic/button.qh b/qcsrc/menu/xonotic/button.qh
index 6f70f09be..c7e85fabe 100644
--- a/qcsrc/menu/xonotic/button.qh
+++ b/qcsrc/menu/xonotic/button.qh
@@ -1 +1,20 @@
 #pragma once
+
+#include "../item/button.qh"
+CLASS(XonoticButton, Button)
+	METHOD(XonoticButton, configureXonoticButton, void(entity, string, vector, string));
+	ATTRIB(XonoticButton, fontSize, float, SKINFONTSIZE_NORMAL)
+	ATTRIB(XonoticButton, image, string, SKINGFX_BUTTON)
+	ATTRIB(XonoticButton, grayImage, string, SKINGFX_BUTTON_GRAY)
+	ATTRIB(XonoticButton, color, vector, SKINCOLOR_BUTTON_N)
+	ATTRIB(XonoticButton, colorC, vector, SKINCOLOR_BUTTON_C)
+	ATTRIB(XonoticButton, colorF, vector, SKINCOLOR_BUTTON_F)
+	ATTRIB(XonoticButton, colorD, vector, SKINCOLOR_BUTTON_D)
+	ATTRIB(XonoticButton, alpha, float, SKINALPHA_TEXT)
+	ATTRIB(XonoticButton, disabledAlpha, float, SKINALPHA_DISABLED)
+	ATTRIB(XonoticButton, marginLeft, float, SKINMARGIN_BUTTON)  // chars
+	ATTRIB(XonoticButton, marginRight, float, SKINMARGIN_BUTTON) // chars
+ENDCLASS(XonoticButton)
+
+entity makeXonoticButton_T(string theText, vector theColor, string theTooltip);
+entity makeXonoticButton(string theText, vector theColor);
diff --git a/qcsrc/menu/xonotic/campaign.qc b/qcsrc/menu/xonotic/campaign.qc
index ae9c8cfec..b6dfc60b0 100644
--- a/qcsrc/menu/xonotic/campaign.qc
+++ b/qcsrc/menu/xonotic/campaign.qc
@@ -1,54 +1,8 @@
 #include "campaign.qh"
-#include <common/campaign_common.qh>
-
-#ifndef CAMPAIGN_H
-#define CAMPAIGN_H
-#include "listbox.qc"
-CLASS(XonoticCampaignList, XonoticListBox)
-	METHOD(XonoticCampaignList, configureXonoticCampaignList, void(entity));
-	ATTRIB(XonoticCampaignList, rowsPerItem, float, 10)
-	METHOD(XonoticCampaignList, draw, void(entity));
-	METHOD(XonoticCampaignList, drawListBoxItem, void(entity, int, vector, bool, bool));
-	METHOD(XonoticCampaignList, doubleClickListBoxItem, void(entity, float, vector));
-	METHOD(XonoticCampaignList, resizeNotify, void(entity, vector, vector, vector, vector));
-	METHOD(XonoticCampaignList, setSelected, void(entity, float));
-	METHOD(XonoticCampaignList, keyDown, float(entity, float, float, float));
-	METHOD(XonoticCampaignList, campaignGo, void(entity, float));
-	METHOD(XonoticCampaignList, destroy, void(entity));
-
-	ATTRIB(XonoticCampaignList, campaignGlob, float, 0)
-	ATTRIB(XonoticCampaignList, realFontSize, vector, '0 0 0')
-	ATTRIB(XonoticCampaignList, columnPreviewOrigin, float, 0)
-	ATTRIB(XonoticCampaignList, columnPreviewSize, float, 0)
-	ATTRIB(XonoticCampaignList, columnNameOrigin, float, 0)
-	ATTRIB(XonoticCampaignList, columnNameSize, float, 0)
-	ATTRIB(XonoticCampaignList, columnCheckMarkOrigin, float, 0)
-	ATTRIB(XonoticCampaignList, columnCheckMarkSize, float, 0)
-	ATTRIB(XonoticCampaignList, checkMarkOrigin, vector, '0 0 0')
-	ATTRIB(XonoticCampaignList, checkMarkSize, vector, '0 0 0')
-	ATTRIB(XonoticCampaignList, realUpperMargin1, float, 0)
-	ATTRIB(XonoticCampaignList, realUpperMargin2, float, 0)
 
-	ATTRIB(XonoticCampaignList, origin, vector, '0 0 0')
-	ATTRIB(XonoticCampaignList, itemAbsSize, vector, '0 0 0')
-	ATTRIB(XonoticCampaignList, emptyLineHeight, float, 0.5)
-
-	ATTRIB(XonoticCampaignList, campaignIndex, float, 0)
-	ATTRIB(XonoticCampaignList, cvarName, string, string_null)
-	METHOD(XonoticCampaignList, loadCvars, void(entity));
-	METHOD(XonoticCampaignList, saveCvars, void(entity));
-
-	ATTRIB(XonoticCampaignList, buttonNext, entity, NULL)
-	ATTRIB(XonoticCampaignList, buttonPrev, entity, NULL)
-	ATTRIB(XonoticCampaignList, labelTitle, entity, NULL)
-ENDCLASS(XonoticCampaignList)
-entity makeXonoticCampaignList();
-void CampaignList_LoadMap(entity btn, entity me);
-void MultiCampaign_Next(entity btn, entity me);
-void MultiCampaign_Prev(entity btn, entity me);
-#endif
+#include <common/campaign_common.qh>
+#include "inputbox.qh"
 
-#ifdef IMPLEMENTATION
 string campaign_longdesc_wrapped[CAMPAIGN_MAX_ENTRIES];
 
 void rewrapCampaign(float w, float l0, float emptyheight, vector theFontSize)
@@ -323,4 +277,3 @@ float XonoticCampaignList_keyDown(entity me, float scan, float ascii, float shif
 		return SUPER(XonoticCampaignList).keyDown(me, scan, ascii, shift);
 	return 1;
 }
-#endif
diff --git a/qcsrc/menu/xonotic/campaign.qh b/qcsrc/menu/xonotic/campaign.qh
index 6f70f09be..17585a86d 100644
--- a/qcsrc/menu/xonotic/campaign.qh
+++ b/qcsrc/menu/xonotic/campaign.qh
@@ -1 +1,45 @@
 #pragma once
+
+#include "listbox.qh"
+CLASS(XonoticCampaignList, XonoticListBox)
+	METHOD(XonoticCampaignList, configureXonoticCampaignList, void(entity));
+	ATTRIB(XonoticCampaignList, rowsPerItem, float, 10)
+	METHOD(XonoticCampaignList, draw, void(entity));
+	METHOD(XonoticCampaignList, drawListBoxItem, void(entity, int, vector, bool, bool));
+	METHOD(XonoticCampaignList, doubleClickListBoxItem, void(entity, float, vector));
+	METHOD(XonoticCampaignList, resizeNotify, void(entity, vector, vector, vector, vector));
+	METHOD(XonoticCampaignList, setSelected, void(entity, float));
+	METHOD(XonoticCampaignList, keyDown, float(entity, float, float, float));
+	METHOD(XonoticCampaignList, campaignGo, void(entity, float));
+	METHOD(XonoticCampaignList, destroy, void(entity));
+
+	ATTRIB(XonoticCampaignList, campaignGlob, float, 0)
+	ATTRIB(XonoticCampaignList, realFontSize, vector, '0 0 0')
+	ATTRIB(XonoticCampaignList, columnPreviewOrigin, float, 0)
+	ATTRIB(XonoticCampaignList, columnPreviewSize, float, 0)
+	ATTRIB(XonoticCampaignList, columnNameOrigin, float, 0)
+	ATTRIB(XonoticCampaignList, columnNameSize, float, 0)
+	ATTRIB(XonoticCampaignList, columnCheckMarkOrigin, float, 0)
+	ATTRIB(XonoticCampaignList, columnCheckMarkSize, float, 0)
+	ATTRIB(XonoticCampaignList, checkMarkOrigin, vector, '0 0 0')
+	ATTRIB(XonoticCampaignList, checkMarkSize, vector, '0 0 0')
+	ATTRIB(XonoticCampaignList, realUpperMargin1, float, 0)
+	ATTRIB(XonoticCampaignList, realUpperMargin2, float, 0)
+
+	ATTRIB(XonoticCampaignList, origin, vector, '0 0 0')
+	ATTRIB(XonoticCampaignList, itemAbsSize, vector, '0 0 0')
+	ATTRIB(XonoticCampaignList, emptyLineHeight, float, 0.5)
+
+	ATTRIB(XonoticCampaignList, campaignIndex, float, 0)
+	ATTRIB(XonoticCampaignList, cvarName, string, string_null)
+	METHOD(XonoticCampaignList, loadCvars, void(entity));
+	METHOD(XonoticCampaignList, saveCvars, void(entity));
+
+	ATTRIB(XonoticCampaignList, buttonNext, entity, NULL)
+	ATTRIB(XonoticCampaignList, buttonPrev, entity, NULL)
+	ATTRIB(XonoticCampaignList, labelTitle, entity, NULL)
+ENDCLASS(XonoticCampaignList)
+entity makeXonoticCampaignList();
+void CampaignList_LoadMap(entity btn, entity me);
+void MultiCampaign_Next(entity btn, entity me);
+void MultiCampaign_Prev(entity btn, entity me);
diff --git a/qcsrc/menu/xonotic/charmap.qc b/qcsrc/menu/xonotic/charmap.qc
index 7a10648c9..28f67d9f5 100644
--- a/qcsrc/menu/xonotic/charmap.qc
+++ b/qcsrc/menu/xonotic/charmap.qc
@@ -1,27 +1,6 @@
 #include "charmap.qh"
-#ifndef CHARMAP_H
-#define CHARMAP_H
-#include "picker.qc"
-CLASS(XonoticCharmap, XonoticPicker)
-	METHOD(XonoticCharmap, configureXonoticCharmap, void(entity, entity));
-	METHOD(XonoticCharmap, focusLeave, void(entity));
-	METHOD(XonoticCharmap, resizeNotify, void(entity, vector, vector, vector, vector));
-	METHOD(XonoticCharmap, keyDown, float(entity, float, float, float));
-	ATTRIB(XonoticCharmap, inputBox, entity, NULL)
-	ATTRIB(XonoticCharmap, realFontSize, vector, '0 0 0')
-
-	ATTRIB(XonoticCharmap, rows, float, 10)
-	ATTRIB(XonoticCharmap, columns, float, 14)
-
-	METHOD(XonoticCharmap, cellSelect, void(entity, vector));
-	METHOD(XonoticCharmap, cellIsValid, bool(entity, vector));
-	METHOD(XonoticCharmap, cellDraw, void(entity, vector, vector));
-	ATTRIB(XonoticCharmap, charOffset, vector, '0 0 0')
-ENDCLASS(XonoticCharmap)
-entity makeXonoticCharmap(entity controlledInputBox);
-#endif
-
-#ifdef IMPLEMENTATION
+
+#include "inputbox.qh"
 
 string CHARMAP =
 	"★◆■▮▰▬◣◤◥◢◀▲▶▼"
@@ -122,4 +101,3 @@ void XonoticCharmap_focusLeave(entity me)
 {
 	me.inputBox.saveCvars(me.inputBox);
 }
-#endif
diff --git a/qcsrc/menu/xonotic/charmap.qh b/qcsrc/menu/xonotic/charmap.qh
index 6f70f09be..c8d5b3134 100644
--- a/qcsrc/menu/xonotic/charmap.qh
+++ b/qcsrc/menu/xonotic/charmap.qh
@@ -1 +1,20 @@
 #pragma once
+
+#include "picker.qh"
+CLASS(XonoticCharmap, XonoticPicker)
+	METHOD(XonoticCharmap, configureXonoticCharmap, void(entity, entity));
+	METHOD(XonoticCharmap, focusLeave, void(entity));
+	METHOD(XonoticCharmap, resizeNotify, void(entity, vector, vector, vector, vector));
+	METHOD(XonoticCharmap, keyDown, float(entity, float, float, float));
+	ATTRIB(XonoticCharmap, inputBox, entity, NULL)
+	ATTRIB(XonoticCharmap, realFontSize, vector, '0 0 0')
+
+	ATTRIB(XonoticCharmap, rows, float, 10)
+	ATTRIB(XonoticCharmap, columns, float, 14)
+
+	METHOD(XonoticCharmap, cellSelect, void(entity, vector));
+	METHOD(XonoticCharmap, cellIsValid, bool(entity, vector));
+	METHOD(XonoticCharmap, cellDraw, void(entity, vector, vector));
+	ATTRIB(XonoticCharmap, charOffset, vector, '0 0 0')
+ENDCLASS(XonoticCharmap)
+entity makeXonoticCharmap(entity controlledInputBox);
diff --git a/qcsrc/menu/xonotic/checkbox.qc b/qcsrc/menu/xonotic/checkbox.qc
index 600560659..21743b9a1 100644
--- a/qcsrc/menu/xonotic/checkbox.qc
+++ b/qcsrc/menu/xonotic/checkbox.qc
@@ -1,35 +1,5 @@
 #include "checkbox.qh"
-#ifndef CHECKBOX_H
-#define CHECKBOX_H
-#include "../item/checkbox.qc"
-CLASS(XonoticCheckBox, CheckBox)
-	METHOD(XonoticCheckBox, configureXonoticCheckBox, void(entity, float, float, string, string, string));
-	METHOD(XonoticCheckBox, setChecked, void(entity, float));
-	ATTRIB(XonoticCheckBox, fontSize, float, SKINFONTSIZE_NORMAL)
-	ATTRIB(XonoticCheckBox, image, string, SKINGFX_CHECKBOX)
-	ATTRIB(XonoticCheckBox, yesValue, float, 1)
-	ATTRIB(XonoticCheckBox, noValue, float, 0)
 
-	ATTRIB(XonoticCheckBox, color, vector, SKINCOLOR_CHECKBOX_N)
-	ATTRIB(XonoticCheckBox, colorC, vector, SKINCOLOR_CHECKBOX_C)
-	ATTRIB(XonoticCheckBox, colorF, vector, SKINCOLOR_CHECKBOX_F)
-	ATTRIB(XonoticCheckBox, colorD, vector, SKINCOLOR_CHECKBOX_D)
-
-	ATTRIB(XonoticCheckBox, cvarName, string, string_null)
-	METHOD(XonoticCheckBox, loadCvars, void(entity));
-	METHOD(XonoticCheckBox, saveCvars, void(entity));
-	ATTRIB(XonoticCheckBox, sendCvars, float, 0)
-
-	ATTRIB(XonoticCheckBox, alpha, float, SKINALPHA_TEXT)
-	ATTRIB(XonoticCheckBox, disabledAlpha, float, SKINALPHA_DISABLED)
-ENDCLASS(XonoticCheckBox)
-entity makeXonoticCheckBox_T(float, string, string, string);
-entity makeXonoticCheckBox(float, string, string);
-entity makeXonoticCheckBoxEx_T(float, float, string, string, string);
-entity makeXonoticCheckBoxEx(float, float, string, string);
-#endif
-
-#ifdef IMPLEMENTATION
 entity makeXonoticCheckBox_T(float isInverted, string theCvar, string theText, string theTooltip)
 {
 	float y, n;
@@ -113,4 +83,3 @@ void XonoticCheckBox_saveCvars(entity me)
 
 	CheckSendCvars(me, me.cvarName);
 }
-#endif
diff --git a/qcsrc/menu/xonotic/checkbox.qh b/qcsrc/menu/xonotic/checkbox.qh
index 6f70f09be..a188f4c0a 100644
--- a/qcsrc/menu/xonotic/checkbox.qh
+++ b/qcsrc/menu/xonotic/checkbox.qh
@@ -1 +1,28 @@
 #pragma once
+
+#include "../item/checkbox.qh"
+CLASS(XonoticCheckBox, CheckBox)
+	METHOD(XonoticCheckBox, configureXonoticCheckBox, void(entity, float, float, string, string, string));
+	METHOD(XonoticCheckBox, setChecked, void(entity, float));
+	ATTRIB(XonoticCheckBox, fontSize, float, SKINFONTSIZE_NORMAL)
+	ATTRIB(XonoticCheckBox, image, string, SKINGFX_CHECKBOX)
+	ATTRIB(XonoticCheckBox, yesValue, float, 1)
+	ATTRIB(XonoticCheckBox, noValue, float, 0)
+
+	ATTRIB(XonoticCheckBox, color, vector, SKINCOLOR_CHECKBOX_N)
+	ATTRIB(XonoticCheckBox, colorC, vector, SKINCOLOR_CHECKBOX_C)
+	ATTRIB(XonoticCheckBox, colorF, vector, SKINCOLOR_CHECKBOX_F)
+	ATTRIB(XonoticCheckBox, colorD, vector, SKINCOLOR_CHECKBOX_D)
+
+	ATTRIB(XonoticCheckBox, cvarName, string, string_null)
+	METHOD(XonoticCheckBox, loadCvars, void(entity));
+	METHOD(XonoticCheckBox, saveCvars, void(entity));
+	ATTRIB(XonoticCheckBox, sendCvars, float, 0)
+
+	ATTRIB(XonoticCheckBox, alpha, float, SKINALPHA_TEXT)
+	ATTRIB(XonoticCheckBox, disabledAlpha, float, SKINALPHA_DISABLED)
+ENDCLASS(XonoticCheckBox)
+entity makeXonoticCheckBox_T(float, string, string, string);
+entity makeXonoticCheckBox(float, string, string);
+entity makeXonoticCheckBoxEx_T(float, float, string, string, string);
+entity makeXonoticCheckBoxEx(float, float, string, string);
diff --git a/qcsrc/menu/xonotic/checkbox_slider_invalid.qc b/qcsrc/menu/xonotic/checkbox_slider_invalid.qc
index 723a37a9e..839e66b21 100644
--- a/qcsrc/menu/xonotic/checkbox_slider_invalid.qc
+++ b/qcsrc/menu/xonotic/checkbox_slider_invalid.qc
@@ -1,31 +1,7 @@
 #include "checkbox_slider_invalid.qh"
-#ifndef CHECKBOX_SLIDER_INVALID_H
-#define CHECKBOX_SLIDER_INVALID_H
-#include "../item/checkbox.qc"
-CLASS(XonoticSliderCheckBox, CheckBox)
-	METHOD(XonoticSliderCheckBox, configureXonoticSliderCheckBox, void(entity, float, float, entity, string));
-	METHOD(XonoticSliderCheckBox, setChecked, void(entity, float));
-	METHOD(XonoticSliderCheckBox, draw, void(entity));
-	ATTRIB(XonoticSliderCheckBox, fontSize, float, SKINFONTSIZE_NORMAL)
-	ATTRIB(XonoticSliderCheckBox, image, string, SKINGFX_CHECKBOX)
 
-	ATTRIB(XonoticSliderCheckBox, color, vector, SKINCOLOR_CHECKBOX_N)
-	ATTRIB(XonoticSliderCheckBox, colorC, vector, SKINCOLOR_CHECKBOX_C)
-	ATTRIB(XonoticSliderCheckBox, colorF, vector, SKINCOLOR_CHECKBOX_F)
-	ATTRIB(XonoticSliderCheckBox, colorD, vector, SKINCOLOR_CHECKBOX_D)
+#include "slider.qh"
 
-	ATTRIB(XonoticSliderCheckBox, alpha, float, SKINALPHA_TEXT)
-	ATTRIB(XonoticSliderCheckBox, disabledAlpha, float, SKINALPHA_DISABLED)
-
-	ATTRIB(XonoticSliderCheckBox, controlledSlider, entity, NULL)
-	ATTRIB(XonoticSliderCheckBox, offValue, float, -1)
-	ATTRIB(XonoticSliderCheckBox, inverted, float, 0)
-	ATTRIB(XonoticSliderCheckBox, savedValue, float, -1)
-ENDCLASS(XonoticSliderCheckBox)
-entity makeXonoticSliderCheckBox(float, float, entity, string);
-#endif
-
-#ifdef IMPLEMENTATION
 entity makeXonoticSliderCheckBox(float theOffValue, float isInverted, entity theControlledSlider, string theText)
 {
 	entity me;
@@ -64,5 +40,3 @@ void XonoticSliderCheckBox_setChecked(entity me, float val)
 	else
 		me.controlledSlider.setValue(me.controlledSlider, me.offValue);
 }
-
-#endif
diff --git a/qcsrc/menu/xonotic/checkbox_slider_invalid.qh b/qcsrc/menu/xonotic/checkbox_slider_invalid.qh
index 6f70f09be..d9c144c6a 100644
--- a/qcsrc/menu/xonotic/checkbox_slider_invalid.qh
+++ b/qcsrc/menu/xonotic/checkbox_slider_invalid.qh
@@ -1 +1,24 @@
 #pragma once
+
+#include "../item/checkbox.qh"
+CLASS(XonoticSliderCheckBox, CheckBox)
+	METHOD(XonoticSliderCheckBox, configureXonoticSliderCheckBox, void(entity, float, float, entity, string));
+	METHOD(XonoticSliderCheckBox, setChecked, void(entity, float));
+	METHOD(XonoticSliderCheckBox, draw, void(entity));
+	ATTRIB(XonoticSliderCheckBox, fontSize, float, SKINFONTSIZE_NORMAL)
+	ATTRIB(XonoticSliderCheckBox, image, string, SKINGFX_CHECKBOX)
+
+	ATTRIB(XonoticSliderCheckBox, color, vector, SKINCOLOR_CHECKBOX_N)
+	ATTRIB(XonoticSliderCheckBox, colorC, vector, SKINCOLOR_CHECKBOX_C)
+	ATTRIB(XonoticSliderCheckBox, colorF, vector, SKINCOLOR_CHECKBOX_F)
+	ATTRIB(XonoticSliderCheckBox, colorD, vector, SKINCOLOR_CHECKBOX_D)
+
+	ATTRIB(XonoticSliderCheckBox, alpha, float, SKINALPHA_TEXT)
+	ATTRIB(XonoticSliderCheckBox, disabledAlpha, float, SKINALPHA_DISABLED)
+
+	ATTRIB(XonoticSliderCheckBox, controlledSlider, entity, NULL)
+	ATTRIB(XonoticSliderCheckBox, offValue, float, -1)
+	ATTRIB(XonoticSliderCheckBox, inverted, float, 0)
+	ATTRIB(XonoticSliderCheckBox, savedValue, float, -1)
+ENDCLASS(XonoticSliderCheckBox)
+entity makeXonoticSliderCheckBox(float, float, entity, string);
diff --git a/qcsrc/menu/xonotic/checkbox_string.qc b/qcsrc/menu/xonotic/checkbox_string.qc
index e605390f2..99db16e35 100644
--- a/qcsrc/menu/xonotic/checkbox_string.qc
+++ b/qcsrc/menu/xonotic/checkbox_string.qc
@@ -1,32 +1,5 @@
 #include "checkbox_string.qh"
-#ifndef CHECKBOX_STRING_H
-#define CHECKBOX_STRING_H
-#include "../item/checkbox.qc"
-CLASS(XonoticCheckBoxString, CheckBox)
-	METHOD(XonoticCheckBoxString, configureXonoticCheckBoxString, void(entity, string, string, string, string));
-	METHOD(XonoticCheckBoxString, setChecked, void(entity, float));
-	ATTRIB(XonoticCheckBoxString, fontSize, float, SKINFONTSIZE_NORMAL)
-	ATTRIB(XonoticCheckBoxString, image, string, SKINGFX_CHECKBOX)
-	ATTRIB(XonoticCheckBoxString, yesString, string, string_null)
-	ATTRIB(XonoticCheckBoxString, noString, string, string_null)
 
-	ATTRIB(XonoticCheckBoxString, color, vector, SKINCOLOR_CHECKBOX_N)
-	ATTRIB(XonoticCheckBoxString, colorC, vector, SKINCOLOR_CHECKBOX_C)
-	ATTRIB(XonoticCheckBoxString, colorF, vector, SKINCOLOR_CHECKBOX_F)
-	ATTRIB(XonoticCheckBoxString, colorD, vector, SKINCOLOR_CHECKBOX_D)
-
-	ATTRIB(XonoticCheckBoxString, cvarName, string, string_null)
-	METHOD(XonoticCheckBoxString, loadCvars, void(entity));
-	METHOD(XonoticCheckBoxString, saveCvars, void(entity));
-	ATTRIB(XonoticCheckBoxString, sendCvars, float, 0)
-
-	ATTRIB(XonoticCheckBoxString, alpha, float, SKINALPHA_TEXT)
-	ATTRIB(XonoticCheckBoxString, disabledAlpha, float, SKINALPHA_DISABLED)
-ENDCLASS(XonoticCheckBoxString)
-entity makeXonoticCheckBoxString(string, string, string, string);
-#endif
-
-#ifdef IMPLEMENTATION
 entity makeXonoticCheckBoxString(string theYesValue, string theNoValue, string theCvar, string theText)
 {
 	entity me;
@@ -68,4 +41,3 @@ void XonoticCheckBoxString_saveCvars(entity me)
 
 	CheckSendCvars(me, me.cvarName);
 }
-#endif
diff --git a/qcsrc/menu/xonotic/checkbox_string.qh b/qcsrc/menu/xonotic/checkbox_string.qh
index 6f70f09be..b4dc8e5d2 100644
--- a/qcsrc/menu/xonotic/checkbox_string.qh
+++ b/qcsrc/menu/xonotic/checkbox_string.qh
@@ -1 +1,25 @@
 #pragma once
+
+#include "../item/checkbox.qh"
+CLASS(XonoticCheckBoxString, CheckBox)
+	METHOD(XonoticCheckBoxString, configureXonoticCheckBoxString, void(entity, string, string, string, string));
+	METHOD(XonoticCheckBoxString, setChecked, void(entity, float));
+	ATTRIB(XonoticCheckBoxString, fontSize, float, SKINFONTSIZE_NORMAL)
+	ATTRIB(XonoticCheckBoxString, image, string, SKINGFX_CHECKBOX)
+	ATTRIB(XonoticCheckBoxString, yesString, string, string_null)
+	ATTRIB(XonoticCheckBoxString, noString, string, string_null)
+
+	ATTRIB(XonoticCheckBoxString, color, vector, SKINCOLOR_CHECKBOX_N)
+	ATTRIB(XonoticCheckBoxString, colorC, vector, SKINCOLOR_CHECKBOX_C)
+	ATTRIB(XonoticCheckBoxString, colorF, vector, SKINCOLOR_CHECKBOX_F)
+	ATTRIB(XonoticCheckBoxString, colorD, vector, SKINCOLOR_CHECKBOX_D)
+
+	ATTRIB(XonoticCheckBoxString, cvarName, string, string_null)
+	METHOD(XonoticCheckBoxString, loadCvars, void(entity));
+	METHOD(XonoticCheckBoxString, saveCvars, void(entity));
+	ATTRIB(XonoticCheckBoxString, sendCvars, float, 0)
+
+	ATTRIB(XonoticCheckBoxString, alpha, float, SKINALPHA_TEXT)
+	ATTRIB(XonoticCheckBoxString, disabledAlpha, float, SKINALPHA_DISABLED)
+ENDCLASS(XonoticCheckBoxString)
+entity makeXonoticCheckBoxString(string, string, string, string);
diff --git a/qcsrc/menu/xonotic/colorbutton.qc b/qcsrc/menu/xonotic/colorbutton.qc
index ac86697b8..6675c1aee 100644
--- a/qcsrc/menu/xonotic/colorbutton.qc
+++ b/qcsrc/menu/xonotic/colorbutton.qc
@@ -1,26 +1,5 @@
 #include "colorbutton.qh"
-#ifndef COLORBUTTON_H
-#define COLORBUTTON_H
-#include "../item/radiobutton.qc"
-CLASS(XonoticColorButton, RadioButton)
-	METHOD(XonoticColorButton, configureXonoticColorButton, void(entity, float, float, float));
-	METHOD(XonoticColorButton, setChecked, void(entity, float));
-	METHOD(XonoticColorButton, draw, void(entity));
-	ATTRIB(XonoticColorButton, fontSize, float, 0)
-	ATTRIB(XonoticColorButton, image, string, SKINGFX_COLORBUTTON)
 
-	ATTRIB(XonoticColorButton, useDownAsChecked, float, 1)
-
-	ATTRIB(XonoticColorButton, cvarPart, float, 0)
-	ATTRIB(XonoticColorButton, cvarName, string, string_null)
-	ATTRIB(XonoticColorButton, cvarValueFloat, float, 0)
-	METHOD(XonoticColorButton, loadCvars, void(entity));
-	METHOD(XonoticColorButton, saveCvars, void(entity));
-ENDCLASS(XonoticColorButton)
-entity makeXonoticColorButton(float, float, float);
-#endif
-
-#ifdef IMPLEMENTATION
 entity makeXonoticColorButton(float theGroup, float theColor, float theValue)
 {
 	entity me;
@@ -100,4 +79,3 @@ void XonoticColorButton_draw(entity me)
 	me.colorD = me.color;
 	SUPER(XonoticColorButton).draw(me);
 }
-#endif
diff --git a/qcsrc/menu/xonotic/colorbutton.qh b/qcsrc/menu/xonotic/colorbutton.qh
index 6f70f09be..c253f8f11 100644
--- a/qcsrc/menu/xonotic/colorbutton.qh
+++ b/qcsrc/menu/xonotic/colorbutton.qh
@@ -1 +1,19 @@
 #pragma once
+
+#include "../item/radiobutton.qh"
+CLASS(XonoticColorButton, RadioButton)
+	METHOD(XonoticColorButton, configureXonoticColorButton, void(entity, float, float, float));
+	METHOD(XonoticColorButton, setChecked, void(entity, float));
+	METHOD(XonoticColorButton, draw, void(entity));
+	ATTRIB(XonoticColorButton, fontSize, float, 0)
+	ATTRIB(XonoticColorButton, image, string, SKINGFX_COLORBUTTON)
+
+	ATTRIB(XonoticColorButton, useDownAsChecked, float, 1)
+
+	ATTRIB(XonoticColorButton, cvarPart, float, 0)
+	ATTRIB(XonoticColorButton, cvarName, string, string_null)
+	ATTRIB(XonoticColorButton, cvarValueFloat, float, 0)
+	METHOD(XonoticColorButton, loadCvars, void(entity));
+	METHOD(XonoticColorButton, saveCvars, void(entity));
+ENDCLASS(XonoticColorButton)
+entity makeXonoticColorButton(float, float, float);
diff --git a/qcsrc/menu/xonotic/colorpicker.qc b/qcsrc/menu/xonotic/colorpicker.qc
index 069f086b9..b88d5d9a7 100644
--- a/qcsrc/menu/xonotic/colorpicker.qc
+++ b/qcsrc/menu/xonotic/colorpicker.qc
@@ -1,24 +1,7 @@
 #include "colorpicker.qh"
-#ifndef COLORPICKER_H
-#define COLORPICKER_H
-#include "../item/image.qc"
-CLASS(XonoticColorpicker, Image)
-	METHOD(XonoticColorpicker, configureXonoticColorpicker, void(entity, entity));
-	METHOD(XonoticColorpicker, mousePress, float(entity, vector));
-	METHOD(XonoticColorpicker, mouseRelease, float(entity, vector));
-	METHOD(XonoticColorpicker, mouseDrag, float(entity, vector));
-	ATTRIB(XonoticColorpicker, controlledTextbox, entity, NULL)
-	ATTRIB(XonoticColorpicker, image, string, SKINGFX_COLORPICKER)
-	ATTRIB(XonoticColorpicker, imagemargin, vector, SKINMARGIN_COLORPICKER)
-	ATTRIB(XonoticColorpicker, focusable, float, 1)
-	METHOD(XonoticColorpicker, focusLeave, void(entity));
-	METHOD(XonoticColorpicker, keyDown, float(entity, float, float, float));
-	METHOD(XonoticColorpicker, draw, void(entity));
-ENDCLASS(XonoticColorpicker)
-entity makeXonoticColorpicker(entity theTextbox);
-#endif
-
-#ifdef IMPLEMENTATION
+
+#include "inputbox.qh"
+
 entity makeXonoticColorpicker(entity theTextbox)
 {
 	entity me;
@@ -175,4 +158,3 @@ void XonoticColorpicker_draw(entity me)
 	draw_Picture(me.imgOrigin, strcat(me.src, "_m"), me.imgSize, '0 0 0', aC);
 	draw_Picture(me.imgOrigin, strcat(me.src, "_m"), me.imgSize, me.color, B);
 }
-#endif
diff --git a/qcsrc/menu/xonotic/colorpicker.qh b/qcsrc/menu/xonotic/colorpicker.qh
index 6f70f09be..03567dfa4 100644
--- a/qcsrc/menu/xonotic/colorpicker.qh
+++ b/qcsrc/menu/xonotic/colorpicker.qh
@@ -1 +1,20 @@
 #pragma once
+
+#include "../item/image.qh"
+CLASS(XonoticColorpicker, Image)
+	METHOD(XonoticColorpicker, configureXonoticColorpicker, void(entity, entity));
+	METHOD(XonoticColorpicker, mousePress, float(entity, vector));
+	METHOD(XonoticColorpicker, mouseRelease, float(entity, vector));
+	METHOD(XonoticColorpicker, mouseDrag, float(entity, vector));
+	ATTRIB(XonoticColorpicker, controlledTextbox, entity, NULL)
+	ATTRIB(XonoticColorpicker, image, string, SKINGFX_COLORPICKER)
+	ATTRIB(XonoticColorpicker, imagemargin, vector, SKINMARGIN_COLORPICKER)
+	ATTRIB(XonoticColorpicker, focusable, float, 1)
+	METHOD(XonoticColorpicker, focusLeave, void(entity));
+	METHOD(XonoticColorpicker, keyDown, float(entity, float, float, float));
+	METHOD(XonoticColorpicker, draw, void(entity));
+ENDCLASS(XonoticColorpicker)
+entity makeXonoticColorpicker(entity theTextbox);
+
+vector color_hslimage(vector v, vector margin);
+vector hslimage_color(vector v, vector margin);
diff --git a/qcsrc/menu/xonotic/colorpicker_string.qc b/qcsrc/menu/xonotic/colorpicker_string.qc
index 6485cfaa4..200204c00 100644
--- a/qcsrc/menu/xonotic/colorpicker_string.qc
+++ b/qcsrc/menu/xonotic/colorpicker_string.qc
@@ -1,28 +1,7 @@
 #include "colorpicker_string.qh"
-#ifndef COLORPICKER_STRING_H
-#define COLORPICKER_STRING_H
-#include "../item/image.qc"
-CLASS(XonoticColorpickerString, Image)
-	METHOD(XonoticColorpickerString, configureXonoticColorpickerString, void(entity, string, string));
-	METHOD(XonoticColorpickerString, mousePress, float(entity, vector));
-	METHOD(XonoticColorpickerString, mouseRelease, float(entity, vector));
-	METHOD(XonoticColorpickerString, mouseDrag, float(entity, vector));
-
-	ATTRIB(XonoticColorpickerString, cvarName, string, string_null)
-	METHOD(XonoticColorpickerString, loadCvars, void(entity));
-	METHOD(XonoticColorpickerString, saveCvars, void(entity));
-
-	ATTRIB(XonoticColorpickerString, prevcoords, vector, '0 0 0')
-	ATTRIB(XonoticColorpickerString, image, string, SKINGFX_COLORPICKER)
-	ATTRIB(XonoticColorpickerString, imagemargin, vector, SKINMARGIN_COLORPICKER)
-	ATTRIB(XonoticColorpickerString, focusable, float, 1)
-	METHOD(XonoticColorpickerString, draw, void(entity));
-	ATTRIB(XonoticColorpickerString, disabledAlpha, float, 0.3)
-ENDCLASS(XonoticColorpickerString)
-entity makeXonoticColorpickerString(string theCvar, string theDefaultCvar);
-#endif
-
-#ifdef IMPLEMENTATION
+
+.bool disabled;
+
 entity makeXonoticColorpickerString(string theCvar, string theDefaultCvar)
 {
 	entity me;
@@ -120,4 +99,3 @@ void XonoticColorpickerString_draw(entity me)
 
 	draw_alpha = save;
 }
-#endif
diff --git a/qcsrc/menu/xonotic/colorpicker_string.qh b/qcsrc/menu/xonotic/colorpicker_string.qh
index 6f70f09be..3caf9d9bf 100644
--- a/qcsrc/menu/xonotic/colorpicker_string.qh
+++ b/qcsrc/menu/xonotic/colorpicker_string.qh
@@ -1 +1,23 @@
 #pragma once
+
+#include "colorpicker.qh"
+
+#include "../item/image.qh"
+CLASS(XonoticColorpickerString, Image)
+	METHOD(XonoticColorpickerString, configureXonoticColorpickerString, void(entity, string, string));
+	METHOD(XonoticColorpickerString, mousePress, float(entity, vector));
+	METHOD(XonoticColorpickerString, mouseRelease, float(entity, vector));
+	METHOD(XonoticColorpickerString, mouseDrag, float(entity, vector));
+
+	ATTRIB(XonoticColorpickerString, cvarName, string, string_null)
+	METHOD(XonoticColorpickerString, loadCvars, void(entity));
+	METHOD(XonoticColorpickerString, saveCvars, void(entity));
+
+	ATTRIB(XonoticColorpickerString, prevcoords, vector, '0 0 0')
+	ATTRIB(XonoticColorpickerString, image, string, SKINGFX_COLORPICKER)
+	ATTRIB(XonoticColorpickerString, imagemargin, vector, SKINMARGIN_COLORPICKER)
+	ATTRIB(XonoticColorpickerString, focusable, float, 1)
+	METHOD(XonoticColorpickerString, draw, void(entity));
+	ATTRIB(XonoticColorpickerString, disabledAlpha, float, 0.3)
+ENDCLASS(XonoticColorpickerString)
+entity makeXonoticColorpickerString(string theCvar, string theDefaultCvar);
diff --git a/qcsrc/menu/xonotic/commandbutton.qc b/qcsrc/menu/xonotic/commandbutton.qc
index 22a9820eb..8e691a036 100644
--- a/qcsrc/menu/xonotic/commandbutton.qc
+++ b/qcsrc/menu/xonotic/commandbutton.qc
@@ -1,23 +1,5 @@
 #include "commandbutton.qh"
-#ifndef COMMANDBUTTON_CLOSE
-# define COMMANDBUTTON_CLOSE 1
-# define COMMANDBUTTON_APPLY 2
-//# define COMMANDBUTTON_REVERT 4
-#endif
 
-#ifndef COMMANDBUTTON_H
-#define COMMANDBUTTON_H
-#include "button.qc"
-CLASS(XonoticCommandButton, XonoticButton)
-	METHOD(XonoticCommandButton, configureXonoticCommandButton, void(entity, string, vector, string, float, string));
-	ATTRIB(XonoticCommandButton, onClickCommand, string, string_null)
-	ATTRIB(XonoticCommandButton, flags, float, 0)
-ENDCLASS(XonoticCommandButton)
-entity makeXonoticCommandButton_T(string theText, vector theColor, string theCommand, float closesMenu, string theTooltip);
-entity makeXonoticCommandButton(string theText, vector theColor, string theCommand, float closesMenu);
-#endif
-
-#ifdef IMPLEMENTATION
 entity makeXonoticCommandButton_T(string theText, vector theColor, string theCommand, float theFlags, string theTooltip)
 {
 	entity me;
@@ -49,4 +31,3 @@ void XonoticCommandButton_configureXonoticCommandButton(entity me, string theTex
 	me.onClick = XonoticCommandButton_Click;
 	me.onClickEntity = me;
 }
-#endif
diff --git a/qcsrc/menu/xonotic/commandbutton.qh b/qcsrc/menu/xonotic/commandbutton.qh
index 6f70f09be..072890ab1 100644
--- a/qcsrc/menu/xonotic/commandbutton.qh
+++ b/qcsrc/menu/xonotic/commandbutton.qh
@@ -1 +1,17 @@
 #pragma once
+
+#include "button.qh"
+CLASS(XonoticCommandButton, XonoticButton)
+	METHOD(XonoticCommandButton, configureXonoticCommandButton, void(entity, string, vector, string, float, string));
+	ATTRIB(XonoticCommandButton, onClickCommand, string, string_null)
+	ATTRIB(XonoticCommandButton, flags, float, 0)
+ENDCLASS(XonoticCommandButton)
+
+entity makeXonoticCommandButton_T(string theText, vector theColor, string theCommand, float closesMenu, string theTooltip);
+entity makeXonoticCommandButton(string theText, vector theColor, string theCommand, float closesMenu);
+
+#ifndef COMMANDBUTTON_CLOSE
+# define COMMANDBUTTON_CLOSE 1
+# define COMMANDBUTTON_APPLY 2
+//# define COMMANDBUTTON_REVERT 4
+#endif
diff --git a/qcsrc/menu/xonotic/credits.qc b/qcsrc/menu/xonotic/credits.qc
index c1068e7aa..d30ab3d44 100644
--- a/qcsrc/menu/xonotic/credits.qc
+++ b/qcsrc/menu/xonotic/credits.qc
@@ -1,6 +1,4 @@
 #include "credits.qh"
-#ifndef CREDITS_H
-#define CREDITS_H
 
 #define CREDITS(TITLE, FUNCTION, PERSON, PERSON_, NL) \
 	TITLE(_("Core Team")) \
@@ -368,28 +366,6 @@ int credits_get()
 
 #undef CREDITS
 
-#include "listbox.qc"
-CLASS(XonoticCreditsList, XonoticListBox)
-	METHOD(XonoticCreditsList, configureXonoticCreditsList, void(entity));
-	ATTRIB(XonoticCreditsList, rowsPerItem, float, 1)
-	METHOD(XonoticCreditsList, draw, void(entity));
-	METHOD(XonoticCreditsList, drawListBoxItem, void(entity, int, vector, bool, bool));
-	METHOD(XonoticCreditsList, resizeNotify, void(entity, vector, vector, vector, vector));
-	METHOD(XonoticCreditsList, keyDown, float(entity, float, float, float));
-	METHOD(XonoticCreditsList, destroy, void(entity));
-	ATTRIB(XonoticCreditsList, selectionDoesntMatter, bool, true)
-
-	ATTRIB(XonoticCreditsList, realFontSize, vector, '0 0 0')
-	ATTRIB(XonoticCreditsList, realUpperMargin, float, 0)
-	ATTRIB(XonoticCreditsList, bufferIndex, float, 0)
-	ATTRIB(XonoticCreditsList, scrolling, float, 0)
-
-	ATTRIB(XonoticCreditsList, alphaBG, float, 0)
-ENDCLASS(XonoticCreditsList)
-entity makeXonoticCreditsList();
-#endif
-
-#ifdef IMPLEMENTATION
 entity makeXonoticCreditsList()
 {
 	entity me;
@@ -459,4 +435,3 @@ float XonoticCreditsList_keyDown(entity me, float key, float ascii, float shift)
 	me.scrolling = 0;
 	return SUPER(XonoticCreditsList).keyDown(me, key, ascii, shift);
 }
-#endif
diff --git a/qcsrc/menu/xonotic/credits.qh b/qcsrc/menu/xonotic/credits.qh
index 6f70f09be..d376beaa7 100644
--- a/qcsrc/menu/xonotic/credits.qh
+++ b/qcsrc/menu/xonotic/credits.qh
@@ -1 +1,23 @@
 #pragma once
+
+#include "listbox.qh"
+CLASS(XonoticCreditsList, XonoticListBox)
+	METHOD(XonoticCreditsList, configureXonoticCreditsList, void(entity));
+	ATTRIB(XonoticCreditsList, rowsPerItem, float, 1)
+	METHOD(XonoticCreditsList, draw, void(entity));
+	METHOD(XonoticCreditsList, drawListBoxItem, void(entity, int, vector, bool, bool));
+	METHOD(XonoticCreditsList, resizeNotify, void(entity, vector, vector, vector, vector));
+	METHOD(XonoticCreditsList, keyDown, float(entity, float, float, float));
+	METHOD(XonoticCreditsList, destroy, void(entity));
+	ATTRIB(XonoticCreditsList, selectionDoesntMatter, bool, true)
+
+	ATTRIB(XonoticCreditsList, realFontSize, vector, '0 0 0')
+	ATTRIB(XonoticCreditsList, realUpperMargin, float, 0)
+	ATTRIB(XonoticCreditsList, bufferIndex, float, 0)
+	ATTRIB(XonoticCreditsList, scrolling, float, 0)
+
+	ATTRIB(XonoticCreditsList, alphaBG, float, 0)
+ENDCLASS(XonoticCreditsList)
+entity makeXonoticCreditsList();
+
+int credits_get();
diff --git a/qcsrc/menu/xonotic/crosshairpicker.qc b/qcsrc/menu/xonotic/crosshairpicker.qc
index 69e540d1b..318141259 100644
--- a/qcsrc/menu/xonotic/crosshairpicker.qc
+++ b/qcsrc/menu/xonotic/crosshairpicker.qc
@@ -1,21 +1,4 @@
 #include "crosshairpicker.qh"
-#ifndef CROSSHAIRPICKER_H
-#define CROSSHAIRPICKER_H
-#include "picker.qc"
-CLASS(XonoticCrosshairPicker, XonoticPicker)
-	METHOD(XonoticCrosshairPicker, configureXonoticCrosshairPicker, void(entity));
-
-	ATTRIB(XonoticCrosshairPicker, rows, float, 3)
-	ATTRIB(XonoticCrosshairPicker, columns, float, 12)
-
-	METHOD(XonoticCrosshairPicker, cellSelect, void(entity, vector));
-	METHOD(XonoticCrosshairPicker, cellIsValid, bool(entity, vector));
-	METHOD(XonoticCrosshairPicker, cellDraw, void(entity, vector, vector));
-ENDCLASS(XonoticCrosshairPicker)
-entity makeXonoticCrosshairPicker();
-#endif
-
-#ifdef IMPLEMENTATION
 
 string crosshairpicker_cellToCrosshair(entity me, vector cell)
 {
@@ -76,4 +59,3 @@ void XonoticCrosshairPicker_cellDraw(entity me, vector cell, vector cellPos)
 	if(cvar("crosshair_dot"))
 		draw_Picture(crosshairPos - 0.5 * sz * cvar("crosshair_dot_size"), "/gfx/crosshairdot", sz * cvar("crosshair_dot_size"), SKINCOLOR_CROSSHAIRPICKER_CROSSHAIR, SKINALPHA_CROSSHAIRPICKER_CROSSHAIR);
 }
-#endif
diff --git a/qcsrc/menu/xonotic/crosshairpicker.qh b/qcsrc/menu/xonotic/crosshairpicker.qh
index 6f70f09be..b6f39457d 100644
--- a/qcsrc/menu/xonotic/crosshairpicker.qh
+++ b/qcsrc/menu/xonotic/crosshairpicker.qh
@@ -1 +1,14 @@
 #pragma once
+
+#include "picker.qh"
+CLASS(XonoticCrosshairPicker, XonoticPicker)
+	METHOD(XonoticCrosshairPicker, configureXonoticCrosshairPicker, void(entity));
+
+	ATTRIB(XonoticCrosshairPicker, rows, float, 3)
+	ATTRIB(XonoticCrosshairPicker, columns, float, 12)
+
+	METHOD(XonoticCrosshairPicker, cellSelect, void(entity, vector));
+	METHOD(XonoticCrosshairPicker, cellIsValid, bool(entity, vector));
+	METHOD(XonoticCrosshairPicker, cellDraw, void(entity, vector, vector));
+ENDCLASS(XonoticCrosshairPicker)
+entity makeXonoticCrosshairPicker();
diff --git a/qcsrc/menu/xonotic/crosshairpreview.qc b/qcsrc/menu/xonotic/crosshairpreview.qc
index 817e452a1..e11d7dcc0 100644
--- a/qcsrc/menu/xonotic/crosshairpreview.qc
+++ b/qcsrc/menu/xonotic/crosshairpreview.qc
@@ -1,19 +1,5 @@
 #include "crosshairpreview.qh"
-#ifndef CROSSHAIRPREVIEW_H
-#define CROSSHAIRPREVIEW_H
-#include "../item.qc"
-CLASS(XonoticCrosshairPreview, Item)
-	METHOD(XonoticCrosshairPreview, configureXonoticCrosshairPreview, void(entity));
-	METHOD(XonoticCrosshairPreview, draw, void(entity));
-	ATTRIB(XonoticCrosshairPreview, src, string, string_null)
-	ATTRIB(XonoticCrosshairPreview, src2, string, string_null)
-	ATTRIB(XonoticCrosshairPreview, disabled, float, 0)
-	ATTRIB(XonoticCrosshairPreview, disabledAlpha, float, SKINALPHA_DISABLED)
-ENDCLASS(XonoticCrosshairPreview)
-entity makeXonoticCrosshairPreview();
-#endif
-
-#ifdef IMPLEMENTATION
+
 entity makeXonoticCrosshairPreview()
 {
 	entity me;
@@ -60,4 +46,3 @@ void XonoticCrosshairPreview_draw(entity me)
 
 	SUPER(XonoticCrosshairPreview).draw(me);
 }
-#endif
diff --git a/qcsrc/menu/xonotic/crosshairpreview.qh b/qcsrc/menu/xonotic/crosshairpreview.qh
index 6f70f09be..dcc7be5ac 100644
--- a/qcsrc/menu/xonotic/crosshairpreview.qh
+++ b/qcsrc/menu/xonotic/crosshairpreview.qh
@@ -1 +1,12 @@
 #pragma once
+
+#include "../item.qh"
+CLASS(XonoticCrosshairPreview, Item)
+	METHOD(XonoticCrosshairPreview, configureXonoticCrosshairPreview, void(entity));
+	METHOD(XonoticCrosshairPreview, draw, void(entity));
+	ATTRIB(XonoticCrosshairPreview, src, string, string_null)
+	ATTRIB(XonoticCrosshairPreview, src2, string, string_null)
+	ATTRIB(XonoticCrosshairPreview, disabled, float, 0)
+	ATTRIB(XonoticCrosshairPreview, disabledAlpha, float, SKINALPHA_DISABLED)
+ENDCLASS(XonoticCrosshairPreview)
+entity makeXonoticCrosshairPreview();
diff --git a/qcsrc/menu/xonotic/cvarlist.qc b/qcsrc/menu/xonotic/cvarlist.qc
index 433194ba0..956285ec8 100644
--- a/qcsrc/menu/xonotic/cvarlist.qc
+++ b/qcsrc/menu/xonotic/cvarlist.qc
@@ -1,50 +1,8 @@
 #include "cvarlist.qh"
-#ifndef CVARLIST_H
-#define CVARLIST_H
-#include "listbox.qc"
-CLASS(XonoticCvarList, XonoticListBox)
-	METHOD(XonoticCvarList, configureXonoticCvarList, void(entity));
-	ATTRIB(XonoticCvarList, rowsPerItem, float, 1)
-	METHOD(XonoticCvarList, drawListBoxItem, void(entity, int, vector, bool, bool));
-	METHOD(XonoticCvarList, resizeNotify, void(entity, vector, vector, vector, vector));
-	METHOD(XonoticCvarList, keyDown, float(entity, float, float, float));
-	METHOD(XonoticCvarList, showNotify, void(entity));
 
-	METHOD(XonoticCvarList, destroy, void(entity));
+#include "inputbox.qh"
+#include "../item/container.qh"
 
-	ATTRIB(XonoticCvarList, realFontSize, vector, '0 0 0')
-	ATTRIB(XonoticCvarList, realUpperMargin, float, 0)
-	ATTRIB(XonoticCvarList, columnNameOrigin, float, 0)
-	ATTRIB(XonoticCvarList, columnNameSize, float, 0)
-	ATTRIB(XonoticCvarList, columnValueOrigin, float, 0)
-	ATTRIB(XonoticCvarList, columnValueSize, float, 0)
-
-	METHOD(XonoticCvarList, mouseRelease, float(entity, vector));
-	METHOD(XonoticCvarList, setSelected, void(entity, float));
-	METHOD(XonoticCvarList, updateCvarType, float(entity));
-
-	ATTRIB(XonoticCvarList, controlledTextbox, entity, NULL)
-	ATTRIB(XonoticCvarList, cvarNameBox, entity, NULL)
-	ATTRIB(XonoticCvarList, cvarDescriptionBox, entity, NULL)
-	ATTRIB(XonoticCvarList, cvarTypeBox, entity, NULL)
-	ATTRIB(XonoticCvarList, cvarValueBox, entity, NULL)
-	ATTRIB(XonoticCvarList, cvarDefaultBox, entity, NULL)
-	ATTRIB(XonoticCvarList, cvarNeedsForcing, float, 0)
-
-	ATTRIB(XonoticCvarList, handle, float, -1)
-	ATTRIB(XonoticCvarList, cvarName, string, string_null)
-	ATTRIB(XonoticCvarList, cvarDescription, string, string_null)
-	ATTRIB(XonoticCvarList, cvarType, string, string_null)
-	ATTRIB(XonoticCvarList, cvarDefault, string, string_null)
-ENDCLASS(XonoticCvarList)
-entity makeXonoticCvarList();
-void CvarList_Filter_Change(entity box, entity me);
-void CvarList_Value_Change(entity box, entity me);
-void CvarList_Revert_Click(entity btn, entity me);
-void CvarList_End_Editing(entity box, entity me);
-#endif
-
-#ifdef IMPLEMENTATION
 entity makeXonoticCvarList()
 {
 	entity me;
@@ -266,5 +224,3 @@ void CvarList_End_Editing(entity box, entity me)
 {
 	box.parent.setFocus(box.parent, me);
 }
-
-#endif
diff --git a/qcsrc/menu/xonotic/cvarlist.qh b/qcsrc/menu/xonotic/cvarlist.qh
index 6f70f09be..4bc56b3b8 100644
--- a/qcsrc/menu/xonotic/cvarlist.qh
+++ b/qcsrc/menu/xonotic/cvarlist.qh
@@ -1 +1,43 @@
 #pragma once
+
+#include "listbox.qh"
+CLASS(XonoticCvarList, XonoticListBox)
+	METHOD(XonoticCvarList, configureXonoticCvarList, void(entity));
+	ATTRIB(XonoticCvarList, rowsPerItem, float, 1)
+	METHOD(XonoticCvarList, drawListBoxItem, void(entity, int, vector, bool, bool));
+	METHOD(XonoticCvarList, resizeNotify, void(entity, vector, vector, vector, vector));
+	METHOD(XonoticCvarList, keyDown, float(entity, float, float, float));
+	METHOD(XonoticCvarList, showNotify, void(entity));
+
+	METHOD(XonoticCvarList, destroy, void(entity));
+
+	ATTRIB(XonoticCvarList, realFontSize, vector, '0 0 0')
+	ATTRIB(XonoticCvarList, realUpperMargin, float, 0)
+	ATTRIB(XonoticCvarList, columnNameOrigin, float, 0)
+	ATTRIB(XonoticCvarList, columnNameSize, float, 0)
+	ATTRIB(XonoticCvarList, columnValueOrigin, float, 0)
+	ATTRIB(XonoticCvarList, columnValueSize, float, 0)
+
+	METHOD(XonoticCvarList, mouseRelease, float(entity, vector));
+	METHOD(XonoticCvarList, setSelected, void(entity, float));
+	METHOD(XonoticCvarList, updateCvarType, float(entity));
+
+	ATTRIB(XonoticCvarList, controlledTextbox, entity, NULL)
+	ATTRIB(XonoticCvarList, cvarNameBox, entity, NULL)
+	ATTRIB(XonoticCvarList, cvarDescriptionBox, entity, NULL)
+	ATTRIB(XonoticCvarList, cvarTypeBox, entity, NULL)
+	ATTRIB(XonoticCvarList, cvarValueBox, entity, NULL)
+	ATTRIB(XonoticCvarList, cvarDefaultBox, entity, NULL)
+	ATTRIB(XonoticCvarList, cvarNeedsForcing, float, 0)
+
+	ATTRIB(XonoticCvarList, handle, float, -1)
+	ATTRIB(XonoticCvarList, cvarName, string, string_null)
+	ATTRIB(XonoticCvarList, cvarDescription, string, string_null)
+	ATTRIB(XonoticCvarList, cvarType, string, string_null)
+	ATTRIB(XonoticCvarList, cvarDefault, string, string_null)
+ENDCLASS(XonoticCvarList)
+entity makeXonoticCvarList();
+void CvarList_Filter_Change(entity box, entity me);
+void CvarList_Value_Change(entity box, entity me);
+void CvarList_Revert_Click(entity btn, entity me);
+void CvarList_End_Editing(entity box, entity me);
diff --git a/qcsrc/menu/xonotic/datasource.qc b/qcsrc/menu/xonotic/datasource.qc
index 809f79682..d51a1f748 100644
--- a/qcsrc/menu/xonotic/datasource.qc
+++ b/qcsrc/menu/xonotic/datasource.qc
@@ -1,31 +1,5 @@
 #include "datasource.qh"
-#ifndef DATASOURCE_H
-#define DATASOURCE_H
-CLASS(DataSource, Object)
-    entity DataSource_true;
-    entity DataSource_false;
-    INIT_STATIC(DataSource) {
-        DataSource_true = NEW(Object);
-        DataSource_false = NULL;
-    }
-    /**
-     * get entry `i` passing `name` and `icon` through `returns` if it is not null
-     * returns `DataSource_false` if out of bounds
-     * otherwise returns an entity or `DataSource_true`
-     */
-    METHOD(DataSource, getEntry, entity(entity this, int i, void(string name, string icon) returns)) { return DataSource_false; }
-    /** return the index of the first match for `find`. optional */
-    METHOD(DataSource, indexOf, int(entity this, string find)) { return -1; }
-    /** reload all entries matching `filter` returning how many matches were found */
-    METHOD(DataSource, reload, int(entity this, string filter)) { return 0; }
-    /** cleanup on shutdown. optional */
-    METHOD(DataSource, destroy, void(entity this)) { }
-ENDCLASS(DataSource)
-
 
-CLASS(StringSource, DataSource)
-    ATTRIB(StringSource, StringSource_str, string, string_null)
-    ATTRIB(StringSource, StringSource_sep, string, string_null)
     CONSTRUCTOR(StringSource, string str, string sep)
     {
         CONSTRUCT(StringSource);
@@ -44,10 +18,7 @@ CLASS(StringSource, DataSource)
     {
         return tokenizebyseparator(this.StringSource_str, this.StringSource_sep);
     }
-ENDCLASS(StringSource)
 
-CLASS(CvarStringSource, StringSource)
-    ATTRIB(CvarStringSource, CvarStringSource_cvar, string, string_null)
     CONSTRUCTOR(CvarStringSource, string cv, string sep)
     {
         CONSTRUCT(CvarStringSource);
@@ -66,5 +37,3 @@ CLASS(CvarStringSource, StringSource)
         this.StringSource_str = s ? cvar_string(s) : string_null;
         return SUPER(CvarStringSource).reload(this, filter);
     }
-ENDCLASS(CvarStringSource)
-#endif
diff --git a/qcsrc/menu/xonotic/datasource.qh b/qcsrc/menu/xonotic/datasource.qh
index 6f70f09be..1808b7655 100644
--- a/qcsrc/menu/xonotic/datasource.qh
+++ b/qcsrc/menu/xonotic/datasource.qh
@@ -1 +1,38 @@
 #pragma once
+
+CLASS(DataSource, Object)
+    entity DataSource_true;
+    entity DataSource_false;
+    INIT_STATIC(DataSource) {
+        DataSource_true = NEW(Object);
+        DataSource_false = NULL;
+    }
+    /**
+     * get entry `i` passing `name` and `icon` through `returns` if it is not null
+     * returns `DataSource_false` if out of bounds
+     * otherwise returns an entity or `DataSource_true`
+     */
+    METHOD(DataSource, getEntry, entity(entity this, int i, void(string name, string icon) returns)) { return DataSource_false; }
+    /** return the index of the first match for `find`. optional */
+    METHOD(DataSource, indexOf, int(entity this, string find)) { return -1; }
+    /** reload all entries matching `filter` returning how many matches were found */
+    METHOD(DataSource, reload, int(entity this, string filter)) { return 0; }
+    /** cleanup on shutdown. optional */
+    METHOD(DataSource, destroy, void(entity this)) { }
+ENDCLASS(DataSource)
+
+
+CLASS(StringSource, DataSource)
+    ATTRIB(StringSource, StringSource_str, string, string_null)
+    ATTRIB(StringSource, StringSource_sep, string, string_null)
+    CONSTRUCTOR(StringSource, string str, string sep);
+    METHOD(StringSource, getEntry, entity(entity this, int i, void(string name, string icon) returns));
+    METHOD(StringSource, reload, int(entity this, string filter));
+ENDCLASS(StringSource)
+
+CLASS(CvarStringSource, StringSource)
+    ATTRIB(CvarStringSource, CvarStringSource_cvar, string, string_null)
+    CONSTRUCTOR(CvarStringSource, string cv, string sep);
+    METHOD(CvarStringSource, getEntry, entity(entity this, int i, void(string name, string icon) returns));
+    METHOD(CvarStringSource, reload, int(entity this, string filter));
+ENDCLASS(CvarStringSource)
diff --git a/qcsrc/menu/xonotic/demolist.qc b/qcsrc/menu/xonotic/demolist.qc
index 6f1a2a6e1..b527542a5 100644
--- a/qcsrc/menu/xonotic/demolist.qc
+++ b/qcsrc/menu/xonotic/demolist.qc
@@ -1,42 +1,6 @@
 #include "demolist.qh"
-#ifndef DEMOLIST_H
-#define DEMOLIST_H
-#include "listbox.qc"
-CLASS(XonoticDemoList, XonoticListBox)
-	METHOD(XonoticDemoList, configureXonoticDemoList, void(entity));
-	ATTRIB(XonoticDemoList, rowsPerItem, float, 1)
-	METHOD(XonoticDemoList, resizeNotify, void(entity, vector, vector, vector, vector));
-	METHOD(XonoticDemoList, drawListBoxItem, void(entity, int, vector, bool, bool));
-	METHOD(XonoticDemoList, getDemos, void(entity));
-	METHOD(XonoticDemoList, startDemo, void(entity));
-	METHOD(XonoticDemoList, timeDemo, void(entity));
-	METHOD(XonoticDemoList, demoName, string(entity, float));
-	METHOD(XonoticDemoList, doubleClickListBoxItem, void(entity, float, vector));
-	METHOD(XonoticDemoList, keyDown, float(entity, float, float, float));
-	METHOD(XonoticDemoList, destroy, void(entity));
-	METHOD(XonoticDemoList, showNotify, void(entity));
-
-	ATTRIB(XonoticDemoList, listDemo, float, -1)
-	ATTRIB(XonoticDemoList, realFontSize, vector, '0 0 0')
-	ATTRIB(XonoticDemoList, columnNameOrigin, float, 0)
-	ATTRIB(XonoticDemoList, columnNameSize, float, 0)
-	ATTRIB(XonoticDemoList, realUpperMargin, float, 0)
-	ATTRIB(XonoticDemoList, origin, vector, '0 0 0')
-	ATTRIB(XonoticDemoList, itemAbsSize, vector, '0 0 0')
-
-	ATTRIB(XonoticDemoList, filterString, string, string_null)
-ENDCLASS(XonoticDemoList)
-
-#ifndef IMPLEMENTATION
-// public:
-entity demolist; // for reference elsewhere
-entity makeXonoticDemoList();
-#endif
-void DemoList_Refresh_Click(entity btn, entity me);
-void DemoList_Filter_Change(entity box, entity me);
-#endif
-
-#ifdef IMPLEMENTATION
+
+#include "inputbox.qh"
 
 entity makeXonoticDemoList()
 {
@@ -233,5 +197,3 @@ float XonoticDemoList_keyDown(entity me, float scan, float ascii, float shift)
 		return SUPER(XonoticDemoList).keyDown(me, scan, ascii, shift);
 	}
 }
-#endif
-
diff --git a/qcsrc/menu/xonotic/demolist.qh b/qcsrc/menu/xonotic/demolist.qh
index 6f70f09be..547bf6695 100644
--- a/qcsrc/menu/xonotic/demolist.qh
+++ b/qcsrc/menu/xonotic/demolist.qh
@@ -1 +1,33 @@
 #pragma once
+
+#include "mainwindow.qh"
+#include "listbox.qh"
+CLASS(XonoticDemoList, XonoticListBox)
+	METHOD(XonoticDemoList, configureXonoticDemoList, void(entity));
+	ATTRIB(XonoticDemoList, rowsPerItem, float, 1)
+	METHOD(XonoticDemoList, resizeNotify, void(entity, vector, vector, vector, vector));
+	METHOD(XonoticDemoList, drawListBoxItem, void(entity, int, vector, bool, bool));
+	METHOD(XonoticDemoList, getDemos, void(entity));
+	METHOD(XonoticDemoList, startDemo, void(entity));
+	METHOD(XonoticDemoList, timeDemo, void(entity));
+	METHOD(XonoticDemoList, demoName, string(entity, float));
+	METHOD(XonoticDemoList, doubleClickListBoxItem, void(entity, float, vector));
+	METHOD(XonoticDemoList, keyDown, float(entity, float, float, float));
+	METHOD(XonoticDemoList, destroy, void(entity));
+	METHOD(XonoticDemoList, showNotify, void(entity));
+
+	ATTRIB(XonoticDemoList, listDemo, float, -1)
+	ATTRIB(XonoticDemoList, realFontSize, vector, '0 0 0')
+	ATTRIB(XonoticDemoList, columnNameOrigin, float, 0)
+	ATTRIB(XonoticDemoList, columnNameSize, float, 0)
+	ATTRIB(XonoticDemoList, realUpperMargin, float, 0)
+	ATTRIB(XonoticDemoList, origin, vector, '0 0 0')
+	ATTRIB(XonoticDemoList, itemAbsSize, vector, '0 0 0')
+
+	ATTRIB(XonoticDemoList, filterString, string, string_null)
+ENDCLASS(XonoticDemoList)
+
+entity demolist;  // for reference elsewhere
+entity makeXonoticDemoList();
+void DemoList_Refresh_Click(entity btn, entity me);
+void DemoList_Filter_Change(entity box, entity me);
diff --git a/qcsrc/menu/xonotic/dialog.qc b/qcsrc/menu/xonotic/dialog.qc
index 1394b1897..6b5e7a1c8 100644
--- a/qcsrc/menu/xonotic/dialog.qc
+++ b/qcsrc/menu/xonotic/dialog.qc
@@ -1,46 +1,7 @@
 #include "dialog.qh"
-#ifndef DIALOG_H
-#define DIALOG_H
-#include "../item/dialog.qc"
-CLASS(XonoticDialog, Dialog)
-	// still to be customized by user
-	/*
-	ATTRIB(XonoticDialog, closable, float, 1)
-	ATTRIB(XonoticDialog, title, string, _("Form1")) // ;)
-	ATTRIB(XonoticDialog, color, vector, '1 0.5 1')
-	ATTRIB(XonoticDialog, intendedWidth, float, 0)
-	ATTRIB(XonoticDialog, rows, float, 3)
-	ATTRIB(XonoticDialog, columns, float, 2)
-	*/
-	ATTRIB(XonoticDialog, marginTop, float, SKINMARGIN_TOP) // pixels
-	ATTRIB(XonoticDialog, marginBottom, float, SKINMARGIN_BOTTOM) // pixels
-	ATTRIB(XonoticDialog, marginLeft, float, SKINMARGIN_LEFT) // pixels
-	ATTRIB(XonoticDialog, marginRight, float, SKINMARGIN_RIGHT) // pixels
-	ATTRIB(XonoticDialog, columnSpacing, float, SKINMARGIN_COLUMNS) // pixels
-	ATTRIB(XonoticDialog, rowSpacing, float, SKINMARGIN_ROWS) // pixels
-	ATTRIB(XonoticDialog, rowHeight, float, SKINFONTSIZE_NORMAL * SKINHEIGHT_NORMAL) // pixels
-	ATTRIB(XonoticDialog, titleHeight, float, SKINFONTSIZE_TITLE * SKINHEIGHT_TITLE) // pixels
-	ATTRIB(XonoticDialog, titleFontSize, float, SKINFONTSIZE_TITLE) // pixels
 
-	ATTRIB(XonoticDialog, backgroundImage, string, SKINGFX_DIALOGBORDER)
-	ATTRIB(XonoticDialog, borderLines, float, SKINHEIGHT_DIALOGBORDER)
-	ATTRIB(XonoticDialog, closeButtonImage, string, SKINGFX_CLOSEBUTTON)
-	ATTRIB(XonoticDialog, zoomedOutTitleBarPosition, float, SKINHEIGHT_ZOOMEDTITLE * 0.5 - 0.5)
-	ATTRIB(XonoticDialog, zoomedOutTitleBar, float, SKINHEIGHT_ZOOMEDTITLE != 0)
-
-	ATTRIB(XonoticDialog, alpha, float, SKINALPHA_TEXT)
-
-	METHOD(XonoticDialog, configureDialog, void(entity));
-ENDCLASS(XonoticDialog)
-#ifndef IMPLEMENTATION
-entity currentDialog;
-#endif
-#endif
-
-#ifdef IMPLEMENTATION
 void XonoticDialog_configureDialog(entity me)
 {
 	currentDialog = me;
 	SUPER(XonoticDialog).configureDialog(me);
 }
-#endif
diff --git a/qcsrc/menu/xonotic/dialog.qh b/qcsrc/menu/xonotic/dialog.qh
index 6f70f09be..a3612698f 100644
--- a/qcsrc/menu/xonotic/dialog.qh
+++ b/qcsrc/menu/xonotic/dialog.qh
@@ -1 +1,35 @@
 #pragma once
+
+#include "../item/dialog.qh"
+CLASS(XonoticDialog, Dialog)
+	// still to be customized by user
+	/*
+	ATTRIB(XonoticDialog, closable, float, 1)
+	ATTRIB(XonoticDialog, title, string, _("Form1")) // ;)
+	ATTRIB(XonoticDialog, color, vector, '1 0.5 1')
+	ATTRIB(XonoticDialog, intendedWidth, float, 0)
+	ATTRIB(XonoticDialog, rows, float, 3)
+	ATTRIB(XonoticDialog, columns, float, 2)
+	*/
+	ATTRIB(XonoticDialog, marginTop, float, SKINMARGIN_TOP)                          // pixels
+	ATTRIB(XonoticDialog, marginBottom, float, SKINMARGIN_BOTTOM)                    // pixels
+	ATTRIB(XonoticDialog, marginLeft, float, SKINMARGIN_LEFT)                        // pixels
+	ATTRIB(XonoticDialog, marginRight, float, SKINMARGIN_RIGHT)                      // pixels
+	ATTRIB(XonoticDialog, columnSpacing, float, SKINMARGIN_COLUMNS)                  // pixels
+	ATTRIB(XonoticDialog, rowSpacing, float, SKINMARGIN_ROWS)                        // pixels
+	ATTRIB(XonoticDialog, rowHeight, float, SKINFONTSIZE_NORMAL * SKINHEIGHT_NORMAL) // pixels
+	ATTRIB(XonoticDialog, titleHeight, float, SKINFONTSIZE_TITLE * SKINHEIGHT_TITLE) // pixels
+	ATTRIB(XonoticDialog, titleFontSize, float, SKINFONTSIZE_TITLE)                  // pixels
+
+	ATTRIB(XonoticDialog, backgroundImage, string, SKINGFX_DIALOGBORDER)
+	ATTRIB(XonoticDialog, borderLines, float, SKINHEIGHT_DIALOGBORDER)
+	ATTRIB(XonoticDialog, closeButtonImage, string, SKINGFX_CLOSEBUTTON)
+	ATTRIB(XonoticDialog, zoomedOutTitleBarPosition, float, SKINHEIGHT_ZOOMEDTITLE * 0.5 - 0.5)
+	ATTRIB(XonoticDialog, zoomedOutTitleBar, float, SKINHEIGHT_ZOOMEDTITLE != 0)
+
+	ATTRIB(XonoticDialog, alpha, float, SKINALPHA_TEXT)
+
+	METHOD(XonoticDialog, configureDialog, void(entity));
+ENDCLASS(XonoticDialog)
+
+entity currentDialog;
diff --git a/qcsrc/menu/xonotic/dialog_credits.qc b/qcsrc/menu/xonotic/dialog_credits.qc
index 8a2568dac..16469dbdd 100644
--- a/qcsrc/menu/xonotic/dialog_credits.qc
+++ b/qcsrc/menu/xonotic/dialog_credits.qc
@@ -1,21 +1,9 @@
 #include "dialog_credits.qh"
-#ifndef DIALOG_CREDITS_H
-#define DIALOG_CREDITS_H
-#include "dialog.qc"
-CLASS(XonoticCreditsDialog, XonoticDialog)
-	METHOD(XonoticCreditsDialog, fill, void(entity));
-	METHOD(XonoticCreditsDialog, focusEnter, void(entity));
-	ATTRIB(XonoticCreditsDialog, title, string, _("Credits"))
-	ATTRIB(XonoticCreditsDialog, tooltip, string, _("The Xonotic credits"))
-	ATTRIB(XonoticCreditsDialog, color, vector, SKINCOLOR_DIALOG_CREDITS)
-	ATTRIB(XonoticCreditsDialog, intendedWidth, float, SKINWIDTH_CREDITS)
-	ATTRIB(XonoticCreditsDialog, rows, float, SKINROWS_CREDITS)
-	ATTRIB(XonoticCreditsDialog, columns, float, 2)
-	ATTRIB(XonoticCreditsDialog, creditsList, entity, NULL)
-ENDCLASS(XonoticCreditsDialog)
-#endif
 
-#ifdef IMPLEMENTATION
+#include "credits.qh"
+#include "button.qh"
+#include "../item/dialog.qh"
+
 void XonoticCreditsDialog_fill(entity me)
 {
 	entity e;
@@ -30,4 +18,3 @@ void XonoticCreditsDialog_focusEnter(entity me)
 {
 	me.creditsList.scrolling = time + 1;
 }
-#endif
diff --git a/qcsrc/menu/xonotic/dialog_credits.qh b/qcsrc/menu/xonotic/dialog_credits.qh
index 6f70f09be..90d722ed3 100644
--- a/qcsrc/menu/xonotic/dialog_credits.qh
+++ b/qcsrc/menu/xonotic/dialog_credits.qh
@@ -1 +1,14 @@
 #pragma once
+
+#include "dialog.qh"
+CLASS(XonoticCreditsDialog, XonoticDialog)
+	METHOD(XonoticCreditsDialog, fill, void(entity));
+	METHOD(XonoticCreditsDialog, focusEnter, void(entity));
+	ATTRIB(XonoticCreditsDialog, title, string, _("Credits"))
+	ATTRIB(XonoticCreditsDialog, tooltip, string, _("The Xonotic credits"))
+	ATTRIB(XonoticCreditsDialog, color, vector, SKINCOLOR_DIALOG_CREDITS)
+	ATTRIB(XonoticCreditsDialog, intendedWidth, float, SKINWIDTH_CREDITS)
+	ATTRIB(XonoticCreditsDialog, rows, float, SKINROWS_CREDITS)
+	ATTRIB(XonoticCreditsDialog, columns, float, 2)
+	ATTRIB(XonoticCreditsDialog, creditsList, entity, NULL)
+ENDCLASS(XonoticCreditsDialog)
diff --git a/qcsrc/menu/xonotic/dialog_firstrun.qc b/qcsrc/menu/xonotic/dialog_firstrun.qc
index f117d3a6f..0d3b5c975 100644
--- a/qcsrc/menu/xonotic/dialog_firstrun.qc
+++ b/qcsrc/menu/xonotic/dialog_firstrun.qc
@@ -1,23 +1,13 @@
 #include "dialog_firstrun.qh"
-#ifndef DIALOG_FIRSTRUN_H
-#define DIALOG_FIRSTRUN_H
-#include "rootdialog.qc"
-CLASS(XonoticFirstRunDialog, XonoticRootDialog)
-	METHOD(XonoticFirstRunDialog, fill, void(entity));
-	ATTRIB(XonoticFirstRunDialog, title, string, _("Welcome"))
-	ATTRIB(XonoticFirstRunDialog, color, vector, SKINCOLOR_DIALOG_FIRSTRUN)
-	ATTRIB(XonoticFirstRunDialog, intendedWidth, float, 0.7)
-	ATTRIB(XonoticFirstRunDialog, rows, float, 16)
-	ATTRIB(XonoticFirstRunDialog, columns, float, 6)
-	ATTRIB(XonoticFirstRunDialog, name, string, "FirstRun")
-	ATTRIB(XonoticFirstRunDialog, playerNameLabel, entity, NULL)
-	ATTRIB(XonoticFirstRunDialog, playerNameLabelAlpha, float, 0)
 
-	ATTRIB(XonoticFirstRunDialog, closable, float, 0)
-ENDCLASS(XonoticFirstRunDialog)
-#endif
+#include "textlabel.qh"
+#include "inputbox.qh"
+#include "languagelist.qh"
+#include "radiobutton.qh"
+#include "colorpicker.qh"
+#include "charmap.qh"
+#include "commandbutton.qh"
 
-#ifdef IMPLEMENTATION
 float CheckFirstRunButton(entity me)
 {
 	if(cvar_string("_cl_name") != cvar_defstring("_cl_name"))
@@ -98,4 +88,3 @@ void XonoticFirstRunDialog_fill(entity me)
 	me.TD(me, 1, me.columns, e = makeXonoticCommandButton(_("Save settings"), '0 0 0', "prvm_language \"$_menu_prvm_language\"; saveconfig; menu_restart", COMMANDBUTTON_APPLY));
 		setDependentWeird(e, CheckFirstRunButton);
 }
-#endif
diff --git a/qcsrc/menu/xonotic/dialog_firstrun.qh b/qcsrc/menu/xonotic/dialog_firstrun.qh
index 6f70f09be..ff7099b6b 100644
--- a/qcsrc/menu/xonotic/dialog_firstrun.qh
+++ b/qcsrc/menu/xonotic/dialog_firstrun.qh
@@ -1 +1,16 @@
 #pragma once
+
+#include "rootdialog.qh"
+CLASS(XonoticFirstRunDialog, XonoticRootDialog)
+	METHOD(XonoticFirstRunDialog, fill, void(entity));
+	ATTRIB(XonoticFirstRunDialog, title, string, _("Welcome"))
+	ATTRIB(XonoticFirstRunDialog, color, vector, SKINCOLOR_DIALOG_FIRSTRUN)
+	ATTRIB(XonoticFirstRunDialog, intendedWidth, float, 0.7)
+	ATTRIB(XonoticFirstRunDialog, rows, float, 16)
+	ATTRIB(XonoticFirstRunDialog, columns, float, 6)
+	ATTRIB(XonoticFirstRunDialog, name, string, "FirstRun")
+	ATTRIB(XonoticFirstRunDialog, playerNameLabel, entity, NULL)
+	ATTRIB(XonoticFirstRunDialog, playerNameLabelAlpha, float, 0)
+
+	ATTRIB(XonoticFirstRunDialog, closable, float, 0)
+ENDCLASS(XonoticFirstRunDialog)
diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_ammo.qc b/qcsrc/menu/xonotic/dialog_hudpanel_ammo.qc
index 49b7ba272..2e67e7acf 100644
--- a/qcsrc/menu/xonotic/dialog_hudpanel_ammo.qc
+++ b/qcsrc/menu/xonotic/dialog_hudpanel_ammo.qc
@@ -1,20 +1,10 @@
 #include "dialog_hudpanel_ammo.qh"
-#ifndef DIALOG_HUDPANEL_AMMO_H
-#define DIALOG_HUDPANEL_AMMO_H
-#include "rootdialog.qc"
-CLASS(XonoticHUDAmmoDialog, XonoticRootDialog)
-	METHOD(XonoticHUDAmmoDialog, fill, void(entity));
-	ATTRIB(XonoticHUDAmmoDialog, title, string, _("Ammo Panel"))
-	ATTRIB(XonoticHUDAmmoDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT)
-	ATTRIB(XonoticHUDAmmoDialog, intendedWidth, float, 0.4)
-	ATTRIB(XonoticHUDAmmoDialog, rows, float, 15)
-	ATTRIB(XonoticHUDAmmoDialog, columns, float, 4)
-	ATTRIB(XonoticHUDAmmoDialog, name, string, "HUDammo")
-	ATTRIB(XonoticHUDAmmoDialog, requiresConnection, float, true)
-ENDCLASS(XonoticHUDAmmoDialog)
-#endif
 
-#ifdef IMPLEMENTATION
+#include "slider.qh"
+#include "checkbox.qh"
+#include "textlabel.qh"
+#include "radiobutton.qh"
+
 void XonoticHUDAmmoDialog_fill(entity me)
 {
 	entity e;
@@ -41,4 +31,3 @@ void XonoticHUDAmmoDialog_fill(entity me)
 			me.TD(me, 1, 2.6/2, e = makeXonoticRadioButton(2, "hud_panel_ammo_iconalign", "0", _("Left")));
 			me.TD(me, 1, 2.6/2, e = makeXonoticRadioButton(2, "hud_panel_ammo_iconalign", "1", _("Right")));
 }
-#endif
diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_ammo.qh b/qcsrc/menu/xonotic/dialog_hudpanel_ammo.qh
index 6f70f09be..237bcbbd1 100644
--- a/qcsrc/menu/xonotic/dialog_hudpanel_ammo.qh
+++ b/qcsrc/menu/xonotic/dialog_hudpanel_ammo.qh
@@ -1 +1,13 @@
 #pragma once
+
+#include "rootdialog.qh"
+CLASS(XonoticHUDAmmoDialog, XonoticRootDialog)
+	METHOD(XonoticHUDAmmoDialog, fill, void(entity));
+	ATTRIB(XonoticHUDAmmoDialog, title, string, _("Ammo Panel"))
+	ATTRIB(XonoticHUDAmmoDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT)
+	ATTRIB(XonoticHUDAmmoDialog, intendedWidth, float, 0.4)
+	ATTRIB(XonoticHUDAmmoDialog, rows, float, 15)
+	ATTRIB(XonoticHUDAmmoDialog, columns, float, 4)
+	ATTRIB(XonoticHUDAmmoDialog, name, string, "HUDammo")
+	ATTRIB(XonoticHUDAmmoDialog, requiresConnection, float, true)
+ENDCLASS(XonoticHUDAmmoDialog)
diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_centerprint.qc b/qcsrc/menu/xonotic/dialog_hudpanel_centerprint.qc
index c1fa78578..332f6753f 100644
--- a/qcsrc/menu/xonotic/dialog_hudpanel_centerprint.qc
+++ b/qcsrc/menu/xonotic/dialog_hudpanel_centerprint.qc
@@ -1,20 +1,10 @@
 #include "dialog_hudpanel_centerprint.qh"
-#ifndef DIALOG_HUDPANEL_CENTERPRINT_H
-#define DIALOG_HUDPANEL_CENTERPRINT_H
-#include "rootdialog.qc"
-CLASS(XonoticHUDCenterprintDialog, XonoticRootDialog)
-	METHOD(XonoticHUDCenterprintDialog, fill, void(entity));
-	ATTRIB(XonoticHUDCenterprintDialog, title, string, _("Centerprint Panel"))
-	ATTRIB(XonoticHUDCenterprintDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT)
-	ATTRIB(XonoticHUDCenterprintDialog, intendedWidth, float, 0.4)
-	ATTRIB(XonoticHUDCenterprintDialog, rows, float, 15)
-	ATTRIB(XonoticHUDCenterprintDialog, columns, float, 4)
-	ATTRIB(XonoticHUDCenterprintDialog, name, string, "HUDcenterprint")
-	ATTRIB(XonoticHUDCenterprintDialog, requiresConnection, float, true)
-ENDCLASS(XonoticHUDCenterprintDialog)
-#endif
 
-#ifdef IMPLEMENTATION
+#include "checkbox.qh"
+#include "textlabel.qh"
+#include "slider.qh"
+#include "radiobutton.qh"
+
 void XonoticHUDCenterprintDialog_fill(entity me)
 {
 	entity e;
@@ -45,4 +35,3 @@ void XonoticHUDCenterprintDialog_fill(entity me)
 		me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Font scale:")));
 		me.TD(me, 1, 2.6, e = makeXonoticSlider(0.5, 2, 0.1, "hud_panel_centerprint_fontscale"));
 }
-#endif
diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_centerprint.qh b/qcsrc/menu/xonotic/dialog_hudpanel_centerprint.qh
index 6f70f09be..370dbe4eb 100644
--- a/qcsrc/menu/xonotic/dialog_hudpanel_centerprint.qh
+++ b/qcsrc/menu/xonotic/dialog_hudpanel_centerprint.qh
@@ -1 +1,13 @@
 #pragma once
+
+#include "rootdialog.qh"
+CLASS(XonoticHUDCenterprintDialog, XonoticRootDialog)
+	METHOD(XonoticHUDCenterprintDialog, fill, void(entity));
+	ATTRIB(XonoticHUDCenterprintDialog, title, string, _("Centerprint Panel"))
+	ATTRIB(XonoticHUDCenterprintDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT)
+	ATTRIB(XonoticHUDCenterprintDialog, intendedWidth, float, 0.4)
+	ATTRIB(XonoticHUDCenterprintDialog, rows, float, 15)
+	ATTRIB(XonoticHUDCenterprintDialog, columns, float, 4)
+	ATTRIB(XonoticHUDCenterprintDialog, name, string, "HUDcenterprint")
+	ATTRIB(XonoticHUDCenterprintDialog, requiresConnection, float, true)
+ENDCLASS(XonoticHUDCenterprintDialog)
diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_chat.qc b/qcsrc/menu/xonotic/dialog_hudpanel_chat.qc
index 380dfcc03..1ffa41f68 100644
--- a/qcsrc/menu/xonotic/dialog_hudpanel_chat.qc
+++ b/qcsrc/menu/xonotic/dialog_hudpanel_chat.qc
@@ -1,20 +1,9 @@
 #include "dialog_hudpanel_chat.qh"
-#ifndef DIALOG_HUDPANEL_CHAT_H
-#define DIALOG_HUDPANEL_CHAT_H
-#include "rootdialog.qc"
-CLASS(XonoticHUDChatDialog, XonoticRootDialog)
-	METHOD(XonoticHUDChatDialog, fill, void(entity));
-	ATTRIB(XonoticHUDChatDialog, title, string, _("Chat Panel"))
-	ATTRIB(XonoticHUDChatDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT)
-	ATTRIB(XonoticHUDChatDialog, intendedWidth, float, 0.4)
-	ATTRIB(XonoticHUDChatDialog, rows, float, 15)
-	ATTRIB(XonoticHUDChatDialog, columns, float, 4)
-	ATTRIB(XonoticHUDChatDialog, name, string, "HUDchat")
-	ATTRIB(XonoticHUDChatDialog, requiresConnection, float, true)
-ENDCLASS(XonoticHUDChatDialog)
-#endif
 
-#ifdef IMPLEMENTATION
+#include "textlabel.qh"
+#include "checkbox.qh"
+#include "slider.qh"
+
 void XonoticHUDChatDialog_fill(entity me)
 {
 	entity e;
@@ -36,4 +25,3 @@ void XonoticHUDChatDialog_fill(entity me)
 		me.TDempty(me, 0.2);
 		me.TD(me, 1, 3.8, e = makeXonoticCheckBox(0, "con_chatsound", _("Chat beep sound")));
 }
-#endif
diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_chat.qh b/qcsrc/menu/xonotic/dialog_hudpanel_chat.qh
index 6f70f09be..b30ea9fb2 100644
--- a/qcsrc/menu/xonotic/dialog_hudpanel_chat.qh
+++ b/qcsrc/menu/xonotic/dialog_hudpanel_chat.qh
@@ -1 +1,13 @@
 #pragma once
+
+#include "rootdialog.qh"
+CLASS(XonoticHUDChatDialog, XonoticRootDialog)
+	METHOD(XonoticHUDChatDialog, fill, void(entity));
+	ATTRIB(XonoticHUDChatDialog, title, string, _("Chat Panel"))
+	ATTRIB(XonoticHUDChatDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT)
+	ATTRIB(XonoticHUDChatDialog, intendedWidth, float, 0.4)
+	ATTRIB(XonoticHUDChatDialog, rows, float, 15)
+	ATTRIB(XonoticHUDChatDialog, columns, float, 4)
+	ATTRIB(XonoticHUDChatDialog, name, string, "HUDchat")
+	ATTRIB(XonoticHUDChatDialog, requiresConnection, float, true)
+ENDCLASS(XonoticHUDChatDialog)
diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_engineinfo.qc b/qcsrc/menu/xonotic/dialog_hudpanel_engineinfo.qc
index 6b2c8ea59..b46d3aa02 100644
--- a/qcsrc/menu/xonotic/dialog_hudpanel_engineinfo.qc
+++ b/qcsrc/menu/xonotic/dialog_hudpanel_engineinfo.qc
@@ -1,20 +1,8 @@
 #include "dialog_hudpanel_engineinfo.qh"
-#ifndef DIALOG_HUDPANEL_ENGINEINFO_H
-#define DIALOG_HUDPANEL_ENGINEINFO_H
-#include "rootdialog.qc"
-CLASS(XonoticHUDEngineInfoDialog, XonoticRootDialog)
-	METHOD(XonoticHUDEngineInfoDialog, fill, void(entity));
-	ATTRIB(XonoticHUDEngineInfoDialog, title, string, _("Engine Info Panel"))
-	ATTRIB(XonoticHUDEngineInfoDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT)
-	ATTRIB(XonoticHUDEngineInfoDialog, intendedWidth, float, 0.4)
-	ATTRIB(XonoticHUDEngineInfoDialog, rows, float, 15)
-	ATTRIB(XonoticHUDEngineInfoDialog, columns, float, 4)
-	ATTRIB(XonoticHUDEngineInfoDialog, name, string, "HUDengineinfo")
-	ATTRIB(XonoticHUDEngineInfoDialog, requiresConnection, float, true)
-ENDCLASS(XonoticHUDEngineInfoDialog)
-#endif
 
-#ifdef IMPLEMENTATION
+#include "textlabel.qh"
+#include "checkbox.qh"
+
 void XonoticHUDEngineInfoDialog_fill(entity me)
 {
 	entity e;
@@ -28,4 +16,3 @@ void XonoticHUDEngineInfoDialog_fill(entity me)
 		me.TDempty(me, 0.2);
 		me.TD(me, 1, 3.8, e = makeXonoticCheckBox(0, "hud_panel_engineinfo_framecounter_exponentialmovingaverage", _("Use an averaging algorithm for fps")));
 }
-#endif
diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_engineinfo.qh b/qcsrc/menu/xonotic/dialog_hudpanel_engineinfo.qh
index 6f70f09be..a28897d8c 100644
--- a/qcsrc/menu/xonotic/dialog_hudpanel_engineinfo.qh
+++ b/qcsrc/menu/xonotic/dialog_hudpanel_engineinfo.qh
@@ -1 +1,13 @@
 #pragma once
+
+#include "rootdialog.qh"
+CLASS(XonoticHUDEngineInfoDialog, XonoticRootDialog)
+	METHOD(XonoticHUDEngineInfoDialog, fill, void(entity));
+	ATTRIB(XonoticHUDEngineInfoDialog, title, string, _("Engine Info Panel"))
+	ATTRIB(XonoticHUDEngineInfoDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT)
+	ATTRIB(XonoticHUDEngineInfoDialog, intendedWidth, float, 0.4)
+	ATTRIB(XonoticHUDEngineInfoDialog, rows, float, 15)
+	ATTRIB(XonoticHUDEngineInfoDialog, columns, float, 4)
+	ATTRIB(XonoticHUDEngineInfoDialog, name, string, "HUDengineinfo")
+	ATTRIB(XonoticHUDEngineInfoDialog, requiresConnection, float, true)
+ENDCLASS(XonoticHUDEngineInfoDialog)
diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_healtharmor.qc b/qcsrc/menu/xonotic/dialog_hudpanel_healtharmor.qc
index ddf3e9ac0..c158ebabf 100644
--- a/qcsrc/menu/xonotic/dialog_hudpanel_healtharmor.qc
+++ b/qcsrc/menu/xonotic/dialog_hudpanel_healtharmor.qc
@@ -1,20 +1,9 @@
 #include "dialog_hudpanel_healtharmor.qh"
-#ifndef DIALOG_HUDPANEL_HEALTHARMOR_H
-#define DIALOG_HUDPANEL_HEALTHARMOR_H
-#include "rootdialog.qc"
-CLASS(XonoticHUDHealthArmorDialog, XonoticRootDialog)
-	METHOD(XonoticHUDHealthArmorDialog, fill, void(entity));
-	ATTRIB(XonoticHUDHealthArmorDialog, title, string, _("Health/Armor Panel"))
-	ATTRIB(XonoticHUDHealthArmorDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT)
-	ATTRIB(XonoticHUDHealthArmorDialog, intendedWidth, float, 0.4)
-	ATTRIB(XonoticHUDHealthArmorDialog, rows, float, 15)
-	ATTRIB(XonoticHUDHealthArmorDialog, columns, float, 4)
-	ATTRIB(XonoticHUDHealthArmorDialog, name, string, "HUDhealtharmor")
-	ATTRIB(XonoticHUDHealthArmorDialog, requiresConnection, float, true)
-ENDCLASS(XonoticHUDHealthArmorDialog)
-#endif
 
-#ifdef IMPLEMENTATION
+#include "textlabel.qh"
+#include "checkbox.qh"
+#include "radiobutton.qh"
+
 void XonoticHUDHealthArmorDialog_fill(entity me)
 {
 	entity e;
@@ -48,4 +37,3 @@ void XonoticHUDHealthArmorDialog_fill(entity me)
 	me.TR(me);
 		me.TD(me, 1, 4, e = makeXonoticCheckBox(0, "hud_panel_healtharmor_flip", _("Flip health and armor positions")));
 }
-#endif
diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_healtharmor.qh b/qcsrc/menu/xonotic/dialog_hudpanel_healtharmor.qh
index 6f70f09be..68ffe79ea 100644
--- a/qcsrc/menu/xonotic/dialog_hudpanel_healtharmor.qh
+++ b/qcsrc/menu/xonotic/dialog_hudpanel_healtharmor.qh
@@ -1 +1,13 @@
 #pragma once
+
+#include "rootdialog.qh"
+CLASS(XonoticHUDHealthArmorDialog, XonoticRootDialog)
+	METHOD(XonoticHUDHealthArmorDialog, fill, void(entity));
+	ATTRIB(XonoticHUDHealthArmorDialog, title, string, _("Health/Armor Panel"))
+	ATTRIB(XonoticHUDHealthArmorDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT)
+	ATTRIB(XonoticHUDHealthArmorDialog, intendedWidth, float, 0.4)
+	ATTRIB(XonoticHUDHealthArmorDialog, rows, float, 15)
+	ATTRIB(XonoticHUDHealthArmorDialog, columns, float, 4)
+	ATTRIB(XonoticHUDHealthArmorDialog, name, string, "HUDhealtharmor")
+	ATTRIB(XonoticHUDHealthArmorDialog, requiresConnection, float, true)
+ENDCLASS(XonoticHUDHealthArmorDialog)
diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_infomessages.qc b/qcsrc/menu/xonotic/dialog_hudpanel_infomessages.qc
index 1d7f6ba61..d758ad206 100644
--- a/qcsrc/menu/xonotic/dialog_hudpanel_infomessages.qc
+++ b/qcsrc/menu/xonotic/dialog_hudpanel_infomessages.qc
@@ -1,20 +1,8 @@
 #include "dialog_hudpanel_infomessages.qh"
-#ifndef DIALOG_HUDPANEL_INFOMESSAGES_H
-#define DIALOG_HUDPANEL_INFOMESSAGES_H
-#include "rootdialog.qc"
-CLASS(XonoticHUDInfoMessagesDialog, XonoticRootDialog)
-	METHOD(XonoticHUDInfoMessagesDialog, fill, void(entity));
-	ATTRIB(XonoticHUDInfoMessagesDialog, title, string, _("Info Messages Panel"))
-	ATTRIB(XonoticHUDInfoMessagesDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT)
-	ATTRIB(XonoticHUDInfoMessagesDialog, intendedWidth, float, 0.4)
-	ATTRIB(XonoticHUDInfoMessagesDialog, rows, float, 15)
-	ATTRIB(XonoticHUDInfoMessagesDialog, columns, float, 4)
-	ATTRIB(XonoticHUDInfoMessagesDialog, name, string, "HUDinfomessages")
-	ATTRIB(XonoticHUDInfoMessagesDialog, requiresConnection, float, true)
-ENDCLASS(XonoticHUDInfoMessagesDialog)
-#endif
 
-#ifdef IMPLEMENTATION
+#include "textlabel.qh"
+#include "checkbox.qh"
+
 void XonoticHUDInfoMessagesDialog_fill(entity me)
 {
 	entity e;
@@ -28,4 +16,3 @@ void XonoticHUDInfoMessagesDialog_fill(entity me)
 		me.TDempty(me, 0.2);
 		me.TD(me, 1, 3.8, e = makeXonoticCheckBox(0, "hud_panel_infomessages_flip", _("Flip align")));
 }
-#endif
diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_infomessages.qh b/qcsrc/menu/xonotic/dialog_hudpanel_infomessages.qh
index 6f70f09be..093bc00df 100644
--- a/qcsrc/menu/xonotic/dialog_hudpanel_infomessages.qh
+++ b/qcsrc/menu/xonotic/dialog_hudpanel_infomessages.qh
@@ -1 +1,13 @@
 #pragma once
+
+#include "rootdialog.qh"
+CLASS(XonoticHUDInfoMessagesDialog, XonoticRootDialog)
+	METHOD(XonoticHUDInfoMessagesDialog, fill, void(entity));
+	ATTRIB(XonoticHUDInfoMessagesDialog, title, string, _("Info Messages Panel"))
+	ATTRIB(XonoticHUDInfoMessagesDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT)
+	ATTRIB(XonoticHUDInfoMessagesDialog, intendedWidth, float, 0.4)
+	ATTRIB(XonoticHUDInfoMessagesDialog, rows, float, 15)
+	ATTRIB(XonoticHUDInfoMessagesDialog, columns, float, 4)
+	ATTRIB(XonoticHUDInfoMessagesDialog, name, string, "HUDinfomessages")
+	ATTRIB(XonoticHUDInfoMessagesDialog, requiresConnection, float, true)
+ENDCLASS(XonoticHUDInfoMessagesDialog)
diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_itemstime.qc b/qcsrc/menu/xonotic/dialog_hudpanel_itemstime.qc
index b99adb6b9..f06038377 100644
--- a/qcsrc/menu/xonotic/dialog_hudpanel_itemstime.qc
+++ b/qcsrc/menu/xonotic/dialog_hudpanel_itemstime.qc
@@ -1,19 +1,11 @@
 #include "dialog_hudpanel_itemstime.qh"
-#ifndef DIALOG_HUDPANEL_ITEMSTIME_H
-#define DIALOG_HUDPANEL_ITEMSTIME_H
-#include "rootdialog.qc"
-CLASS(XonoticHUDItemsTimeDialog, XonoticRootDialog)
-	METHOD(XonoticHUDItemsTimeDialog, fill, void(entity));
-	ATTRIB(XonoticHUDItemsTimeDialog, title, string, _("Items Time Panel"))
-	ATTRIB(XonoticHUDItemsTimeDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT)
-	ATTRIB(XonoticHUDItemsTimeDialog, intendedWidth, float, 0.4)
-	ATTRIB(XonoticHUDItemsTimeDialog, rows, float, 15)
-	ATTRIB(XonoticHUDItemsTimeDialog, columns, float, 4)
-	ATTRIB(XonoticHUDItemsTimeDialog, name, string, "HUDitemstime")
-ENDCLASS(XonoticHUDItemsTimeDialog)
-#endif
 
-#ifdef IMPLEMENTATION
+#include "textlabel.qh"
+#include "textslider.qh"
+#include "radiobutton.qh"
+#include "checkbox.qh"
+#include "slider.qh"
+
 void XonoticHUDItemsTimeDialog_fill(entity me)
 {
 	entity e;
@@ -46,4 +38,3 @@ void XonoticHUDItemsTimeDialog_fill(entity me)
 	me.TR(me);
 		me.TD(me, 1, 4, e = makeXonoticCheckBox(0, "hud_panel_itemstime_dynamicsize", _("Dynamic size")));
 }
-#endif
diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_itemstime.qh b/qcsrc/menu/xonotic/dialog_hudpanel_itemstime.qh
index 6f70f09be..71b53e690 100644
--- a/qcsrc/menu/xonotic/dialog_hudpanel_itemstime.qh
+++ b/qcsrc/menu/xonotic/dialog_hudpanel_itemstime.qh
@@ -1 +1,12 @@
 #pragma once
+
+#include "rootdialog.qh"
+CLASS(XonoticHUDItemsTimeDialog, XonoticRootDialog)
+	METHOD(XonoticHUDItemsTimeDialog, fill, void(entity));
+	ATTRIB(XonoticHUDItemsTimeDialog, title, string, _("Items Time Panel"))
+	ATTRIB(XonoticHUDItemsTimeDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT)
+	ATTRIB(XonoticHUDItemsTimeDialog, intendedWidth, float, 0.4)
+	ATTRIB(XonoticHUDItemsTimeDialog, rows, float, 15)
+	ATTRIB(XonoticHUDItemsTimeDialog, columns, float, 4)
+	ATTRIB(XonoticHUDItemsTimeDialog, name, string, "HUDitemstime")
+ENDCLASS(XonoticHUDItemsTimeDialog)
diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_modicons.qc b/qcsrc/menu/xonotic/dialog_hudpanel_modicons.qc
index a664f2933..53cad1a93 100644
--- a/qcsrc/menu/xonotic/dialog_hudpanel_modicons.qc
+++ b/qcsrc/menu/xonotic/dialog_hudpanel_modicons.qc
@@ -1,20 +1,7 @@
 #include "dialog_hudpanel_modicons.qh"
-#ifndef DIALOG_HUDPANEL_MODICONS_H
-#define DIALOG_HUDPANEL_MODICONS_H
-#include "rootdialog.qc"
-CLASS(XonoticHUDModIconsDialog, XonoticRootDialog)
-	METHOD(XonoticHUDModIconsDialog, fill, void(entity));
-	ATTRIB(XonoticHUDModIconsDialog, title, string, _("Mod Icons Panel"))
-	ATTRIB(XonoticHUDModIconsDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT)
-	ATTRIB(XonoticHUDModIconsDialog, intendedWidth, float, 0.4)
-	ATTRIB(XonoticHUDModIconsDialog, rows, float, 15)
-	ATTRIB(XonoticHUDModIconsDialog, columns, float, 4)
-	ATTRIB(XonoticHUDModIconsDialog, name, string, "HUDmodicons")
-	ATTRIB(XonoticHUDModIconsDialog, requiresConnection, float, true)
-ENDCLASS(XonoticHUDModIconsDialog)
-#endif
 
-#ifdef IMPLEMENTATION
+#include "checkbox.qh"
+
 void XonoticHUDModIconsDialog_fill(entity me)
 {
 	entity e;
@@ -22,4 +9,3 @@ void XonoticHUDModIconsDialog_fill(entity me)
 
 	DIALOG_HUDPANEL_COMMON();
 }
-#endif
diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_modicons.qh b/qcsrc/menu/xonotic/dialog_hudpanel_modicons.qh
index 6f70f09be..feb36e206 100644
--- a/qcsrc/menu/xonotic/dialog_hudpanel_modicons.qh
+++ b/qcsrc/menu/xonotic/dialog_hudpanel_modicons.qh
@@ -1 +1,13 @@
 #pragma once
+
+#include "rootdialog.qh"
+CLASS(XonoticHUDModIconsDialog, XonoticRootDialog)
+	METHOD(XonoticHUDModIconsDialog, fill, void(entity));
+	ATTRIB(XonoticHUDModIconsDialog, title, string, _("Mod Icons Panel"))
+	ATTRIB(XonoticHUDModIconsDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT)
+	ATTRIB(XonoticHUDModIconsDialog, intendedWidth, float, 0.4)
+	ATTRIB(XonoticHUDModIconsDialog, rows, float, 15)
+	ATTRIB(XonoticHUDModIconsDialog, columns, float, 4)
+	ATTRIB(XonoticHUDModIconsDialog, name, string, "HUDmodicons")
+	ATTRIB(XonoticHUDModIconsDialog, requiresConnection, float, true)
+ENDCLASS(XonoticHUDModIconsDialog)
diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_notification.qc b/qcsrc/menu/xonotic/dialog_hudpanel_notification.qc
index 3625ac086..490051846 100644
--- a/qcsrc/menu/xonotic/dialog_hudpanel_notification.qc
+++ b/qcsrc/menu/xonotic/dialog_hudpanel_notification.qc
@@ -1,20 +1,9 @@
 #include "dialog_hudpanel_notification.qh"
-#ifndef DIALOG_HUDPANEL_NOTIFICATION_H
-#define DIALOG_HUDPANEL_NOTIFICATION_H
-#include "rootdialog.qc"
-CLASS(XonoticHUDNotificationDialog, XonoticRootDialog)
-	METHOD(XonoticHUDNotificationDialog, fill, void(entity));
-	ATTRIB(XonoticHUDNotificationDialog, title, string, _("Notification Panel"))
-	ATTRIB(XonoticHUDNotificationDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT)
-	ATTRIB(XonoticHUDNotificationDialog, intendedWidth, float, 0.4)
-	ATTRIB(XonoticHUDNotificationDialog, rows, float, 15)
-	ATTRIB(XonoticHUDNotificationDialog, columns, float, 4)
-	ATTRIB(XonoticHUDNotificationDialog, name, string, "HUDnotify")
-	ATTRIB(XonoticHUDNotificationDialog, requiresConnection, float, true)
-ENDCLASS(XonoticHUDNotificationDialog)
-#endif
 
-#ifdef IMPLEMENTATION
+#include "textlabel.qh"
+#include "checkbox.qh"
+#include "slider.qh"
+
 void XonoticHUDNotificationDialog_fill(entity me)
 {
 	entity e;
@@ -39,4 +28,3 @@ void XonoticHUDNotificationDialog_fill(entity me)
 		me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Entry fadetime:")));
 			me.TD(me, 1, 2.6, e = makeXonoticSlider(0.5, 5, 0.5, "hud_panel_notify_fadetime"));
 }
-#endif
diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_notification.qh b/qcsrc/menu/xonotic/dialog_hudpanel_notification.qh
index 6f70f09be..ad150076d 100644
--- a/qcsrc/menu/xonotic/dialog_hudpanel_notification.qh
+++ b/qcsrc/menu/xonotic/dialog_hudpanel_notification.qh
@@ -1 +1,13 @@
 #pragma once
+
+#include "rootdialog.qh"
+CLASS(XonoticHUDNotificationDialog, XonoticRootDialog)
+	METHOD(XonoticHUDNotificationDialog, fill, void(entity));
+	ATTRIB(XonoticHUDNotificationDialog, title, string, _("Notification Panel"))
+	ATTRIB(XonoticHUDNotificationDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT)
+	ATTRIB(XonoticHUDNotificationDialog, intendedWidth, float, 0.4)
+	ATTRIB(XonoticHUDNotificationDialog, rows, float, 15)
+	ATTRIB(XonoticHUDNotificationDialog, columns, float, 4)
+	ATTRIB(XonoticHUDNotificationDialog, name, string, "HUDnotify")
+	ATTRIB(XonoticHUDNotificationDialog, requiresConnection, float, true)
+ENDCLASS(XonoticHUDNotificationDialog)
diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_physics.qc b/qcsrc/menu/xonotic/dialog_hudpanel_physics.qc
index 1ef02288a..eabc93dab 100644
--- a/qcsrc/menu/xonotic/dialog_hudpanel_physics.qc
+++ b/qcsrc/menu/xonotic/dialog_hudpanel_physics.qc
@@ -1,21 +1,10 @@
 #include "dialog_hudpanel_physics.qh"
-#ifndef DIALOG_HUDPANEL_PHYSICS_H
-#define DIALOG_HUDPANEL_PHYSICS_H
-#include "rootdialog.qc"
-CLASS(XonoticHUDPhysicsDialog, XonoticRootDialog)
-	METHOD(XonoticHUDPhysicsDialog, fill, void(entity));
-	ATTRIB(XonoticHUDPhysicsDialog, title, string, _("Physics Panel"))
-	ATTRIB(XonoticHUDPhysicsDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT)
-	ATTRIB(XonoticHUDPhysicsDialog, intendedWidth, float, 0.4)
-	ATTRIB(XonoticHUDPhysicsDialog, rows, float, 15)
-	ATTRIB(XonoticHUDPhysicsDialog, columns, float, 4)
-	ATTRIB(XonoticHUDPhysicsDialog, name, string, "HUDphysics")
-	ATTRIB(XonoticHUDPhysicsDialog, sliderTopspeedTime, entity, NULL)
-	ATTRIB(XonoticHUDPhysicsDialog, requiresConnection, float, true)
-ENDCLASS(XonoticHUDPhysicsDialog)
-#endif
 
-#ifdef IMPLEMENTATION
+#include "textlabel.qh"
+#include "textslider.qh"
+#include "checkbox.qh"
+#include "slider.qh"
+
 void XonoticHUDPhysicsDialog_fill(entity me)
 {
 	entity e;
@@ -83,4 +72,3 @@ void XonoticHUDPhysicsDialog_fill(entity me)
 		// me.TD(me, 1, 0.6, e = makeXonoticInputBox(1, "hud_panel_physics_acceleration_max"));
 			// setDependent(e, "hud_panel_physics_progressbar", 1, 1);
 }
-#endif
diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_physics.qh b/qcsrc/menu/xonotic/dialog_hudpanel_physics.qh
index 6f70f09be..1d9c29289 100644
--- a/qcsrc/menu/xonotic/dialog_hudpanel_physics.qh
+++ b/qcsrc/menu/xonotic/dialog_hudpanel_physics.qh
@@ -1 +1,14 @@
 #pragma once
+
+#include "rootdialog.qh"
+CLASS(XonoticHUDPhysicsDialog, XonoticRootDialog)
+	METHOD(XonoticHUDPhysicsDialog, fill, void(entity));
+	ATTRIB(XonoticHUDPhysicsDialog, title, string, _("Physics Panel"))
+	ATTRIB(XonoticHUDPhysicsDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT)
+	ATTRIB(XonoticHUDPhysicsDialog, intendedWidth, float, 0.4)
+	ATTRIB(XonoticHUDPhysicsDialog, rows, float, 15)
+	ATTRIB(XonoticHUDPhysicsDialog, columns, float, 4)
+	ATTRIB(XonoticHUDPhysicsDialog, name, string, "HUDphysics")
+	ATTRIB(XonoticHUDPhysicsDialog, sliderTopspeedTime, entity, NULL)
+	ATTRIB(XonoticHUDPhysicsDialog, requiresConnection, float, true)
+ENDCLASS(XonoticHUDPhysicsDialog)
diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_powerups.qc b/qcsrc/menu/xonotic/dialog_hudpanel_powerups.qc
index 0168385c4..1b490d102 100644
--- a/qcsrc/menu/xonotic/dialog_hudpanel_powerups.qc
+++ b/qcsrc/menu/xonotic/dialog_hudpanel_powerups.qc
@@ -1,20 +1,9 @@
 #include "dialog_hudpanel_powerups.qh"
-#ifndef DIALOG_HUDPANEL_POWERUPS_H
-#define DIALOG_HUDPANEL_POWERUPS_H
-#include "rootdialog.qc"
-CLASS(XonoticHUDPowerupsDialog, XonoticRootDialog)
-	METHOD(XonoticHUDPowerupsDialog, fill, void(entity));
-	ATTRIB(XonoticHUDPowerupsDialog, title, string, _("Powerups Panel"))
-	ATTRIB(XonoticHUDPowerupsDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT)
-	ATTRIB(XonoticHUDPowerupsDialog, intendedWidth, float, 0.4)
-	ATTRIB(XonoticHUDPowerupsDialog, rows, float, 14)
-	ATTRIB(XonoticHUDPowerupsDialog, columns, float, 4)
-	ATTRIB(XonoticHUDPowerupsDialog, name, string, "HUDpowerups")
-	ATTRIB(XonoticHUDPowerupsDialog, requiresConnection, float, true)
-ENDCLASS(XonoticHUDPowerupsDialog)
-#endif
 
-#ifdef IMPLEMENTATION
+#include "checkbox.qh"
+#include "textlabel.qh"
+#include "radiobutton.qh"
+
 void XonoticHUDPowerupsDialog_fill(entity me)
 {
 	entity e;
@@ -46,4 +35,3 @@ void XonoticHUDPowerupsDialog_fill(entity me)
 			me.TD(me, 1, 0.95, e = makeXonoticRadioButton(3, "hud_panel_powerups_iconalign", "2", _("Inward")));
 			me.TD(me, 1, 0.95, e = makeXonoticRadioButton(3, "hud_panel_powerups_iconalign", "3", _("Outward")));
 }
-#endif
diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_powerups.qh b/qcsrc/menu/xonotic/dialog_hudpanel_powerups.qh
index 6f70f09be..ebb09b0ba 100644
--- a/qcsrc/menu/xonotic/dialog_hudpanel_powerups.qh
+++ b/qcsrc/menu/xonotic/dialog_hudpanel_powerups.qh
@@ -1 +1,13 @@
 #pragma once
+
+#include "rootdialog.qh"
+CLASS(XonoticHUDPowerupsDialog, XonoticRootDialog)
+	METHOD(XonoticHUDPowerupsDialog, fill, void(entity));
+	ATTRIB(XonoticHUDPowerupsDialog, title, string, _("Powerups Panel"))
+	ATTRIB(XonoticHUDPowerupsDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT)
+	ATTRIB(XonoticHUDPowerupsDialog, intendedWidth, float, 0.4)
+	ATTRIB(XonoticHUDPowerupsDialog, rows, float, 14)
+	ATTRIB(XonoticHUDPowerupsDialog, columns, float, 4)
+	ATTRIB(XonoticHUDPowerupsDialog, name, string, "HUDpowerups")
+	ATTRIB(XonoticHUDPowerupsDialog, requiresConnection, float, true)
+ENDCLASS(XonoticHUDPowerupsDialog)
diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_pressedkeys.qc b/qcsrc/menu/xonotic/dialog_hudpanel_pressedkeys.qc
index f37b766bd..4e24ff998 100644
--- a/qcsrc/menu/xonotic/dialog_hudpanel_pressedkeys.qc
+++ b/qcsrc/menu/xonotic/dialog_hudpanel_pressedkeys.qc
@@ -1,20 +1,9 @@
 #include "dialog_hudpanel_pressedkeys.qh"
-#ifndef DIALOG_HUDPANEL_PRESSEDKEYS_H
-#define DIALOG_HUDPANEL_PRESSEDKEYS_H
-#include "rootdialog.qc"
-CLASS(XonoticHUDPressedKeysDialog, XonoticRootDialog)
-	METHOD(XonoticHUDPressedKeysDialog, fill, void(entity));
-	ATTRIB(XonoticHUDPressedKeysDialog, title, string, _("Pressed Keys Panel"))
-	ATTRIB(XonoticHUDPressedKeysDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT)
-	ATTRIB(XonoticHUDPressedKeysDialog, intendedWidth, float, 0.4)
-	ATTRIB(XonoticHUDPressedKeysDialog, rows, float, 15)
-	ATTRIB(XonoticHUDPressedKeysDialog, columns, float, 4)
-	ATTRIB(XonoticHUDPressedKeysDialog, name, string, "HUDpressedkeys")
-	ATTRIB(XonoticHUDPressedKeysDialog, requiresConnection, float, true)
-ENDCLASS(XonoticHUDPressedKeysDialog)
-#endif
 
-#ifdef IMPLEMENTATION
+#include "textslider.qh"
+#include "slider.qh"
+#include "textlabel.qh"
+
 void XonoticHUDPressedKeysDialog_fill(entity me)
 {
 	entity e;
@@ -34,4 +23,3 @@ void XonoticHUDPressedKeysDialog_fill(entity me)
 		me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Forced aspect:")));
 			me.TD(me, 1, 2.6, e = makeXonoticSlider(0.2, 4, 0.1, "hud_panel_pressedkeys_aspect"));
 }
-#endif
diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_pressedkeys.qh b/qcsrc/menu/xonotic/dialog_hudpanel_pressedkeys.qh
index 6f70f09be..c4b7a9096 100644
--- a/qcsrc/menu/xonotic/dialog_hudpanel_pressedkeys.qh
+++ b/qcsrc/menu/xonotic/dialog_hudpanel_pressedkeys.qh
@@ -1 +1,13 @@
 #pragma once
+
+#include "rootdialog.qh"
+CLASS(XonoticHUDPressedKeysDialog, XonoticRootDialog)
+	METHOD(XonoticHUDPressedKeysDialog, fill, void(entity));
+	ATTRIB(XonoticHUDPressedKeysDialog, title, string, _("Pressed Keys Panel"))
+	ATTRIB(XonoticHUDPressedKeysDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT)
+	ATTRIB(XonoticHUDPressedKeysDialog, intendedWidth, float, 0.4)
+	ATTRIB(XonoticHUDPressedKeysDialog, rows, float, 15)
+	ATTRIB(XonoticHUDPressedKeysDialog, columns, float, 4)
+	ATTRIB(XonoticHUDPressedKeysDialog, name, string, "HUDpressedkeys")
+	ATTRIB(XonoticHUDPressedKeysDialog, requiresConnection, float, true)
+ENDCLASS(XonoticHUDPressedKeysDialog)
diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_quickmenu.qc b/qcsrc/menu/xonotic/dialog_hudpanel_quickmenu.qc
index d4e157710..4012bc61a 100644
--- a/qcsrc/menu/xonotic/dialog_hudpanel_quickmenu.qc
+++ b/qcsrc/menu/xonotic/dialog_hudpanel_quickmenu.qc
@@ -1,19 +1,9 @@
 #include "dialog_hudpanel_quickmenu.qh"
-#ifndef DIALOG_HUDPANEL_QUICKMENU_H
-#define DIALOG_HUDPANEL_QUICKMENU_H
-#include "rootdialog.qc"
-CLASS(XonoticHUDQuickMenuDialog, XonoticRootDialog)
-	METHOD(XonoticHUDQuickMenuDialog, fill, void(entity));
-	ATTRIB(XonoticHUDQuickMenuDialog, title, string, _("Quick Menu Panel"))
-	ATTRIB(XonoticHUDQuickMenuDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT)
-	ATTRIB(XonoticHUDQuickMenuDialog, intendedWidth, float, 0.4)
-	ATTRIB(XonoticHUDQuickMenuDialog, rows, float, 15)
-	ATTRIB(XonoticHUDQuickMenuDialog, columns, float, 4)
-	ATTRIB(XonoticHUDQuickMenuDialog, name, string, "HUDquickmenu")
-ENDCLASS(XonoticHUDQuickMenuDialog)
-#endif
 
-#ifdef IMPLEMENTATION
+#include "checkbox.qh"
+#include "textlabel.qh"
+#include "radiobutton.qh"
+
 void XonoticHUDQuickMenuDialog_fill(entity me)
 {
 	entity e;
@@ -29,4 +19,3 @@ void XonoticHUDQuickMenuDialog_fill(entity me)
 			me.TD(me, 1, 3.8/3, e = makeXonoticRadioButton(3, "hud_panel_quickmenu_align", "0.5", _("Center")));
 			me.TD(me, 1, 3.8/3, e = makeXonoticRadioButton(3, "hud_panel_quickmenu_align", "1", _("Right")));
 }
-#endif
diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_quickmenu.qh b/qcsrc/menu/xonotic/dialog_hudpanel_quickmenu.qh
index 6f70f09be..396f62b26 100644
--- a/qcsrc/menu/xonotic/dialog_hudpanel_quickmenu.qh
+++ b/qcsrc/menu/xonotic/dialog_hudpanel_quickmenu.qh
@@ -1 +1,12 @@
 #pragma once
+
+#include "rootdialog.qh"
+CLASS(XonoticHUDQuickMenuDialog, XonoticRootDialog)
+	METHOD(XonoticHUDQuickMenuDialog, fill, void(entity));
+	ATTRIB(XonoticHUDQuickMenuDialog, title, string, _("Quick Menu Panel"))
+	ATTRIB(XonoticHUDQuickMenuDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT)
+	ATTRIB(XonoticHUDQuickMenuDialog, intendedWidth, float, 0.4)
+	ATTRIB(XonoticHUDQuickMenuDialog, rows, float, 15)
+	ATTRIB(XonoticHUDQuickMenuDialog, columns, float, 4)
+	ATTRIB(XonoticHUDQuickMenuDialog, name, string, "HUDquickmenu")
+ENDCLASS(XonoticHUDQuickMenuDialog)
diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_racetimer.qc b/qcsrc/menu/xonotic/dialog_hudpanel_racetimer.qc
index d938cc04c..2673e5460 100644
--- a/qcsrc/menu/xonotic/dialog_hudpanel_racetimer.qc
+++ b/qcsrc/menu/xonotic/dialog_hudpanel_racetimer.qc
@@ -1,20 +1,7 @@
 #include "dialog_hudpanel_racetimer.qh"
-#ifndef DIALOG_HUDPANEL_RACETIMER_H
-#define DIALOG_HUDPANEL_RACETIMER_H
-#include "rootdialog.qc"
-CLASS(XonoticHUDRaceTimerDialog, XonoticRootDialog)
-	METHOD(XonoticHUDRaceTimerDialog, fill, void(entity));
-	ATTRIB(XonoticHUDRaceTimerDialog, title, string, _("Race Timer Panel"))
-	ATTRIB(XonoticHUDRaceTimerDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT)
-	ATTRIB(XonoticHUDRaceTimerDialog, intendedWidth, float, 0.4)
-	ATTRIB(XonoticHUDRaceTimerDialog, rows, float, 15)
-	ATTRIB(XonoticHUDRaceTimerDialog, columns, float, 4)
-	ATTRIB(XonoticHUDRaceTimerDialog, name, string, "HUDracetimer")
-	ATTRIB(XonoticHUDRaceTimerDialog, requiresConnection, float, true)
-ENDCLASS(XonoticHUDRaceTimerDialog)
-#endif
 
-#ifdef IMPLEMENTATION
+#include "checkbox.qh"
+
 void XonoticHUDRaceTimerDialog_fill(entity me)
 {
 	entity e;
@@ -22,4 +9,3 @@ void XonoticHUDRaceTimerDialog_fill(entity me)
 
 	DIALOG_HUDPANEL_COMMON();
 }
-#endif
diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_racetimer.qh b/qcsrc/menu/xonotic/dialog_hudpanel_racetimer.qh
index 6f70f09be..81dca5126 100644
--- a/qcsrc/menu/xonotic/dialog_hudpanel_racetimer.qh
+++ b/qcsrc/menu/xonotic/dialog_hudpanel_racetimer.qh
@@ -1 +1,13 @@
 #pragma once
+
+#include "rootdialog.qh"
+CLASS(XonoticHUDRaceTimerDialog, XonoticRootDialog)
+	METHOD(XonoticHUDRaceTimerDialog, fill, void(entity));
+	ATTRIB(XonoticHUDRaceTimerDialog, title, string, _("Race Timer Panel"))
+	ATTRIB(XonoticHUDRaceTimerDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT)
+	ATTRIB(XonoticHUDRaceTimerDialog, intendedWidth, float, 0.4)
+	ATTRIB(XonoticHUDRaceTimerDialog, rows, float, 15)
+	ATTRIB(XonoticHUDRaceTimerDialog, columns, float, 4)
+	ATTRIB(XonoticHUDRaceTimerDialog, name, string, "HUDracetimer")
+	ATTRIB(XonoticHUDRaceTimerDialog, requiresConnection, float, true)
+ENDCLASS(XonoticHUDRaceTimerDialog)
diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_radar.qc b/qcsrc/menu/xonotic/dialog_hudpanel_radar.qc
index 4d02e8d09..de9ed6898 100644
--- a/qcsrc/menu/xonotic/dialog_hudpanel_radar.qc
+++ b/qcsrc/menu/xonotic/dialog_hudpanel_radar.qc
@@ -1,20 +1,10 @@
 #include "dialog_hudpanel_radar.qh"
-#ifndef DIALOG_HUDPANEL_RADAR_H
-#define DIALOG_HUDPANEL_RADAR_H
-#include "rootdialog.qc"
-CLASS(XonoticHUDRadarDialog, XonoticRootDialog)
-	METHOD(XonoticHUDRadarDialog, fill, void(entity));
-	ATTRIB(XonoticHUDRadarDialog, title, string, _("Radar Panel"))
-	ATTRIB(XonoticHUDRadarDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT)
-	ATTRIB(XonoticHUDRadarDialog, intendedWidth, float, 0.4)
-	ATTRIB(XonoticHUDRadarDialog, rows, float, 15)
-	ATTRIB(XonoticHUDRadarDialog, columns, float, 4)
-	ATTRIB(XonoticHUDRadarDialog, name, string, "HUDradar")
-	ATTRIB(XonoticHUDRadarDialog, requiresConnection, float, true)
-ENDCLASS(XonoticHUDRadarDialog)
-#endif
 
-#ifdef IMPLEMENTATION
+#include "checkbox.qh"
+#include "textslider.qh"
+#include "slider.qh"
+#include "textlabel.qh"
+
 void XonoticHUDRadarDialog_fill(entity me)
 {
 	entity e;
@@ -59,4 +49,3 @@ void XonoticHUDRadarDialog_fill(entity me)
 				e.addValue(e, _("Never zoomed"), "3");
 				e.configureXonoticTextSliderValues(e);
 }
-#endif
diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_radar.qh b/qcsrc/menu/xonotic/dialog_hudpanel_radar.qh
index 6f70f09be..6744e2274 100644
--- a/qcsrc/menu/xonotic/dialog_hudpanel_radar.qh
+++ b/qcsrc/menu/xonotic/dialog_hudpanel_radar.qh
@@ -1 +1,13 @@
 #pragma once
+
+#include "rootdialog.qh"
+CLASS(XonoticHUDRadarDialog, XonoticRootDialog)
+	METHOD(XonoticHUDRadarDialog, fill, void(entity));
+	ATTRIB(XonoticHUDRadarDialog, title, string, _("Radar Panel"))
+	ATTRIB(XonoticHUDRadarDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT)
+	ATTRIB(XonoticHUDRadarDialog, intendedWidth, float, 0.4)
+	ATTRIB(XonoticHUDRadarDialog, rows, float, 15)
+	ATTRIB(XonoticHUDRadarDialog, columns, float, 4)
+	ATTRIB(XonoticHUDRadarDialog, name, string, "HUDradar")
+	ATTRIB(XonoticHUDRadarDialog, requiresConnection, float, true)
+ENDCLASS(XonoticHUDRadarDialog)
diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_score.qc b/qcsrc/menu/xonotic/dialog_hudpanel_score.qc
index e13b9a8ae..f04ca30da 100644
--- a/qcsrc/menu/xonotic/dialog_hudpanel_score.qc
+++ b/qcsrc/menu/xonotic/dialog_hudpanel_score.qc
@@ -1,20 +1,9 @@
 #include "dialog_hudpanel_score.qh"
-#ifndef DIALOG_HUDPANEL_SCORE_H
-#define DIALOG_HUDPANEL_SCORE_H
-#include "rootdialog.qc"
-CLASS(XonoticHUDScoreDialog, XonoticRootDialog)
-	METHOD(XonoticHUDScoreDialog, fill, void(entity));
-	ATTRIB(XonoticHUDScoreDialog, title, string, _("Score Panel"))
-	ATTRIB(XonoticHUDScoreDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT)
-	ATTRIB(XonoticHUDScoreDialog, intendedWidth, float, 0.4)
-	ATTRIB(XonoticHUDScoreDialog, rows, float, 15)
-	ATTRIB(XonoticHUDScoreDialog, columns, float, 4)
-	ATTRIB(XonoticHUDScoreDialog, name, string, "HUDscore")
-	ATTRIB(XonoticHUDScoreDialog, requiresConnection, float, true)
-ENDCLASS(XonoticHUDScoreDialog)
-#endif
 
-#ifdef IMPLEMENTATION
+#include "checkbox.qh"
+#include "textlabel.qh"
+#include "radiobutton.qh"
+
 void XonoticHUDScoreDialog_fill(entity me)
 {
 	entity e;
@@ -31,4 +20,3 @@ void XonoticHUDScoreDialog_fill(entity me)
 		me.TD(me, 1, 2.6/3, e = makeXonoticRadioButton(1, "hud_panel_score_rankings", "1", _("And me")));
 		me.TD(me, 1, 2.6/3, e = makeXonoticRadioButton(1, "hud_panel_score_rankings", "2", _("Pure")));
 }
-#endif
diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_score.qh b/qcsrc/menu/xonotic/dialog_hudpanel_score.qh
index 6f70f09be..68015eaa6 100644
--- a/qcsrc/menu/xonotic/dialog_hudpanel_score.qh
+++ b/qcsrc/menu/xonotic/dialog_hudpanel_score.qh
@@ -1 +1,13 @@
 #pragma once
+
+#include "rootdialog.qh"
+CLASS(XonoticHUDScoreDialog, XonoticRootDialog)
+	METHOD(XonoticHUDScoreDialog, fill, void(entity));
+	ATTRIB(XonoticHUDScoreDialog, title, string, _("Score Panel"))
+	ATTRIB(XonoticHUDScoreDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT)
+	ATTRIB(XonoticHUDScoreDialog, intendedWidth, float, 0.4)
+	ATTRIB(XonoticHUDScoreDialog, rows, float, 15)
+	ATTRIB(XonoticHUDScoreDialog, columns, float, 4)
+	ATTRIB(XonoticHUDScoreDialog, name, string, "HUDscore")
+	ATTRIB(XonoticHUDScoreDialog, requiresConnection, float, true)
+ENDCLASS(XonoticHUDScoreDialog)
diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_timer.qc b/qcsrc/menu/xonotic/dialog_hudpanel_timer.qc
index dcdc170c1..dd9a7b878 100644
--- a/qcsrc/menu/xonotic/dialog_hudpanel_timer.qc
+++ b/qcsrc/menu/xonotic/dialog_hudpanel_timer.qc
@@ -1,20 +1,8 @@
 #include "dialog_hudpanel_timer.qh"
-#ifndef DIALOG_HUDPANEL_TIMER_H
-#define DIALOG_HUDPANEL_TIMER_H
-#include "rootdialog.qc"
-CLASS(XonoticHUDTimerDialog, XonoticRootDialog)
-	METHOD(XonoticHUDTimerDialog, fill, void(entity));
-	ATTRIB(XonoticHUDTimerDialog, title, string, _("Timer Panel"))
-	ATTRIB(XonoticHUDTimerDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT)
-	ATTRIB(XonoticHUDTimerDialog, intendedWidth, float, 0.4)
-	ATTRIB(XonoticHUDTimerDialog, rows, float, 15)
-	ATTRIB(XonoticHUDTimerDialog, columns, float, 4)
-	ATTRIB(XonoticHUDTimerDialog, name, string, "HUDtimer")
-	ATTRIB(XonoticHUDTimerDialog, requiresConnection, float, true)
-ENDCLASS(XonoticHUDTimerDialog)
-#endif
 
-#ifdef IMPLEMENTATION
+#include "checkbox.qh"
+#include "textlabel.qh"
+
 void XonoticHUDTimerDialog_fill(entity me)
 {
 	entity e;
@@ -28,4 +16,3 @@ void XonoticHUDTimerDialog_fill(entity me)
 		me.TDempty(me, 0.2);
 		me.TD(me, 1, 3.8, e = makeXonoticCheckBox(0, "hud_panel_timer_increment", _("Show elapsed time")));
 }
-#endif
diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_timer.qh b/qcsrc/menu/xonotic/dialog_hudpanel_timer.qh
index 6f70f09be..7f7509713 100644
--- a/qcsrc/menu/xonotic/dialog_hudpanel_timer.qh
+++ b/qcsrc/menu/xonotic/dialog_hudpanel_timer.qh
@@ -1 +1,13 @@
 #pragma once
+
+#include "rootdialog.qh"
+CLASS(XonoticHUDTimerDialog, XonoticRootDialog)
+	METHOD(XonoticHUDTimerDialog, fill, void(entity));
+	ATTRIB(XonoticHUDTimerDialog, title, string, _("Timer Panel"))
+	ATTRIB(XonoticHUDTimerDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT)
+	ATTRIB(XonoticHUDTimerDialog, intendedWidth, float, 0.4)
+	ATTRIB(XonoticHUDTimerDialog, rows, float, 15)
+	ATTRIB(XonoticHUDTimerDialog, columns, float, 4)
+	ATTRIB(XonoticHUDTimerDialog, name, string, "HUDtimer")
+	ATTRIB(XonoticHUDTimerDialog, requiresConnection, float, true)
+ENDCLASS(XonoticHUDTimerDialog)
diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_vote.qc b/qcsrc/menu/xonotic/dialog_hudpanel_vote.qc
index fe6d98fd4..e8afa7ca7 100644
--- a/qcsrc/menu/xonotic/dialog_hudpanel_vote.qc
+++ b/qcsrc/menu/xonotic/dialog_hudpanel_vote.qc
@@ -1,20 +1,9 @@
 #include "dialog_hudpanel_vote.qh"
-#ifndef DIALOG_HUDPANEL_VOTE_H
-#define DIALOG_HUDPANEL_VOTE_H
-#include "rootdialog.qc"
-CLASS(XonoticHUDVoteDialog, XonoticRootDialog)
-	METHOD(XonoticHUDVoteDialog, fill, void(entity));
-	ATTRIB(XonoticHUDVoteDialog, title, string, _("Vote Panel"))
-	ATTRIB(XonoticHUDVoteDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT)
-	ATTRIB(XonoticHUDVoteDialog, intendedWidth, float, 0.4)
-	ATTRIB(XonoticHUDVoteDialog, rows, float, 15)
-	ATTRIB(XonoticHUDVoteDialog, columns, float, 4)
-	ATTRIB(XonoticHUDVoteDialog, name, string, "HUDvote")
-	ATTRIB(XonoticHUDVoteDialog, requiresConnection, float, true)
-ENDCLASS(XonoticHUDVoteDialog)
-#endif
 
-#ifdef IMPLEMENTATION
+#include "checkbox.qh"
+#include "textlabel.qh"
+#include "slider.qh"
+
 void XonoticHUDVoteDialog_fill(entity me)
 {
 	entity e;
@@ -26,4 +15,3 @@ void XonoticHUDVoteDialog_fill(entity me)
 		me.TD(me, 1, 1.4, e = makeXonoticTextLabel(0, _("Alpha after voting:")));
 		me.TD(me, 1, 2.6, e = makeXonoticSlider(0.1, 1, 0.1, "hud_panel_vote_alreadyvoted_alpha"));
 }
-#endif
diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_vote.qh b/qcsrc/menu/xonotic/dialog_hudpanel_vote.qh
index 6f70f09be..1ee05a2f8 100644
--- a/qcsrc/menu/xonotic/dialog_hudpanel_vote.qh
+++ b/qcsrc/menu/xonotic/dialog_hudpanel_vote.qh
@@ -1 +1,13 @@
 #pragma once
+
+#include "rootdialog.qh"
+CLASS(XonoticHUDVoteDialog, XonoticRootDialog)
+	METHOD(XonoticHUDVoteDialog, fill, void(entity));
+	ATTRIB(XonoticHUDVoteDialog, title, string, _("Vote Panel"))
+	ATTRIB(XonoticHUDVoteDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT)
+	ATTRIB(XonoticHUDVoteDialog, intendedWidth, float, 0.4)
+	ATTRIB(XonoticHUDVoteDialog, rows, float, 15)
+	ATTRIB(XonoticHUDVoteDialog, columns, float, 4)
+	ATTRIB(XonoticHUDVoteDialog, name, string, "HUDvote")
+	ATTRIB(XonoticHUDVoteDialog, requiresConnection, float, true)
+ENDCLASS(XonoticHUDVoteDialog)
diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc b/qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc
index 01ce3463d..1676aab80 100644
--- a/qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc
+++ b/qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc
@@ -1,20 +1,12 @@
 #include "dialog_hudpanel_weapons.qh"
-#ifndef DIALOG_HUDPANEL_WEAPONS_H
-#define DIALOG_HUDPANEL_WEAPONS_H
-#include "rootdialog.qc"
-CLASS(XonoticHUDWeaponsDialog, XonoticRootDialog)
-	METHOD(XonoticHUDWeaponsDialog, fill, void(entity));
-	ATTRIB(XonoticHUDWeaponsDialog, title, string, _("Weapons Panel"))
-	ATTRIB(XonoticHUDWeaponsDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT)
-	ATTRIB(XonoticHUDWeaponsDialog, intendedWidth, float, 0.4)
-	ATTRIB(XonoticHUDWeaponsDialog, rows, float, 21)
-	ATTRIB(XonoticHUDWeaponsDialog, columns, float, 4)
-	ATTRIB(XonoticHUDWeaponsDialog, name, string, "HUDweapons")
-	ATTRIB(XonoticHUDWeaponsDialog, requiresConnection, float, true)
-ENDCLASS(XonoticHUDWeaponsDialog)
-#endif
 
-#ifdef IMPLEMENTATION
+#include "checkbox.qh"
+#include "textlabel.qh"
+#include "textslider.qh"
+#include "slider.qh"
+#include "radiobutton.qh"
+#include "colorpicker_string.qh"
+
 void XonoticHUDWeaponsDialog_fill(entity me)
 {
 	entity e;
@@ -82,4 +74,3 @@ void XonoticHUDWeaponsDialog_fill(entity me)
 			setDependent(e, "hud_panel_weapons_ammo", 1, 1);
 		me.TR(me);
 }
-#endif
diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_weapons.qh b/qcsrc/menu/xonotic/dialog_hudpanel_weapons.qh
index 6f70f09be..649f7ddd1 100644
--- a/qcsrc/menu/xonotic/dialog_hudpanel_weapons.qh
+++ b/qcsrc/menu/xonotic/dialog_hudpanel_weapons.qh
@@ -1 +1,13 @@
 #pragma once
+
+#include "rootdialog.qh"
+CLASS(XonoticHUDWeaponsDialog, XonoticRootDialog)
+	METHOD(XonoticHUDWeaponsDialog, fill, void(entity));
+	ATTRIB(XonoticHUDWeaponsDialog, title, string, _("Weapons Panel"))
+	ATTRIB(XonoticHUDWeaponsDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT)
+	ATTRIB(XonoticHUDWeaponsDialog, intendedWidth, float, 0.4)
+	ATTRIB(XonoticHUDWeaponsDialog, rows, float, 21)
+	ATTRIB(XonoticHUDWeaponsDialog, columns, float, 4)
+	ATTRIB(XonoticHUDWeaponsDialog, name, string, "HUDweapons")
+	ATTRIB(XonoticHUDWeaponsDialog, requiresConnection, float, true)
+ENDCLASS(XonoticHUDWeaponsDialog)
diff --git a/qcsrc/menu/xonotic/dialog_hudsetup_exit.qc b/qcsrc/menu/xonotic/dialog_hudsetup_exit.qc
index 169986122..802ee96b5 100644
--- a/qcsrc/menu/xonotic/dialog_hudsetup_exit.qc
+++ b/qcsrc/menu/xonotic/dialog_hudsetup_exit.qc
@@ -1,21 +1,14 @@
 #include "dialog_hudsetup_exit.qh"
-#ifndef DIALOG_HUDSETUP_EXIT_H
-#define DIALOG_HUDSETUP_EXIT_H
-#include "rootdialog.qc"
-CLASS(XonoticHUDExitDialog, XonoticRootDialog)
-	METHOD(XonoticHUDExitDialog, fill, void(entity));
-	ATTRIB(XonoticHUDExitDialog, title, string, _("Panel HUD Setup"))
-	ATTRIB(XonoticHUDExitDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT)
-	ATTRIB(XonoticHUDExitDialog, intendedWidth, float, 0.8)
-	ATTRIB(XonoticHUDExitDialog, rows, float, 18)
-	ATTRIB(XonoticHUDExitDialog, columns, float, 8.2)
-	ATTRIB(XonoticHUDExitDialog, name, string, "HUDExit")
-	ATTRIB(XonoticHUDExitDialog, requiresConnection, float, true)
-ENDCLASS(XonoticHUDExitDialog)
 
-#endif
+#include "textlabel.qh"
+#include "button.qh"
+#include "textslider.qh"
+#include "inputbox.qh"
+#include "hudskinlist.qh"
+#include "colorpicker_string.qh"
+#include "checkbox.qh"
+#include "commandbutton.qh"
 
-#ifdef IMPLEMENTATION
 void XonoticHUDExitDialog_fill(entity me)
 {
 	entity e;
@@ -151,4 +144,3 @@ void XonoticHUDExitDialog_fill(entity me)
 	me.gotoRC(me, me.rows - 1, 0);
 		me.TD(me, 1, me.columns, e = makeXonoticCommandButton(_("Exit setup"), '0 0 0', "_hud_configure 0", 1));
 }
-#endif
diff --git a/qcsrc/menu/xonotic/dialog_hudsetup_exit.qh b/qcsrc/menu/xonotic/dialog_hudsetup_exit.qh
index 6f70f09be..e26cfad9b 100644
--- a/qcsrc/menu/xonotic/dialog_hudsetup_exit.qh
+++ b/qcsrc/menu/xonotic/dialog_hudsetup_exit.qh
@@ -1 +1,13 @@
 #pragma once
+
+#include "rootdialog.qh"
+CLASS(XonoticHUDExitDialog, XonoticRootDialog)
+	METHOD(XonoticHUDExitDialog, fill, void(entity));
+	ATTRIB(XonoticHUDExitDialog, title, string, _("Panel HUD Setup"))
+	ATTRIB(XonoticHUDExitDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT)
+	ATTRIB(XonoticHUDExitDialog, intendedWidth, float, 0.8)
+	ATTRIB(XonoticHUDExitDialog, rows, float, 18)
+	ATTRIB(XonoticHUDExitDialog, columns, float, 8.2)
+	ATTRIB(XonoticHUDExitDialog, name, string, "HUDExit")
+	ATTRIB(XonoticHUDExitDialog, requiresConnection, float, true)
+ENDCLASS(XonoticHUDExitDialog)
diff --git a/qcsrc/menu/xonotic/dialog_monstertools.qc b/qcsrc/menu/xonotic/dialog_monstertools.qc
index d35a1d29a..2a21242ef 100644
--- a/qcsrc/menu/xonotic/dialog_monstertools.qc
+++ b/qcsrc/menu/xonotic/dialog_monstertools.qc
@@ -1,19 +1,10 @@
 #include "dialog_monstertools.qh"
-#ifndef DIALOG_MONSTERTOOLS_H
-#define DIALOG_MONSTERTOOLS_H
-#include "rootdialog.qc"
-CLASS(XonoticMonsterToolsDialog, XonoticRootDialog)
-	METHOD(XonoticMonsterToolsDialog, fill, void(entity));
-	ATTRIB(XonoticMonsterToolsDialog, title, string, _("Monster Tools"))
-	ATTRIB(XonoticMonsterToolsDialog, color, vector, SKINCOLOR_DIALOG_SANDBOXTOOLS)
-	ATTRIB(XonoticMonsterToolsDialog, intendedWidth, float, 0.8)
-	ATTRIB(XonoticMonsterToolsDialog, rows, float, 16)
-	ATTRIB(XonoticMonsterToolsDialog, columns, float, 4)
-	ATTRIB(XonoticMonsterToolsDialog, name, string, "MonsterTools")
-ENDCLASS(XonoticMonsterToolsDialog)
-#endif
 
-#ifdef IMPLEMENTATION
+#include "textlabel.qh"
+#include "radiobutton.qh"
+#include "commandbutton.qh"
+#include "slider.qh"
+
 void XonoticMonsterToolsDialog_fill(entity me)
 {
 	entity e;
@@ -48,6 +39,3 @@ void XonoticMonsterToolsDialog_fill(entity me)
 			e.onClick = Dialog_Close;
 			e.onClickEntity = me;
 }
-#endif
-
-/* Click. The c-word is here so you can grep for it :-) */
diff --git a/qcsrc/menu/xonotic/dialog_monstertools.qh b/qcsrc/menu/xonotic/dialog_monstertools.qh
index 6f70f09be..2b6f8b44d 100644
--- a/qcsrc/menu/xonotic/dialog_monstertools.qh
+++ b/qcsrc/menu/xonotic/dialog_monstertools.qh
@@ -1 +1,12 @@
 #pragma once
+
+#include "rootdialog.qh"
+CLASS(XonoticMonsterToolsDialog, XonoticRootDialog)
+	METHOD(XonoticMonsterToolsDialog, fill, void(entity));
+	ATTRIB(XonoticMonsterToolsDialog, title, string, _("Monster Tools"))
+	ATTRIB(XonoticMonsterToolsDialog, color, vector, SKINCOLOR_DIALOG_SANDBOXTOOLS)
+	ATTRIB(XonoticMonsterToolsDialog, intendedWidth, float, 0.8)
+	ATTRIB(XonoticMonsterToolsDialog, rows, float, 16)
+	ATTRIB(XonoticMonsterToolsDialog, columns, float, 4)
+	ATTRIB(XonoticMonsterToolsDialog, name, string, "MonsterTools")
+ENDCLASS(XonoticMonsterToolsDialog)
diff --git a/qcsrc/menu/xonotic/dialog_multiplayer.qc b/qcsrc/menu/xonotic/dialog_multiplayer.qc
index a6237b72a..41ab2f93f 100644
--- a/qcsrc/menu/xonotic/dialog_multiplayer.qc
+++ b/qcsrc/menu/xonotic/dialog_multiplayer.qc
@@ -1,19 +1,11 @@
 #include "dialog_multiplayer.qh"
-#ifndef DIALOG_MULTIPLAYER_H
-#define DIALOG_MULTIPLAYER_H
-#include "dialog.qc"
-CLASS(XonoticMultiplayerDialog, XonoticDialog)
-	METHOD(XonoticMultiplayerDialog, fill, void(entity));
-	ATTRIB(XonoticMultiplayerDialog, title, string, _("Multiplayer"))
-	ATTRIB(XonoticMultiplayerDialog, tooltip, string, _("Play online, against your friends in LAN, view demos or change player settings"))
-	ATTRIB(XonoticMultiplayerDialog, color, vector, SKINCOLOR_DIALOG_MULTIPLAYER)
-	ATTRIB(XonoticMultiplayerDialog, intendedWidth, float, 0.96)
-	ATTRIB(XonoticMultiplayerDialog, rows, float, 24)
-	ATTRIB(XonoticMultiplayerDialog, columns, float, 4)
-ENDCLASS(XonoticMultiplayerDialog)
-#endif
 
-#ifdef IMPLEMENTATION
+#include "tabcontroller.qh"
+#include "dialog_multiplayer_join.qh"
+#include "dialog_multiplayer_create.qh"
+#include "dialog_multiplayer_media.qh"
+#include "dialog_multiplayer_profile.qh"
+
 void XonoticMultiplayerDialog_fill(entity me)
 {
 	entity mc, e;
@@ -29,4 +21,3 @@ void XonoticMultiplayerDialog_fill(entity me)
 	me.TR(me);
 		me.TD(me, me.rows - 1, me.columns, mc);
 }
-#endif
diff --git a/qcsrc/menu/xonotic/dialog_multiplayer.qh b/qcsrc/menu/xonotic/dialog_multiplayer.qh
index 6f70f09be..b18ca5560 100644
--- a/qcsrc/menu/xonotic/dialog_multiplayer.qh
+++ b/qcsrc/menu/xonotic/dialog_multiplayer.qh
@@ -1 +1,12 @@
 #pragma once
+
+#include "dialog.qh"
+CLASS(XonoticMultiplayerDialog, XonoticDialog)
+	METHOD(XonoticMultiplayerDialog, fill, void(entity));
+	ATTRIB(XonoticMultiplayerDialog, title, string, _("Multiplayer"))
+	ATTRIB(XonoticMultiplayerDialog, tooltip, string, _("Play online, against your friends in LAN, view demos or change player settings"))
+	ATTRIB(XonoticMultiplayerDialog, color, vector, SKINCOLOR_DIALOG_MULTIPLAYER)
+	ATTRIB(XonoticMultiplayerDialog, intendedWidth, float, 0.96)
+	ATTRIB(XonoticMultiplayerDialog, rows, float, 24)
+	ATTRIB(XonoticMultiplayerDialog, columns, float, 4)
+ENDCLASS(XonoticMultiplayerDialog)
diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_create.qc b/qcsrc/menu/xonotic/dialog_multiplayer_create.qc
index 58731ca27..85e0e9e69 100644
--- a/qcsrc/menu/xonotic/dialog_multiplayer_create.qc
+++ b/qcsrc/menu/xonotic/dialog_multiplayer_create.qc
@@ -1,26 +1,19 @@
 #include "dialog_multiplayer_create.qh"
-#ifndef DIALOG_MULTIPLAYER_CREATE_H
-#define DIALOG_MULTIPLAYER_CREATE_H
-#include "tab.qc"
-CLASS(XonoticServerCreateTab, XonoticTab)
-	METHOD(XonoticServerCreateTab, fill, void(entity));
-	METHOD(XonoticServerCreateTab, gameTypeChangeNotify, void(entity));
-	METHOD(XonoticServerCreateTab, gameTypeSelectNotify, void(entity));
-	ATTRIB(XonoticServerCreateTab, intendedWidth, float, 0.9)
-	ATTRIB(XonoticServerCreateTab, rows, float, 23)
-	ATTRIB(XonoticServerCreateTab, columns, float, 6.2) // added extra .2 for center space
-
-	ATTRIB(XonoticServerCreateTab, mapListBox, entity, NULL)
-	ATTRIB(XonoticServerCreateTab, sliderFraglimit, entity, NULL)
-	ATTRIB(XonoticServerCreateTab, sliderTeams, entity, NULL)
-	ATTRIB(XonoticServerCreateTab, sliderTimelimit, entity, NULL)
-	ATTRIB(XonoticServerCreateTab, labelFraglimit, entity, NULL)
-	ATTRIB(XonoticServerCreateTab, labelTeams, entity, NULL)
-ENDCLASS(XonoticServerCreateTab)
-entity makeXonoticServerCreateTab();
-#endif
-
-#ifdef IMPLEMENTATION
+
+#include "dialog_multiplayer_create_mapinfo.qh"
+#include "dialog_multiplayer_create_mutators.qh"
+
+#include "gametypelist.qh"
+#include "maplist.qh"
+#include <common/mapinfo.qh>
+
+#include "image.qh"
+#include "textslider.qh"
+#include "textlabel.qh"
+#include "slider.qh"
+#include "mainwindow.qh"
+#include "button.qh"
+#include "inputbox.qh"
 
 void GameType_ConfigureSliders(entity me, string pLabel, float pMin, float pMax, float pStep, string pCvar, string tCvar, string pTooltip)
 {
@@ -247,5 +240,3 @@ void XonoticServerCreateTab_gameTypeSelectNotify(entity me)
 {
 	me.setFocus(me, me.mapListBox);
 }
-
-#endif
diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_create.qh b/qcsrc/menu/xonotic/dialog_multiplayer_create.qh
index 6f70f09be..5a747a945 100644
--- a/qcsrc/menu/xonotic/dialog_multiplayer_create.qh
+++ b/qcsrc/menu/xonotic/dialog_multiplayer_create.qh
@@ -1 +1,19 @@
 #pragma once
+
+#include "tab.qh"
+CLASS(XonoticServerCreateTab, XonoticTab)
+	METHOD(XonoticServerCreateTab, fill, void(entity));
+	METHOD(XonoticServerCreateTab, gameTypeChangeNotify, void(entity));
+	METHOD(XonoticServerCreateTab, gameTypeSelectNotify, void(entity));
+	ATTRIB(XonoticServerCreateTab, intendedWidth, float, 0.9)
+	ATTRIB(XonoticServerCreateTab, rows, float, 23)
+	ATTRIB(XonoticServerCreateTab, columns, float, 6.2)  // added extra .2 for center space
+
+	ATTRIB(XonoticServerCreateTab, mapListBox, entity, NULL)
+	ATTRIB(XonoticServerCreateTab, sliderFraglimit, entity, NULL)
+	ATTRIB(XonoticServerCreateTab, sliderTeams, entity, NULL)
+	ATTRIB(XonoticServerCreateTab, sliderTimelimit, entity, NULL)
+	ATTRIB(XonoticServerCreateTab, labelFraglimit, entity, NULL)
+	ATTRIB(XonoticServerCreateTab, labelTeams, entity, NULL)
+ENDCLASS(XonoticServerCreateTab)
+entity makeXonoticServerCreateTab();
diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.qc b/qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.qc
index f79563f22..9bc82ebc2 100644
--- a/qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.qc
+++ b/qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.qc
@@ -1,34 +1,11 @@
 #include "dialog_multiplayer_create_mapinfo.qh"
-#ifndef DIALOG_MULTIPLAYER_CREATE_MAPINFO_H
-#define DIALOG_MULTIPLAYER_CREATE_MAPINFO_H
-#include "dialog.qc"
-CLASS(XonoticMapInfoDialog, XonoticDialog)
-	METHOD(XonoticMapInfoDialog, fill, void(entity));
-	METHOD(XonoticMapInfoDialog, loadMapInfo, void(entity, float, entity));
-	ATTRIB(XonoticMapInfoDialog, title, string, _("Map Information"))
-	ATTRIB(XonoticMapInfoDialog, color, vector, SKINCOLOR_DIALOG_MAPINFO)
-	ATTRIB(XonoticMapInfoDialog, intendedWidth, float, 1.0)
-	ATTRIB(XonoticMapInfoDialog, rows, float, 11)
-	ATTRIB(XonoticMapInfoDialog, columns, float, 10)
 
-	ATTRIB(XonoticMapInfoDialog, previewImage, entity, NULL)
-	ATTRIB(XonoticMapInfoDialog, titleLabel, entity, NULL)
-	ATTRIB(XonoticMapInfoDialog, authorLabel, entity, NULL)
-	ATTRIB(XonoticMapInfoDialog, descriptionLabel, entity, NULL)
-	ATTRIB(XonoticMapInfoDialog, featuresLabel, entity, NULL)
+#include "button.qh"
+#include "image.qh"
+#include "maplist.qh"
+#include "textlabel.qh"
+#include <common/mapinfo.qh>
 
-	ATTRIBARRAY(XonoticMapInfoDialog, typeLabels, entity, 24)
-
-	ATTRIB(XonoticMapInfoDialog, currentMapIndex, float, 0)
-	ATTRIB(XonoticMapInfoDialog, currentMapBSPName, string, string_null)
-	ATTRIB(XonoticMapInfoDialog, currentMapTitle, string, string_null)
-	ATTRIB(XonoticMapInfoDialog, currentMapAuthor, string, string_null)
-	ATTRIB(XonoticMapInfoDialog, currentMapDescription, string, string_null)
-	ATTRIB(XonoticMapInfoDialog, currentMapPreviewImage, string, string_null)
-ENDCLASS(XonoticMapInfoDialog)
-#endif
-
-#ifdef IMPLEMENTATION
 void XonoticMapInfoDialog_loadMapInfo(entity me, int i, entity mlb)
 {
 	me.currentMapIndex = i;
@@ -120,4 +97,3 @@ void XonoticMapInfoDialog_fill(entity me)
 			me.startButton.onClick = MapList_LoadMap;
 			me.startButton.onClickEntity = NULL; // filled later
 }
-#endif
diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.qh b/qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.qh
index 6f70f09be..13acfcc77 100644
--- a/qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.qh
+++ b/qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.qh
@@ -1 +1,27 @@
 #pragma once
+
+#include "dialog.qh"
+CLASS(XonoticMapInfoDialog, XonoticDialog)
+	METHOD(XonoticMapInfoDialog, fill, void(entity));
+	METHOD(XonoticMapInfoDialog, loadMapInfo, void(entity, float, entity));
+	ATTRIB(XonoticMapInfoDialog, title, string, _("Map Information"))
+	ATTRIB(XonoticMapInfoDialog, color, vector, SKINCOLOR_DIALOG_MAPINFO)
+	ATTRIB(XonoticMapInfoDialog, intendedWidth, float, 1.0)
+	ATTRIB(XonoticMapInfoDialog, rows, float, 11)
+	ATTRIB(XonoticMapInfoDialog, columns, float, 10)
+
+	ATTRIB(XonoticMapInfoDialog, previewImage, entity, NULL)
+	ATTRIB(XonoticMapInfoDialog, titleLabel, entity, NULL)
+	ATTRIB(XonoticMapInfoDialog, authorLabel, entity, NULL)
+	ATTRIB(XonoticMapInfoDialog, descriptionLabel, entity, NULL)
+	ATTRIB(XonoticMapInfoDialog, featuresLabel, entity, NULL)
+
+	ATTRIBARRAY(XonoticMapInfoDialog, typeLabels, entity, 24)
+
+	ATTRIB(XonoticMapInfoDialog, currentMapIndex, float, 0)
+	ATTRIB(XonoticMapInfoDialog, currentMapBSPName, string, string_null)
+	ATTRIB(XonoticMapInfoDialog, currentMapTitle, string, string_null)
+	ATTRIB(XonoticMapInfoDialog, currentMapAuthor, string, string_null)
+	ATTRIB(XonoticMapInfoDialog, currentMapDescription, string, string_null)
+	ATTRIB(XonoticMapInfoDialog, currentMapPreviewImage, string, string_null)
+ENDCLASS(XonoticMapInfoDialog)
diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc b/qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc
index 63a22cac5..f2f7f5c8e 100644
--- a/qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc
+++ b/qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc
@@ -1,24 +1,14 @@
 #include "dialog_multiplayer_create_mutators.qh"
 #include <common/weapons/all.qh>
 
-#ifndef DIALOG_MULTIPLAYER_CREATE_MUTATORS_H
-#define DIALOG_MULTIPLAYER_CREATE_MUTATORS_H
-#include "dialog.qc"
-CLASS(XonoticMutatorsDialog, XonoticDialog)
-	METHOD(XonoticMutatorsDialog, toString, string(entity));
-	METHOD(XonoticMutatorsDialog, fill, void(entity));
-	METHOD(XonoticMutatorsDialog, showNotify, void(entity));
-	METHOD(XonoticMutatorsDialog, close, void(entity));
-	ATTRIB(XonoticMutatorsDialog, title, string, _("Mutators"))
-	ATTRIB(XonoticMutatorsDialog, color, vector, SKINCOLOR_DIALOG_MUTATORS)
-	ATTRIB(XonoticMutatorsDialog, intendedWidth, float, 0.9)
-	ATTRIB(XonoticMutatorsDialog, rows, float, 20)
-	ATTRIB(XonoticMutatorsDialog, columns, float, 6)
-	ATTRIB(XonoticMutatorsDialog, refilterEntity, entity, NULL)
-ENDCLASS(XonoticMutatorsDialog)
-#endif
+#include "weaponarenacheckbox.qh"
+#include "checkbox.qh"
+#include "slider.qh"
+#include "textlabel.qh"
+#include "checkbox_slider_invalid.qh"
+#include "radiobutton.qh"
+#include "button.qh"
 
-#ifdef IMPLEMENTATION
 void XonoticMutatorsDialog_showNotify(entity me)
 {
 	SUPER(XonoticMutatorsDialog).showNotify(me);
@@ -301,10 +291,11 @@ void XonoticMutatorsDialog_fill(entity me)
 			e.onClickEntity = me;
 }
 
+.void(entity) refilter;
+
 void XonoticMutatorsDialog_close(entity me)
 {
 	if(me.refilterEntity)
 		me.refilterEntity.refilter(me.refilterEntity);
 	SUPER(XonoticMutatorsDialog).close(me);
 }
-#endif
diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qh b/qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qh
index 6f70f09be..ede8f4cb1 100644
--- a/qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qh
+++ b/qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qh
@@ -1 +1,15 @@
 #pragma once
+
+#include "dialog.qh"
+CLASS(XonoticMutatorsDialog, XonoticDialog)
+	METHOD(XonoticMutatorsDialog, toString, string(entity));
+	METHOD(XonoticMutatorsDialog, fill, void(entity));
+	METHOD(XonoticMutatorsDialog, showNotify, void(entity));
+	METHOD(XonoticMutatorsDialog, close, void(entity));
+	ATTRIB(XonoticMutatorsDialog, title, string, _("Mutators"))
+	ATTRIB(XonoticMutatorsDialog, color, vector, SKINCOLOR_DIALOG_MUTATORS)
+	ATTRIB(XonoticMutatorsDialog, intendedWidth, float, 0.9)
+	ATTRIB(XonoticMutatorsDialog, rows, float, 20)
+	ATTRIB(XonoticMutatorsDialog, columns, float, 6)
+	ATTRIB(XonoticMutatorsDialog, refilterEntity, entity, NULL)
+ENDCLASS(XonoticMutatorsDialog)
diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_join.qc b/qcsrc/menu/xonotic/dialog_multiplayer_join.qc
index d76c0c822..f387f429b 100644
--- a/qcsrc/menu/xonotic/dialog_multiplayer_join.qc
+++ b/qcsrc/menu/xonotic/dialog_multiplayer_join.qc
@@ -1,17 +1,11 @@
 #include "dialog_multiplayer_join.qh"
-#ifndef DIALOG_MULTIPLAYER_JOIN_H
-#define DIALOG_MULTIPLAYER_JOIN_H
-#include "tab.qc"
-CLASS(XonoticServerListTab, XonoticTab)
-	METHOD(XonoticServerListTab, fill, void(entity));
-	ATTRIB(XonoticServerListTab, intendedWidth, float, 0.9)
-	ATTRIB(XonoticServerListTab, rows, float, 23)
-	ATTRIB(XonoticServerListTab, columns, float, 6.5)
-ENDCLASS(XonoticServerListTab)
-entity makeXonoticServerListTab();
-#endif
 
-#ifdef IMPLEMENTATION
+#include "serverlist.qh"
+
+#include "textlabel.qh"
+#include "inputbox.qh"
+#include "checkbox.qh"
+#include "button.qh"
 
 entity makeXonoticServerListTab()
 {
@@ -82,4 +76,3 @@ void XonoticServerListTab_fill(entity me)
 			e.onClickEntity = slist;
 			slist.connectButton = e;
 }
-#endif
diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_join.qh b/qcsrc/menu/xonotic/dialog_multiplayer_join.qh
index 6f70f09be..7fa837976 100644
--- a/qcsrc/menu/xonotic/dialog_multiplayer_join.qh
+++ b/qcsrc/menu/xonotic/dialog_multiplayer_join.qh
@@ -1 +1,10 @@
 #pragma once
+
+#include "tab.qh"
+CLASS(XonoticServerListTab, XonoticTab)
+	METHOD(XonoticServerListTab, fill, void(entity));
+	ATTRIB(XonoticServerListTab, intendedWidth, float, 0.9)
+	ATTRIB(XonoticServerListTab, rows, float, 23)
+	ATTRIB(XonoticServerListTab, columns, float, 6.5)
+ENDCLASS(XonoticServerListTab)
+entity makeXonoticServerListTab();
diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc b/qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc
index 7e0f39ce6..d5532bcd9 100644
--- a/qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc
+++ b/qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc
@@ -1,54 +1,12 @@
 #include "dialog_multiplayer_join_serverinfo.qh"
 #include <common/mapinfo.qh>
 
-#ifndef DIALOG_MULTIPLAYER_JOIN_SERVERINFO_H
-#define DIALOG_MULTIPLAYER_JOIN_SERVERINFO_H
-#include "dialog.qc"
-CLASS(XonoticServerInfoDialog, XonoticDialog)
-	METHOD(XonoticServerInfoDialog, fill, void(entity));
-	METHOD(XonoticServerInfoDialog, loadServerInfo, void(entity, float));
-	ATTRIB(XonoticServerInfoDialog, title, string, _("Server Information"))
-	ATTRIB(XonoticServerInfoDialog, color, vector, SKINCOLOR_DIALOG_SERVERINFO)
-	ATTRIB(XonoticServerInfoDialog, intendedWidth, float, 0.8)
-	ATTRIB(XonoticServerInfoDialog, rows, float, 18)
-	ATTRIB(XonoticServerInfoDialog, columns, float, 6.2)
-
-	ATTRIB(XonoticServerInfoDialog, currentServerName, string, string_null)
-	ATTRIB(XonoticServerInfoDialog, currentServerCName, string, string_null)
-	ATTRIB(XonoticServerInfoDialog, currentServerType, string, string_null)
-	ATTRIB(XonoticServerInfoDialog, currentServerMap, string, string_null)
-	ATTRIB(XonoticServerInfoDialog, currentServerPlayers, string, string_null)
-	ATTRIB(XonoticServerInfoDialog, currentServerNumPlayers, string, string_null)
-	ATTRIB(XonoticServerInfoDialog, currentServerNumBots, string, string_null)
-	ATTRIB(XonoticServerInfoDialog, currentServerNumFreeSlots, string, string_null)
-	ATTRIB(XonoticServerInfoDialog, currentServerMod, string, string_null)
-	ATTRIB(XonoticServerInfoDialog, currentServerVersion, string, string_null)
-	ATTRIB(XonoticServerInfoDialog, currentServerKey, string, string_null)
-	ATTRIB(XonoticServerInfoDialog, currentServerID, string, string_null)
-	ATTRIB(XonoticServerInfoDialog, currentServerEncrypt, string, string_null)
-	ATTRIB(XonoticServerInfoDialog, currentServerPure, string, string_null)
-
-	ATTRIB(XonoticServerInfoDialog, nameLabel, entity, NULL)
-	ATTRIB(XonoticServerInfoDialog, cnameLabel, entity, NULL)
-	ATTRIB(XonoticServerInfoDialog, typeLabel, entity, NULL)
-	ATTRIB(XonoticServerInfoDialog, mapLabel, entity, NULL)
-	ATTRIB(XonoticServerInfoDialog, rawPlayerList, entity, NULL)
-	ATTRIB(XonoticServerInfoDialog, numPlayersLabel, entity, NULL)
-	ATTRIB(XonoticServerInfoDialog, numBotsLabel, entity, NULL)
-	ATTRIB(XonoticServerInfoDialog, numFreeSlotsLabel, entity, NULL)
-	ATTRIB(XonoticServerInfoDialog, modLabel, entity, NULL)
-	ATTRIB(XonoticServerInfoDialog, versionLabel, entity, NULL)
-	ATTRIB(XonoticServerInfoDialog, keyLabel, entity, NULL)
-	ATTRIB(XonoticServerInfoDialog, idLabel, entity, NULL)
-	ATTRIB(XonoticServerInfoDialog, encryptLabel, entity, NULL)
-	ATTRIB(XonoticServerInfoDialog, canConnectLabel, entity, NULL)
-	ATTRIB(XonoticServerInfoDialog, pureLabel, entity, NULL)
-ENDCLASS(XonoticServerInfoDialog)
-
-void Join_Click(entity btn, entity me);
-#endif
+#include "serverlist.qh"
+#include "playerlist.qh"
+#include "inputbox.qh"
+#include "textlabel.qh"
+#include "button.qh"
 
-#ifdef IMPLEMENTATION
 void XonoticServerInfoDialog_loadServerInfo(entity me, float i)
 {
 	bool pure_available;
@@ -351,5 +309,3 @@ void Join_Click(entity btn, entity me)
 {
 	localcmd("connect ", me.currentServerCName, "\n");
 }
-
-#endif
diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qh b/qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qh
index 6f70f09be..201f737e9 100644
--- a/qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qh
+++ b/qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qh
@@ -1 +1,45 @@
 #pragma once
+
+#include "dialog.qh"
+CLASS(XonoticServerInfoDialog, XonoticDialog)
+	METHOD(XonoticServerInfoDialog, fill, void(entity));
+	METHOD(XonoticServerInfoDialog, loadServerInfo, void(entity, float));
+	ATTRIB(XonoticServerInfoDialog, title, string, _("Server Information"))
+	ATTRIB(XonoticServerInfoDialog, color, vector, SKINCOLOR_DIALOG_SERVERINFO)
+	ATTRIB(XonoticServerInfoDialog, intendedWidth, float, 0.8)
+	ATTRIB(XonoticServerInfoDialog, rows, float, 18)
+	ATTRIB(XonoticServerInfoDialog, columns, float, 6.2)
+
+	ATTRIB(XonoticServerInfoDialog, currentServerName, string, string_null)
+	ATTRIB(XonoticServerInfoDialog, currentServerCName, string, string_null)
+	ATTRIB(XonoticServerInfoDialog, currentServerType, string, string_null)
+	ATTRIB(XonoticServerInfoDialog, currentServerMap, string, string_null)
+	ATTRIB(XonoticServerInfoDialog, currentServerPlayers, string, string_null)
+	ATTRIB(XonoticServerInfoDialog, currentServerNumPlayers, string, string_null)
+	ATTRIB(XonoticServerInfoDialog, currentServerNumBots, string, string_null)
+	ATTRIB(XonoticServerInfoDialog, currentServerNumFreeSlots, string, string_null)
+	ATTRIB(XonoticServerInfoDialog, currentServerMod, string, string_null)
+	ATTRIB(XonoticServerInfoDialog, currentServerVersion, string, string_null)
+	ATTRIB(XonoticServerInfoDialog, currentServerKey, string, string_null)
+	ATTRIB(XonoticServerInfoDialog, currentServerID, string, string_null)
+	ATTRIB(XonoticServerInfoDialog, currentServerEncrypt, string, string_null)
+	ATTRIB(XonoticServerInfoDialog, currentServerPure, string, string_null)
+
+	ATTRIB(XonoticServerInfoDialog, nameLabel, entity, NULL)
+	ATTRIB(XonoticServerInfoDialog, cnameLabel, entity, NULL)
+	ATTRIB(XonoticServerInfoDialog, typeLabel, entity, NULL)
+	ATTRIB(XonoticServerInfoDialog, mapLabel, entity, NULL)
+	ATTRIB(XonoticServerInfoDialog, rawPlayerList, entity, NULL)
+	ATTRIB(XonoticServerInfoDialog, numPlayersLabel, entity, NULL)
+	ATTRIB(XonoticServerInfoDialog, numBotsLabel, entity, NULL)
+	ATTRIB(XonoticServerInfoDialog, numFreeSlotsLabel, entity, NULL)
+	ATTRIB(XonoticServerInfoDialog, modLabel, entity, NULL)
+	ATTRIB(XonoticServerInfoDialog, versionLabel, entity, NULL)
+	ATTRIB(XonoticServerInfoDialog, keyLabel, entity, NULL)
+	ATTRIB(XonoticServerInfoDialog, idLabel, entity, NULL)
+	ATTRIB(XonoticServerInfoDialog, encryptLabel, entity, NULL)
+	ATTRIB(XonoticServerInfoDialog, canConnectLabel, entity, NULL)
+	ATTRIB(XonoticServerInfoDialog, pureLabel, entity, NULL)
+ENDCLASS(XonoticServerInfoDialog)
+
+void Join_Click(entity btn, entity me);
diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_media.qc b/qcsrc/menu/xonotic/dialog_multiplayer_media.qc
index 32a1dfd3f..bc379d3b9 100644
--- a/qcsrc/menu/xonotic/dialog_multiplayer_media.qc
+++ b/qcsrc/menu/xonotic/dialog_multiplayer_media.qc
@@ -1,18 +1,14 @@
 #include "dialog_multiplayer_media.qh"
-#ifndef DIALOG_MULTIPLAYER_MEDIA_H
-#define DIALOG_MULTIPLAYER_MEDIA_H
-#include "tab.qc"
-CLASS(XonoticMediaTab, XonoticTab)
-	METHOD(XonoticMediaTab, fill, void(entity));
-	ATTRIB(XonoticMediaTab, intendedWidth, float, 0.9)
-	ATTRIB(XonoticMediaTab, rows, float, 23)
-	ATTRIB(XonoticMediaTab, columns, float, 3)
-	ATTRIB(XonoticMediaTab, name, string, "Media")
-ENDCLASS(XonoticMediaTab)
-entity makeXonoticMediaTab();
-#endif
 
-#ifdef IMPLEMENTATION
+#include "demolist.qh"
+#include "dialog_multiplayer_media_demo.qh"
+#include "dialog_multiplayer_media_screenshot.qh"
+#include "dialog_multiplayer_media_musicplayer.qh"
+#include "dialog_multiplayer_media_demo_timeconfirm.qh"
+#include "dialog_multiplayer_media_demo_startconfirm.qh"
+
+#include "tabcontroller.qh"
+
 entity makeXonoticMediaTab()
 {
 	entity me;
@@ -33,4 +29,3 @@ void XonoticMediaTab_fill(entity me)
 	me.gotoRC(me, 3, 0);
 		me.TD(me, me.rows - 2, me.columns, mc);
 }
-#endif
diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_media.qh b/qcsrc/menu/xonotic/dialog_multiplayer_media.qh
index 6f70f09be..96c1aeb75 100644
--- a/qcsrc/menu/xonotic/dialog_multiplayer_media.qh
+++ b/qcsrc/menu/xonotic/dialog_multiplayer_media.qh
@@ -1 +1,11 @@
 #pragma once
+
+#include "tab.qh"
+CLASS(XonoticMediaTab, XonoticTab)
+	METHOD(XonoticMediaTab, fill, void(entity));
+	ATTRIB(XonoticMediaTab, intendedWidth, float, 0.9)
+	ATTRIB(XonoticMediaTab, rows, float, 23)
+	ATTRIB(XonoticMediaTab, columns, float, 3)
+	ATTRIB(XonoticMediaTab, name, string, "Media")
+ENDCLASS(XonoticMediaTab)
+entity makeXonoticMediaTab();
diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc b/qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc
index 36d9597a7..6ba33e2a7 100644
--- a/qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc
+++ b/qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc
@@ -1,19 +1,11 @@
 #include "dialog_multiplayer_media_demo.qh"
-#ifndef DIALOG_MULTIPLAYER_MEDIA_DEMO_H
-#define DIALOG_MULTIPLAYER_MEDIA_DEMO_H
-#include "tab.qc"
-CLASS(XonoticDemoBrowserTab, XonoticTab)
-	METHOD(XonoticDemoBrowserTab, fill, void(entity));
-	ATTRIB(XonoticDemoBrowserTab, intendedWidth, float, 0.9)
-	ATTRIB(XonoticDemoBrowserTab, rows, float, 21)
-	ATTRIB(XonoticDemoBrowserTab, columns, float, 6.5)
-	ATTRIB(XonoticDemoBrowserTab, name, string, "DemoBrowser")
-	ATTRIB(XonoticDemoBrowserTab, democlicktype, float, 0)
-ENDCLASS(XonoticDemoBrowserTab)
-entity makeXonoticDemoBrowserTab();
-#endif
 
-#ifdef IMPLEMENTATION
+#include "demolist.qh"
+#include "textlabel.qh"
+#include "inputbox.qh"
+#include "checkbox.qh"
+#include "button.qh"
+
 const float DMO_PLAY = 1;
 const float DMO_TIME = 2;
 void DemoConfirm_Check_Gamestatus(entity btn, entity me)
@@ -72,4 +64,3 @@ void XonoticDemoBrowserTab_fill(entity me)
 			e.onClick = DemoConfirm_Check_Gamestatus;
 			e.onClickEntity = me; // demolist is global anyway
 }
-#endif
diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qh b/qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qh
index 6f70f09be..f41bb9e81 100644
--- a/qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qh
+++ b/qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qh
@@ -1 +1,12 @@
 #pragma once
+
+#include "tab.qh"
+CLASS(XonoticDemoBrowserTab, XonoticTab)
+	METHOD(XonoticDemoBrowserTab, fill, void(entity));
+	ATTRIB(XonoticDemoBrowserTab, intendedWidth, float, 0.9)
+	ATTRIB(XonoticDemoBrowserTab, rows, float, 21)
+	ATTRIB(XonoticDemoBrowserTab, columns, float, 6.5)
+	ATTRIB(XonoticDemoBrowserTab, name, string, "DemoBrowser")
+	ATTRIB(XonoticDemoBrowserTab, democlicktype, float, 0)
+ENDCLASS(XonoticDemoBrowserTab)
+entity makeXonoticDemoBrowserTab();
diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_media_demo_startconfirm.qc b/qcsrc/menu/xonotic/dialog_multiplayer_media_demo_startconfirm.qc
index 8479b3a83..068a8217b 100644
--- a/qcsrc/menu/xonotic/dialog_multiplayer_media_demo_startconfirm.qc
+++ b/qcsrc/menu/xonotic/dialog_multiplayer_media_demo_startconfirm.qc
@@ -1,18 +1,9 @@
 #include "dialog_multiplayer_media_demo_startconfirm.qh"
-#ifndef DIALOG_MULTIPLAYER_MEDIA_DEMO_STARTCONFIRM_H
-#define DIALOG_MULTIPLAYER_MEDIA_DEMO_STARTCONFIRM_H
-#include "dialog.qc"
-CLASS(XonoticDemoStartConfirmDialog, XonoticDialog)
-	METHOD(XonoticDemoStartConfirmDialog, fill, void(entity));
-	ATTRIB(XonoticDemoStartConfirmDialog, title, string, _("Disconnect"))
-	ATTRIB(XonoticDemoStartConfirmDialog, color, vector, SKINCOLOR_DIALOG_HUDCONFIRM)
-	ATTRIB(XonoticDemoStartConfirmDialog, intendedWidth, float, 0.5)
-	ATTRIB(XonoticDemoStartConfirmDialog, rows, float, 4)
-	ATTRIB(XonoticDemoStartConfirmDialog, columns, float, 2)
-ENDCLASS(XonoticDemoStartConfirmDialog)
-#endif
 
-#ifdef IMPLEMENTATION
+#include "demolist.qh"
+#include "textlabel.qh"
+#include "button.qh"
+
 void Handle_StartDemo_Click(entity unused, entity me) { demolist.startDemo(demolist); }
 void XonoticDemoStartConfirmDialog_fill(entity me)
 {
@@ -31,4 +22,3 @@ void XonoticDemoStartConfirmDialog_fill(entity me)
 			e.onClick = Dialog_Close;
 			e.onClickEntity = me;
 }
-#endif
diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_media_demo_startconfirm.qh b/qcsrc/menu/xonotic/dialog_multiplayer_media_demo_startconfirm.qh
index 6f70f09be..598dd5503 100644
--- a/qcsrc/menu/xonotic/dialog_multiplayer_media_demo_startconfirm.qh
+++ b/qcsrc/menu/xonotic/dialog_multiplayer_media_demo_startconfirm.qh
@@ -1 +1,11 @@
 #pragma once
+
+#include "dialog.qh"
+CLASS(XonoticDemoStartConfirmDialog, XonoticDialog)
+	METHOD(XonoticDemoStartConfirmDialog, fill, void(entity));
+	ATTRIB(XonoticDemoStartConfirmDialog, title, string, _("Disconnect"))
+	ATTRIB(XonoticDemoStartConfirmDialog, color, vector, SKINCOLOR_DIALOG_HUDCONFIRM)
+	ATTRIB(XonoticDemoStartConfirmDialog, intendedWidth, float, 0.5)
+	ATTRIB(XonoticDemoStartConfirmDialog, rows, float, 4)
+	ATTRIB(XonoticDemoStartConfirmDialog, columns, float, 2)
+ENDCLASS(XonoticDemoStartConfirmDialog)
diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_media_demo_timeconfirm.qc b/qcsrc/menu/xonotic/dialog_multiplayer_media_demo_timeconfirm.qc
index 295dd91ba..55760d14a 100644
--- a/qcsrc/menu/xonotic/dialog_multiplayer_media_demo_timeconfirm.qc
+++ b/qcsrc/menu/xonotic/dialog_multiplayer_media_demo_timeconfirm.qc
@@ -1,18 +1,9 @@
 #include "dialog_multiplayer_media_demo_timeconfirm.qh"
-#ifndef DIALOG_MULTIPLAYER_MEDIA_DEMO_TIMECONFIRM_H
-#define DIALOG_MULTIPLAYER_MEDIA_DEMO_TIMECONFIRM_H
-#include "dialog.qc"
-CLASS(XonoticDemoTimeConfirmDialog, XonoticDialog)
-	METHOD(XonoticDemoTimeConfirmDialog, fill, void(entity));
-	ATTRIB(XonoticDemoTimeConfirmDialog, title, string, _("Disconnect"))
-	ATTRIB(XonoticDemoTimeConfirmDialog, color, vector, SKINCOLOR_DIALOG_HUDCONFIRM)
-	ATTRIB(XonoticDemoTimeConfirmDialog, intendedWidth, float, 0.5)
-	ATTRIB(XonoticDemoTimeConfirmDialog, rows, float, 4)
-	ATTRIB(XonoticDemoTimeConfirmDialog, columns, float, 2)
-ENDCLASS(XonoticDemoTimeConfirmDialog)
-#endif
 
-#ifdef IMPLEMENTATION
+#include "demolist.qh"
+#include "textlabel.qh"
+#include "button.qh"
+
 void Handle_TimeDemo_Click(entity unused, entity unused) { demolist.timeDemo(demolist); }
 void XonoticDemoTimeConfirmDialog_fill(entity me)
 {
@@ -31,4 +22,3 @@ void XonoticDemoTimeConfirmDialog_fill(entity me)
 			e.onClick = Dialog_Close;
 			e.onClickEntity = me;
 }
-#endif
diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_media_demo_timeconfirm.qh b/qcsrc/menu/xonotic/dialog_multiplayer_media_demo_timeconfirm.qh
index 6f70f09be..96e2d6310 100644
--- a/qcsrc/menu/xonotic/dialog_multiplayer_media_demo_timeconfirm.qh
+++ b/qcsrc/menu/xonotic/dialog_multiplayer_media_demo_timeconfirm.qh
@@ -1 +1,11 @@
 #pragma once
+
+#include "dialog.qh"
+CLASS(XonoticDemoTimeConfirmDialog, XonoticDialog)
+	METHOD(XonoticDemoTimeConfirmDialog, fill, void(entity));
+	ATTRIB(XonoticDemoTimeConfirmDialog, title, string, _("Disconnect"))
+	ATTRIB(XonoticDemoTimeConfirmDialog, color, vector, SKINCOLOR_DIALOG_HUDCONFIRM)
+	ATTRIB(XonoticDemoTimeConfirmDialog, intendedWidth, float, 0.5)
+	ATTRIB(XonoticDemoTimeConfirmDialog, rows, float, 4)
+	ATTRIB(XonoticDemoTimeConfirmDialog, columns, float, 2)
+ENDCLASS(XonoticDemoTimeConfirmDialog)
diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc b/qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc
index caf5bf724..c3606508a 100644
--- a/qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc
+++ b/qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc
@@ -1,18 +1,13 @@
 #include "dialog_multiplayer_media_musicplayer.qh"
-#ifndef DIALOG_MULTIPLAYER_MEDIA_MUSICPLAYER_H
-#define DIALOG_MULTIPLAYER_MEDIA_MUSICPLAYER_H
-#include "tab.qc"
-CLASS(XonoticMusicPlayerTab, XonoticTab)
-	METHOD(XonoticMusicPlayerTab, fill, void(entity));
-	ATTRIB(XonoticMusicPlayerTab, intendedWidth, float, 0.9)
-	ATTRIB(XonoticMusicPlayerTab, rows, float, 21)
-	ATTRIB(XonoticMusicPlayerTab, columns, float, 6.5)
-	ATTRIB(XonoticMusicPlayerTab, name, string, "MusicPlayer")
-ENDCLASS(XonoticMusicPlayerTab)
-entity makeXonoticMusicPlayerTab();
-#endif
 
-#ifdef IMPLEMENTATION
+#include "soundlist.qh"
+#include "playlist.qh"
+
+#include "textlabel.qh"
+#include "inputbox.qh"
+#include "button.qh"
+#include "checkbox.qh"
+
 entity makeXonoticMusicPlayerTab()
 {
 	entity me;
@@ -85,4 +80,3 @@ void XonoticMusicPlayerTab_fill(entity me)
 			e.onClick = PlayList_Remove_All;
 			e.onClickEntity = playList;
 }
-#endif
diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qh b/qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qh
index 6f70f09be..4d98f6ec1 100644
--- a/qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qh
+++ b/qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qh
@@ -1 +1,11 @@
 #pragma once
+
+#include "tab.qh"
+CLASS(XonoticMusicPlayerTab, XonoticTab)
+	METHOD(XonoticMusicPlayerTab, fill, void(entity));
+	ATTRIB(XonoticMusicPlayerTab, intendedWidth, float, 0.9)
+	ATTRIB(XonoticMusicPlayerTab, rows, float, 21)
+	ATTRIB(XonoticMusicPlayerTab, columns, float, 6.5)
+	ATTRIB(XonoticMusicPlayerTab, name, string, "MusicPlayer")
+ENDCLASS(XonoticMusicPlayerTab)
+entity makeXonoticMusicPlayerTab();
diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot.qc b/qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot.qc
index 92ef5ef51..1229be714 100644
--- a/qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot.qc
+++ b/qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot.qc
@@ -1,22 +1,13 @@
 #include "dialog_multiplayer_media_screenshot.qh"
-#ifndef DIALOG_MULTIPLAYER_MEDIA_SCREENSHOT_H
-#define DIALOG_MULTIPLAYER_MEDIA_SCREENSHOT_H
-#include "tab.qc"
-CLASS(XonoticScreenshotBrowserTab, XonoticTab)
-	METHOD(XonoticScreenshotBrowserTab, fill, void(entity));
-	ATTRIB(XonoticScreenshotBrowserTab, intendedWidth, float, 1)
-	ATTRIB(XonoticScreenshotBrowserTab, rows, float, 21)
-	ATTRIB(XonoticScreenshotBrowserTab, columns, float, 6.5)
-	ATTRIB(XonoticScreenshotBrowserTab, name, string, "ScreenshotBrowser")
 
-	METHOD(XonoticScreenshotBrowserTab, loadPreviewScreenshot, void(entity, string));
-	ATTRIB(XonoticScreenshotBrowserTab, screenshotImage, entity, NULL)
-	ATTRIB(XonoticScreenshotBrowserTab, currentScrPath, string, string_null)
-ENDCLASS(XonoticScreenshotBrowserTab)
-entity makeXonoticScreenshotBrowserTab();
-#endif
+#include "dialog_multiplayer_media_screenshot_viewer.qh"
+#include "screenshotlist.qh"
+
+#include "textlabel.qh"
+#include "inputbox.qh"
+#include "checkbox.qh"
+#include "button.qh"
 
-#ifdef IMPLEMENTATION
 entity makeXonoticScreenshotBrowserTab()
 {
 	entity me;
@@ -81,4 +72,3 @@ void XonoticScreenshotBrowserTab_fill(entity me)
 			slist.screenshotBrowserDialog = me;
 */
 }
-#endif
diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot.qh b/qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot.qh
index 6f70f09be..62ea8438a 100644
--- a/qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot.qh
+++ b/qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot.qh
@@ -1 +1,15 @@
 #pragma once
+
+#include "tab.qh"
+CLASS(XonoticScreenshotBrowserTab, XonoticTab)
+	METHOD(XonoticScreenshotBrowserTab, fill, void(entity));
+	ATTRIB(XonoticScreenshotBrowserTab, intendedWidth, float, 1)
+	ATTRIB(XonoticScreenshotBrowserTab, rows, float, 21)
+	ATTRIB(XonoticScreenshotBrowserTab, columns, float, 6.5)
+	ATTRIB(XonoticScreenshotBrowserTab, name, string, "ScreenshotBrowser")
+
+	METHOD(XonoticScreenshotBrowserTab, loadPreviewScreenshot, void(entity, string));
+	ATTRIB(XonoticScreenshotBrowserTab, screenshotImage, entity, NULL)
+	ATTRIB(XonoticScreenshotBrowserTab, currentScrPath, string, string_null)
+ENDCLASS(XonoticScreenshotBrowserTab)
+entity makeXonoticScreenshotBrowserTab();
diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot_viewer.qc b/qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot_viewer.qc
index 3a2f90091..d6d545eee 100644
--- a/qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot_viewer.qc
+++ b/qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot_viewer.qc
@@ -1,26 +1,9 @@
 #include "dialog_multiplayer_media_screenshot_viewer.qh"
-#ifndef DIALOG_MULTIPLAYER_MEDIA_SCREENSHOT_VIEWER_H
-#define DIALOG_MULTIPLAYER_MEDIA_SCREENSHOT_VIEWER_H
-#include "dialog.qc"
-CLASS(XonoticScreenshotViewerDialog, XonoticDialog)
-	METHOD(XonoticScreenshotViewerDialog, fill, void(entity));
-	METHOD(XonoticScreenshotViewerDialog, keyDown, float(entity, float, float, float));
-	METHOD(XonoticScreenshotViewerDialog, loadScreenshot, void(entity, string));
-	METHOD(XonoticScreenshotViewerDialog, close, void(entity));
-	ATTRIB(XonoticScreenshotViewerDialog, title, string, "Screenshot Viewer")
-	ATTRIB(XonoticScreenshotViewerDialog, name, string, "ScreenshotViewer")
-	ATTRIB(XonoticScreenshotViewerDialog, intendedWidth, float, 1)
-	ATTRIB(XonoticScreenshotViewerDialog, rows, float, 25)
-	ATTRIB(XonoticScreenshotViewerDialog, columns, float, 4)
-	ATTRIB(XonoticScreenshotViewerDialog, color, vector, SKINCOLOR_DIALOG_SCREENSHOTVIEWER)
-	ATTRIB(XonoticScreenshotViewerDialog, scrList, entity, NULL)
-	ATTRIB(XonoticScreenshotViewerDialog, screenshotImage, entity, NULL)
-	ATTRIB(XonoticScreenshotViewerDialog, slideShowButton, entity, NULL)
-	ATTRIB(XonoticScreenshotViewerDialog, currentScrPath, string, string_null)
-ENDCLASS(XonoticScreenshotViewerDialog)
-#endif
 
-#ifdef IMPLEMENTATION
+#include "screenshotlist.qh"
+#include "inputbox.qh"
+#include "button.qh"
+
 float music_playlist_index_backup;
 void XonoticScreenshotViewerDialog_loadScreenshot(entity me, string scrImage)
 {
@@ -171,4 +154,3 @@ void XonoticScreenshotViewerDialog_fill(entity me)
 			e.onClickEntity = me;
 			me.slideShowButton = e;
 }
-#endif
diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot_viewer.qh b/qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot_viewer.qh
index 6f70f09be..c4f7e6126 100644
--- a/qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot_viewer.qh
+++ b/qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot_viewer.qh
@@ -1 +1,22 @@
 #pragma once
+
+#include "dialog.qh"
+
+#include "screenshotimage.qh"
+
+CLASS(XonoticScreenshotViewerDialog, XonoticDialog)
+	METHOD(XonoticScreenshotViewerDialog, fill, void(entity));
+	METHOD(XonoticScreenshotViewerDialog, keyDown, float(entity, float, float, float));
+	METHOD(XonoticScreenshotViewerDialog, loadScreenshot, void(entity, string));
+	METHOD(XonoticScreenshotViewerDialog, close, void(entity));
+	ATTRIB(XonoticScreenshotViewerDialog, title, string, "Screenshot Viewer")
+	ATTRIB(XonoticScreenshotViewerDialog, name, string, "ScreenshotViewer")
+	ATTRIB(XonoticScreenshotViewerDialog, intendedWidth, float, 1)
+	ATTRIB(XonoticScreenshotViewerDialog, rows, float, 25)
+	ATTRIB(XonoticScreenshotViewerDialog, columns, float, 4)
+	ATTRIB(XonoticScreenshotViewerDialog, color, vector, SKINCOLOR_DIALOG_SCREENSHOTVIEWER)
+	ATTRIB(XonoticScreenshotViewerDialog, scrList, entity, NULL)
+	ATTRIB(XonoticScreenshotViewerDialog, screenshotImage, entity, NULL)
+	ATTRIB(XonoticScreenshotViewerDialog, slideShowButton, entity, NULL)
+	ATTRIB(XonoticScreenshotViewerDialog, currentScrPath, string, string_null)
+ENDCLASS(XonoticScreenshotViewerDialog)
diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_profile.qc b/qcsrc/menu/xonotic/dialog_multiplayer_profile.qc
index 4093099c1..681542218 100644
--- a/qcsrc/menu/xonotic/dialog_multiplayer_profile.qc
+++ b/qcsrc/menu/xonotic/dialog_multiplayer_profile.qc
@@ -1,20 +1,17 @@
 #include "dialog_multiplayer_profile.qh"
-#ifndef DIALOG_MULTIPLAYER_PROFILE_H
-#define DIALOG_MULTIPLAYER_PROFILE_H
-#include "tab.qc"
-CLASS(XonoticProfileTab, XonoticTab)
-	METHOD(XonoticProfileTab, fill, void(entity));
-	METHOD(XonoticProfileTab, draw, void(entity));
-	ATTRIB(XonoticProfileTab, intendedWidth, float, 0.9)
-	ATTRIB(XonoticProfileTab, rows, float, 23)
-	ATTRIB(XonoticProfileTab, columns, float, 6.1) // added extra .2 for center space
-	ATTRIB(XonoticProfileTab, playerNameLabel, entity, NULL)
-	ATTRIB(XonoticProfileTab, playerNameLabelAlpha, float, SKINALPHA_HEADER)
-ENDCLASS(XonoticProfileTab)
-entity makeXonoticProfileTab();
-#endif
 
-#ifdef IMPLEMENTATION
+#include "playermodel.qh"
+#include "statslist.qh"
+#include "languagelist.qh"
+#include "textlabel.qh"
+#include "commandbutton.qh"
+#include "inputbox.qh"
+#include "colorpicker.qh"
+#include "charmap.qh"
+#include "colorbutton.qh"
+#include "checkbox.qh"
+#include "radiobutton.qh"
+
 entity makeXonoticProfileTab()
 {
 	entity me;
@@ -180,4 +177,3 @@ void XonoticProfileTab_fill(entity me)
 	me.gotoRC(me, me.rows - 1, 0);
 		me.TD(me, 1, me.columns, profileApplyButton);
 }
-#endif
diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_profile.qh b/qcsrc/menu/xonotic/dialog_multiplayer_profile.qh
index 6f70f09be..f60e9e0bb 100644
--- a/qcsrc/menu/xonotic/dialog_multiplayer_profile.qh
+++ b/qcsrc/menu/xonotic/dialog_multiplayer_profile.qh
@@ -1 +1,13 @@
 #pragma once
+
+#include "tab.qh"
+CLASS(XonoticProfileTab, XonoticTab)
+	METHOD(XonoticProfileTab, fill, void(entity));
+	METHOD(XonoticProfileTab, draw, void(entity));
+	ATTRIB(XonoticProfileTab, intendedWidth, float, 0.9)
+	ATTRIB(XonoticProfileTab, rows, float, 23)
+	ATTRIB(XonoticProfileTab, columns, float, 6.1)  // added extra .2 for center space
+	ATTRIB(XonoticProfileTab, playerNameLabel, entity, NULL)
+	ATTRIB(XonoticProfileTab, playerNameLabelAlpha, float, SKINALPHA_HEADER)
+ENDCLASS(XonoticProfileTab)
+entity makeXonoticProfileTab();
diff --git a/qcsrc/menu/xonotic/dialog_quit.qc b/qcsrc/menu/xonotic/dialog_quit.qc
index 5736de712..e68b967a0 100644
--- a/qcsrc/menu/xonotic/dialog_quit.qc
+++ b/qcsrc/menu/xonotic/dialog_quit.qc
@@ -1,20 +1,9 @@
 #include "dialog_quit.qh"
-#ifndef DIALOG_QUIT_H
-#define DIALOG_QUIT_H
-#include "dialog.qc"
-CLASS(XonoticQuitDialog, XonoticDialog)
-	METHOD(XonoticQuitDialog, fill, void(entity));
-	ATTRIB(XonoticQuitDialog, title, string, _("Quit"))
-	ATTRIB(XonoticQuitDialog, tooltip, string, _("Quit the game"))
-	ATTRIB(XonoticQuitDialog, color, vector, SKINCOLOR_DIALOG_QUIT)
-	ATTRIB(XonoticQuitDialog, intendedWidth, float, 0.5)
-	ATTRIB(XonoticQuitDialog, rows, float, 3)
-	ATTRIB(XonoticQuitDialog, columns, float, 2)
-	ATTRIB(XonoticQuitDialog, name, string, "Quit")
-ENDCLASS(XonoticQuitDialog)
-#endif
 
-#ifdef IMPLEMENTATION
+#include "textlabel.qh"
+#include "commandbutton.qh"
+#include "button.qh"
+
 void XonoticQuitDialog_fill(entity me)
 {
 	entity e;
@@ -29,4 +18,3 @@ void XonoticQuitDialog_fill(entity me)
 			e.onClick = Dialog_Close;
 			e.onClickEntity = me;
 }
-#endif
diff --git a/qcsrc/menu/xonotic/dialog_quit.qh b/qcsrc/menu/xonotic/dialog_quit.qh
index 6f70f09be..0b06c30d6 100644
--- a/qcsrc/menu/xonotic/dialog_quit.qh
+++ b/qcsrc/menu/xonotic/dialog_quit.qh
@@ -1 +1,13 @@
 #pragma once
+
+#include "dialog.qh"
+CLASS(XonoticQuitDialog, XonoticDialog)
+	METHOD(XonoticQuitDialog, fill, void(entity));
+	ATTRIB(XonoticQuitDialog, title, string, _("Quit"))
+	ATTRIB(XonoticQuitDialog, tooltip, string, _("Quit the game"))
+	ATTRIB(XonoticQuitDialog, color, vector, SKINCOLOR_DIALOG_QUIT)
+	ATTRIB(XonoticQuitDialog, intendedWidth, float, 0.5)
+	ATTRIB(XonoticQuitDialog, rows, float, 3)
+	ATTRIB(XonoticQuitDialog, columns, float, 2)
+	ATTRIB(XonoticQuitDialog, name, string, "Quit")
+ENDCLASS(XonoticQuitDialog)
diff --git a/qcsrc/menu/xonotic/dialog_sandboxtools.qc b/qcsrc/menu/xonotic/dialog_sandboxtools.qc
index 4b530adbf..bfd26b5fe 100644
--- a/qcsrc/menu/xonotic/dialog_sandboxtools.qc
+++ b/qcsrc/menu/xonotic/dialog_sandboxtools.qc
@@ -1,20 +1,12 @@
 #include "dialog_sandboxtools.qh"
-#ifndef DIALOG_SANDBOXTOOLS_H
-#define DIALOG_SANDBOXTOOLS_H
-#include "rootdialog.qc"
-CLASS(XonoticSandboxToolsDialog, XonoticRootDialog)
-	METHOD(XonoticSandboxToolsDialog, fill, void(entity));
-	ATTRIB(XonoticSandboxToolsDialog, title, string, _("Sandbox Tools"))
-	ATTRIB(XonoticSandboxToolsDialog, color, vector, SKINCOLOR_DIALOG_SANDBOXTOOLS)
-	ATTRIB(XonoticSandboxToolsDialog, intendedWidth, float, 0.8)
-	ATTRIB(XonoticSandboxToolsDialog, rows, float, 16)
-	ATTRIB(XonoticSandboxToolsDialog, columns, float, 4)
-	ATTRIB(XonoticSandboxToolsDialog, name, string, "SandboxTools")
-	ATTRIB(XonoticSandboxToolsDialog, requiresConnection, float, true)
-ENDCLASS(XonoticSandboxToolsDialog)
-#endif
 
-#ifdef IMPLEMENTATION
+#include "textlabel.qh"
+#include "inputbox.qh"
+#include "commandbutton.qh"
+#include "colorpicker_string.qh"
+#include "slider.qh"
+#include "radiobutton.qh"
+
 void XonoticSandboxToolsDialog_fill(entity me)
 {
 	entity e, box;
@@ -94,6 +86,3 @@ void XonoticSandboxToolsDialog_fill(entity me)
 			e.onClick = Dialog_Close;
 			e.onClickEntity = me;
 }
-#endif
-
-/* Click. The c-word is here so you can grep for it :-) */
diff --git a/qcsrc/menu/xonotic/dialog_sandboxtools.qh b/qcsrc/menu/xonotic/dialog_sandboxtools.qh
index 6f70f09be..ab49ec867 100644
--- a/qcsrc/menu/xonotic/dialog_sandboxtools.qh
+++ b/qcsrc/menu/xonotic/dialog_sandboxtools.qh
@@ -1 +1,13 @@
 #pragma once
+
+#include "rootdialog.qh"
+CLASS(XonoticSandboxToolsDialog, XonoticRootDialog)
+	METHOD(XonoticSandboxToolsDialog, fill, void(entity));
+	ATTRIB(XonoticSandboxToolsDialog, title, string, _("Sandbox Tools"))
+	ATTRIB(XonoticSandboxToolsDialog, color, vector, SKINCOLOR_DIALOG_SANDBOXTOOLS)
+	ATTRIB(XonoticSandboxToolsDialog, intendedWidth, float, 0.8)
+	ATTRIB(XonoticSandboxToolsDialog, rows, float, 16)
+	ATTRIB(XonoticSandboxToolsDialog, columns, float, 4)
+	ATTRIB(XonoticSandboxToolsDialog, name, string, "SandboxTools")
+	ATTRIB(XonoticSandboxToolsDialog, requiresConnection, float, true)
+ENDCLASS(XonoticSandboxToolsDialog)
diff --git a/qcsrc/menu/xonotic/dialog_settings.qc b/qcsrc/menu/xonotic/dialog_settings.qc
index 27c4c32b9..bd6fd4c4f 100644
--- a/qcsrc/menu/xonotic/dialog_settings.qc
+++ b/qcsrc/menu/xonotic/dialog_settings.qc
@@ -1,19 +1,15 @@
 #include "dialog_settings.qh"
-#ifndef DIALOG_SETTINGS_H
-#define DIALOG_SETTINGS_H
-#include "dialog.qc"
-CLASS(XonoticSettingsDialog, XonoticDialog)
-	METHOD(XonoticSettingsDialog, fill, void(entity));
-	ATTRIB(XonoticSettingsDialog, title, string, _("Settings"))
-	ATTRIB(XonoticSettingsDialog, tooltip, string, _("Change the game settings"))
-	ATTRIB(XonoticSettingsDialog, color, vector, SKINCOLOR_DIALOG_SETTINGS)
-	ATTRIB(XonoticSettingsDialog, intendedWidth, float, 0.96)
-	ATTRIB(XonoticSettingsDialog, rows, float, 18)
-	ATTRIB(XonoticSettingsDialog, columns, float, 6)
-ENDCLASS(XonoticSettingsDialog)
-#endif
 
-#ifdef IMPLEMENTATION
+#include "dialog_settings_video.qh"
+#include "dialog_settings_effects.qh"
+#include "dialog_settings_audio.qh"
+#include "dialog_settings_game.qh"
+#include "dialog_settings_input.qh"
+#include "dialog_settings_user.qh"
+#include "dialog_settings_misc.qh"
+
+#include "tabcontroller.qh"
+
 void XonoticSettingsDialog_fill(entity me)
 {
 	entity mc;
@@ -30,4 +26,3 @@ void XonoticSettingsDialog_fill(entity me)
 	me.gotoRC(me, 2.5, 0);
 		me.TD(me, me.rows - 2.5, me.columns, mc);
 }
-#endif
diff --git a/qcsrc/menu/xonotic/dialog_settings.qh b/qcsrc/menu/xonotic/dialog_settings.qh
index 6f70f09be..6c7eacb7c 100644
--- a/qcsrc/menu/xonotic/dialog_settings.qh
+++ b/qcsrc/menu/xonotic/dialog_settings.qh
@@ -1 +1,12 @@
 #pragma once
+
+#include "dialog.qh"
+CLASS(XonoticSettingsDialog, XonoticDialog)
+	METHOD(XonoticSettingsDialog, fill, void(entity));
+	ATTRIB(XonoticSettingsDialog, title, string, _("Settings"))
+	ATTRIB(XonoticSettingsDialog, tooltip, string, _("Change the game settings"))
+	ATTRIB(XonoticSettingsDialog, color, vector, SKINCOLOR_DIALOG_SETTINGS)
+	ATTRIB(XonoticSettingsDialog, intendedWidth, float, 0.96)
+	ATTRIB(XonoticSettingsDialog, rows, float, 18)
+	ATTRIB(XonoticSettingsDialog, columns, float, 6)
+ENDCLASS(XonoticSettingsDialog)
diff --git a/qcsrc/menu/xonotic/dialog_settings_audio.qc b/qcsrc/menu/xonotic/dialog_settings_audio.qc
index 2742e9bcd..4a25682e0 100644
--- a/qcsrc/menu/xonotic/dialog_settings_audio.qc
+++ b/qcsrc/menu/xonotic/dialog_settings_audio.qc
@@ -1,18 +1,12 @@
 #include "dialog_settings_audio.qh"
-#ifndef DIALOG_SETTINGS_AUDIO_H
-#define DIALOG_SETTINGS_AUDIO_H
-#include "tab.qc"
-CLASS(XonoticAudioSettingsTab, XonoticTab)
-	METHOD(XonoticAudioSettingsTab, fill, void(entity));
-	ATTRIB(XonoticAudioSettingsTab, intendedWidth, float, 0.9)
-	ATTRIB(XonoticAudioSettingsTab, rows, float, 15.5)
-	ATTRIB(XonoticAudioSettingsTab, columns, float, 6.2) // added extra .2 for center space
-	ATTRIB(XonoticAudioSettingsTab, hiddenMenuSoundsSlider, entity, NULL)
-ENDCLASS(XonoticAudioSettingsTab)
-entity makeXonoticAudioSettingsTab();
-#endif
 
-#ifdef IMPLEMENTATION
+#include "slider_decibels.qh"
+#include "commandbutton.qh"
+#include "textlabel.qh"
+#include "checkbox.qh"
+#include "textslider.qh"
+#include "checkbox_slider_invalid.qh"
+
 entity makeXonoticAudioSettingsTab()
 {
 	entity me;
@@ -186,4 +180,3 @@ void XonoticAudioSettingsTab_fill(entity me)
 	me.gotoRC(me, me.rows - 1, 0);
 		me.TD(me, 1, me.columns, audioApplyButton);
 }
-#endif
diff --git a/qcsrc/menu/xonotic/dialog_settings_audio.qh b/qcsrc/menu/xonotic/dialog_settings_audio.qh
index 6f70f09be..a3e8a8c53 100644
--- a/qcsrc/menu/xonotic/dialog_settings_audio.qh
+++ b/qcsrc/menu/xonotic/dialog_settings_audio.qh
@@ -1 +1,11 @@
 #pragma once
+
+#include "tab.qh"
+CLASS(XonoticAudioSettingsTab, XonoticTab)
+	METHOD(XonoticAudioSettingsTab, fill, void(entity));
+	ATTRIB(XonoticAudioSettingsTab, intendedWidth, float, 0.9)
+	ATTRIB(XonoticAudioSettingsTab, rows, float, 15.5)
+	ATTRIB(XonoticAudioSettingsTab, columns, float, 6.2)  // added extra .2 for center space
+	ATTRIB(XonoticAudioSettingsTab, hiddenMenuSoundsSlider, entity, NULL)
+ENDCLASS(XonoticAudioSettingsTab)
+entity makeXonoticAudioSettingsTab();
diff --git a/qcsrc/menu/xonotic/dialog_settings_effects.qc b/qcsrc/menu/xonotic/dialog_settings_effects.qc
index 143a36f68..1b0666c75 100644
--- a/qcsrc/menu/xonotic/dialog_settings_effects.qc
+++ b/qcsrc/menu/xonotic/dialog_settings_effects.qc
@@ -1,17 +1,18 @@
 #include "dialog_settings_effects.qh"
-#ifndef DIALOG_SETTINGS_EFFECTS_H
-#define DIALOG_SETTINGS_EFFECTS_H
-#include "tab.qc"
-CLASS(XonoticEffectsSettingsTab, XonoticTab)
-	METHOD(XonoticEffectsSettingsTab, fill, void(entity));
-	ATTRIB(XonoticEffectsSettingsTab, intendedWidth, float, 0.9)
-	ATTRIB(XonoticEffectsSettingsTab, rows, float, 15.5)
-	ATTRIB(XonoticEffectsSettingsTab, columns, float, 6.2) // added extra .2 for center space
-ENDCLASS(XonoticEffectsSettingsTab)
-entity makeXonoticEffectsSettingsTab();
-#endif
 
-#ifdef IMPLEMENTATION
+#include "slider_picmip.qh"
+#include "slider_particles.qh"
+#include "slider_sbfadetime.qh"
+#include "weaponslist.qh"
+#include "keybinder.qh"
+#include "commandbutton.qh"
+#include "textlabel.qh"
+#include "checkbox.qh"
+#include "textslider.qh"
+#include "slider.qh"
+#include "radiobutton.qh"
+#include "checkbox_slider_invalid.qh"
+
 entity makeXonoticEffectsSettingsTab()
 {
 	entity me;
@@ -257,4 +258,3 @@ void XonoticEffectsSettingsTab_fill(entity me)
 	me.gotoRC(me, me.rows - 1, 0);
 		me.TD(me, 1, me.columns, effectsApplyButton);
 }
-#endif
diff --git a/qcsrc/menu/xonotic/dialog_settings_effects.qh b/qcsrc/menu/xonotic/dialog_settings_effects.qh
index 6f70f09be..97f3854fb 100644
--- a/qcsrc/menu/xonotic/dialog_settings_effects.qh
+++ b/qcsrc/menu/xonotic/dialog_settings_effects.qh
@@ -1 +1,10 @@
 #pragma once
+
+#include "tab.qh"
+CLASS(XonoticEffectsSettingsTab, XonoticTab)
+	METHOD(XonoticEffectsSettingsTab, fill, void(entity));
+	ATTRIB(XonoticEffectsSettingsTab, intendedWidth, float, 0.9)
+	ATTRIB(XonoticEffectsSettingsTab, rows, float, 15.5)
+	ATTRIB(XonoticEffectsSettingsTab, columns, float, 6.2)  // added extra .2 for center space
+ENDCLASS(XonoticEffectsSettingsTab)
+entity makeXonoticEffectsSettingsTab();
diff --git a/qcsrc/menu/xonotic/dialog_settings_game.qc b/qcsrc/menu/xonotic/dialog_settings_game.qc
index ac2df7cb6..32d29d7dc 100644
--- a/qcsrc/menu/xonotic/dialog_settings_game.qc
+++ b/qcsrc/menu/xonotic/dialog_settings_game.qc
@@ -1,166 +1,128 @@
 #include "dialog_settings_game.qh"
-#ifndef DIALOG_SETTINGS_GAME_H
-#define DIALOG_SETTINGS_GAME_H
 
 #include "../gamesettings.qh"
 
-#include "datasource.qc"
-CLASS(SettingSource, DataSource)
-    METHOD(SettingSource, getEntry, entity(entity this, int i, void(string name, string icon) returns))
+METHOD(SettingSource, getEntry, entity(entity this, int i, void(string name, string icon) returns))
+{
+    Lazy l = Settings_from(i);
+    entity it = l.m_get();
+    if (returns) returns(it.title, string_null);
+    return it;
+}
+METHOD(SettingSource, getEntryTooltip, entity(entity this, int i, void(string theTooltip) returns))
+{
+    Lazy l = Settings_from(i);
+    entity it = l.m_get();
+    if (returns) returns(it.tooltip);
+    return it;
+}
+METHOD(SettingSource, reload, int(entity this, string filter)) { return Settings_COUNT; }
+
+string XonoticRegisteredSettingsList_cb_name;
+string XonoticRegisteredSettingsList_cb_tooltip;
+void XonoticRegisteredSettingsList_getNameIcon_cb(string _name, string _icon)
+{
+    XonoticRegisteredSettingsList_cb_name = _name;
+}
+void XonoticRegisteredSettingsList_getTooltip_cb(string _tooltip)
+{
+    XonoticRegisteredSettingsList_cb_tooltip = _tooltip;
+}
+
+METHOD(XonoticRegisteredSettingsList, drawListBoxItem, void(entity this, int i, vector absSize, bool isSelected, bool isFocused))
+{
+    if (!this.source) return;
+    if (!this.source.getEntry(this.source, i, XonoticRegisteredSettingsList_getNameIcon_cb)) return;
+    string name = XonoticRegisteredSettingsList_cb_name;
+    if (isSelected) {
+        draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_SELECTED, SKINALPHA_LISTBOX_SELECTED);
+    } else if (isFocused) {
+        this.focusedItemAlpha = getFadedAlpha(this.focusedItemAlpha, SKINALPHA_LISTBOX_FOCUSED, SKINFADEALPHA_LISTBOX_FOCUSED);
+        draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_FOCUSED, this.focusedItemAlpha);
+    }
+    string s = draw_TextShortenToWidth(strdecolorize(name), 1, 0, this.realFontSize);
+    draw_Text(this.realUpperMargin * eY + (0.5 * this.realFontSize.x) * eX, s, this.realFontSize, '1 1 1', SKINALPHA_TEXT, 0);
+}
+
+METHOD(XonoticRegisteredSettingsList, focusedItemChangeNotify, void(entity this))
+{
+    if (this.focusedItem == -1 || !this.source)
     {
-        Lazy l = Settings_from(i);
-        entity it = l.m_get();
-        if (returns) returns(it.title, string_null);
-        return it;
+        clearTooltip(this);
+        return;
     }
-    METHOD(SettingSource, getEntryTooltip, entity(entity this, int i, void(string theTooltip) returns))
+    if (!this.source.getEntryTooltip(this, this.focusedItem, XonoticRegisteredSettingsList_getTooltip_cb))
     {
-        Lazy l = Settings_from(i);
-        entity it = l.m_get();
-        if (returns) returns(it.tooltip);
-        return it;
+        clearTooltip(this);
+        return;
     }
-    METHOD(SettingSource, reload, int(entity this, string filter)) { return Settings_COUNT; }
-ENDCLASS(SettingSource)
-
-#include "listbox.qc"
-CLASS(XonoticRegisteredSettingsList, XonoticListBox)
-    ATTRIB(XonoticRegisteredSettingsList, alphaBG, float, 0)
-    ATTRIB(XonoticRegisteredSettingsList, itemAbsSize, vector, '0 0 0')
-    ATTRIB(XonoticRegisteredSettingsList, origin, vector, '0 0 0')
-    ATTRIB(XonoticRegisteredSettingsList, realFontSize, vector, '0 0 0')
-    ATTRIB(XonoticRegisteredSettingsList, realUpperMargin, float, 0)
-    ATTRIB(XonoticRegisteredSettingsList, rowsPerItem, float, 2)
-    ATTRIB(XonoticRegisteredSettingsList, stringFilterBox, entity, NULL)
-    ATTRIB(XonoticRegisteredSettingsList, stringFilter, string, string_null)
-    ATTRIB(XonoticRegisteredSettingsList, typeToSearchString, string, string_null)
-    ATTRIB(XonoticRegisteredSettingsList, typeToSearchTime, float, 0)
-    ATTRIB(XonoticRegisteredSettingsList, source, DataSource, NULL)
-	ATTRIB(XonoticRegisteredSettingsList, onChange, void(entity, entity), func_null)
-	ATTRIB(XonoticRegisteredSettingsList, onChangeEntity, entity, NULL)
-	METHOD(XonoticRegisteredSettingsList, focusedItemChangeNotify, void(entity));
-
-	string XonoticRegisteredSettingsList_cb_name;
-	string XonoticRegisteredSettingsList_cb_tooltip;
-	void XonoticRegisteredSettingsList_getNameIcon_cb(string _name, string _icon)
-	{
-		XonoticRegisteredSettingsList_cb_name = _name;
-	}
-	void XonoticRegisteredSettingsList_getTooltip_cb(string _tooltip)
-	{
-		XonoticRegisteredSettingsList_cb_tooltip = _tooltip;
-	}
+    string theTooltip = XonoticRegisteredSettingsList_cb_tooltip;
+    if(theTooltip != "")
+        setZonedTooltip(this, theTooltip, string_null);
+    else
+        clearTooltip(this);
+}
 
-	METHOD(XonoticRegisteredSettingsList, drawListBoxItem, void(entity this, int i, vector absSize, bool isSelected, bool isFocused))
-	{
-		if (!this.source) return;
-		if (!this.source.getEntry(this.source, i, XonoticRegisteredSettingsList_getNameIcon_cb)) return;
-		string name = XonoticRegisteredSettingsList_cb_name;
-		if (isSelected) {
-			draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_SELECTED, SKINALPHA_LISTBOX_SELECTED);
-		} else if (isFocused) {
-			this.focusedItemAlpha = getFadedAlpha(this.focusedItemAlpha, SKINALPHA_LISTBOX_FOCUSED, SKINFADEALPHA_LISTBOX_FOCUSED);
-			draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_FOCUSED, this.focusedItemAlpha);
-		}
-		string s = draw_TextShortenToWidth(strdecolorize(name), 1, 0, this.realFontSize);
-		draw_Text(this.realUpperMargin * eY + (0.5 * this.realFontSize.x) * eX, s, this.realFontSize, '1 1 1', SKINALPHA_TEXT, 0);
-	}
-
-	METHOD(XonoticRegisteredSettingsList, focusedItemChangeNotify, void(entity this))
-	{
-		if (this.focusedItem == -1 || !this.source)
-		{
-			clearTooltip(this);
-			return;
-		}
-		if (!this.source.getEntryTooltip(this, this.focusedItem, XonoticRegisteredSettingsList_getTooltip_cb))
-		{
-			clearTooltip(this);
-			return;
-		}
-		string theTooltip = XonoticRegisteredSettingsList_cb_tooltip;
-		if(theTooltip != "")
-			setZonedTooltip(this, theTooltip, string_null);
-		else
-			clearTooltip(this);
-	}
+METHOD(XonoticRegisteredSettingsList, refilter, void(entity this))
+{
+    if (!this.source) {
+        this.nItems = 0;
+        return;
+    }
+    this.nItems = this.source.reload(this.source, this.stringFilter);
+}
+METHOD(XonoticRegisteredSettingsList, resizeNotify, void(entity this, vector relOrigin, vector relSize, vector absOrigin, vector absSize))
+{
+    SUPER(XonoticRegisteredSettingsList).resizeNotify(this, relOrigin, relSize, absOrigin, absSize);
 
-	METHOD(XonoticRegisteredSettingsList, refilter, void(entity this))
-	{
-		if (!this.source) {
-			this.nItems = 0;
-			return;
-		}
-		this.nItems = this.source.reload(this.source, this.stringFilter);
-	}
-	METHOD(XonoticRegisteredSettingsList, resizeNotify, void(entity this, vector relOrigin, vector relSize, vector absOrigin, vector absSize))
-	{
-		SUPER(XonoticRegisteredSettingsList).resizeNotify(this, relOrigin, relSize, absOrigin, absSize);
+    this.itemAbsSize = '0 0 0';
+    this.realFontSize_y = this.fontSize / (this.itemAbsSize_y = (absSize.y * this.itemHeight));
+    this.realFontSize_x = this.fontSize / (this.itemAbsSize_x = (absSize.x * (1 - this.controlWidth)));
+    this.realUpperMargin = 0.5 * (1 - this.realFontSize.y);
+}
+METHOD(XonoticRegisteredSettingsList, setSelected, void(entity this, int i))
+{
+    SUPER(XonoticRegisteredSettingsList).setSelected(this, i);
+    this.onChange(this, this.onChangeEntity);
+}
+CONSTRUCTOR(XonoticRegisteredSettingsList, DataSource _source) {
+    CONSTRUCT(XonoticRegisteredSettingsList);
+    this.source = _source;
+    this.configureXonoticListBox(this);
+    this.refilter(this);
+}
 
-		this.itemAbsSize = '0 0 0';
-		this.realFontSize_y = this.fontSize / (this.itemAbsSize_y = (absSize.y * this.itemHeight));
-		this.realFontSize_x = this.fontSize / (this.itemAbsSize_x = (absSize.x * (1 - this.controlWidth)));
-		this.realUpperMargin = 0.5 * (1 - this.realFontSize.y);
-	}
-	METHOD(XonoticRegisteredSettingsList, setSelected, void(entity this, int i))
-	{
-		SUPER(XonoticRegisteredSettingsList).setSelected(this, i);
-		this.onChange(this, this.onChangeEntity);
-	}
-    CONSTRUCTOR(XonoticRegisteredSettingsList, DataSource _source) {
-        CONSTRUCT(XonoticRegisteredSettingsList);
-        this.source = _source;
-        this.configureXonoticListBox(this);
-        this.refilter(this);
+METHOD(XonoticGameSettingsTab, topicChangeNotify, void(entity, entity this))
+{
+    entity c = this.currentPanel;
+    entity removing = this.currentItem;
+    DataSource data = this.topicList.source;
+    entity adding = data.getEntry(data, this.topicList.selectedItem, func_null);
+    if (removing == adding) return;
+    if (removing) {
+        this.currentItem = NULL;
+        c.removeItem(c, removing);
     }
-ENDCLASS(XonoticRegisteredSettingsList)
-
-#include "tab.qc"
-CLASS(XonoticGameSettingsTab, XonoticTab)
-	ATTRIB(XonoticGameSettingsTab, intendedWidth, float, 0.9)
-    ATTRIB(XonoticGameSettingsTab, rows, float, 15.5)
-    ATTRIB(XonoticGameSettingsTab, columns, float, 6.5)
-    ATTRIB(XonoticGameSettingsTab, source, DataSource, NEW(SettingSource))
-    ATTRIB(XonoticGameSettingsTab, topicList, entity, NEW(XonoticRegisteredSettingsList, this.source))
-    ATTRIB(XonoticGameSettingsTab, currentPanel, entity, NEW(XonoticTab))
-    ATTRIB(XonoticGameSettingsTab, currentItem, entity, NULL)
-    METHOD(XonoticGameSettingsTab, topicChangeNotify, void(entity, entity this))
-	{
-		entity c = this.currentPanel;
-		entity removing = this.currentItem;
-		DataSource data = this.topicList.source;
-		entity adding = data.getEntry(data, this.topicList.selectedItem, func_null);
-		if (removing == adding) return;
-		if (removing) {
-			this.currentItem = NULL;
-			c.removeItem(c, removing);
-		}
-		if (adding) {
-			this.currentItem = adding;
-			adding.resizeNotify(adding, '0 0 0', c.size, '0 0 0', c.size);
-			c.addItem(c, adding, '0 0 0', '1 1 0', 1);
-		}
-	}
-	METHOD(XonoticGameSettingsTab, fill, void(entity this))
-	{
-		entity topics = this.topicList;
-			topics.onChange = this.topicChangeNotify;
-			topics.onChangeEntity = this;
+    if (adding) {
+        this.currentItem = adding;
+        adding.resizeNotify(adding, '0 0 0', c.size, '0 0 0', c.size);
+        c.addItem(c, adding, '0 0 0', '1 1 0', 1);
+    }
+}
+METHOD(XonoticGameSettingsTab, fill, void(entity this))
+{
+    entity topics = this.topicList;
+        topics.onChange = this.topicChangeNotify;
+        topics.onChangeEntity = this;
 
-		int
-		col = 0, width = 1;
-		this.gotoRC(this, 0, col);
-			this.TD(this, this.rows, width, topics);
+    int
+    col = 0, width = 1;
+    this.gotoRC(this, 0, col);
+        this.TD(this, this.rows, width, topics);
 
-		col += width, width = this.columns - col;
-		this.gotoRC(this, 0, col); this.setFirstColumn(this, this.currentColumn);
-			this.TD(this, this.rows, width, this.currentPanel);
+    col += width, width = this.columns - col;
+    this.gotoRC(this, 0, col); this.setFirstColumn(this, this.currentColumn);
+        this.TD(this, this.rows, width, this.currentPanel);
 
-		this.topicChangeNotify(topics, this);
-	}
-    INIT(XonoticGameSettingsTab)
-    {
-		this.configureDialog(this);
-	}
-ENDCLASS(XonoticGameSettingsTab)
-#endif
+    this.topicChangeNotify(topics, this);
+}
diff --git a/qcsrc/menu/xonotic/dialog_settings_game.qh b/qcsrc/menu/xonotic/dialog_settings_game.qh
index 6f70f09be..c415e9673 100644
--- a/qcsrc/menu/xonotic/dialog_settings_game.qh
+++ b/qcsrc/menu/xonotic/dialog_settings_game.qh
@@ -1 +1,49 @@
 #pragma once
+
+#include "datasource.qh"
+CLASS(SettingSource, DataSource)
+	METHOD(SettingSource, getEntry, entity(entity this, int i, void(string name, string icon) returns));
+	METHOD(SettingSource, getEntryTooltip, entity(entity this, int i, void(string theTooltip) returns));
+	METHOD(SettingSource, reload, int(entity this, string filter));
+ENDCLASS(SettingSource)
+
+#include "listbox.qh"
+CLASS(XonoticRegisteredSettingsList, XonoticListBox)
+	ATTRIB(XonoticRegisteredSettingsList, alphaBG, float, 0)
+	ATTRIB(XonoticRegisteredSettingsList, itemAbsSize, vector, '0 0 0')
+	ATTRIB(XonoticRegisteredSettingsList, origin, vector, '0 0 0')
+	ATTRIB(XonoticRegisteredSettingsList, realFontSize, vector, '0 0 0')
+	ATTRIB(XonoticRegisteredSettingsList, realUpperMargin, float, 0)
+	ATTRIB(XonoticRegisteredSettingsList, rowsPerItem, float, 2)
+	ATTRIB(XonoticRegisteredSettingsList, stringFilterBox, entity, NULL)
+	ATTRIB(XonoticRegisteredSettingsList, stringFilter, string, string_null)
+	ATTRIB(XonoticRegisteredSettingsList, typeToSearchString, string, string_null)
+	ATTRIB(XonoticRegisteredSettingsList, typeToSearchTime, float, 0)
+	ATTRIB(XonoticRegisteredSettingsList, source, DataSource, NULL)
+	ATTRIB(XonoticRegisteredSettingsList, onChange, void(entity, entity), func_null)
+	ATTRIB(XonoticRegisteredSettingsList, onChangeEntity, entity, NULL)
+	METHOD(XonoticRegisteredSettingsList, focusedItemChangeNotify, void(entity));
+	METHOD(XonoticRegisteredSettingsList, drawListBoxItem, void(entity this, int i, vector absSize, bool isSelected, bool isFocused));
+	METHOD(XonoticRegisteredSettingsList, focusedItemChangeNotify, void(entity this));
+	METHOD(XonoticRegisteredSettingsList, refilter, void(entity this));
+	METHOD(XonoticRegisteredSettingsList, resizeNotify, void(entity this, vector relOrigin, vector relSize, vector absOrigin, vector absSize));
+	METHOD(XonoticRegisteredSettingsList, setSelected, void(entity this, int i));
+	CONSTRUCTOR(XonoticRegisteredSettingsList, DataSource _source);
+ENDCLASS(XonoticRegisteredSettingsList)
+
+#include "tab.qh"
+CLASS(XonoticGameSettingsTab, XonoticTab)
+	ATTRIB(XonoticGameSettingsTab, intendedWidth, float, 0.9)
+	ATTRIB(XonoticGameSettingsTab, rows, float, 15.5)
+	ATTRIB(XonoticGameSettingsTab, columns, float, 6.5)
+	ATTRIB(XonoticGameSettingsTab, source, DataSource, NEW(SettingSource))
+	ATTRIB(XonoticGameSettingsTab, topicList, entity, NEW(XonoticRegisteredSettingsList, this.source))
+	ATTRIB(XonoticGameSettingsTab, currentPanel, entity, NEW(XonoticTab))
+	ATTRIB(XonoticGameSettingsTab, currentItem, entity, NULL)
+	METHOD(XonoticGameSettingsTab, topicChangeNotify, void(entity, entity this));
+	METHOD(XonoticGameSettingsTab, fill, void(entity this));
+	INIT(XonoticGameSettingsTab)
+    {
+        this.configureDialog(this);
+    }
+ENDCLASS(XonoticGameSettingsTab)
diff --git a/qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc b/qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc
index 2be11eecd..664306738 100644
--- a/qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc
+++ b/qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc
@@ -1,21 +1,14 @@
 #include "dialog_settings_game_crosshair.qh"
-#ifndef DIALOG_SETTINGS_GAME_CROSSHAIR_H
-#define DIALOG_SETTINGS_GAME_CROSSHAIR_H
-#include "tab.qc"
-CLASS(XonoticGameCrosshairSettingsTab, XonoticTab)
-	METHOD(XonoticGameCrosshairSettingsTab, fill, void(entity));
-	METHOD(XonoticGameCrosshairSettingsTab, showNotify, void(entity));
-	ATTRIB(XonoticGameCrosshairSettingsTab, title, string, _("Crosshair"))
-	ATTRIB(XonoticGameCrosshairSettingsTab, intendedWidth, float, 0.9)
-	ATTRIB(XonoticGameCrosshairSettingsTab, rows, float, 15.5)
-	ATTRIB(XonoticGameCrosshairSettingsTab, columns, float, 6.2)
-ENDCLASS(XonoticGameCrosshairSettingsTab)
-entity makeXonoticGameCrosshairSettingsTab();
-#include "../gamesettings.qh"
-REGISTER_SETTINGS(Crosshair, makeXonoticGameCrosshairSettingsTab());
-#endif
 
-#ifdef IMPLEMENTATION
+#include "radiobutton.qh"
+#include "crosshairpicker.qh"
+#include "crosshairpreview.qh"
+#include "textlabel.qh"
+#include "slider.qh"
+#include "colorpicker_string.qh"
+#include "checkbox.qh"
+#include "textslider.qh"
+
 void XonoticGameCrosshairSettingsTab_showNotify(entity me)
 {
 	loadAllCvars(me);
@@ -152,4 +145,3 @@ void XonoticGameCrosshairSettingsTab_fill(entity me)
 		me.TD(me, 1, 3, e = makeXonoticCheckBoxEx(0.25, 0, "crosshair_pickup", _("Animate crosshair when picking up an item")));
 			setDependent(e, "crosshair_enabled", 1, 2);
 }
-#endif
diff --git a/qcsrc/menu/xonotic/dialog_settings_game_crosshair.qh b/qcsrc/menu/xonotic/dialog_settings_game_crosshair.qh
index 6f70f09be..3e1222056 100644
--- a/qcsrc/menu/xonotic/dialog_settings_game_crosshair.qh
+++ b/qcsrc/menu/xonotic/dialog_settings_game_crosshair.qh
@@ -1 +1,15 @@
 #pragma once
+
+#include "tab.qh"
+CLASS(XonoticGameCrosshairSettingsTab, XonoticTab)
+	METHOD(XonoticGameCrosshairSettingsTab, fill, void(entity));
+	METHOD(XonoticGameCrosshairSettingsTab, showNotify, void(entity));
+	ATTRIB(XonoticGameCrosshairSettingsTab, title, string, _("Crosshair"))
+	ATTRIB(XonoticGameCrosshairSettingsTab, intendedWidth, float, 0.9)
+	ATTRIB(XonoticGameCrosshairSettingsTab, rows, float, 15.5)
+	ATTRIB(XonoticGameCrosshairSettingsTab, columns, float, 6.2)
+ENDCLASS(XonoticGameCrosshairSettingsTab)
+entity makeXonoticGameCrosshairSettingsTab();
+
+#include "../gamesettings.qh"
+REGISTER_SETTINGS(Crosshair, makeXonoticGameCrosshairSettingsTab());
diff --git a/qcsrc/menu/xonotic/dialog_settings_game_hud.qc b/qcsrc/menu/xonotic/dialog_settings_game_hud.qc
index a2ef43e6b..becefc660 100644
--- a/qcsrc/menu/xonotic/dialog_settings_game_hud.qc
+++ b/qcsrc/menu/xonotic/dialog_settings_game_hud.qc
@@ -1,22 +1,13 @@
 #include "dialog_settings_game_hud.qh"
-#ifndef DIALOG_SETTINGS_GAME_HUD_H
-#define DIALOG_SETTINGS_GAME_HUD_H
-#include "tab.qc"
-CLASS(XonoticGameHUDSettingsTab, XonoticTab)
-	METHOD(XonoticGameHUDSettingsTab, fill, void(entity));
-	METHOD(XonoticGameHUDSettingsTab, showNotify, void(entity));
-	ATTRIB(XonoticGameHUDSettingsTab, title, string, _("HUD"))
-	ATTRIB(XonoticGameHUDSettingsTab, intendedWidth, float, 0.9)
-	ATTRIB(XonoticGameHUDSettingsTab, rows, float, 15.5)
-	ATTRIB(XonoticGameHUDSettingsTab, columns, float, 6.2)
-ENDCLASS(XonoticGameHUDSettingsTab)
-entity makeXonoticGameHUDSettingsTab();
-void HUDSetup_Start(entity me, entity btn);
-#include "../gamesettings.qh"
-REGISTER_SETTINGS(HUD, makeXonoticGameHUDSettingsTab());
-#endif
 
-#ifdef IMPLEMENTATION
+#include "../item/modalcontroller.qh"
+#include "mainwindow.qh"
+#include "textlabel.qh"
+#include "slider.qh"
+#include "slider_sbfadetime.qh"
+#include "checkbox.qh"
+#include "button.qh"
+
 void HUDSetup_Check_Gamestatus(entity me, entity btn)
 {
 	if(!(gamestatus & (GAME_CONNECTED | GAME_ISSERVER))) // we're not in a match, ask the player if they want to start one anyway
@@ -175,4 +166,3 @@ void XonoticGameHUDSettingsTab_fill(entity me)
 			e.onClickEntity = me;
 		// TODO: show hud config name with text here
 }
-#endif
diff --git a/qcsrc/menu/xonotic/dialog_settings_game_hud.qh b/qcsrc/menu/xonotic/dialog_settings_game_hud.qh
index 6f70f09be..1db5890be 100644
--- a/qcsrc/menu/xonotic/dialog_settings_game_hud.qh
+++ b/qcsrc/menu/xonotic/dialog_settings_game_hud.qh
@@ -1 +1,15 @@
 #pragma once
+
+#include "tab.qh"
+CLASS(XonoticGameHUDSettingsTab, XonoticTab)
+	METHOD(XonoticGameHUDSettingsTab, fill, void(entity));
+	METHOD(XonoticGameHUDSettingsTab, showNotify, void(entity));
+	ATTRIB(XonoticGameHUDSettingsTab, title, string, _("HUD"))
+	ATTRIB(XonoticGameHUDSettingsTab, intendedWidth, float, 0.9)
+	ATTRIB(XonoticGameHUDSettingsTab, rows, float, 15.5)
+	ATTRIB(XonoticGameHUDSettingsTab, columns, float, 6.2)
+ENDCLASS(XonoticGameHUDSettingsTab)
+entity makeXonoticGameHUDSettingsTab();
+void HUDSetup_Start(entity me, entity btn);
+#include "../gamesettings.qh"
+REGISTER_SETTINGS(HUD, makeXonoticGameHUDSettingsTab());
diff --git a/qcsrc/menu/xonotic/dialog_settings_game_hudconfirm.qc b/qcsrc/menu/xonotic/dialog_settings_game_hudconfirm.qc
index 18804ab50..b1426c2c9 100644
--- a/qcsrc/menu/xonotic/dialog_settings_game_hudconfirm.qc
+++ b/qcsrc/menu/xonotic/dialog_settings_game_hudconfirm.qc
@@ -1,18 +1,8 @@
 #include "dialog_settings_game_hudconfirm.qh"
-#ifndef DIALOG_SETTINGS_GAME_HUDCONFIRM_H
-#define DIALOG_SETTINGS_GAME_HUDCONFIRM_H
-#include "dialog.qc"
-CLASS(XonoticHUDConfirmDialog, XonoticDialog)
-	METHOD(XonoticHUDConfirmDialog, fill, void(entity));
-	ATTRIB(XonoticHUDConfirmDialog, title, string, _("Enter HUD editor"))
-	ATTRIB(XonoticHUDConfirmDialog, color, vector, SKINCOLOR_DIALOG_HUDCONFIRM)
-	ATTRIB(XonoticHUDConfirmDialog, intendedWidth, float, 0.5)
-	ATTRIB(XonoticHUDConfirmDialog, rows, float, 4)
-	ATTRIB(XonoticHUDConfirmDialog, columns, float, 2)
-ENDCLASS(XonoticHUDConfirmDialog)
-#endif
 
-#ifdef IMPLEMENTATION
+#include "textlabel.qh"
+#include "button.qh"
+
 void HUDSetup_Start(entity me, entity btn)
 {
 	if (!(gamestatus & (GAME_CONNECTED | GAME_ISSERVER)))
@@ -40,4 +30,3 @@ void XonoticHUDConfirmDialog_fill(entity me)
 			e.onClick = Dialog_Close;
 			e.onClickEntity = me;
 }
-#endif
diff --git a/qcsrc/menu/xonotic/dialog_settings_game_hudconfirm.qh b/qcsrc/menu/xonotic/dialog_settings_game_hudconfirm.qh
index 6f70f09be..6e8421eec 100644
--- a/qcsrc/menu/xonotic/dialog_settings_game_hudconfirm.qh
+++ b/qcsrc/menu/xonotic/dialog_settings_game_hudconfirm.qh
@@ -1 +1,11 @@
 #pragma once
+
+#include "dialog.qh"
+CLASS(XonoticHUDConfirmDialog, XonoticDialog)
+	METHOD(XonoticHUDConfirmDialog, fill, void(entity));
+	ATTRIB(XonoticHUDConfirmDialog, title, string, _("Enter HUD editor"))
+	ATTRIB(XonoticHUDConfirmDialog, color, vector, SKINCOLOR_DIALOG_HUDCONFIRM)
+	ATTRIB(XonoticHUDConfirmDialog, intendedWidth, float, 0.5)
+	ATTRIB(XonoticHUDConfirmDialog, rows, float, 4)
+	ATTRIB(XonoticHUDConfirmDialog, columns, float, 2)
+ENDCLASS(XonoticHUDConfirmDialog)
diff --git a/qcsrc/menu/xonotic/dialog_settings_game_messages.qc b/qcsrc/menu/xonotic/dialog_settings_game_messages.qc
index 45b5b7736..58d0de9b6 100644
--- a/qcsrc/menu/xonotic/dialog_settings_game_messages.qc
+++ b/qcsrc/menu/xonotic/dialog_settings_game_messages.qc
@@ -1,22 +1,9 @@
 #include "dialog_settings_game_messages.qh"
-#ifndef DIALOG_SETTINGS_GAME_MESSAGES_H
-#define DIALOG_SETTINGS_GAME_MESSAGES_H
-#include "tab.qc"
-CLASS(XonoticGameMessageSettingsTab, XonoticTab)
-	METHOD(XonoticGameMessageSettingsTab, fill, void(entity));
-	METHOD(XonoticGameMessageSettingsTab, showNotify, void(entity));
-	ATTRIB(XonoticGameMessageSettingsTab, title, string, _("Messages"))
-	ATTRIB(XonoticGameMessageSettingsTab, intendedWidth, float, 0.9)
-	ATTRIB(XonoticGameMessageSettingsTab, rows, float, 15.5)
-	ATTRIB(XonoticGameMessageSettingsTab, columns, float, 6)
-	ATTRIB(XonoticGameMessageSettingsTab, weaponsList, entity, NULL)
-ENDCLASS(XonoticGameMessageSettingsTab)
-entity makeXonoticGameMessageSettingsTab();
-#include "../gamesettings.qh"
-REGISTER_SETTINGS(Messages, makeXonoticGameMessageSettingsTab());
-#endif
 
-#ifdef IMPLEMENTATION
+#include "textlabel.qh"
+#include "checkbox.qh"
+#include "textslider.qh"
+
 void XonoticGameMessageSettingsTab_showNotify(entity me)
 {
 	loadAllCvars(me);
@@ -117,4 +104,3 @@ void XonoticGameMessageSettingsTab_fill(entity me)
 		me.TD(me, 1, 3, e = makeXonoticCheckBoxEx_T(1, 0, "notification_ANNCE_ACHIEVEMENT_AIRSHOT", _("Achievement sounds"), "-"));
 			makeMulti(e, "notification_ANNCE_ACHIEVEMENT_AMAZING notification_ANNCE_ACHIEVEMENT_AWESOME notification_ANNCE_ACHIEVEMENT_BOTLIKE notification_ANNCE_ACHIEVEMENT_ELECTROBITCH notification_ANNCE_ACHIEVEMENT_IMPRESSIVE notification_ANNCE_ACHIEVEMENT_YODA");
 }
-#endif
diff --git a/qcsrc/menu/xonotic/dialog_settings_game_messages.qh b/qcsrc/menu/xonotic/dialog_settings_game_messages.qh
index 6f70f09be..56d13bcb9 100644
--- a/qcsrc/menu/xonotic/dialog_settings_game_messages.qh
+++ b/qcsrc/menu/xonotic/dialog_settings_game_messages.qh
@@ -1 +1,15 @@
 #pragma once
+
+#include "tab.qh"
+CLASS(XonoticGameMessageSettingsTab, XonoticTab)
+	METHOD(XonoticGameMessageSettingsTab, fill, void(entity));
+	METHOD(XonoticGameMessageSettingsTab, showNotify, void(entity));
+	ATTRIB(XonoticGameMessageSettingsTab, title, string, _("Messages"))
+	ATTRIB(XonoticGameMessageSettingsTab, intendedWidth, float, 0.9)
+	ATTRIB(XonoticGameMessageSettingsTab, rows, float, 15.5)
+	ATTRIB(XonoticGameMessageSettingsTab, columns, float, 6)
+	ATTRIB(XonoticGameMessageSettingsTab, weaponsList, entity, NULL)
+ENDCLASS(XonoticGameMessageSettingsTab)
+entity makeXonoticGameMessageSettingsTab();
+#include "../gamesettings.qh"
+REGISTER_SETTINGS(Messages, makeXonoticGameMessageSettingsTab());
diff --git a/qcsrc/menu/xonotic/dialog_settings_game_model.qc b/qcsrc/menu/xonotic/dialog_settings_game_model.qc
index bdeb10fa7..f0f95d74b 100644
--- a/qcsrc/menu/xonotic/dialog_settings_game_model.qc
+++ b/qcsrc/menu/xonotic/dialog_settings_game_model.qc
@@ -1,22 +1,10 @@
 #include "dialog_settings_game_model.qh"
-#ifndef DIALOG_SETTINGS_GAME_MODEL_H
-#define DIALOG_SETTINGS_GAME_MODEL_H
-#include "tab.qc"
-CLASS(XonoticGameModelSettingsTab, XonoticTab)
-	METHOD(XonoticGameModelSettingsTab, fill, void(entity));
-	METHOD(XonoticGameModelSettingsTab, showNotify, void(entity));
-	ATTRIB(XonoticGameModelSettingsTab, title, string, _("Models"))
-	ATTRIB(XonoticGameModelSettingsTab, tooltip, string, _("Customize how players and items are displayed in game"))
-	ATTRIB(XonoticGameModelSettingsTab, intendedWidth, float, 0.9)
-	ATTRIB(XonoticGameModelSettingsTab, rows, float, 15.5)
-	ATTRIB(XonoticGameModelSettingsTab, columns, float, 5)
-ENDCLASS(XonoticGameModelSettingsTab)
-entity makeXonoticGameModelSettingsTab();
-#include "../gamesettings.qh"
-REGISTER_SETTINGS(Models, makeXonoticGameModelSettingsTab());
-#endif
 
-#ifdef IMPLEMENTATION
+#include "textlabel.qh"
+#include "checkbox.qh"
+#include "textslider.qh"
+#include "slider.qh"
+
 void XonoticGameModelSettingsTab_showNotify(entity me)
 {
 	loadAllCvars(me);
@@ -76,4 +64,3 @@ void XonoticGameModelSettingsTab_fill(entity me)
 			e.configureXonoticTextSliderValues(e);
 			setDependent(e, "cl_gentle", 0, 0);
 }
-#endif
diff --git a/qcsrc/menu/xonotic/dialog_settings_game_model.qh b/qcsrc/menu/xonotic/dialog_settings_game_model.qh
index 6f70f09be..8ca179d36 100644
--- a/qcsrc/menu/xonotic/dialog_settings_game_model.qh
+++ b/qcsrc/menu/xonotic/dialog_settings_game_model.qh
@@ -1 +1,15 @@
 #pragma once
+
+#include "tab.qh"
+CLASS(XonoticGameModelSettingsTab, XonoticTab)
+	METHOD(XonoticGameModelSettingsTab, fill, void(entity));
+	METHOD(XonoticGameModelSettingsTab, showNotify, void(entity));
+	ATTRIB(XonoticGameModelSettingsTab, title, string, _("Models"))
+	ATTRIB(XonoticGameModelSettingsTab, tooltip, string, _("Customize how players and items are displayed in game"))
+	ATTRIB(XonoticGameModelSettingsTab, intendedWidth, float, 0.9)
+	ATTRIB(XonoticGameModelSettingsTab, rows, float, 15.5)
+	ATTRIB(XonoticGameModelSettingsTab, columns, float, 5)
+ENDCLASS(XonoticGameModelSettingsTab)
+entity makeXonoticGameModelSettingsTab();
+#include "../gamesettings.qh"
+REGISTER_SETTINGS(Models, makeXonoticGameModelSettingsTab());
diff --git a/qcsrc/menu/xonotic/dialog_settings_game_view.qc b/qcsrc/menu/xonotic/dialog_settings_game_view.qc
index d2ae09a6a..2f5d79586 100644
--- a/qcsrc/menu/xonotic/dialog_settings_game_view.qc
+++ b/qcsrc/menu/xonotic/dialog_settings_game_view.qc
@@ -1,21 +1,11 @@
 #include "dialog_settings_game_view.qh"
-#ifndef DIALOG_SETTINGS_GAME_VIEW_H
-#define DIALOG_SETTINGS_GAME_VIEW_H
-#include "tab.qc"
-CLASS(XonoticGameViewSettingsTab, XonoticTab)
-	METHOD(XonoticGameViewSettingsTab, fill, void(entity));
-	METHOD(XonoticGameViewSettingsTab, showNotify, void(entity));
-	ATTRIB(XonoticGameViewSettingsTab, title, string, _("View"))
-	ATTRIB(XonoticGameViewSettingsTab, intendedWidth, float, 0.9)
-	ATTRIB(XonoticGameViewSettingsTab, rows, float, 15.5)
-	ATTRIB(XonoticGameViewSettingsTab, columns, float, 6.2)
-ENDCLASS(XonoticGameViewSettingsTab)
-entity makeXonoticGameViewSettingsTab();
-#include "../gamesettings.qh"
-REGISTER_SETTINGS(View, makeXonoticGameViewSettingsTab());
-#endif
 
-#ifdef IMPLEMENTATION
+#include "textlabel.qh"
+#include "checkbox.qh"
+#include "textslider.qh"
+#include "slider.qh"
+#include "radiobutton.qh"
+
 void XonoticGameViewSettingsTab_showNotify(entity me)
 {
 	loadAllCvars(me);
@@ -129,4 +119,3 @@ void XonoticGameViewSettingsTab_fill(entity me)
 		//me.TDempty(me, 0.2);
 		me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "cl_unpress_zoom_on_weapon_switch", _("Release zoom when you switch weapons")));
 }
-#endif
diff --git a/qcsrc/menu/xonotic/dialog_settings_game_view.qh b/qcsrc/menu/xonotic/dialog_settings_game_view.qh
index 6f70f09be..7ec4c7936 100644
--- a/qcsrc/menu/xonotic/dialog_settings_game_view.qh
+++ b/qcsrc/menu/xonotic/dialog_settings_game_view.qh
@@ -1 +1,14 @@
 #pragma once
+
+#include "tab.qh"
+CLASS(XonoticGameViewSettingsTab, XonoticTab)
+	METHOD(XonoticGameViewSettingsTab, fill, void(entity));
+	METHOD(XonoticGameViewSettingsTab, showNotify, void(entity));
+	ATTRIB(XonoticGameViewSettingsTab, title, string, _("View"))
+	ATTRIB(XonoticGameViewSettingsTab, intendedWidth, float, 0.9)
+	ATTRIB(XonoticGameViewSettingsTab, rows, float, 15.5)
+	ATTRIB(XonoticGameViewSettingsTab, columns, float, 6.2)
+ENDCLASS(XonoticGameViewSettingsTab)
+entity makeXonoticGameViewSettingsTab();
+#include "../gamesettings.qh"
+REGISTER_SETTINGS(View, makeXonoticGameViewSettingsTab());
diff --git a/qcsrc/menu/xonotic/dialog_settings_game_weapons.qc b/qcsrc/menu/xonotic/dialog_settings_game_weapons.qc
index 34baba0bf..1d75ecb49 100644
--- a/qcsrc/menu/xonotic/dialog_settings_game_weapons.qc
+++ b/qcsrc/menu/xonotic/dialog_settings_game_weapons.qc
@@ -1,22 +1,12 @@
 #include "dialog_settings_game_weapons.qh"
-#ifndef DIALOG_SETTINGS_GAME_WEAPONS_H
-#define DIALOG_SETTINGS_GAME_WEAPONS_H
-#include "tab.qc"
-CLASS(XonoticGameWeaponsSettingsTab, XonoticTab)
-	METHOD(XonoticGameWeaponsSettingsTab, fill, void(entity));
-	METHOD(XonoticGameWeaponsSettingsTab, showNotify, void(entity));
-	ATTRIB(XonoticGameWeaponsSettingsTab, title, string, _("Weapons"))
-	ATTRIB(XonoticGameWeaponsSettingsTab, intendedWidth, float, 0.9)
-	ATTRIB(XonoticGameWeaponsSettingsTab, rows, float, 15.5)
-	ATTRIB(XonoticGameWeaponsSettingsTab, columns, float, 6)
-	ATTRIB(XonoticGameWeaponsSettingsTab, weaponsList, entity, NULL)
-ENDCLASS(XonoticGameWeaponsSettingsTab)
-entity makeXonoticGameWeaponsSettingsTab();
-#include "../gamesettings.qh"
-REGISTER_SETTINGS(Weapons, makeXonoticGameWeaponsSettingsTab());
-#endif
 
-#ifdef IMPLEMENTATION
+#include "weaponslist.qh"
+#include "commandbutton.qh"
+#include "textlabel.qh"
+#include "checkbox.qh"
+#include "button.qh"
+#include "radiobutton.qh"
+
 void XonoticGameWeaponsSettingsTab_showNotify(entity me)
 {
 	loadAllCvars(me);
@@ -97,4 +87,3 @@ void XonoticGameWeaponsSettingsTab_fill(entity me)
 	me.gotoRC(me, me.rows - 1, 0); me.setFirstColumn(me, me.currentColumn);
 		me.TD(me, 1, me.columns, weaponsApplyButton);
 }
-#endif
diff --git a/qcsrc/menu/xonotic/dialog_settings_game_weapons.qh b/qcsrc/menu/xonotic/dialog_settings_game_weapons.qh
index 6f70f09be..73ee66fb2 100644
--- a/qcsrc/menu/xonotic/dialog_settings_game_weapons.qh
+++ b/qcsrc/menu/xonotic/dialog_settings_game_weapons.qh
@@ -1 +1,15 @@
 #pragma once
+
+#include "tab.qh"
+CLASS(XonoticGameWeaponsSettingsTab, XonoticTab)
+	METHOD(XonoticGameWeaponsSettingsTab, fill, void(entity));
+	METHOD(XonoticGameWeaponsSettingsTab, showNotify, void(entity));
+	ATTRIB(XonoticGameWeaponsSettingsTab, title, string, _("Weapons"))
+	ATTRIB(XonoticGameWeaponsSettingsTab, intendedWidth, float, 0.9)
+	ATTRIB(XonoticGameWeaponsSettingsTab, rows, float, 15.5)
+	ATTRIB(XonoticGameWeaponsSettingsTab, columns, float, 6)
+	ATTRIB(XonoticGameWeaponsSettingsTab, weaponsList, entity, NULL)
+ENDCLASS(XonoticGameWeaponsSettingsTab)
+entity makeXonoticGameWeaponsSettingsTab();
+#include "../gamesettings.qh"
+REGISTER_SETTINGS(Weapons, makeXonoticGameWeaponsSettingsTab());
diff --git a/qcsrc/menu/xonotic/dialog_settings_input.qc b/qcsrc/menu/xonotic/dialog_settings_input.qc
index 5bf16d991..7f3af39f8 100644
--- a/qcsrc/menu/xonotic/dialog_settings_input.qc
+++ b/qcsrc/menu/xonotic/dialog_settings_input.qc
@@ -1,17 +1,15 @@
 #include "dialog_settings_input.qh"
-#ifndef DIALOG_SETTINGS_INPUT_H
-#define DIALOG_SETTINGS_INPUT_H
-#include "tab.qc"
-CLASS(XonoticInputSettingsTab, XonoticTab)
-	METHOD(XonoticInputSettingsTab, fill, void(entity));
-	ATTRIB(XonoticInputSettingsTab, intendedWidth, float, 0.9)
-	ATTRIB(XonoticInputSettingsTab, rows, float, 15.5)
-	ATTRIB(XonoticInputSettingsTab, columns, float, 6.2) // added extra .2 for center space
-ENDCLASS(XonoticInputSettingsTab)
-entity makeXonoticInputSettingsTab();
-#endif
 
-#ifdef IMPLEMENTATION
+#include "dialog_settings_input_userbind.qh"
+#include "skinlist.qh"
+#include "slider_resolution.qh"
+#include "../item/checkbox.qh"
+#include "keybinder.qh"
+#include "textlabel.qh"
+#include "button.qh"
+#include "slider.qh"
+#include "checkbox.qh"
+
 entity makeXonoticInputSettingsTab()
 {
 	entity me;
@@ -122,4 +120,3 @@ void XonoticInputSettingsTab_fill(entity me)
 			e.disabled = 1; // the option is never available in this case, just there for show
 		}
 }
-#endif
diff --git a/qcsrc/menu/xonotic/dialog_settings_input.qh b/qcsrc/menu/xonotic/dialog_settings_input.qh
index 6f70f09be..f8e6feda6 100644
--- a/qcsrc/menu/xonotic/dialog_settings_input.qh
+++ b/qcsrc/menu/xonotic/dialog_settings_input.qh
@@ -1 +1,10 @@
 #pragma once
+
+#include "tab.qh"
+CLASS(XonoticInputSettingsTab, XonoticTab)
+	METHOD(XonoticInputSettingsTab, fill, void(entity));
+	ATTRIB(XonoticInputSettingsTab, intendedWidth, float, 0.9)
+	ATTRIB(XonoticInputSettingsTab, rows, float, 15.5)
+	ATTRIB(XonoticInputSettingsTab, columns, float, 6.2)  // added extra .2 for center space
+ENDCLASS(XonoticInputSettingsTab)
+entity makeXonoticInputSettingsTab();
diff --git a/qcsrc/menu/xonotic/dialog_settings_input_userbind.qc b/qcsrc/menu/xonotic/dialog_settings_input_userbind.qc
index 9fa18d3b7..d8d5e7e18 100644
--- a/qcsrc/menu/xonotic/dialog_settings_input_userbind.qc
+++ b/qcsrc/menu/xonotic/dialog_settings_input_userbind.qc
@@ -1,24 +1,10 @@
 #include "dialog_settings_input_userbind.qh"
-#ifndef DIALOG_SETTINGS_INPUT_USERBIND_H
-#define DIALOG_SETTINGS_INPUT_USERBIND_H
-#include "dialog.qc"
-CLASS(XonoticUserbindEditDialog, XonoticDialog)
-	METHOD(XonoticUserbindEditDialog, loadUserBind, void(entity, string, string, string));
-	METHOD(XonoticUserbindEditDialog, fill, void(entity));
-	ATTRIB(XonoticUserbindEditDialog, title, string, _("User defined key bind"))
-	ATTRIB(XonoticUserbindEditDialog, color, vector, SKINCOLOR_DIALOG_USERBIND)
-	ATTRIB(XonoticUserbindEditDialog, intendedWidth, float, 0.7)
-	ATTRIB(XonoticUserbindEditDialog, rows, float, 4)
-	ATTRIB(XonoticUserbindEditDialog, columns, float, 3)
-	ATTRIB(XonoticUserbindEditDialog, keybindBox, entity, NULL)
 
-	ATTRIB(XonoticUserbindEditDialog, nameBox, entity, NULL)
-	ATTRIB(XonoticUserbindEditDialog, commandPressBox, entity, NULL)
-	ATTRIB(XonoticUserbindEditDialog, commandReleaseBox, entity, NULL)
-ENDCLASS(XonoticUserbindEditDialog)
-#endif
+#include "keybinder.qh"
+#include "textlabel.qh"
+#include "inputbox.qh"
+#include "button.qh"
 
-#ifdef IMPLEMENTATION
 void XonoticUserbindEditDialog_Save(entity btn, entity me)
 {
 	me.keybindBox.editUserbind(me.keybindBox, me.nameBox.text, me.commandPressBox.text, me.commandReleaseBox.text);
@@ -55,4 +41,3 @@ void XonoticUserbindEditDialog_fill(entity me)
 			e.onClick = Dialog_Close;
 			e.onClickEntity = me;
 }
-#endif
diff --git a/qcsrc/menu/xonotic/dialog_settings_input_userbind.qh b/qcsrc/menu/xonotic/dialog_settings_input_userbind.qh
index 6f70f09be..5ff3a2e0b 100644
--- a/qcsrc/menu/xonotic/dialog_settings_input_userbind.qh
+++ b/qcsrc/menu/xonotic/dialog_settings_input_userbind.qh
@@ -1 +1,17 @@
 #pragma once
+
+#include "dialog.qh"
+CLASS(XonoticUserbindEditDialog, XonoticDialog)
+	METHOD(XonoticUserbindEditDialog, loadUserBind, void(entity, string, string, string));
+	METHOD(XonoticUserbindEditDialog, fill, void(entity));
+	ATTRIB(XonoticUserbindEditDialog, title, string, _("User defined key bind"))
+	ATTRIB(XonoticUserbindEditDialog, color, vector, SKINCOLOR_DIALOG_USERBIND)
+	ATTRIB(XonoticUserbindEditDialog, intendedWidth, float, 0.7)
+	ATTRIB(XonoticUserbindEditDialog, rows, float, 4)
+	ATTRIB(XonoticUserbindEditDialog, columns, float, 3)
+	ATTRIB(XonoticUserbindEditDialog, keybindBox, entity, NULL)
+
+	ATTRIB(XonoticUserbindEditDialog, nameBox, entity, NULL)
+	ATTRIB(XonoticUserbindEditDialog, commandPressBox, entity, NULL)
+	ATTRIB(XonoticUserbindEditDialog, commandReleaseBox, entity, NULL)
+ENDCLASS(XonoticUserbindEditDialog)
diff --git a/qcsrc/menu/xonotic/dialog_settings_misc.qc b/qcsrc/menu/xonotic/dialog_settings_misc.qc
index b2488d050..d951275db 100644
--- a/qcsrc/menu/xonotic/dialog_settings_misc.qc
+++ b/qcsrc/menu/xonotic/dialog_settings_misc.qc
@@ -1,17 +1,13 @@
 #include "dialog_settings_misc.qh"
-#ifndef DIALOG_SETTINGS_MISC_H
-#define DIALOG_SETTINGS_MISC_H
-#include "tab.qc"
-CLASS(XonoticMiscSettingsTab, XonoticTab)
-	METHOD(XonoticMiscSettingsTab, fill, void(entity));
-	ATTRIB(XonoticMiscSettingsTab, intendedWidth, float, 0.9)
-	ATTRIB(XonoticMiscSettingsTab, rows, float, 15.5)
-	ATTRIB(XonoticMiscSettingsTab, columns, float, 6.2)
-ENDCLASS(XonoticMiscSettingsTab)
-entity makeXonoticMiscSettingsTab();
-#endif
 
-#ifdef IMPLEMENTATION
+#include "textlabel.qh"
+#include "inputbox.qh"
+#include "textslider.qh"
+#include "slider.qh"
+#include "checkbox.qh"
+#include "button.qh"
+#include "mainwindow.qh"
+
 #define ADDVALUE_FPS(i) e.addValue(e, strzone(sprintf(_("%d fps"), i)), #i)
 entity makeXonoticMiscSettingsTab()
 {
@@ -153,4 +149,3 @@ void XonoticMiscSettingsTab_fill(entity me)
 			e.onClickEntity = main.resetDialog;
 }
 #undef ADDVALUE_FPS
-#endif
diff --git a/qcsrc/menu/xonotic/dialog_settings_misc.qh b/qcsrc/menu/xonotic/dialog_settings_misc.qh
index 6f70f09be..f3f367e68 100644
--- a/qcsrc/menu/xonotic/dialog_settings_misc.qh
+++ b/qcsrc/menu/xonotic/dialog_settings_misc.qh
@@ -1 +1,10 @@
 #pragma once
+
+#include "tab.qh"
+CLASS(XonoticMiscSettingsTab, XonoticTab)
+	METHOD(XonoticMiscSettingsTab, fill, void(entity));
+	ATTRIB(XonoticMiscSettingsTab, intendedWidth, float, 0.9)
+	ATTRIB(XonoticMiscSettingsTab, rows, float, 15.5)
+	ATTRIB(XonoticMiscSettingsTab, columns, float, 6.2)
+ENDCLASS(XonoticMiscSettingsTab)
+entity makeXonoticMiscSettingsTab();
diff --git a/qcsrc/menu/xonotic/dialog_settings_misc_cvars.qc b/qcsrc/menu/xonotic/dialog_settings_misc_cvars.qc
index d4b9ff93d..f1fec78cf 100644
--- a/qcsrc/menu/xonotic/dialog_settings_misc_cvars.qc
+++ b/qcsrc/menu/xonotic/dialog_settings_misc_cvars.qc
@@ -1,19 +1,10 @@
 #include "dialog_settings_misc_cvars.qh"
-#ifndef DIALOG_SETTINGS_MISC_CVARS_H
-#define DIALOG_SETTINGS_MISC_CVARS_H
-#include "dialog.qc"
-CLASS(XonoticCvarsDialog, XonoticDialog)
-	METHOD(XonoticCvarsDialog, fill, void(entity));
-	METHOD(XonoticCvarsDialog, showNotify, void(entity));
-	ATTRIB(XonoticCvarsDialog, title, string, _("Advanced settings"))
-	ATTRIB(XonoticCvarsDialog, color, vector, SKINCOLOR_DIALOG_CVARS)
-	ATTRIB(XonoticCvarsDialog, intendedWidth, float, 0.8)
-	ATTRIB(XonoticCvarsDialog, rows, float, 24)
-	ATTRIB(XonoticCvarsDialog, columns, float, 6)
-ENDCLASS(XonoticCvarsDialog)
-#endif
 
-#ifdef IMPLEMENTATION
+#include "cvarlist.qh"
+#include "textlabel.qh"
+#include "inputbox.qh"
+#include "button.qh"
+
 void XonoticCvarsDialog_showNotify(entity me)
 {
 	SUPER(XonoticCvarsDialog).showNotify(me);
@@ -86,5 +77,3 @@ void XonoticCvarsDialog_fill(entity me) // in this dialog, use SKINCOLOR_CVARLIS
 			e.onClick = Dialog_Close;
 			e.onClickEntity = me;
 }
-
-#endif
diff --git a/qcsrc/menu/xonotic/dialog_settings_misc_cvars.qh b/qcsrc/menu/xonotic/dialog_settings_misc_cvars.qh
index 6f70f09be..f5011f771 100644
--- a/qcsrc/menu/xonotic/dialog_settings_misc_cvars.qh
+++ b/qcsrc/menu/xonotic/dialog_settings_misc_cvars.qh
@@ -1 +1,12 @@
 #pragma once
+
+#include "dialog.qh"
+CLASS(XonoticCvarsDialog, XonoticDialog)
+	METHOD(XonoticCvarsDialog, fill, void(entity));
+	METHOD(XonoticCvarsDialog, showNotify, void(entity));
+	ATTRIB(XonoticCvarsDialog, title, string, _("Advanced settings"))
+	ATTRIB(XonoticCvarsDialog, color, vector, SKINCOLOR_DIALOG_CVARS)
+	ATTRIB(XonoticCvarsDialog, intendedWidth, float, 0.8)
+	ATTRIB(XonoticCvarsDialog, rows, float, 24)
+	ATTRIB(XonoticCvarsDialog, columns, float, 6)
+ENDCLASS(XonoticCvarsDialog)
diff --git a/qcsrc/menu/xonotic/dialog_settings_misc_reset.qc b/qcsrc/menu/xonotic/dialog_settings_misc_reset.qc
index a8bd5e730..d3ba0e420 100644
--- a/qcsrc/menu/xonotic/dialog_settings_misc_reset.qc
+++ b/qcsrc/menu/xonotic/dialog_settings_misc_reset.qc
@@ -1,19 +1,9 @@
 #include "dialog_settings_misc_reset.qh"
-#ifndef DIALOG_SETTINGS_MISC_RESET_H
-#define DIALOG_SETTINGS_MISC_RESET_H
-#include "dialog.qc"
-CLASS(XonoticResetDialog, XonoticDialog)
-	METHOD(XonoticResetDialog, fill, void(entity));
-	ATTRIB(XonoticResetDialog, title, string, _("Factory reset"))
-	ATTRIB(XonoticResetDialog, color, vector, SKINCOLOR_DIALOG_QUIT)
-	ATTRIB(XonoticResetDialog, intendedWidth, float, 0.5)
-	ATTRIB(XonoticResetDialog, rows, float, 4)
-	ATTRIB(XonoticResetDialog, columns, float, 2)
-	ATTRIB(XonoticResetDialog, name, string, "Factory reset")
-ENDCLASS(XonoticResetDialog)
-#endif
 
-#ifdef IMPLEMENTATION
+#include "textlabel.qh"
+#include "commandbutton.qh"
+#include "button.qh"
+
 void XonoticResetDialog_fill(entity me)
 {
 	entity e;
@@ -28,4 +18,3 @@ void XonoticResetDialog_fill(entity me)
 			e.onClick = Dialog_Close;
 			e.onClickEntity = me;
 }
-#endif
diff --git a/qcsrc/menu/xonotic/dialog_settings_misc_reset.qh b/qcsrc/menu/xonotic/dialog_settings_misc_reset.qh
index 6f70f09be..1cbc7773a 100644
--- a/qcsrc/menu/xonotic/dialog_settings_misc_reset.qh
+++ b/qcsrc/menu/xonotic/dialog_settings_misc_reset.qh
@@ -1 +1,12 @@
 #pragma once
+
+#include "dialog.qh"
+CLASS(XonoticResetDialog, XonoticDialog)
+	METHOD(XonoticResetDialog, fill, void(entity));
+	ATTRIB(XonoticResetDialog, title, string, _("Factory reset"))
+	ATTRIB(XonoticResetDialog, color, vector, SKINCOLOR_DIALOG_QUIT)
+	ATTRIB(XonoticResetDialog, intendedWidth, float, 0.5)
+	ATTRIB(XonoticResetDialog, rows, float, 4)
+	ATTRIB(XonoticResetDialog, columns, float, 2)
+	ATTRIB(XonoticResetDialog, name, string, "Factory reset")
+ENDCLASS(XonoticResetDialog)
diff --git a/qcsrc/menu/xonotic/dialog_settings_user.qc b/qcsrc/menu/xonotic/dialog_settings_user.qc
index d102da638..fc6521c4d 100644
--- a/qcsrc/menu/xonotic/dialog_settings_user.qc
+++ b/qcsrc/menu/xonotic/dialog_settings_user.qc
@@ -1,17 +1,11 @@
 #include "dialog_settings_user.qh"
-#ifndef DIALOG_SETTINGS_USER_H
-#define DIALOG_SETTINGS_USER_H
-#include "tab.qc"
-CLASS(XonoticUserSettingsTab, XonoticTab)
-	METHOD(XonoticUserSettingsTab, fill, void(entity));
-	ATTRIB(XonoticUserSettingsTab, intendedWidth, float, 0.9)
-	ATTRIB(XonoticUserSettingsTab, rows, float, 15.5)
-	ATTRIB(XonoticUserSettingsTab, columns, float, 6)
-ENDCLASS(XonoticUserSettingsTab)
-entity makeXonoticUserSettingsTab();
-#endif
 
-#ifdef IMPLEMENTATION
+#include "commandbutton.qh"
+#include "textlabel.qh"
+#include "languagelist.qh"
+#include "skinlist.qh"
+#include "checkbox.qh"
+
 entity makeXonoticUserSettingsTab()
 {
 	entity me;
@@ -85,4 +79,3 @@ void XonoticUserSettingsTab_fill(entity me)
 		me.TD(me, 1, 6, userApplyButton);
 
 }
-#endif
diff --git a/qcsrc/menu/xonotic/dialog_settings_user.qh b/qcsrc/menu/xonotic/dialog_settings_user.qh
index 6f70f09be..3a5ccc3b6 100644
--- a/qcsrc/menu/xonotic/dialog_settings_user.qh
+++ b/qcsrc/menu/xonotic/dialog_settings_user.qh
@@ -1 +1,10 @@
 #pragma once
+
+#include "tab.qh"
+CLASS(XonoticUserSettingsTab, XonoticTab)
+	METHOD(XonoticUserSettingsTab, fill, void(entity));
+	ATTRIB(XonoticUserSettingsTab, intendedWidth, float, 0.9)
+	ATTRIB(XonoticUserSettingsTab, rows, float, 15.5)
+	ATTRIB(XonoticUserSettingsTab, columns, float, 6)
+ENDCLASS(XonoticUserSettingsTab)
+entity makeXonoticUserSettingsTab();
diff --git a/qcsrc/menu/xonotic/dialog_settings_user_languagewarning.qc b/qcsrc/menu/xonotic/dialog_settings_user_languagewarning.qc
index 00b209301..3cbd15bb4 100644
--- a/qcsrc/menu/xonotic/dialog_settings_user_languagewarning.qc
+++ b/qcsrc/menu/xonotic/dialog_settings_user_languagewarning.qc
@@ -1,18 +1,8 @@
 #include "dialog_settings_user_languagewarning.qh"
-#ifndef DIALOG_SETTINGS_USER_LANGUAGEWARNING_H
-#define DIALOG_SETTINGS_USER_LANGUAGEWARNING_H
-#include "dialog.qc"
-CLASS(XonoticLanguageWarningDialog, XonoticDialog)
-	METHOD(XonoticLanguageWarningDialog, fill, void(entity));
-	ATTRIB(XonoticLanguageWarningDialog, title, string, _("Warning"))
-	ATTRIB(XonoticLanguageWarningDialog, color, vector, SKINCOLOR_DIALOG_HUDCONFIRM)
-	ATTRIB(XonoticLanguageWarningDialog, intendedWidth, float, 0.6)
-	ATTRIB(XonoticLanguageWarningDialog, rows, float, 5)
-	ATTRIB(XonoticLanguageWarningDialog, columns, float, 4)
-ENDCLASS(XonoticLanguageWarningDialog)
-#endif
 
-#ifdef IMPLEMENTATION
+#include "textlabel.qh"
+#include "commandbutton.qh"
+
 void XonoticLanguageWarningDialog_fill(entity me)
 {
 	entity e;
@@ -26,4 +16,3 @@ void XonoticLanguageWarningDialog_fill(entity me)
 		me.TD(me, 1, 2, e = makeXonoticCommandButton(_("Disconnect now"), '0 0 0', "disconnect", 0));
 		me.TD(me, 1, 2, e = makeXonoticCommandButton(_("Switch language"), '0 0 0', "prvm_language \"$_menu_prvm_language\"; menu_restart; menu_cmd languageselect", 0));
 }
-#endif
diff --git a/qcsrc/menu/xonotic/dialog_settings_user_languagewarning.qh b/qcsrc/menu/xonotic/dialog_settings_user_languagewarning.qh
index 6f70f09be..6028a441c 100644
--- a/qcsrc/menu/xonotic/dialog_settings_user_languagewarning.qh
+++ b/qcsrc/menu/xonotic/dialog_settings_user_languagewarning.qh
@@ -1 +1,11 @@
 #pragma once
+
+#include "dialog.qh"
+CLASS(XonoticLanguageWarningDialog, XonoticDialog)
+	METHOD(XonoticLanguageWarningDialog, fill, void(entity));
+	ATTRIB(XonoticLanguageWarningDialog, title, string, _("Warning"))
+	ATTRIB(XonoticLanguageWarningDialog, color, vector, SKINCOLOR_DIALOG_HUDCONFIRM)
+	ATTRIB(XonoticLanguageWarningDialog, intendedWidth, float, 0.6)
+	ATTRIB(XonoticLanguageWarningDialog, rows, float, 5)
+	ATTRIB(XonoticLanguageWarningDialog, columns, float, 4)
+ENDCLASS(XonoticLanguageWarningDialog)
diff --git a/qcsrc/menu/xonotic/dialog_settings_video.qc b/qcsrc/menu/xonotic/dialog_settings_video.qc
index f78571784..1ec53c623 100644
--- a/qcsrc/menu/xonotic/dialog_settings_video.qc
+++ b/qcsrc/menu/xonotic/dialog_settings_video.qc
@@ -1,18 +1,13 @@
 #include "dialog_settings_video.qh"
-#ifndef DIALOG_SETTINGS_VIDEO_H
-#define DIALOG_SETTINGS_VIDEO_H
-#include "tab.qc"
-CLASS(XonoticVideoSettingsTab, XonoticTab)
-	METHOD(XonoticVideoSettingsTab, fill, void(entity));
-	ATTRIB(XonoticVideoSettingsTab, intendedWidth, float, 0.9)
-	ATTRIB(XonoticVideoSettingsTab, rows, float, 15.5)
-	ATTRIB(XonoticVideoSettingsTab, columns, float, 6.2) // added extra .2 for center space
-	ATTRIB(XonoticVideoSettingsTab, name, string, "videosettings")
-ENDCLASS(XonoticVideoSettingsTab)
-entity makeXonoticVideoSettingsTab();
-#endif
 
-#ifdef IMPLEMENTATION
+#include "commandbutton.qh"
+#include "textlabel.qh"
+#include "textslider.qh"
+#include "checkbox.qh"
+#include "slider.qh"
+#include "slider_resolution.qh"
+#include "radiobutton.qh"
+
 entity makeXonoticVideoSettingsTab()
 {
 	entity me;
@@ -177,4 +172,3 @@ void XonoticVideoSettingsTab_fill(entity me)
 	me.gotoRC(me, me.rows - 1, 0);
 		me.TD(me, 1, me.columns, videoApplyButton);
 }
-#endif
diff --git a/qcsrc/menu/xonotic/dialog_settings_video.qh b/qcsrc/menu/xonotic/dialog_settings_video.qh
index 6f70f09be..0abe322c3 100644
--- a/qcsrc/menu/xonotic/dialog_settings_video.qh
+++ b/qcsrc/menu/xonotic/dialog_settings_video.qh
@@ -1 +1,11 @@
 #pragma once
+
+#include "tab.qh"
+CLASS(XonoticVideoSettingsTab, XonoticTab)
+	METHOD(XonoticVideoSettingsTab, fill, void(entity));
+	ATTRIB(XonoticVideoSettingsTab, intendedWidth, float, 0.9)
+	ATTRIB(XonoticVideoSettingsTab, rows, float, 15.5)
+	ATTRIB(XonoticVideoSettingsTab, columns, float, 6.2)  // added extra .2 for center space
+	ATTRIB(XonoticVideoSettingsTab, name, string, "videosettings")
+ENDCLASS(XonoticVideoSettingsTab)
+entity makeXonoticVideoSettingsTab();
diff --git a/qcsrc/menu/xonotic/dialog_singleplayer.qc b/qcsrc/menu/xonotic/dialog_singleplayer.qc
index 6337a665a..20984034d 100644
--- a/qcsrc/menu/xonotic/dialog_singleplayer.qc
+++ b/qcsrc/menu/xonotic/dialog_singleplayer.qc
@@ -1,20 +1,10 @@
 #include "dialog_singleplayer.qh"
-#ifndef DIALOG_SINGLEPLAYER_H
-#define DIALOG_SINGLEPLAYER_H
-#include "dialog.qc"
-CLASS(XonoticSingleplayerDialog, XonoticDialog)
-	METHOD(XonoticSingleplayerDialog, fill, void(entity));
-	ATTRIB(XonoticSingleplayerDialog, title, string, _("Singleplayer"))
-	ATTRIB(XonoticSingleplayerDialog, tooltip, string, _("Play the singleplayer campaign or instant action matches against bots"))
-	ATTRIB(XonoticSingleplayerDialog, color, vector, SKINCOLOR_DIALOG_SINGLEPLAYER)
-	ATTRIB(XonoticSingleplayerDialog, intendedWidth, float, 0.80)
-	ATTRIB(XonoticSingleplayerDialog, rows, float, 24)
-	ATTRIB(XonoticSingleplayerDialog, columns, float, 5)
-	ATTRIB(XonoticSingleplayerDialog, campaignBox, entity, NULL)
-ENDCLASS(XonoticSingleplayerDialog)
-#endif
 
-#ifdef IMPLEMENTATION
+#include <common/mapinfo.qh>
+#include "bigbutton.qh"
+#include "radiobutton.qh"
+#include "textlabel.qh"
+#include "campaign.qh"
 
 void InstantAction_LoadMap(entity btn, entity dummy)
 {
@@ -146,4 +136,3 @@ void XonoticSingleplayerDialog_fill(entity me)
 			e.onClick = CampaignList_LoadMap;
 			e.onClickEntity = me.campaignBox;
 }
-#endif
diff --git a/qcsrc/menu/xonotic/dialog_singleplayer.qh b/qcsrc/menu/xonotic/dialog_singleplayer.qh
index 6f70f09be..b3dabaf6c 100644
--- a/qcsrc/menu/xonotic/dialog_singleplayer.qh
+++ b/qcsrc/menu/xonotic/dialog_singleplayer.qh
@@ -1 +1,13 @@
 #pragma once
+
+#include "dialog.qh"
+CLASS(XonoticSingleplayerDialog, XonoticDialog)
+	METHOD(XonoticSingleplayerDialog, fill, void(entity));
+	ATTRIB(XonoticSingleplayerDialog, title, string, _("Singleplayer"))
+	ATTRIB(XonoticSingleplayerDialog, tooltip, string, _("Play the singleplayer campaign or instant action matches against bots"))
+	ATTRIB(XonoticSingleplayerDialog, color, vector, SKINCOLOR_DIALOG_SINGLEPLAYER)
+	ATTRIB(XonoticSingleplayerDialog, intendedWidth, float, 0.80)
+	ATTRIB(XonoticSingleplayerDialog, rows, float, 24)
+	ATTRIB(XonoticSingleplayerDialog, columns, float, 5)
+	ATTRIB(XonoticSingleplayerDialog, campaignBox, entity, NULL)
+ENDCLASS(XonoticSingleplayerDialog)
diff --git a/qcsrc/menu/xonotic/dialog_singleplayer_winner.qc b/qcsrc/menu/xonotic/dialog_singleplayer_winner.qc
index b484e282a..ff81d7d89 100644
--- a/qcsrc/menu/xonotic/dialog_singleplayer_winner.qc
+++ b/qcsrc/menu/xonotic/dialog_singleplayer_winner.qc
@@ -1,19 +1,8 @@
 #include "dialog_singleplayer_winner.qh"
-#ifndef DIALOG_SINGLEPLAYER_WINNER_H
-#define DIALOG_SINGLEPLAYER_WINNER_H
-#include "dialog.qc"
-CLASS(XonoticWinnerDialog, XonoticDialog)
-	METHOD(XonoticWinnerDialog, fill, void(entity));
-	METHOD(XonoticWinnerDialog, focusEnter, void(entity));
-	ATTRIB(XonoticWinnerDialog, title, string, _("Winner"))
-	ATTRIB(XonoticWinnerDialog, color, vector, SKINCOLOR_DIALOG_SINGLEPLAYER)
-	ATTRIB(XonoticWinnerDialog, intendedWidth, float, 0.32)
-	ATTRIB(XonoticWinnerDialog, rows, float, 12)
-	ATTRIB(XonoticWinnerDialog, columns, float, 3)
-ENDCLASS(XonoticWinnerDialog)
-#endif
 
-#ifdef IMPLEMENTATION
+#include "image.qh"
+#include "button.qh"
+
 void XonoticWinnerDialog_fill(entity me)
 {
 	entity e;
@@ -30,4 +19,3 @@ void XonoticWinnerDialog_focusEnter(entity me)
 {
 	m_play_click_sound(MENU_SOUND_WINNER);
 }
-#endif
diff --git a/qcsrc/menu/xonotic/dialog_singleplayer_winner.qh b/qcsrc/menu/xonotic/dialog_singleplayer_winner.qh
index 6f70f09be..1de958b8b 100644
--- a/qcsrc/menu/xonotic/dialog_singleplayer_winner.qh
+++ b/qcsrc/menu/xonotic/dialog_singleplayer_winner.qh
@@ -1 +1,12 @@
 #pragma once
+
+#include "dialog.qh"
+CLASS(XonoticWinnerDialog, XonoticDialog)
+	METHOD(XonoticWinnerDialog, fill, void(entity));
+	METHOD(XonoticWinnerDialog, focusEnter, void(entity));
+	ATTRIB(XonoticWinnerDialog, title, string, _("Winner"))
+	ATTRIB(XonoticWinnerDialog, color, vector, SKINCOLOR_DIALOG_SINGLEPLAYER)
+	ATTRIB(XonoticWinnerDialog, intendedWidth, float, 0.32)
+	ATTRIB(XonoticWinnerDialog, rows, float, 12)
+	ATTRIB(XonoticWinnerDialog, columns, float, 3)
+ENDCLASS(XonoticWinnerDialog)
diff --git a/qcsrc/menu/xonotic/dialog_teamselect.qc b/qcsrc/menu/xonotic/dialog_teamselect.qc
index 33ded408f..b12de7c29 100644
--- a/qcsrc/menu/xonotic/dialog_teamselect.qc
+++ b/qcsrc/menu/xonotic/dialog_teamselect.qc
@@ -1,25 +1,7 @@
 #include "dialog_teamselect.qh"
-#ifndef DIALOG_TEAMSELECT_H
-#define DIALOG_TEAMSELECT_H
-#include "rootdialog.qc"
-CLASS(XonoticTeamSelectDialog, XonoticRootDialog)
-	METHOD(XonoticTeamSelectDialog, fill, void(entity));
-	METHOD(XonoticTeamSelectDialog, showNotify, void(entity));
-	ATTRIB(XonoticTeamSelectDialog, title, string, _("Team Selection"))
-	ATTRIB(XonoticTeamSelectDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT)
-	ATTRIB(XonoticTeamSelectDialog, intendedWidth, float, 0.4)
-	ATTRIB(XonoticTeamSelectDialog, rows, float, 5)
-	ATTRIB(XonoticTeamSelectDialog, columns, float, 4)
-	ATTRIB(XonoticTeamSelectDialog, name, string, "TeamSelect")
-	ATTRIB(XonoticTeamSelectDialog, team1, entity, NULL)
-	ATTRIB(XonoticTeamSelectDialog, team2, entity, NULL)
-	ATTRIB(XonoticTeamSelectDialog, team3, entity, NULL)
-	ATTRIB(XonoticTeamSelectDialog, team4, entity, NULL)
-	ATTRIB(XonoticTeamSelectDialog, requiresConnection, float, true)
-ENDCLASS(XonoticTeamSelectDialog)
-#endif
 
-#ifdef IMPLEMENTATION
+#include "bigcommandbutton.qh"
+
 entity makeTeamButton_T(string theName, vector theColor, string commandtheName, string theTooltip)
 {
 	entity b;
@@ -60,6 +42,3 @@ void XonoticTeamSelectDialog_fill(entity me)
 	me.TR(me);
 		me.TD(me, 1, 4, makeXonoticCommandButton(_("spectate"), '0 0 0', "cmd spectate", 1));
 }
-#endif
-
-/* Click. The c-word is here so you can grep for it :-) */
diff --git a/qcsrc/menu/xonotic/dialog_teamselect.qh b/qcsrc/menu/xonotic/dialog_teamselect.qh
index 6f70f09be..b4056bb3b 100644
--- a/qcsrc/menu/xonotic/dialog_teamselect.qh
+++ b/qcsrc/menu/xonotic/dialog_teamselect.qh
@@ -1 +1,18 @@
 #pragma once
+
+#include "rootdialog.qh"
+CLASS(XonoticTeamSelectDialog, XonoticRootDialog)
+	METHOD(XonoticTeamSelectDialog, fill, void(entity));
+	METHOD(XonoticTeamSelectDialog, showNotify, void(entity));
+	ATTRIB(XonoticTeamSelectDialog, title, string, _("Team Selection"))
+	ATTRIB(XonoticTeamSelectDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT)
+	ATTRIB(XonoticTeamSelectDialog, intendedWidth, float, 0.4)
+	ATTRIB(XonoticTeamSelectDialog, rows, float, 5)
+	ATTRIB(XonoticTeamSelectDialog, columns, float, 4)
+	ATTRIB(XonoticTeamSelectDialog, name, string, "TeamSelect")
+	ATTRIB(XonoticTeamSelectDialog, team1, entity, NULL)
+	ATTRIB(XonoticTeamSelectDialog, team2, entity, NULL)
+	ATTRIB(XonoticTeamSelectDialog, team3, entity, NULL)
+	ATTRIB(XonoticTeamSelectDialog, team4, entity, NULL)
+	ATTRIB(XonoticTeamSelectDialog, requiresConnection, float, true)
+ENDCLASS(XonoticTeamSelectDialog)
diff --git a/qcsrc/menu/xonotic/gametypebutton.qc b/qcsrc/menu/xonotic/gametypebutton.qc
deleted file mode 100644
index 707a9aed5..000000000
--- a/qcsrc/menu/xonotic/gametypebutton.qc
+++ /dev/null
@@ -1,73 +0,0 @@
-#include "gametypebutton.qh"
-#ifndef GAMETYPEBUTTON_H
-#define GAMETYPEBUTTON_H
-#include "../item/radiobutton.qc"
-CLASS(XonoticGametypeButton, RadioButton)
-	METHOD(XonoticGametypeButton, configureXonoticGametypeButton, void(entity, float, string, string));
-	METHOD(XonoticGametypeButton, setChecked, void(entity, float));
-	ATTRIB(XonoticGametypeButton, fontSize, float, SKINFONTSIZE_NORMAL)
-	ATTRIB(XonoticGametypeButton, image, string, SKINGFX_BUTTON_BIG)
-	ATTRIB(XonoticGametypeButton, color, vector, SKINCOLOR_BUTTON_N)
-	ATTRIB(XonoticGametypeButton, colorC, vector, SKINCOLOR_BUTTON_C)
-	ATTRIB(XonoticGametypeButton, colorF, vector, SKINCOLOR_BUTTON_F)
-	ATTRIB(XonoticGametypeButton, colorD, vector, SKINCOLOR_BUTTON_D)
-	ATTRIB(XonoticGametypeButton, srcMulti, float, 1)
-	ATTRIB(XonoticGametypeButton, useDownAsChecked, float, 1)
-
-	ATTRIB(XonoticGametypeButton, cvarName, string, string_null)
-	METHOD(XonoticGametypeButton, loadCvars, void(entity));
-	METHOD(XonoticGametypeButton, saveCvars, void(entity));
-
-	ATTRIB(XonoticGametypeButton, alpha, float, SKINALPHA_TEXT)
-	ATTRIB(XonoticGametypeButton, disabledAlpha, float, SKINALPHA_DISABLED)
-ENDCLASS(XonoticGametypeButton)
-entity makeXonoticGametypeButton(float, string, string);
-#endif
-
-#ifdef IMPLEMENTATION
-void GameTypeButton_Click(entity me, entity other);
-entity makeXonoticGametypeButton(float theGroup, string theCvar, string theText)
-{
-	entity me;
-	me = NEW(XonoticGametypeButton);
-	me.configureXonoticGametypeButton(me, theGroup, theCvar, theText, theTooltip);
-	return me;
-}
-void XonoticGametypeButton_configureXonoticGametypeButton(entity me, float theGroup, string theCvar, string theText, string theTooltip)
-{
-	me.cvarName = (theCvar) ? theCvar : string_null;
-	me.loadCvars(me);
-	setZonedTooltip(me, theTooltip, theCvar);
-	me.configureRadioButton(me, theText, me.fontSize, me.image, theGroup, 0);
-	me.align = 0.5;
-	me.onClick = GameTypeButton_Click;
-	me.onClickEntity = NULL;
-}
-void XonoticGametypeButton_setChecked(entity me, float val)
-{
-	if(val != me.checked)
-	{
-		me.checked = val;
-		me.saveCvars(me);
-	}
-}
-void XonoticGametypeButton_loadCvars(entity me)
-{
-	if (!me.cvarName)
-		return;
-
-	me.checked = cvar(me.cvarName);
-}
-void XonoticGametypeButton_saveCvars(entity me)
-{
-	if (!me.cvarName)
-		return;
-
-	cvar_set(me.cvarName, ftos(me.checked));
-}
-void GameTypeButton_Click(entity me, entity other)
-{
-	RadioButton_Click(me, other);
-	me.parent.gameTypeChangeNotify(me.parent);
-}
-#endif
diff --git a/qcsrc/menu/xonotic/gametypebutton.qh b/qcsrc/menu/xonotic/gametypebutton.qh
deleted file mode 100644
index 6f70f09be..000000000
--- a/qcsrc/menu/xonotic/gametypebutton.qh
+++ /dev/null
@@ -1 +0,0 @@
-#pragma once
diff --git a/qcsrc/menu/xonotic/gametypelist.qc b/qcsrc/menu/xonotic/gametypelist.qc
index 89cfc1b58..9ee031dc7 100644
--- a/qcsrc/menu/xonotic/gametypelist.qc
+++ b/qcsrc/menu/xonotic/gametypelist.qc
@@ -1,30 +1,7 @@
 #include "gametypelist.qh"
-#ifndef GAMETYPELIST_H
-#define GAMETYPELIST_H
-#include "listbox.qc"
-CLASS(XonoticGametypeList, XonoticListBox)
-	METHOD(XonoticGametypeList, configureXonoticGametypeList, void(entity));
-	ATTRIB(XonoticGametypeList, rowsPerItem, float, 2)
-	METHOD(XonoticGametypeList, drawListBoxItem, void(entity, int, vector, bool, bool));
-	METHOD(XonoticGametypeList, resizeNotify, void(entity, vector, vector, vector, vector));
-	METHOD(XonoticGametypeList, setSelected, void(entity, float));
-	METHOD(XonoticGametypeList, loadCvars, void(entity));
-	METHOD(XonoticGametypeList, saveCvars, void(entity));
-	METHOD(XonoticGametypeList, keyDown, float(entity, float, float, float));
-	METHOD(XonoticGametypeList, clickListBoxItem, void(entity, float, vector));
-	METHOD(XonoticGametypeList, focusedItemChangeNotify, void(entity));
 
-	ATTRIB(XonoticGametypeList, realFontSize, vector, '0 0 0')
-	ATTRIB(XonoticGametypeList, realUpperMargin, float, 0)
-	ATTRIB(XonoticGametypeList, columnIconOrigin, float, 0)
-	ATTRIB(XonoticGametypeList, columnIconSize, float, 0)
-	ATTRIB(XonoticGametypeList, columnNameOrigin, float, 0)
-	ATTRIB(XonoticGametypeList, columnNameSize, float, 0)
-ENDCLASS(XonoticGametypeList)
-entity makeXonoticGametypeList();
-#endif
-
-#ifdef IMPLEMENTATION
+#include "dialog_multiplayer_create.qh"
+#include <common/mapinfo.qh>
 
 entity makeXonoticGametypeList()
 {
@@ -114,7 +91,7 @@ void XonoticGametypeList_drawListBoxItem(entity me, int i, vector absSize, bool
 void XonoticGametypeList_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize)
 {
 	me.itemAbsSize = '0 0 0';
-	SUPER(XonoticServerList).resizeNotify(me, relOrigin, relSize, absOrigin, absSize);
+	SUPER(XonoticGametypeList).resizeNotify(me, relOrigin, relSize, absOrigin, absSize);
 
 	me.realFontSize_y = me.fontSize / (me.itemAbsSize_y = (absSize.y * me.itemHeight));
 	me.realFontSize_x = me.fontSize / (me.itemAbsSize_x = (absSize.x * (1 - me.controlWidth)));
@@ -146,4 +123,3 @@ void XonoticGametypeList_focusedItemChangeNotify(entity me)
 	else
 		clearTooltip(me);
 }
-#endif
diff --git a/qcsrc/menu/xonotic/gametypelist.qh b/qcsrc/menu/xonotic/gametypelist.qh
index 6f70f09be..95eceaa09 100644
--- a/qcsrc/menu/xonotic/gametypelist.qh
+++ b/qcsrc/menu/xonotic/gametypelist.qh
@@ -1 +1,23 @@
 #pragma once
+
+#include "listbox.qh"
+CLASS(XonoticGametypeList, XonoticListBox)
+	METHOD(XonoticGametypeList, configureXonoticGametypeList, void(entity));
+	ATTRIB(XonoticGametypeList, rowsPerItem, float, 2)
+	METHOD(XonoticGametypeList, drawListBoxItem, void(entity, int, vector, bool, bool));
+	METHOD(XonoticGametypeList, resizeNotify, void(entity, vector, vector, vector, vector));
+	METHOD(XonoticGametypeList, setSelected, void(entity, float));
+	METHOD(XonoticGametypeList, loadCvars, void(entity));
+	METHOD(XonoticGametypeList, saveCvars, void(entity));
+	METHOD(XonoticGametypeList, keyDown, float(entity, float, float, float));
+	METHOD(XonoticGametypeList, clickListBoxItem, void(entity, float, vector));
+	METHOD(XonoticGametypeList, focusedItemChangeNotify, void(entity));
+
+	ATTRIB(XonoticGametypeList, realFontSize, vector, '0 0 0')
+	ATTRIB(XonoticGametypeList, realUpperMargin, float, 0)
+	ATTRIB(XonoticGametypeList, columnIconOrigin, float, 0)
+	ATTRIB(XonoticGametypeList, columnIconSize, float, 0)
+	ATTRIB(XonoticGametypeList, columnNameOrigin, float, 0)
+	ATTRIB(XonoticGametypeList, columnNameSize, float, 0)
+ENDCLASS(XonoticGametypeList)
+entity makeXonoticGametypeList();
diff --git a/qcsrc/menu/xonotic/hudskinlist.qc b/qcsrc/menu/xonotic/hudskinlist.qc
index bcb20523a..66c96046d 100644
--- a/qcsrc/menu/xonotic/hudskinlist.qc
+++ b/qcsrc/menu/xonotic/hudskinlist.qc
@@ -1,50 +1,6 @@
 #include "hudskinlist.qh"
-#ifndef HUDSKINLIST_H
-#define HUDSKINLIST_H
-#include "listbox.qc"
-CLASS(XonoticHUDSkinList, XonoticListBox)
-	METHOD(XonoticHUDSkinList, configureXonoticHUDSkinList, void(entity));
-	ATTRIB(XonoticHUDSkinList, rowsPerItem, float, 1)
-	METHOD(XonoticHUDSkinList, resizeNotify, void(entity, vector, vector, vector, vector));
-	METHOD(XonoticHUDSkinList, draw, void(entity));
-	METHOD(XonoticHUDSkinList, drawListBoxItem, void(entity, int, vector, bool, bool));
-	METHOD(XonoticHUDSkinList, getHUDSkins, void(entity));
-	METHOD(XonoticHUDSkinList, setHUDSkin, void(entity));
-	METHOD(XonoticHUDSkinList, hudskinName, string(entity, float));
-	METHOD(XonoticHUDSkinList, hudskinPath, string(entity, float));
-	METHOD(XonoticHUDSkinList, hudskinTitle, string(entity, float));
-	METHOD(XonoticHUDSkinList, hudskinAuthor, string(entity, float));
-	METHOD(XonoticHUDSkinList, doubleClickListBoxItem, void(entity, float, vector));
-	METHOD(XonoticHUDSkinList, keyDown, float(entity, float, float, float));
-	METHOD(XonoticHUDSkinList, destroy, void(entity));
-	METHOD(XonoticHUDSkinList, showNotify, void(entity));
 
-	ATTRIB(XonoticHUDSkinList, listHUDSkin, float, -1)
-	ATTRIB(XonoticHUDSkinList, realFontSize, vector, '0 0 0')
-	ATTRIB(XonoticHUDSkinList, columnNameOrigin, float, 0)
-	ATTRIB(XonoticHUDSkinList, columnNameSize, float, 0)
-	ATTRIB(XonoticHUDSkinList, realUpperMargin, float, 0)
-	ATTRIB(XonoticHUDSkinList, origin, vector, '0 0 0')
-	ATTRIB(XonoticHUDSkinList, itemAbsSize, vector, '0 0 0')
-
-	ATTRIB(XonoticHUDSkinList, filterString, string, string_null)
-	ATTRIB(XonoticHUDSkinList, delayedRefreshTime, float, 0)
-	ATTRIB(XonoticHUDSkinList, savedName, string, string_null)
-ENDCLASS(XonoticHUDSkinList)
-
-#ifndef IMPLEMENTATION
-// public:
-entity hudskinlist;
-entity makeXonoticHUDSkinList();
-void SaveHUDSkin_Click(entity btn, entity me);
-void SetHUDSkin_Click(entity btn, entity me);
-#endif
-void HUDSkinList_Refresh_Click(entity btn, entity me);
-void HUDSkinList_Filter_Change(entity box, entity me);
-void HUDSkinList_SavedName_Change(entity box, entity me);
-#endif
-
-#ifdef IMPLEMENTATION
+#include "inputbox.qh"
 
 entity makeXonoticHUDSkinList()
 {
@@ -307,5 +263,3 @@ float XonoticHUDSkinList_keyDown(entity me, float scan, float ascii, float shift
 		return SUPER(XonoticHUDSkinList).keyDown(me, scan, ascii, shift);
 	}
 }
-#endif
-
diff --git a/qcsrc/menu/xonotic/hudskinlist.qh b/qcsrc/menu/xonotic/hudskinlist.qh
index 6f70f09be..f5808698c 100644
--- a/qcsrc/menu/xonotic/hudskinlist.qh
+++ b/qcsrc/menu/xonotic/hudskinlist.qh
@@ -1 +1,39 @@
 #pragma once
+
+#include "listbox.qh"
+CLASS(XonoticHUDSkinList, XonoticListBox)
+	METHOD(XonoticHUDSkinList, configureXonoticHUDSkinList, void(entity));
+	ATTRIB(XonoticHUDSkinList, rowsPerItem, float, 1)
+	METHOD(XonoticHUDSkinList, resizeNotify, void(entity, vector, vector, vector, vector));
+	METHOD(XonoticHUDSkinList, draw, void(entity));
+	METHOD(XonoticHUDSkinList, drawListBoxItem, void(entity, int, vector, bool, bool));
+	METHOD(XonoticHUDSkinList, getHUDSkins, void(entity));
+	METHOD(XonoticHUDSkinList, setHUDSkin, void(entity));
+	METHOD(XonoticHUDSkinList, hudskinName, string(entity, float));
+	METHOD(XonoticHUDSkinList, hudskinPath, string(entity, float));
+	METHOD(XonoticHUDSkinList, hudskinTitle, string(entity, float));
+	METHOD(XonoticHUDSkinList, hudskinAuthor, string(entity, float));
+	METHOD(XonoticHUDSkinList, doubleClickListBoxItem, void(entity, float, vector));
+	METHOD(XonoticHUDSkinList, keyDown, float(entity, float, float, float));
+	METHOD(XonoticHUDSkinList, destroy, void(entity));
+	METHOD(XonoticHUDSkinList, showNotify, void(entity));
+
+	ATTRIB(XonoticHUDSkinList, listHUDSkin, float, -1)
+	ATTRIB(XonoticHUDSkinList, realFontSize, vector, '0 0 0')
+	ATTRIB(XonoticHUDSkinList, columnNameOrigin, float, 0)
+	ATTRIB(XonoticHUDSkinList, columnNameSize, float, 0)
+	ATTRIB(XonoticHUDSkinList, realUpperMargin, float, 0)
+	ATTRIB(XonoticHUDSkinList, origin, vector, '0 0 0')
+	ATTRIB(XonoticHUDSkinList, itemAbsSize, vector, '0 0 0')
+
+	ATTRIB(XonoticHUDSkinList, filterString, string, string_null)
+	ATTRIB(XonoticHUDSkinList, delayedRefreshTime, float, 0)
+	ATTRIB(XonoticHUDSkinList, savedName, string, string_null)
+ENDCLASS(XonoticHUDSkinList)
+entity hudskinlist;
+entity makeXonoticHUDSkinList();
+void SaveHUDSkin_Click(entity btn, entity me);
+void SetHUDSkin_Click(entity btn, entity me);
+void HUDSkinList_Filter_Change(entity box, entity me);
+void HUDSkinList_Refresh_Click(entity btn, entity me);
+void HUDSkinList_SavedName_Change(entity box, entity me);
diff --git a/qcsrc/menu/xonotic/image.qc b/qcsrc/menu/xonotic/image.qc
index 931261f6d..f99fc5d94 100644
--- a/qcsrc/menu/xonotic/image.qc
+++ b/qcsrc/menu/xonotic/image.qc
@@ -1,14 +1,5 @@
 #include "image.qh"
-#ifndef IMAGE_H
-#define IMAGE_H
-#include "../item/image.qc"
-CLASS(XonoticImage, Image)
-	METHOD(XonoticImage, configureXonoticImage, void(entity, string, float));
-ENDCLASS(XonoticImage)
-entity makeXonoticImage(string theImage, float theAspect);
-#endif
 
-#ifdef IMPLEMENTATION
 entity makeXonoticImage(string theImage, float theAspect)
 {
 	entity me;
@@ -21,4 +12,3 @@ void XonoticImage_configureXonoticImage(entity me, string theImage, float theAsp
 	me.configureImage(me, theImage);
 	me.forcedAspect = theAspect;
 }
-#endif
diff --git a/qcsrc/menu/xonotic/image.qh b/qcsrc/menu/xonotic/image.qh
index 6f70f09be..b31c703a9 100644
--- a/qcsrc/menu/xonotic/image.qh
+++ b/qcsrc/menu/xonotic/image.qh
@@ -1 +1,7 @@
 #pragma once
+
+#include "../item/image.qh"
+CLASS(XonoticImage, Image)
+	METHOD(XonoticImage, configureXonoticImage, void(entity, string, float));
+ENDCLASS(XonoticImage)
+entity makeXonoticImage(string theImage, float theAspect);
diff --git a/qcsrc/menu/xonotic/inputbox.qc b/qcsrc/menu/xonotic/inputbox.qc
index eccf68f0d..22a7ce717 100644
--- a/qcsrc/menu/xonotic/inputbox.qc
+++ b/qcsrc/menu/xonotic/inputbox.qc
@@ -1,44 +1,5 @@
 #include "inputbox.qh"
-#ifndef INPUTBOX_H
-#define INPUTBOX_H
-#include "../item/inputbox.qc"
-CLASS(XonoticInputBox, InputBox)
-	METHOD(XonoticInputBox, configureXonoticInputBox, void(entity, float, string, string));
-	METHOD(XonoticInputBox, focusLeave, void(entity));
-	METHOD(XonoticInputBox, setText, void(entity, string));
-	METHOD(XonoticInputBox, keyDown, float(entity, float, float, float));
-	ATTRIB(XonoticInputBox, fontSize, float, SKINFONTSIZE_NORMAL)
-	ATTRIB(XonoticInputBox, image, string, SKINGFX_INPUTBOX)
-	ATTRIB(XonoticInputBox, onChange, void(entity, entity), func_null)
-	ATTRIB(XonoticInputBox, onChangeEntity, entity, NULL)
-	ATTRIB(XonoticInputBox, onEnter, void(entity, entity), func_null)
-	ATTRIB(XonoticInputBox, onEnterEntity, entity, NULL)
-	ATTRIB(XonoticInputBox, marginLeft, float, SKINMARGIN_INPUTBOX_CHARS)
-	ATTRIB(XonoticInputBox, marginRight, float, SKINMARGIN_INPUTBOX_CHARS)
-	ATTRIB(XonoticInputBox, color, vector, SKINCOLOR_INPUTBOX_N)
-	ATTRIB(XonoticInputBox, colorF, vector, SKINCOLOR_INPUTBOX_F)
 
-	ATTRIB(XonoticInputBox, alpha, float, SKINALPHA_TEXT)
-
-	// Clear button attributes
-	ATTRIB(XonoticInputBox, cb_offset, float, SKINOFFSET_CLEARBUTTON) // bound to range -1, 0
-	ATTRIB(XonoticInputBox, cb_src, string, SKINGFX_CLEARBUTTON)
-	ATTRIB(XonoticInputBox, cb_color, vector, SKINCOLOR_CLEARBUTTON_N)
-	ATTRIB(XonoticInputBox, cb_colorF, vector, SKINCOLOR_CLEARBUTTON_F)
-	ATTRIB(XonoticInputBox, cb_colorC, vector, SKINCOLOR_CLEARBUTTON_C)
-
-	ATTRIB(XonoticInputBox, cvarName, string, string_null)
-	METHOD(XonoticInputBox, loadCvars, void(entity));
-	METHOD(XonoticInputBox, saveCvars, void(entity));
-	ATTRIB(XonoticInputBox, sendCvars, float, 0)
-
-	ATTRIB(XonoticInputBox, saveImmediately, float, 0)
-ENDCLASS(XonoticInputBox)
-entity makeXonoticInputBox_T(float, string, string theTooltip);
-entity makeXonoticInputBox(float, string);
-#endif
-
-#ifdef IMPLEMENTATION
 entity makeXonoticInputBox_T(float doEditColorCodes, string theCvar, string theTooltip)
 {
 	entity me;
@@ -107,4 +68,3 @@ float XonoticInputBox_keyDown(entity me, float key, float ascii, float shift)
 		r = 1;
 	return r;
 }
-#endif
diff --git a/qcsrc/menu/xonotic/inputbox.qh b/qcsrc/menu/xonotic/inputbox.qh
index 6f70f09be..c09817943 100644
--- a/qcsrc/menu/xonotic/inputbox.qh
+++ b/qcsrc/menu/xonotic/inputbox.qh
@@ -1 +1,37 @@
 #pragma once
+
+#include "../item/inputbox.qh"
+CLASS(XonoticInputBox, InputBox)
+	METHOD(XonoticInputBox, configureXonoticInputBox, void(entity, float, string, string));
+	METHOD(XonoticInputBox, focusLeave, void(entity));
+	METHOD(XonoticInputBox, setText, void(entity, string));
+	METHOD(XonoticInputBox, keyDown, float(entity, float, float, float));
+	ATTRIB(XonoticInputBox, fontSize, float, SKINFONTSIZE_NORMAL)
+	ATTRIB(XonoticInputBox, image, string, SKINGFX_INPUTBOX)
+	ATTRIB(XonoticInputBox, onChange, void(entity, entity), func_null)
+	ATTRIB(XonoticInputBox, onChangeEntity, entity, NULL)
+	ATTRIB(XonoticInputBox, onEnter, void(entity, entity), func_null)
+	ATTRIB(XonoticInputBox, onEnterEntity, entity, NULL)
+	ATTRIB(XonoticInputBox, marginLeft, float, SKINMARGIN_INPUTBOX_CHARS)
+	ATTRIB(XonoticInputBox, marginRight, float, SKINMARGIN_INPUTBOX_CHARS)
+	ATTRIB(XonoticInputBox, color, vector, SKINCOLOR_INPUTBOX_N)
+	ATTRIB(XonoticInputBox, colorF, vector, SKINCOLOR_INPUTBOX_F)
+
+	ATTRIB(XonoticInputBox, alpha, float, SKINALPHA_TEXT)
+
+	// Clear button attributes
+	ATTRIB(XonoticInputBox, cb_offset, float, SKINOFFSET_CLEARBUTTON)  // bound to range -1, 0
+	ATTRIB(XonoticInputBox, cb_src, string, SKINGFX_CLEARBUTTON)
+	ATTRIB(XonoticInputBox, cb_color, vector, SKINCOLOR_CLEARBUTTON_N)
+	ATTRIB(XonoticInputBox, cb_colorF, vector, SKINCOLOR_CLEARBUTTON_F)
+	ATTRIB(XonoticInputBox, cb_colorC, vector, SKINCOLOR_CLEARBUTTON_C)
+
+	ATTRIB(XonoticInputBox, cvarName, string, string_null)
+	METHOD(XonoticInputBox, loadCvars, void(entity));
+	METHOD(XonoticInputBox, saveCvars, void(entity));
+	ATTRIB(XonoticInputBox, sendCvars, float, 0)
+
+	ATTRIB(XonoticInputBox, saveImmediately, float, 0)
+ENDCLASS(XonoticInputBox)
+entity makeXonoticInputBox_T(float, string, string theTooltip);
+entity makeXonoticInputBox(float, string);
diff --git a/qcsrc/menu/xonotic/keybinder.qc b/qcsrc/menu/xonotic/keybinder.qc
index fe7b95ef7..3cb20d301 100644
--- a/qcsrc/menu/xonotic/keybinder.qc
+++ b/qcsrc/menu/xonotic/keybinder.qc
@@ -1,43 +1,10 @@
 #include "keybinder.qh"
-#ifndef KEYBINDER_H
-#define KEYBINDER_H
-#include "listbox.qc"
-CLASS(XonoticKeyBinder, XonoticListBox)
-	METHOD(XonoticKeyBinder, configureXonoticKeyBinder, void(entity));
-	ATTRIB(XonoticKeyBinder, rowsPerItem, int, 1)
-	METHOD(XonoticKeyBinder, drawListBoxItem, void(entity, int, vector, bool, bool));
-	METHOD(XonoticKeyBinder, doubleClickListBoxItem, void(entity, float, vector));
-	METHOD(XonoticKeyBinder, resizeNotify, void(entity, vector, vector, vector, vector));
-	METHOD(XonoticKeyBinder, showNotify, void(entity));
-	METHOD(XonoticKeyBinder, setSelected, void(entity, float));
-	METHOD(XonoticKeyBinder, keyDown, float(entity, float, float, float));
-	METHOD(XonoticKeyBinder, keyGrabbed, void(entity, float, float));
-	METHOD(XonoticKeyBinder, destroy, void(entity));
-
-	ATTRIB(XonoticKeyBinder, realFontSize, vector, '0 0 0')
-	ATTRIB(XonoticKeyBinder, realUpperMargin, float, 0)
-	ATTRIB(XonoticKeyBinder, columnFunctionOrigin, float, 0)
-	ATTRIB(XonoticKeyBinder, columnFunctionSize, float, 0)
-	ATTRIB(XonoticKeyBinder, columnKeysOrigin, float, 0)
-	ATTRIB(XonoticKeyBinder, columnKeysSize, float, 0)
-
-	METHOD(XonoticKeyBinder, loadKeyBinds, void(entity));
-	ATTRIB(XonoticKeyBinder, previouslySelected, int, -1)
-	ATTRIB(XonoticKeyBinder, inMouseHandler, float, 0)
-	ATTRIB(XonoticKeyBinder, userbindEditButton, entity, NULL)
-	ATTRIB(XonoticKeyBinder, keyGrabButton, entity, NULL)
-	ATTRIB(XonoticKeyBinder, clearButton, entity, NULL)
-	ATTRIB(XonoticKeyBinder, userbindEditDialog, entity, NULL)
-	METHOD(XonoticKeyBinder, editUserbind, void(entity, string, string, string));
-ENDCLASS(XonoticKeyBinder)
-entity makeXonoticKeyBinder();
-void KeyBinder_Bind_Change(entity btn, entity me);
-void KeyBinder_Bind_Clear(entity btn, entity me);
-void KeyBinder_Bind_Edit(entity btn, entity me);
-void KeyBinder_Bind_Reset_All(entity btn, entity me);
-#endif
-
-#ifdef IMPLEMENTATION
+
+#include <common/weapons/all.qh>
+.int flags;
+
+#include "button.qh"
+#include "dialog_settings_input_userbind.qh"
 
 const string KEY_NOT_BOUND_CMD = "// not bound";
 
@@ -478,4 +445,3 @@ void XonoticKeyBinder_drawListBoxItem(entity me, int i, vector absSize, bool isS
 		draw_CenterText(me.realUpperMargin * eY + (me.columnKeysOrigin + 0.5 * me.columnKeysSize) * eX, s, me.realFontSize, theColor, theAlpha, 0);
 	}
 }
-#endif
diff --git a/qcsrc/menu/xonotic/keybinder.qh b/qcsrc/menu/xonotic/keybinder.qh
index 6f70f09be..4d0482dd9 100644
--- a/qcsrc/menu/xonotic/keybinder.qh
+++ b/qcsrc/menu/xonotic/keybinder.qh
@@ -1 +1,36 @@
 #pragma once
+
+#include "listbox.qh"
+CLASS(XonoticKeyBinder, XonoticListBox)
+	METHOD(XonoticKeyBinder, configureXonoticKeyBinder, void(entity));
+	ATTRIB(XonoticKeyBinder, rowsPerItem, int, 1)
+	METHOD(XonoticKeyBinder, drawListBoxItem, void(entity, int, vector, bool, bool));
+	METHOD(XonoticKeyBinder, doubleClickListBoxItem, void(entity, float, vector));
+	METHOD(XonoticKeyBinder, resizeNotify, void(entity, vector, vector, vector, vector));
+	METHOD(XonoticKeyBinder, showNotify, void(entity));
+	METHOD(XonoticKeyBinder, setSelected, void(entity, float));
+	METHOD(XonoticKeyBinder, keyDown, float(entity, float, float, float));
+	METHOD(XonoticKeyBinder, keyGrabbed, void(entity, float, float));
+	METHOD(XonoticKeyBinder, destroy, void(entity));
+
+	ATTRIB(XonoticKeyBinder, realFontSize, vector, '0 0 0')
+	ATTRIB(XonoticKeyBinder, realUpperMargin, float, 0)
+	ATTRIB(XonoticKeyBinder, columnFunctionOrigin, float, 0)
+	ATTRIB(XonoticKeyBinder, columnFunctionSize, float, 0)
+	ATTRIB(XonoticKeyBinder, columnKeysOrigin, float, 0)
+	ATTRIB(XonoticKeyBinder, columnKeysSize, float, 0)
+
+	METHOD(XonoticKeyBinder, loadKeyBinds, void(entity));
+	ATTRIB(XonoticKeyBinder, previouslySelected, int, -1)
+	ATTRIB(XonoticKeyBinder, inMouseHandler, float, 0)
+	ATTRIB(XonoticKeyBinder, userbindEditButton, entity, NULL)
+	ATTRIB(XonoticKeyBinder, keyGrabButton, entity, NULL)
+	ATTRIB(XonoticKeyBinder, clearButton, entity, NULL)
+	ATTRIB(XonoticKeyBinder, userbindEditDialog, entity, NULL)
+	METHOD(XonoticKeyBinder, editUserbind, void(entity, string, string, string));
+ENDCLASS(XonoticKeyBinder)
+entity makeXonoticKeyBinder();
+void KeyBinder_Bind_Change(entity btn, entity me);
+void KeyBinder_Bind_Clear(entity btn, entity me);
+void KeyBinder_Bind_Edit(entity btn, entity me);
+void KeyBinder_Bind_Reset_All(entity btn, entity me);
diff --git a/qcsrc/menu/xonotic/languagelist.qc b/qcsrc/menu/xonotic/languagelist.qc
index 258a19716..6840769d7 100644
--- a/qcsrc/menu/xonotic/languagelist.qc
+++ b/qcsrc/menu/xonotic/languagelist.qc
@@ -1,41 +1,7 @@
 #include "languagelist.qh"
-#ifndef LANGUAGELIST_H
-#define LANGUAGELIST_H
-#include "listbox.qc"
-CLASS(XonoticLanguageList, XonoticListBox)
-	METHOD(XonoticLanguageList, configureXonoticLanguageList, void(entity));
-	ATTRIB(XonoticLanguageList, rowsPerItem, float, 1)
-	METHOD(XonoticLanguageList, drawListBoxItem, void(entity, int, vector, bool, bool));
-	METHOD(XonoticLanguageList, resizeNotify, void(entity, vector, vector, vector, vector));
-	METHOD(XonoticLanguageList, setSelected, void(entity, float));
-	METHOD(XonoticLanguageList, loadCvars, void(entity));
-	METHOD(XonoticLanguageList, saveCvars, void(entity));
-
-	ATTRIB(XonoticLanguageList, realFontSize, vector, '0 0 0')
-	ATTRIB(XonoticLanguageList, realUpperMargin, float, 0)
-	ATTRIB(XonoticLanguageList, columnNameOrigin, float, 0)
-	ATTRIB(XonoticLanguageList, columnNameSize, float, 0)
-	ATTRIB(XonoticLanguageList, columnPercentageOrigin, float, 0)
-	ATTRIB(XonoticLanguageList, columnPercentageSize, float, 0)
-
-	METHOD(XonoticLanguageList, doubleClickListBoxItem, void(entity, float, vector));
-	METHOD(XonoticLanguageList, keyDown, float(entity, float, float, float)); // enter handling
-
-	METHOD(XonoticLanguageList, destroy, void(entity));
-
-	ATTRIB(XonoticLanguageList, languagelist, float, -1)
-	METHOD(XonoticLanguageList, getLanguages, void(entity));
-	METHOD(XonoticLanguageList, setLanguage, void(entity));
-	METHOD(XonoticLanguageList, languageParameter, string(entity, float, float));
-
-	ATTRIB(XonoticLanguageList, name, string, "languageselector") // change this to make it noninteractive (for first run dialog)
-ENDCLASS(XonoticLanguageList)
-
-entity makeXonoticLanguageList();
-void SetLanguage_Click(entity btn, entity me);
-#endif
-
-#ifdef IMPLEMENTATION
+
+#include "../item/modalcontroller.qh"
+#include "mainwindow.qh"
 
 const float LANGPARM_ID = 0;
 const float LANGPARM_NAME = 1;
@@ -217,5 +183,3 @@ void SetLanguage_Click(entity btn, entity me)
 {
 	me.setLanguage(me);
 }
-
-#endif
diff --git a/qcsrc/menu/xonotic/languagelist.qh b/qcsrc/menu/xonotic/languagelist.qh
index 6f70f09be..8febd6467 100644
--- a/qcsrc/menu/xonotic/languagelist.qh
+++ b/qcsrc/menu/xonotic/languagelist.qh
@@ -1 +1,34 @@
 #pragma once
+
+#include "listbox.qh"
+CLASS(XonoticLanguageList, XonoticListBox)
+	METHOD(XonoticLanguageList, configureXonoticLanguageList, void(entity));
+	ATTRIB(XonoticLanguageList, rowsPerItem, float, 1)
+	METHOD(XonoticLanguageList, drawListBoxItem, void(entity, int, vector, bool, bool));
+	METHOD(XonoticLanguageList, resizeNotify, void(entity, vector, vector, vector, vector));
+	METHOD(XonoticLanguageList, setSelected, void(entity, float));
+	METHOD(XonoticLanguageList, loadCvars, void(entity));
+	METHOD(XonoticLanguageList, saveCvars, void(entity));
+
+	ATTRIB(XonoticLanguageList, realFontSize, vector, '0 0 0')
+	ATTRIB(XonoticLanguageList, realUpperMargin, float, 0)
+	ATTRIB(XonoticLanguageList, columnNameOrigin, float, 0)
+	ATTRIB(XonoticLanguageList, columnNameSize, float, 0)
+	ATTRIB(XonoticLanguageList, columnPercentageOrigin, float, 0)
+	ATTRIB(XonoticLanguageList, columnPercentageSize, float, 0)
+
+	METHOD(XonoticLanguageList, doubleClickListBoxItem, void(entity, float, vector));
+	METHOD(XonoticLanguageList, keyDown, float(entity, float, float, float));  // enter handling
+
+	METHOD(XonoticLanguageList, destroy, void(entity));
+
+	ATTRIB(XonoticLanguageList, languagelist, float, -1)
+	METHOD(XonoticLanguageList, getLanguages, void(entity));
+	METHOD(XonoticLanguageList, setLanguage, void(entity));
+	METHOD(XonoticLanguageList, languageParameter, string(entity, float, float));
+
+	ATTRIB(XonoticLanguageList, name, string, "languageselector")  // change this to make it noninteractive (for first run dialog)
+ENDCLASS(XonoticLanguageList)
+
+entity makeXonoticLanguageList();
+void SetLanguage_Click(entity btn, entity me);
diff --git a/qcsrc/menu/xonotic/listbox.qc b/qcsrc/menu/xonotic/listbox.qc
index f2d639f9f..aa8487c8b 100644
--- a/qcsrc/menu/xonotic/listbox.qc
+++ b/qcsrc/menu/xonotic/listbox.qc
@@ -1,26 +1,5 @@
 #include "listbox.qh"
-#ifndef LISTBOX_H
-#define LISTBOX_H
-#include "../item/listbox.qc"
-CLASS(XonoticListBox, ListBox)
-	METHOD(XonoticListBox, configureXonoticListBox, void(entity));
-	ATTRIB(XonoticListBox, fontSize, float, SKINFONTSIZE_NORMAL)
-	ATTRIB(XonoticListBox, scrollbarWidth, float, SKINWIDTH_SCROLLBAR)
-	ATTRIB(XonoticListBox, src, string, SKINGFX_SCROLLBAR)
-	ATTRIB(XonoticListBox, tolerance, vector, SKINTOLERANCE_SLIDER)
-	ATTRIB(XonoticListBox, rowsPerItem, float, 1)
-	METHOD(XonoticListBox, resizeNotify, void(entity, vector, vector, vector, vector));
-	ATTRIB(XonoticListBox, color, vector, SKINCOLOR_SCROLLBAR_N)
-	ATTRIB(XonoticListBox, colorF, vector, SKINCOLOR_SCROLLBAR_F)
-	ATTRIB(XonoticListBox, color2, vector, SKINCOLOR_SCROLLBAR_S)
-	ATTRIB(XonoticListBox, colorC, vector, SKINCOLOR_SCROLLBAR_C)
-	ATTRIB(XonoticListBox, colorBG, vector, SKINCOLOR_LISTBOX_BACKGROUND)
-	ATTRIB(XonoticListBox, alphaBG, float, SKINALPHA_LISTBOX_BACKGROUND)
-ENDCLASS(XonoticListBox)
-entity makeXonoticListBox();
-#endif
 
-#ifdef IMPLEMENTATION
 entity makeXonoticListBox()
 {
 	entity me;
@@ -37,4 +16,3 @@ void XonoticListBox_resizeNotify(entity me, vector relOrigin, vector relSize, ve
 	me.itemHeight = me.rowsPerItem * me.fontSize / absSize.y;
 	SUPER(XonoticListBox).resizeNotify(me, relOrigin, relSize, absOrigin, absSize);
 }
-#endif
diff --git a/qcsrc/menu/xonotic/listbox.qh b/qcsrc/menu/xonotic/listbox.qh
index 6f70f09be..3e789e772 100644
--- a/qcsrc/menu/xonotic/listbox.qh
+++ b/qcsrc/menu/xonotic/listbox.qh
@@ -1 +1,19 @@
 #pragma once
+
+#include "../item/listbox.qh"
+CLASS(XonoticListBox, ListBox)
+	METHOD(XonoticListBox, configureXonoticListBox, void(entity));
+	ATTRIB(XonoticListBox, fontSize, float, SKINFONTSIZE_NORMAL)
+	ATTRIB(XonoticListBox, scrollbarWidth, float, SKINWIDTH_SCROLLBAR)
+	ATTRIB(XonoticListBox, src, string, SKINGFX_SCROLLBAR)
+	ATTRIB(XonoticListBox, tolerance, vector, SKINTOLERANCE_SLIDER)
+	ATTRIB(XonoticListBox, rowsPerItem, float, 1)
+	METHOD(XonoticListBox, resizeNotify, void(entity, vector, vector, vector, vector));
+	ATTRIB(XonoticListBox, color, vector, SKINCOLOR_SCROLLBAR_N)
+	ATTRIB(XonoticListBox, colorF, vector, SKINCOLOR_SCROLLBAR_F)
+	ATTRIB(XonoticListBox, color2, vector, SKINCOLOR_SCROLLBAR_S)
+	ATTRIB(XonoticListBox, colorC, vector, SKINCOLOR_SCROLLBAR_C)
+	ATTRIB(XonoticListBox, colorBG, vector, SKINCOLOR_LISTBOX_BACKGROUND)
+	ATTRIB(XonoticListBox, alphaBG, float, SKINALPHA_LISTBOX_BACKGROUND)
+ENDCLASS(XonoticListBox)
+entity makeXonoticListBox();
diff --git a/qcsrc/menu/xonotic/mainwindow.qc b/qcsrc/menu/xonotic/mainwindow.qc
index 8d65d691f..fb25eebde 100644
--- a/qcsrc/menu/xonotic/mainwindow.qc
+++ b/qcsrc/menu/xonotic/mainwindow.qc
@@ -1,32 +1,50 @@
 #include "mainwindow.qh"
-#ifndef MAINWINDOW_H
-#define MAINWINDOW_H
-#include "../item/modalcontroller.qc"
-CLASS(MainWindow, ModalController)
-	METHOD(MainWindow, configureMainWindow, void(entity));
-	METHOD(MainWindow, draw, void(entity));
-	ATTRIB(MainWindow, firstRunDialog, entity, NULL)
-	ATTRIB(MainWindow, advancedDialog, entity, NULL)
-	ATTRIB(MainWindow, mutatorsDialog, entity, NULL)
-	ATTRIB(MainWindow, mapInfoDialog, entity, NULL)
-	ATTRIB(MainWindow, userbindEditDialog, entity, NULL)
-	ATTRIB(MainWindow, winnerDialog, entity, NULL)
-	ATTRIB(MainWindow, serverInfoDialog, entity, NULL)
-	ATTRIB(MainWindow, cvarsDialog, entity, NULL)
-	ATTRIB(MainWindow, screenshotViewerDialog, entity, NULL)
-	ATTRIB(MainWindow, viewDialog, entity, NULL)
-	ATTRIB(MainWindow, hudconfirmDialog, entity, NULL)
-	ATTRIB(MainWindow, languageWarningDialog, entity, NULL)
-	ATTRIB(MainWindow, mainNexposee, entity, NULL)
-	ATTRIB(MainWindow, fadedAlpha, float, SKINALPHA_BEHIND)
-	ATTRIB(MainWindow, dialogToShow, entity, NULL)
-	ATTRIB(MainWindow, demostartconfirmDialog, entity, NULL)
-	ATTRIB(MainWindow, demotimeconfirmDialog, entity, NULL)
-	ATTRIB(MainWindow, resetDialog, entity, NULL)
-ENDCLASS(MainWindow)
-#endif
-
-#ifdef IMPLEMENTATION
+
+#include "nexposee.qh"
+#include "inputbox.qh"
+#include "dialog_firstrun.qh"
+#include "dialog_hudsetup_exit.qh"
+#include "dialog_hudpanel_notification.qh"
+#include "dialog_hudpanel_ammo.qh"
+#include "dialog_hudpanel_healtharmor.qh"
+#include "dialog_hudpanel_chat.qh"
+#include "dialog_hudpanel_modicons.qh"
+#include "dialog_hudpanel_powerups.qh"
+#include "dialog_hudpanel_pressedkeys.qh"
+#include "dialog_hudpanel_racetimer.qh"
+#include "dialog_hudpanel_radar.qh"
+#include "dialog_hudpanel_score.qh"
+#include "dialog_hudpanel_timer.qh"
+#include "dialog_hudpanel_vote.qh"
+#include "dialog_hudpanel_weapons.qh"
+#include "dialog_hudpanel_engineinfo.qh"
+#include "dialog_hudpanel_infomessages.qh"
+#include "dialog_hudpanel_physics.qh"
+#include "dialog_hudpanel_centerprint.qh"
+#include "dialog_hudpanel_itemstime.qh"
+#include "dialog_hudpanel_quickmenu.qh"
+
+#include "dialog_settings_input_userbind.qh"
+#include "dialog_settings_misc_cvars.qh"
+#include "dialog_settings_misc_reset.qh"
+#include "dialog_settings_user_languagewarning.qh"
+#include "dialog_settings_game_hudconfirm.qh"
+#include "dialog_singleplayer_winner.qh"
+#include "dialog_multiplayer_join_serverinfo.qh"
+#include "dialog_multiplayer_media_demo_startconfirm.qh"
+#include "dialog_multiplayer_media_demo_timeconfirm.qh"
+#include "dialog_multiplayer_media_screenshot_viewer.qh"
+#include "dialog_multiplayer_create_mapinfo.qh"
+#include "dialog_multiplayer_create_mutators.qh"
+#include "dialog_sandboxtools.qh"
+#include "dialog_monstertools.qh"
+#include "dialog_teamselect.qh"
+#include "dialog_singleplayer.qh"
+#include "dialog_multiplayer.qh"
+#include "dialog_settings.qh"
+#include "dialog_credits.qh"
+#include "dialog_quit.qh"
+
 void MainWindow_draw(entity me)
 {
 	SUPER(MainWindow).draw(me);
@@ -257,6 +275,3 @@ void MainWindow_configureMainWindow(entity me)
 	if(cvar_string("_cl_name") == cvar_defstring("_cl_name"))
 		me.dialogToShow = me.firstRunDialog;
 }
-#endif
-
-/* Click. The c-word is here so you can grep for it :-) */
diff --git a/qcsrc/menu/xonotic/mainwindow.qh b/qcsrc/menu/xonotic/mainwindow.qh
index 6f70f09be..daf5e0571 100644
--- a/qcsrc/menu/xonotic/mainwindow.qh
+++ b/qcsrc/menu/xonotic/mainwindow.qh
@@ -1 +1,26 @@
 #pragma once
+
+#include <menu/item/modalcontroller.qh>
+
+CLASS(MainWindow, ModalController)
+	METHOD(MainWindow, configureMainWindow, void(entity));
+	METHOD(MainWindow, draw, void(entity));
+	ATTRIB(MainWindow, firstRunDialog, entity, NULL)
+	ATTRIB(MainWindow, advancedDialog, entity, NULL)
+	ATTRIB(MainWindow, mutatorsDialog, entity, NULL)
+	ATTRIB(MainWindow, mapInfoDialog, entity, NULL)
+	ATTRIB(MainWindow, userbindEditDialog, entity, NULL)
+	ATTRIB(MainWindow, winnerDialog, entity, NULL)
+	ATTRIB(MainWindow, serverInfoDialog, entity, NULL)
+	ATTRIB(MainWindow, cvarsDialog, entity, NULL)
+	ATTRIB(MainWindow, screenshotViewerDialog, entity, NULL)
+	ATTRIB(MainWindow, viewDialog, entity, NULL)
+	ATTRIB(MainWindow, hudconfirmDialog, entity, NULL)
+	ATTRIB(MainWindow, languageWarningDialog, entity, NULL)
+	ATTRIB(MainWindow, mainNexposee, entity, NULL)
+	ATTRIB(MainWindow, fadedAlpha, float, SKINALPHA_BEHIND)
+	ATTRIB(MainWindow, dialogToShow, entity, NULL)
+	ATTRIB(MainWindow, demostartconfirmDialog, entity, NULL)
+	ATTRIB(MainWindow, demotimeconfirmDialog, entity, NULL)
+	ATTRIB(MainWindow, resetDialog, entity, NULL)
+ENDCLASS(MainWindow)
diff --git a/qcsrc/menu/xonotic/maplist.qc b/qcsrc/menu/xonotic/maplist.qc
index d24770ba9..4b41f5bd3 100644
--- a/qcsrc/menu/xonotic/maplist.qc
+++ b/qcsrc/menu/xonotic/maplist.qc
@@ -1,64 +1,12 @@
 #include "maplist.qh"
-#ifndef MAPLIST_H
-#define MAPLIST_H
-#include "listbox.qc"
-CLASS(XonoticMapList, XonoticListBox)
-	METHOD(XonoticMapList, configureXonoticMapList, void(entity));
-	ATTRIB(XonoticMapList, rowsPerItem, float, 4)
-	METHOD(XonoticMapList, draw, void(entity));
-	METHOD(XonoticMapList, drawListBoxItem, void(entity, int, vector, bool, bool));
-	METHOD(XonoticMapList, clickListBoxItem, void(entity, float, vector));
-	METHOD(XonoticMapList, doubleClickListBoxItem, void(entity, float, vector));
-	METHOD(XonoticMapList, resizeNotify, void(entity, vector, vector, vector, vector));
-	METHOD(XonoticMapList, refilter, void(entity));
-	METHOD(XonoticMapList, refilterCallback, void(entity, entity));
-	METHOD(XonoticMapList, keyDown, float(entity, float, float, float));
-
-	ATTRIB(XonoticMapList, realFontSize, vector, '0 0 0')
-	ATTRIB(XonoticMapList, columnPreviewOrigin, float, 0)
-	ATTRIB(XonoticMapList, columnPreviewSize, float, 0)
-	ATTRIB(XonoticMapList, columnNameOrigin, float, 0)
-	ATTRIB(XonoticMapList, columnNameSize, float, 0)
-	ATTRIB(XonoticMapList, checkMarkOrigin, vector, '0 0 0')
-	ATTRIB(XonoticMapList, checkMarkSize, vector, '0 0 0')
-	ATTRIB(XonoticMapList, realUpperMargin1, float, 0)
-	ATTRIB(XonoticMapList, realUpperMargin2, float, 0)
-
-	ATTRIB(XonoticMapList, lastGametype, float, 0)
-	ATTRIB(XonoticMapList, lastFeatures, float, 0)
-
-	ATTRIB(XonoticMapList, origin, vector, '0 0 0')
-	ATTRIB(XonoticMapList, itemAbsSize, vector, '0 0 0')
-
-	ATTRIB(XonoticMapList, g_maplistCache, string, string_null)
-	METHOD(XonoticMapList, g_maplistCacheToggle, void(entity, float));
-	METHOD(XonoticMapList, g_maplistCacheQuery, float(entity, float));
-
-	ATTRIB(XonoticMapList, stringFilter, string, string_null)
-	ATTRIB(XonoticMapList, stringFilterBox, entity, NULL)
-
-	ATTRIB(XonoticMapList, startButton, entity, NULL)
-
-	METHOD(XonoticMapList, loadCvars, void(entity));
-
-	ATTRIB(XonoticMapList, typeToSearchString, string, string_null)
-	ATTRIB(XonoticMapList, typeToSearchTime, float, 0)
-
-	METHOD(XonoticMapList, destroy, void(entity));
-
-	ATTRIB(XonoticMapList, alphaBG, float, 0)
-ENDCLASS(XonoticMapList)
-entity makeXonoticMapList();
-void MapList_StringFilterBox_Change(entity box, entity me);
-float MapList_StringFilterBox_keyDown(entity me, float key, float ascii, float shift);
-void MapList_Add_Shown(entity btn, entity me);
-void MapList_Remove_Shown(entity btn, entity me);
-void MapList_Add_All(entity btn, entity me);
-void MapList_Remove_All(entity btn, entity me);
-void MapList_LoadMap(entity btn, entity me);
-#endif
-
-#ifdef IMPLEMENTATION
+
+#include <common/mapinfo.qh>
+#include "dialog_multiplayer_create_mapinfo.qh"
+#include "mainwindow.qh"
+#include "inputbox.qh"
+
+.bool disabled;
+
 void XonoticMapList_destroy(entity me)
 {
 	MapInfo_Shutdown();
@@ -459,4 +407,3 @@ float MapList_StringFilterBox_keyDown(entity me, float scan, float ascii, float
 	}
 	return SUPER(XonoticInputBox).keyDown(me, scan, ascii, shift);
 }
-#endif
diff --git a/qcsrc/menu/xonotic/maplist.qh b/qcsrc/menu/xonotic/maplist.qh
index 6f70f09be..de9d7e28a 100644
--- a/qcsrc/menu/xonotic/maplist.qh
+++ b/qcsrc/menu/xonotic/maplist.qh
@@ -1 +1,57 @@
 #pragma once
+
+#include "listbox.qh"
+CLASS(XonoticMapList, XonoticListBox)
+	METHOD(XonoticMapList, configureXonoticMapList, void(entity));
+	ATTRIB(XonoticMapList, rowsPerItem, float, 4)
+	METHOD(XonoticMapList, draw, void(entity));
+	METHOD(XonoticMapList, drawListBoxItem, void(entity, int, vector, bool, bool));
+	METHOD(XonoticMapList, clickListBoxItem, void(entity, float, vector));
+	METHOD(XonoticMapList, doubleClickListBoxItem, void(entity, float, vector));
+	METHOD(XonoticMapList, resizeNotify, void(entity, vector, vector, vector, vector));
+	METHOD(XonoticMapList, refilter, void(entity));
+	METHOD(XonoticMapList, refilterCallback, void(entity, entity));
+	METHOD(XonoticMapList, keyDown, float(entity, float, float, float));
+
+	ATTRIB(XonoticMapList, realFontSize, vector, '0 0 0')
+	ATTRIB(XonoticMapList, columnPreviewOrigin, float, 0)
+	ATTRIB(XonoticMapList, columnPreviewSize, float, 0)
+	ATTRIB(XonoticMapList, columnNameOrigin, float, 0)
+	ATTRIB(XonoticMapList, columnNameSize, float, 0)
+	ATTRIB(XonoticMapList, checkMarkOrigin, vector, '0 0 0')
+	ATTRIB(XonoticMapList, checkMarkSize, vector, '0 0 0')
+	ATTRIB(XonoticMapList, realUpperMargin1, float, 0)
+	ATTRIB(XonoticMapList, realUpperMargin2, float, 0)
+
+	ATTRIB(XonoticMapList, lastGametype, float, 0)
+	ATTRIB(XonoticMapList, lastFeatures, float, 0)
+
+	ATTRIB(XonoticMapList, origin, vector, '0 0 0')
+	ATTRIB(XonoticMapList, itemAbsSize, vector, '0 0 0')
+
+	ATTRIB(XonoticMapList, g_maplistCache, string, string_null)
+	METHOD(XonoticMapList, g_maplistCacheToggle, void(entity, float));
+	METHOD(XonoticMapList, g_maplistCacheQuery, float(entity, float));
+
+	ATTRIB(XonoticMapList, stringFilter, string, string_null)
+	ATTRIB(XonoticMapList, stringFilterBox, entity, NULL)
+
+	ATTRIB(XonoticMapList, startButton, entity, NULL)
+
+	METHOD(XonoticMapList, loadCvars, void(entity));
+
+	ATTRIB(XonoticMapList, typeToSearchString, string, string_null)
+	ATTRIB(XonoticMapList, typeToSearchTime, float, 0)
+
+	METHOD(XonoticMapList, destroy, void(entity));
+
+	ATTRIB(XonoticMapList, alphaBG, float, 0)
+ENDCLASS(XonoticMapList)
+entity makeXonoticMapList();
+void MapList_StringFilterBox_Change(entity box, entity me);
+float MapList_StringFilterBox_keyDown(entity me, float key, float ascii, float shift);
+void MapList_Add_Shown(entity btn, entity me);
+void MapList_Remove_Shown(entity btn, entity me);
+void MapList_Add_All(entity btn, entity me);
+void MapList_Remove_All(entity btn, entity me);
+void MapList_LoadMap(entity btn, entity me);
diff --git a/qcsrc/menu/xonotic/nexposee.qc b/qcsrc/menu/xonotic/nexposee.qc
index 788a025ca..7c2bcacd9 100644
--- a/qcsrc/menu/xonotic/nexposee.qc
+++ b/qcsrc/menu/xonotic/nexposee.qc
@@ -1,15 +1,5 @@
 #include "nexposee.qh"
-#ifndef NEXPOSEE_H
-#define NEXPOSEE_H
-#include "../item/nexposee.qc"
-CLASS(XonoticNexposee, Nexposee)
-	METHOD(XonoticNexposee, configureXonoticNexposee, void(entity));
-	METHOD(XonoticNexposee, close, void(entity));
-ENDCLASS(XonoticNexposee)
-entity makeXonoticNexposee();
-#endif
 
-#ifdef IMPLEMENTATION
 entity makeXonoticNexposee()
 {
 	entity me;
@@ -26,4 +16,3 @@ void XonoticNexposee_close(entity me)
 {
 	m_goto(string_null); // hide
 }
-#endif
diff --git a/qcsrc/menu/xonotic/nexposee.qh b/qcsrc/menu/xonotic/nexposee.qh
index 6f70f09be..3f4b876a4 100644
--- a/qcsrc/menu/xonotic/nexposee.qh
+++ b/qcsrc/menu/xonotic/nexposee.qh
@@ -1 +1,8 @@
 #pragma once
+
+#include "../item/nexposee.qh"
+CLASS(XonoticNexposee, Nexposee)
+	METHOD(XonoticNexposee, configureXonoticNexposee, void(entity));
+	METHOD(XonoticNexposee, close, void(entity));
+ENDCLASS(XonoticNexposee)
+entity makeXonoticNexposee();
diff --git a/qcsrc/menu/xonotic/picker.qc b/qcsrc/menu/xonotic/picker.qc
index e89361894..db302e9a8 100644
--- a/qcsrc/menu/xonotic/picker.qc
+++ b/qcsrc/menu/xonotic/picker.qc
@@ -1,38 +1,6 @@
 #include "picker.qh"
-#ifndef PICKER_H
-#define PICKER_H
-#include "../item.qc"
-CLASS(XonoticPicker, Item)
-	METHOD(XonoticPicker, configureXonoticPicker, void(entity));
-	METHOD(XonoticPicker, mousePress, float(entity, vector));
-	METHOD(XonoticPicker, mouseRelease, float(entity, vector));
-	METHOD(XonoticPicker, mouseMove, float(entity, vector));
-	METHOD(XonoticPicker, mouseDrag, float(entity, vector));
-	METHOD(XonoticPicker, keyDown, float(entity, float, float, float));
-	METHOD(XonoticPicker, draw, void(entity));
-	ATTRIB(XonoticPicker, focusable, float, 1)
-	ATTRIB(XonoticPicker, disabled, float, 0)
-	ATTRIB(XonoticPicker, alpha, float, 1)
-	ATTRIB(XonoticPicker, disabledAlpha, float, SKINALPHA_DISABLED)
-
-	ATTRIB(XonoticPicker, rows, float, 3)
-	ATTRIB(XonoticPicker, columns, float, 2)
-
-	METHOD(XonoticPicker, moveFocus, void(entity, vector, vector));
-	METHOD(XonoticPicker, cellSelect, void(entity, vector));
-	METHOD(XonoticPicker, cellDraw, void(entity, vector, vector));
-	METHOD(XonoticPicker, cellIsValid, bool(entity, vector));
-	ATTRIB(XonoticPicker, realCellSize, vector, '0 0 0')
-	ATTRIB(XonoticPicker, selectedCell, vector, '-1 -1 0')
-	ATTRIB(XonoticPicker, focusedCell, vector, '-1 -1 0')
-	ATTRIB(XonoticPicker, focusedCellAlpha, float, 0)
-	ATTRIB(XonoticPicker, focusedCellTime, float, 0)
-	ATTRIB(XonoticPicker, pressedCell, vector, '-1 -1 0')
-ENDCLASS(XonoticPicker)
-entity makeXonoticPicker();
-#endif
-
-#ifdef IMPLEMENTATION
+
+.bool pressed;
 
 entity makeXonoticPicker()
 {
@@ -205,4 +173,3 @@ void XonoticPicker_draw(entity me)
 
 	SUPER(XonoticPicker).draw(me);
 }
-#endif
diff --git a/qcsrc/menu/xonotic/picker.qh b/qcsrc/menu/xonotic/picker.qh
index 6f70f09be..c530c7ca9 100644
--- a/qcsrc/menu/xonotic/picker.qh
+++ b/qcsrc/menu/xonotic/picker.qh
@@ -1 +1,31 @@
 #pragma once
+
+#include "../item.qh"
+CLASS(XonoticPicker, Item)
+	METHOD(XonoticPicker, configureXonoticPicker, void(entity));
+	METHOD(XonoticPicker, mousePress, float(entity, vector));
+	METHOD(XonoticPicker, mouseRelease, float(entity, vector));
+	METHOD(XonoticPicker, mouseMove, float(entity, vector));
+	METHOD(XonoticPicker, mouseDrag, float(entity, vector));
+	METHOD(XonoticPicker, keyDown, float(entity, float, float, float));
+	METHOD(XonoticPicker, draw, void(entity));
+	ATTRIB(XonoticPicker, focusable, float, 1)
+	ATTRIB(XonoticPicker, disabled, float, 0)
+	ATTRIB(XonoticPicker, alpha, float, 1)
+	ATTRIB(XonoticPicker, disabledAlpha, float, SKINALPHA_DISABLED)
+
+	ATTRIB(XonoticPicker, rows, float, 3)
+	ATTRIB(XonoticPicker, columns, float, 2)
+
+	METHOD(XonoticPicker, moveFocus, void(entity, vector, vector));
+	METHOD(XonoticPicker, cellSelect, void(entity, vector));
+	METHOD(XonoticPicker, cellDraw, void(entity, vector, vector));
+	METHOD(XonoticPicker, cellIsValid, bool(entity, vector));
+	ATTRIB(XonoticPicker, realCellSize, vector, '0 0 0')
+	ATTRIB(XonoticPicker, selectedCell, vector, '-1 -1 0')
+	ATTRIB(XonoticPicker, focusedCell, vector, '-1 -1 0')
+	ATTRIB(XonoticPicker, focusedCellAlpha, float, 0)
+	ATTRIB(XonoticPicker, focusedCellTime, float, 0)
+	ATTRIB(XonoticPicker, pressedCell, vector, '-1 -1 0')
+ENDCLASS(XonoticPicker)
+entity makeXonoticPicker();
diff --git a/qcsrc/menu/xonotic/playerlist.qc b/qcsrc/menu/xonotic/playerlist.qc
index 5ef53872c..c6033050a 100644
--- a/qcsrc/menu/xonotic/playerlist.qc
+++ b/qcsrc/menu/xonotic/playerlist.qc
@@ -1,29 +1,6 @@
 #include "playerlist.qh"
-#ifndef PLAYERLIST_H
-#define PLAYERLIST_H
-#include "listbox.qc"
-CLASS(XonoticPlayerList, XonoticListBox)
-	ATTRIB(XonoticPlayerList, rowsPerItem, float, 1)
-	METHOD(XonoticPlayerList, resizeNotify, void(entity, vector, vector, vector, vector));
-	METHOD(XonoticPlayerList, drawListBoxItem, void(entity, int, vector, bool, bool));
-	ATTRIB(XonoticPlayerList, allowFocusSound, float, 0)
-	ATTRIB(XonoticPlayerList, realFontSize, vector, '0 0 0')
-	ATTRIB(XonoticPlayerList, columnNameOrigin, float, 0)
-	ATTRIB(XonoticPlayerList, columnNameSize, float, 0)
-	ATTRIB(XonoticPlayerList, columnScoreOrigin, float, 0)
-	ATTRIB(XonoticPlayerList, columnScoreSize, float, 0)
-	ATTRIB(XonoticPlayerList, realUpperMargin, float, 0)
-	ATTRIB(XonoticPlayerList, origin, vector, '0 0 0')
-	ATTRIB(XonoticPlayerList, itemAbsSize, vector, '0 0 0')
-	METHOD(XonoticPlayerList, setPlayerList, void(entity, string));
-	METHOD(XonoticPlayerList, getPlayerList, string(entity, float, float));
-	ATTRIB(XonoticPlayerList, playerList, float, -1)
-	ATTRIB(XonoticPlayerList, selectionDoesntMatter, bool, true)
-ENDCLASS(XonoticPlayerList)
-entity makeXonoticPlayerList();
-#endif
-
-#ifdef IMPLEMENTATION
+
+.float realUpperMargin2;
 
 const float PLAYERPARM_SCORE = 0;
 const float PLAYERPARM_PING = 1;
@@ -139,5 +116,3 @@ void XonoticPlayerList_drawListBoxItem(entity me, int i, vector absSize, bool is
 	score = draw_TextShortenToWidth(score, me.columnScoreSize, 0, me.realFontSize);
 	draw_Text(me.realUpperMargin2 * eY + (me.columnScoreOrigin + 1.00 * (me.columnScoreSize - draw_TextWidth(score, 1, me.realFontSize))) * eX, score, me.realFontSize, rgb, 1, 0);
 }
-
-#endif
diff --git a/qcsrc/menu/xonotic/playerlist.qh b/qcsrc/menu/xonotic/playerlist.qh
index 6f70f09be..8474b9140 100644
--- a/qcsrc/menu/xonotic/playerlist.qh
+++ b/qcsrc/menu/xonotic/playerlist.qh
@@ -1 +1,22 @@
 #pragma once
+
+#include "listbox.qh"
+CLASS(XonoticPlayerList, XonoticListBox)
+	ATTRIB(XonoticPlayerList, rowsPerItem, float, 1)
+	METHOD(XonoticPlayerList, resizeNotify, void(entity, vector, vector, vector, vector));
+	METHOD(XonoticPlayerList, drawListBoxItem, void(entity, int, vector, bool, bool));
+	ATTRIB(XonoticPlayerList, allowFocusSound, float, 0)
+	ATTRIB(XonoticPlayerList, realFontSize, vector, '0 0 0')
+	ATTRIB(XonoticPlayerList, columnNameOrigin, float, 0)
+	ATTRIB(XonoticPlayerList, columnNameSize, float, 0)
+	ATTRIB(XonoticPlayerList, columnScoreOrigin, float, 0)
+	ATTRIB(XonoticPlayerList, columnScoreSize, float, 0)
+	ATTRIB(XonoticPlayerList, realUpperMargin, float, 0)
+	ATTRIB(XonoticPlayerList, origin, vector, '0 0 0')
+	ATTRIB(XonoticPlayerList, itemAbsSize, vector, '0 0 0')
+	METHOD(XonoticPlayerList, setPlayerList, void(entity, string));
+	METHOD(XonoticPlayerList, getPlayerList, string(entity, float, float));
+	ATTRIB(XonoticPlayerList, playerList, float, -1)
+	ATTRIB(XonoticPlayerList, selectionDoesntMatter, bool, true)
+ENDCLASS(XonoticPlayerList)
+entity makeXonoticPlayerList();
diff --git a/qcsrc/menu/xonotic/playermodel.qc b/qcsrc/menu/xonotic/playermodel.qc
index 6fb767858..1a90fa737 100644
--- a/qcsrc/menu/xonotic/playermodel.qc
+++ b/qcsrc/menu/xonotic/playermodel.qc
@@ -1,37 +1,5 @@
 #include "playermodel.qh"
-#ifndef PLAYERMODEL_H
-#define PLAYERMODEL_H
-#include "image.qc"
-CLASS(XonoticPlayerModelSelector, XonoticImage)
-	METHOD(XonoticPlayerModelSelector, configureXonoticPlayerModelSelector, void(entity));
-	METHOD(XonoticPlayerModelSelector, loadModels, void(entity));
-	METHOD(XonoticPlayerModelSelector, loadCvars, void(entity));
-	METHOD(XonoticPlayerModelSelector, saveCvars, void(entity));
-	METHOD(XonoticPlayerModelSelector, draw, void(entity));
-	METHOD(XonoticPlayerModelSelector, resizeNotify, void(entity, vector, vector, vector, vector));
-	METHOD(XonoticPlayerModelSelector, showNotify, void(entity));
-	ATTRIB(XonoticPlayerModelSelector, currentModel, string, string_null)
-	ATTRIB(XonoticPlayerModelSelector, currentSkin, float, 0)
-	ATTRIB(XonoticPlayerModelSelector, currentModelImage, string, string_null)
-	ATTRIB(XonoticPlayerModelSelector, currentModelTitle, string, string_null)
-	ATTRIB(XonoticPlayerModelSelector, currentModelDescription, string, string_null)
-	METHOD(XonoticPlayerModelSelector, go, void(entity, float));
-	METHOD(XonoticPlayerModelSelector, destroy, void(entity));
-	ATTRIB(XonoticPlayerModelSelector, origin, vector, '0 0 0')
-	ATTRIB(XonoticPlayerModelSelector, size, vector, '0 0 0')
-	ATTRIB(XonoticPlayerModelSelector, realFontSize, vector, '0 0 0')
-	ATTRIB(XonoticPlayerModelSelector, fontSize, float, SKINFONTSIZE_NORMAL)
-	ATTRIB(XonoticPlayerModelSelector, titleFontSize, float, SKINFONTSIZE_TITLE)
-	ATTRIB(XonoticPlayerModelSelector, bufModels, float, -1)
-	ATTRIB(XonoticPlayerModelSelector, numModels, float, -1)
-	ATTRIB(XonoticPlayerModelSelector, idxModels, float, -1)
-ENDCLASS(XonoticPlayerModelSelector)
-entity makeXonoticPlayerModelSelector();
-void PlayerModelSelector_Next_Click(entity btn, entity me);
-void PlayerModelSelector_Prev_Click(entity btn, entity me);
-#endif
 
-#ifdef IMPLEMENTATION
 entity makeXonoticPlayerModelSelector()
 {
 	entity me;
@@ -233,4 +201,3 @@ void XonoticPlayerModelSelector_showNotify(entity me)
 	me.destroy(me);
 	me.loadModels(me);
 }
-#endif
diff --git a/qcsrc/menu/xonotic/playermodel.qh b/qcsrc/menu/xonotic/playermodel.qh
index 6f70f09be..664f22c7c 100644
--- a/qcsrc/menu/xonotic/playermodel.qh
+++ b/qcsrc/menu/xonotic/playermodel.qh
@@ -1 +1,30 @@
 #pragma once
+
+#include "image.qh"
+CLASS(XonoticPlayerModelSelector, XonoticImage)
+	METHOD(XonoticPlayerModelSelector, configureXonoticPlayerModelSelector, void(entity));
+	METHOD(XonoticPlayerModelSelector, loadModels, void(entity));
+	METHOD(XonoticPlayerModelSelector, loadCvars, void(entity));
+	METHOD(XonoticPlayerModelSelector, saveCvars, void(entity));
+	METHOD(XonoticPlayerModelSelector, draw, void(entity));
+	METHOD(XonoticPlayerModelSelector, resizeNotify, void(entity, vector, vector, vector, vector));
+	METHOD(XonoticPlayerModelSelector, showNotify, void(entity));
+	ATTRIB(XonoticPlayerModelSelector, currentModel, string, string_null)
+	ATTRIB(XonoticPlayerModelSelector, currentSkin, float, 0)
+	ATTRIB(XonoticPlayerModelSelector, currentModelImage, string, string_null)
+	ATTRIB(XonoticPlayerModelSelector, currentModelTitle, string, string_null)
+	ATTRIB(XonoticPlayerModelSelector, currentModelDescription, string, string_null)
+	METHOD(XonoticPlayerModelSelector, go, void(entity, float));
+	METHOD(XonoticPlayerModelSelector, destroy, void(entity));
+	ATTRIB(XonoticPlayerModelSelector, origin, vector, '0 0 0')
+	ATTRIB(XonoticPlayerModelSelector, size, vector, '0 0 0')
+	ATTRIB(XonoticPlayerModelSelector, realFontSize, vector, '0 0 0')
+	ATTRIB(XonoticPlayerModelSelector, fontSize, float, SKINFONTSIZE_NORMAL)
+	ATTRIB(XonoticPlayerModelSelector, titleFontSize, float, SKINFONTSIZE_TITLE)
+	ATTRIB(XonoticPlayerModelSelector, bufModels, float, -1)
+	ATTRIB(XonoticPlayerModelSelector, numModels, float, -1)
+	ATTRIB(XonoticPlayerModelSelector, idxModels, float, -1)
+ENDCLASS(XonoticPlayerModelSelector)
+entity makeXonoticPlayerModelSelector();
+void PlayerModelSelector_Next_Click(entity btn, entity me);
+void PlayerModelSelector_Prev_Click(entity btn, entity me);
diff --git a/qcsrc/menu/xonotic/playlist.qc b/qcsrc/menu/xonotic/playlist.qc
index 93fa21252..c912ba3a7 100644
--- a/qcsrc/menu/xonotic/playlist.qc
+++ b/qcsrc/menu/xonotic/playlist.qc
@@ -1,46 +1,4 @@
 #include "playlist.qh"
-#ifndef PLAYLIST_H
-#define PLAYLIST_H
-#include "listbox.qc"
-CLASS(XonoticPlayList, XonoticListBox)
-	METHOD(XonoticPlayList, configureXonoticPlayList, void(entity));
-	ATTRIB(XonoticPlayList, rowsPerItem, float, 1)
-	METHOD(XonoticPlayList, resizeNotify, void(entity, vector, vector, vector, vector));
-	METHOD(XonoticPlayList, draw, void(entity));
-	METHOD(XonoticPlayList, drawListBoxItem, void(entity, int, vector, bool, bool));
-	METHOD(XonoticPlayList, stopSound, void(entity));
-	METHOD(XonoticPlayList, startSound, void(entity, float));
-	METHOD(XonoticPlayList, resumeSound, void(entity));
-	METHOD(XonoticPlayList, pauseSound, void(entity));
-	METHOD(XonoticPlayList, doubleClickListBoxItem, void(entity, float, vector));
-	METHOD(XonoticPlayList, keyDown, float(entity, float, float, float));
-	METHOD(XonoticPlayList, mouseDrag, float(entity, vector));
-
-	METHOD(XonoticPlayList, addToPlayList, void(entity, string));
-	METHOD(XonoticPlayList, removeSelectedFromPlayList, void(entity));
-	ATTRIB(XonoticPlayList, playingTrack, float, -1)
-
-	ATTRIB(XonoticPlayList, realFontSize, vector, '0 0 0')
-	ATTRIB(XonoticPlayList, columnNameOrigin, float, 0)
-	ATTRIB(XonoticPlayList, columnNameSize, float, 0)
-	ATTRIB(XonoticPlayList, columnNumberOrigin, float, 0)
-	ATTRIB(XonoticPlayList, columnNumberSize, float, 0)
-	ATTRIB(XonoticPlayList, realUpperMargin, float, 0)
-	ATTRIB(XonoticPlayList, origin, vector, '0 0 0')
-	ATTRIB(XonoticPlayList, itemAbsSize, vector, '0 0 0')
-ENDCLASS(XonoticPlayList)
-
-entity makeXonoticPlayList();
-void PlayList_Remove(entity btn, entity me);
-void PlayList_Remove_All(entity btn, entity me);
-void StopSound_Click(entity btn, entity me);
-void StartSound_Click(entity btn, entity me);
-void PauseSound_Click(entity btn, entity me);
-void PrevSound_Click(entity btn, entity me);
-void NextSound_Click(entity btn, entity me);
-#endif
-
-#ifdef IMPLEMENTATION
 
 entity makeXonoticPlayList()
 {
@@ -306,5 +264,3 @@ float XonoticPlayList_keyDown(entity me, float scan, float ascii, float shift)
 	else
 		return SUPER(XonoticPlayList).keyDown(me, scan, ascii, shift);
 }
-#endif
-
diff --git a/qcsrc/menu/xonotic/playlist.qh b/qcsrc/menu/xonotic/playlist.qh
index 6f70f09be..6bee05bbc 100644
--- a/qcsrc/menu/xonotic/playlist.qh
+++ b/qcsrc/menu/xonotic/playlist.qh
@@ -1 +1,39 @@
 #pragma once
+
+#include "listbox.qh"
+CLASS(XonoticPlayList, XonoticListBox)
+	METHOD(XonoticPlayList, configureXonoticPlayList, void(entity));
+	ATTRIB(XonoticPlayList, rowsPerItem, float, 1)
+	METHOD(XonoticPlayList, resizeNotify, void(entity, vector, vector, vector, vector));
+	METHOD(XonoticPlayList, draw, void(entity));
+	METHOD(XonoticPlayList, drawListBoxItem, void(entity, int, vector, bool, bool));
+	METHOD(XonoticPlayList, stopSound, void(entity));
+	METHOD(XonoticPlayList, startSound, void(entity, float));
+	METHOD(XonoticPlayList, resumeSound, void(entity));
+	METHOD(XonoticPlayList, pauseSound, void(entity));
+	METHOD(XonoticPlayList, doubleClickListBoxItem, void(entity, float, vector));
+	METHOD(XonoticPlayList, keyDown, float(entity, float, float, float));
+	METHOD(XonoticPlayList, mouseDrag, float(entity, vector));
+
+	METHOD(XonoticPlayList, addToPlayList, void(entity, string));
+	METHOD(XonoticPlayList, removeSelectedFromPlayList, void(entity));
+	ATTRIB(XonoticPlayList, playingTrack, float, -1)
+
+	ATTRIB(XonoticPlayList, realFontSize, vector, '0 0 0')
+	ATTRIB(XonoticPlayList, columnNameOrigin, float, 0)
+	ATTRIB(XonoticPlayList, columnNameSize, float, 0)
+	ATTRIB(XonoticPlayList, columnNumberOrigin, float, 0)
+	ATTRIB(XonoticPlayList, columnNumberSize, float, 0)
+	ATTRIB(XonoticPlayList, realUpperMargin, float, 0)
+	ATTRIB(XonoticPlayList, origin, vector, '0 0 0')
+	ATTRIB(XonoticPlayList, itemAbsSize, vector, '0 0 0')
+ENDCLASS(XonoticPlayList)
+
+entity makeXonoticPlayList();
+void PlayList_Remove(entity btn, entity me);
+void PlayList_Remove_All(entity btn, entity me);
+void StopSound_Click(entity btn, entity me);
+void StartSound_Click(entity btn, entity me);
+void PauseSound_Click(entity btn, entity me);
+void PrevSound_Click(entity btn, entity me);
+void NextSound_Click(entity btn, entity me);
diff --git a/qcsrc/menu/xonotic/radiobutton.qc b/qcsrc/menu/xonotic/radiobutton.qc
index de0da5d74..536ea4f15 100644
--- a/qcsrc/menu/xonotic/radiobutton.qc
+++ b/qcsrc/menu/xonotic/radiobutton.qc
@@ -1,33 +1,5 @@
 #include "radiobutton.qh"
-#ifndef RADIOBUTTON_H
-#define RADIOBUTTON_H
-#include "../item/radiobutton.qc"
-CLASS(XonoticRadioButton, RadioButton)
-	METHOD(XonoticRadioButton, configureXonoticRadioButton, void(entity, float, string, string, string, string));
-	METHOD(XonoticRadioButton, draw, void(entity));
-	METHOD(XonoticRadioButton, setChecked, void(entity, float));
-	ATTRIB(XonoticRadioButton, fontSize, float, SKINFONTSIZE_NORMAL)
-	ATTRIB(XonoticRadioButton, image, string, SKINGFX_RADIOBUTTON)
-	ATTRIB(XonoticRadioButton, color, vector, SKINCOLOR_RADIOBUTTON_N)
-	ATTRIB(XonoticRadioButton, colorC, vector, SKINCOLOR_RADIOBUTTON_C)
-	ATTRIB(XonoticRadioButton, colorF, vector, SKINCOLOR_RADIOBUTTON_F)
-	ATTRIB(XonoticRadioButton, colorD, vector, SKINCOLOR_RADIOBUTTON_D)
 
-	ATTRIB(XonoticRadioButton, cvarName, string, string_null)
-	ATTRIB(XonoticRadioButton, cvarValue, string, string_null)
-	ATTRIB(XonoticRadioButton, cvarOffValue, string, string_null)
-	ATTRIB(XonoticRadioButton, cvarValueIsAnotherCvar, float, 0)
-	METHOD(XonoticRadioButton, loadCvars, void(entity));
-	METHOD(XonoticRadioButton, saveCvars, void(entity));
-
-	ATTRIB(XonoticRadioButton, alpha, float, SKINALPHA_TEXT)
-	ATTRIB(XonoticRadioButton, disabledAlpha, float, SKINALPHA_DISABLED)
-ENDCLASS(XonoticRadioButton)
-entity makeXonoticRadioButton_T(float, string, string, string, string theTooltip);
-entity makeXonoticRadioButton(float, string, string, string);
-#endif
-
-#ifdef IMPLEMENTATION
 entity makeXonoticRadioButton_T(float theGroup, string theCvar, string theValue, string theText, string theTooltip)
 {
 	entity me;
@@ -127,4 +99,3 @@ void XonoticRadioButton_saveCvars(entity me)
 		}
 	}
 }
-#endif
diff --git a/qcsrc/menu/xonotic/radiobutton.qh b/qcsrc/menu/xonotic/radiobutton.qh
index 6f70f09be..36c228fcf 100644
--- a/qcsrc/menu/xonotic/radiobutton.qh
+++ b/qcsrc/menu/xonotic/radiobutton.qh
@@ -1 +1,26 @@
 #pragma once
+
+#include "../item/radiobutton.qh"
+CLASS(XonoticRadioButton, RadioButton)
+	METHOD(XonoticRadioButton, configureXonoticRadioButton, void(entity, float, string, string, string, string));
+	METHOD(XonoticRadioButton, draw, void(entity));
+	METHOD(XonoticRadioButton, setChecked, void(entity, float));
+	ATTRIB(XonoticRadioButton, fontSize, float, SKINFONTSIZE_NORMAL)
+	ATTRIB(XonoticRadioButton, image, string, SKINGFX_RADIOBUTTON)
+	ATTRIB(XonoticRadioButton, color, vector, SKINCOLOR_RADIOBUTTON_N)
+	ATTRIB(XonoticRadioButton, colorC, vector, SKINCOLOR_RADIOBUTTON_C)
+	ATTRIB(XonoticRadioButton, colorF, vector, SKINCOLOR_RADIOBUTTON_F)
+	ATTRIB(XonoticRadioButton, colorD, vector, SKINCOLOR_RADIOBUTTON_D)
+
+	ATTRIB(XonoticRadioButton, cvarName, string, string_null)
+	ATTRIB(XonoticRadioButton, cvarValue, string, string_null)
+	ATTRIB(XonoticRadioButton, cvarOffValue, string, string_null)
+	ATTRIB(XonoticRadioButton, cvarValueIsAnotherCvar, float, 0)
+	METHOD(XonoticRadioButton, loadCvars, void(entity));
+	METHOD(XonoticRadioButton, saveCvars, void(entity));
+
+	ATTRIB(XonoticRadioButton, alpha, float, SKINALPHA_TEXT)
+	ATTRIB(XonoticRadioButton, disabledAlpha, float, SKINALPHA_DISABLED)
+ENDCLASS(XonoticRadioButton)
+entity makeXonoticRadioButton_T(float, string, string, string, string theTooltip);
+entity makeXonoticRadioButton(float, string, string, string);
diff --git a/qcsrc/menu/xonotic/rootdialog.qc b/qcsrc/menu/xonotic/rootdialog.qc
index 6a1a23a41..38fbe7fc7 100644
--- a/qcsrc/menu/xonotic/rootdialog.qc
+++ b/qcsrc/menu/xonotic/rootdialog.qc
@@ -1,24 +1,6 @@
 #include "rootdialog.qh"
-#ifndef ROOTDIALOG_H
-#define ROOTDIALOG_H
-#include "dialog.qc"
-CLASS(XonoticRootDialog, XonoticDialog)
-	// still to be customized by user
-	/*
-	ATTRIB(XonoticDialog, closable, float, 1)
-	ATTRIB(XonoticDialog, title, string, _("Form1")) // ;)
-	ATTRIB(XonoticDialog, color, vector, '1 0.5 1')
-	ATTRIB(XonoticDialog, intendedWidth, float, 0)
-	ATTRIB(XonoticDialog, rows, float, 3)
-	ATTRIB(XonoticDialog, columns, float, 2)
-	*/
-	METHOD(XonoticRootDialog, close, void(entity));
-ENDCLASS(XonoticRootDialog)
-#endif
 
-#ifdef IMPLEMENTATION
 void XonoticRootDialog_close(entity me)
 {
 	m_goto(string_null);
 }
-#endif
diff --git a/qcsrc/menu/xonotic/rootdialog.qh b/qcsrc/menu/xonotic/rootdialog.qh
index 6f70f09be..0bfd3364c 100644
--- a/qcsrc/menu/xonotic/rootdialog.qh
+++ b/qcsrc/menu/xonotic/rootdialog.qh
@@ -1 +1,15 @@
 #pragma once
+
+#include "dialog.qh"
+CLASS(XonoticRootDialog, XonoticDialog)
+	// still to be customized by user
+	/*
+	ATTRIB(XonoticDialog, closable, float, 1)
+	ATTRIB(XonoticDialog, title, string, _("Form1")) // ;)
+	ATTRIB(XonoticDialog, color, vector, '1 0.5 1')
+	ATTRIB(XonoticDialog, intendedWidth, float, 0)
+	ATTRIB(XonoticDialog, rows, float, 3)
+	ATTRIB(XonoticDialog, columns, float, 2)
+	*/
+	METHOD(XonoticRootDialog, close, void(entity));
+ENDCLASS(XonoticRootDialog)
diff --git a/qcsrc/menu/xonotic/screenshotimage.qc b/qcsrc/menu/xonotic/screenshotimage.qc
index 34053676f..82ff4ba7b 100644
--- a/qcsrc/menu/xonotic/screenshotimage.qc
+++ b/qcsrc/menu/xonotic/screenshotimage.qc
@@ -1,26 +1,5 @@
 #include "screenshotimage.qh"
-#ifndef SCREENSHOTIMAGE_H
-#define SCREENSHOTIMAGE_H
-#include "image.qc"
-CLASS(XonoticScreenshotImage, XonoticImage)
-	METHOD(XonoticScreenshotImage, configureXonoticScreenshotImage, void(entity));
-	METHOD(XonoticScreenshotImage, load, void(entity, string));
-	METHOD(XonoticScreenshotImage, draw, void(entity));
-	ATTRIB(XonoticScreenshotImage, focusable, float, 1) // mousePress and mouseDrag work only if focusable is set
-	METHOD(XonoticScreenshotImage, mousePress, float(entity, vector));
-	METHOD(XonoticScreenshotImage, mouseDrag, float(entity, vector));
-	METHOD(XonoticScreenshotImage, mouseMove, float(entity, vector));
-	METHOD(XonoticScreenshotImage, resizeNotify, void(entity, vector, vector, vector, vector));
-	ATTRIB(XonoticScreenshotImage, realFontSize, vector, '0 0 0')
-	ATTRIB(XonoticScreenshotImage, fontSize, float, SKINFONTSIZE_NORMAL)
-	ATTRIB(XonoticScreenshotImage, showTitle, float, 1)
-	ATTRIB(XonoticScreenshotImage, screenshotTime, float, 0)
-	ATTRIB(XonoticScreenshotImage, screenshotTitle, string, string_null)
-ENDCLASS(XonoticScreenshotImage)
-entity makeXonoticScreenshotImage();
-#endif
 
-#ifdef IMPLEMENTATION
 entity makeXonoticScreenshotImage()
 {
 	entity me;
@@ -95,4 +74,3 @@ void XonoticScreenshotImage_resizeNotify(entity me, vector relOrigin, vector rel
 	me.realFontSize_y = me.fontSize / absSize.y;
 	me.realFontSize_x = me.fontSize / absSize.x;
 }
-#endif
diff --git a/qcsrc/menu/xonotic/screenshotimage.qh b/qcsrc/menu/xonotic/screenshotimage.qh
index 6f70f09be..eb20c73a2 100644
--- a/qcsrc/menu/xonotic/screenshotimage.qh
+++ b/qcsrc/menu/xonotic/screenshotimage.qh
@@ -1 +1,19 @@
 #pragma once
+
+#include "image.qh"
+CLASS(XonoticScreenshotImage, XonoticImage)
+	METHOD(XonoticScreenshotImage, configureXonoticScreenshotImage, void(entity));
+	METHOD(XonoticScreenshotImage, load, void(entity, string));
+	METHOD(XonoticScreenshotImage, draw, void(entity));
+	ATTRIB(XonoticScreenshotImage, focusable, float, 1)  // mousePress and mouseDrag work only if focusable is set
+	METHOD(XonoticScreenshotImage, mousePress, float(entity, vector));
+	METHOD(XonoticScreenshotImage, mouseDrag, float(entity, vector));
+	METHOD(XonoticScreenshotImage, mouseMove, float(entity, vector));
+	METHOD(XonoticScreenshotImage, resizeNotify, void(entity, vector, vector, vector, vector));
+	ATTRIB(XonoticScreenshotImage, realFontSize, vector, '0 0 0')
+	ATTRIB(XonoticScreenshotImage, fontSize, float, SKINFONTSIZE_NORMAL)
+	ATTRIB(XonoticScreenshotImage, showTitle, float, 1)
+	ATTRIB(XonoticScreenshotImage, screenshotTime, float, 0)
+	ATTRIB(XonoticScreenshotImage, screenshotTitle, string, string_null)
+ENDCLASS(XonoticScreenshotImage)
+entity makeXonoticScreenshotImage();
diff --git a/qcsrc/menu/xonotic/screenshotlist.qc b/qcsrc/menu/xonotic/screenshotlist.qc
index 244a9e61e..a948ce86f 100644
--- a/qcsrc/menu/xonotic/screenshotlist.qc
+++ b/qcsrc/menu/xonotic/screenshotlist.qc
@@ -1,52 +1,9 @@
 #include "screenshotlist.qh"
-#ifndef SCREENSHOTLIST_H
-#define SCREENSHOTLIST_H
-#include "listbox.qc"
-CLASS(XonoticScreenshotList, XonoticListBox)
-	METHOD(XonoticScreenshotList, configureXonoticScreenshotList, void(entity));
-	ATTRIB(XonoticScreenshotList, rowsPerItem, float, 1)
-	METHOD(XonoticScreenshotList, resizeNotify, void(entity, vector, vector, vector, vector));
-	METHOD(XonoticScreenshotList, setSelected, void(entity, float));
-	METHOD(XonoticScreenshotList, draw, void(entity));
-	METHOD(XonoticScreenshotList, drawListBoxItem, void(entity, int, vector, bool, bool));
-	METHOD(XonoticScreenshotList, getScreenshots, void(entity));
-	METHOD(XonoticScreenshotList, previewScreenshot, void(entity));
-	METHOD(XonoticScreenshotList, startScreenshot, void(entity));
-	METHOD(XonoticScreenshotList, screenshotName, string(entity, float));
-	METHOD(XonoticScreenshotList, doubleClickListBoxItem, void(entity, float, vector));
-	METHOD(XonoticScreenshotList, keyDown, float(entity, float, float, float));
-	METHOD(XonoticScreenshotList, destroy, void(entity));
-	METHOD(XonoticScreenshotList, showNotify, void(entity));
-	ATTRIB(XonoticScreenshotList, listScreenshot, float, -1)
-	ATTRIB(XonoticScreenshotList, realFontSize, vector, '0 0 0')
-	ATTRIB(XonoticScreenshotList, columnNameOrigin, float, 0)
-	ATTRIB(XonoticScreenshotList, columnNameSize, float, 0)
-	ATTRIB(XonoticScreenshotList, realUpperMargin, float, 0)
-	ATTRIB(XonoticScreenshotList, origin, vector, '0 0 0')
-	ATTRIB(XonoticScreenshotList, itemAbsSize, vector, '0 0 0')
-	ATTRIB(XonoticScreenshotList, filterString, string, string_null)
-	ATTRIB(XonoticScreenshotList, filterBox, entity, NULL)
-	ATTRIB(XonoticScreenshotList, filterTime, float, 0)
-
-	ATTRIB(XonoticScreenshotList, newScreenshotTime, float, 0)
-	ATTRIB(XonoticScreenshotList, newSlideShowScreenshotTime, float, 0)
-
-	ATTRIB(XonoticScreenshotList, screenshotBrowserDialog, entity, NULL)
-	ATTRIB(XonoticScreenshotList, screenshotPreview, entity, NULL)
-	ATTRIB(XonoticScreenshotList, screenshotViewerDialog, entity, NULL)
-	METHOD(XonoticScreenshotList, goScreenshot, void(entity, float));
-	METHOD(XonoticScreenshotList, startSlideShow, void(entity));
-	METHOD(XonoticScreenshotList, stopSlideShow, void(entity));
-ENDCLASS(XonoticScreenshotList)
-
-entity makeXonoticScreenshotList();
-void StartScreenshot_Click(entity btn, entity me);
-void ScreenshotList_Refresh_Click(entity btn, entity me);
-void ScreenshotList_Filter_Would_Change(entity box, entity me);
-void ScreenshotList_Filter_Change(entity box, entity me);
-#endif
-
-#ifdef IMPLEMENTATION
+
+#include "dialog_multiplayer_media_screenshot.qh"
+#include "dialog_multiplayer_media_screenshot_viewer.qh"
+#include "inputbox.qh"
+#include "../item/modalcontroller.qh"
 
 entity makeXonoticScreenshotList()
 {
@@ -297,4 +254,3 @@ float XonoticScreenshotList_keyDown(entity me, float scan, float ascii, float sh
 	}
 	return SUPER(XonoticScreenshotList).keyDown(me, scan, ascii, shift);
 }
-#endif
diff --git a/qcsrc/menu/xonotic/screenshotlist.qh b/qcsrc/menu/xonotic/screenshotlist.qh
index 6f70f09be..1279c4ad9 100644
--- a/qcsrc/menu/xonotic/screenshotlist.qh
+++ b/qcsrc/menu/xonotic/screenshotlist.qh
@@ -1 +1,45 @@
 #pragma once
+
+#include "listbox.qh"
+CLASS(XonoticScreenshotList, XonoticListBox)
+	METHOD(XonoticScreenshotList, configureXonoticScreenshotList, void(entity));
+	ATTRIB(XonoticScreenshotList, rowsPerItem, float, 1)
+	METHOD(XonoticScreenshotList, resizeNotify, void(entity, vector, vector, vector, vector));
+	METHOD(XonoticScreenshotList, setSelected, void(entity, float));
+	METHOD(XonoticScreenshotList, draw, void(entity));
+	METHOD(XonoticScreenshotList, drawListBoxItem, void(entity, int, vector, bool, bool));
+	METHOD(XonoticScreenshotList, getScreenshots, void(entity));
+	METHOD(XonoticScreenshotList, previewScreenshot, void(entity));
+	METHOD(XonoticScreenshotList, startScreenshot, void(entity));
+	METHOD(XonoticScreenshotList, screenshotName, string(entity, float));
+	METHOD(XonoticScreenshotList, doubleClickListBoxItem, void(entity, float, vector));
+	METHOD(XonoticScreenshotList, keyDown, float(entity, float, float, float));
+	METHOD(XonoticScreenshotList, destroy, void(entity));
+	METHOD(XonoticScreenshotList, showNotify, void(entity));
+	ATTRIB(XonoticScreenshotList, listScreenshot, float, -1)
+	ATTRIB(XonoticScreenshotList, realFontSize, vector, '0 0 0')
+	ATTRIB(XonoticScreenshotList, columnNameOrigin, float, 0)
+	ATTRIB(XonoticScreenshotList, columnNameSize, float, 0)
+	ATTRIB(XonoticScreenshotList, realUpperMargin, float, 0)
+	ATTRIB(XonoticScreenshotList, origin, vector, '0 0 0')
+	ATTRIB(XonoticScreenshotList, itemAbsSize, vector, '0 0 0')
+	ATTRIB(XonoticScreenshotList, filterString, string, string_null)
+	ATTRIB(XonoticScreenshotList, filterBox, entity, NULL)
+	ATTRIB(XonoticScreenshotList, filterTime, float, 0)
+
+	ATTRIB(XonoticScreenshotList, newScreenshotTime, float, 0)
+	ATTRIB(XonoticScreenshotList, newSlideShowScreenshotTime, float, 0)
+
+	ATTRIB(XonoticScreenshotList, screenshotBrowserDialog, entity, NULL)
+	ATTRIB(XonoticScreenshotList, screenshotPreview, entity, NULL)
+	ATTRIB(XonoticScreenshotList, screenshotViewerDialog, entity, NULL)
+	METHOD(XonoticScreenshotList, goScreenshot, void(entity, float));
+	METHOD(XonoticScreenshotList, startSlideShow, void(entity));
+	METHOD(XonoticScreenshotList, stopSlideShow, void(entity));
+ENDCLASS(XonoticScreenshotList)
+
+entity makeXonoticScreenshotList();
+void StartScreenshot_Click(entity btn, entity me);
+void ScreenshotList_Refresh_Click(entity btn, entity me);
+void ScreenshotList_Filter_Would_Change(entity box, entity me);
+void ScreenshotList_Filter_Change(entity box, entity me);
diff --git a/qcsrc/menu/xonotic/serverlist.qc b/qcsrc/menu/xonotic/serverlist.qc
index 35241094a..fc2ba573b 100644
--- a/qcsrc/menu/xonotic/serverlist.qc
+++ b/qcsrc/menu/xonotic/serverlist.qc
@@ -1,175 +1,10 @@
 #include "serverlist.qh"
-#ifndef SERVERLIST_H
-#define SERVERLIST_H
-#include "listbox.qc"
-CLASS(XonoticServerList, XonoticListBox)
-	METHOD(XonoticServerList, configureXonoticServerList, void(entity));
-	ATTRIB(XonoticServerList, rowsPerItem, float, 1)
-	METHOD(XonoticServerList, draw, void(entity));
-	METHOD(XonoticServerList, drawListBoxItem, void(entity, int, vector, bool, bool));
-	METHOD(XonoticServerList, doubleClickListBoxItem, void(entity, float, vector));
-	METHOD(XonoticServerList, resizeNotify, void(entity, vector, vector, vector, vector));
-	METHOD(XonoticServerList, keyDown, float(entity, float, float, float));
-	METHOD(XonoticServerList, toggleFavorite, void(entity, string));
-
-	ATTRIB(XonoticServerList, iconsSizeFactor, float, 0.85)
-	METHOD(XonoticServerList, mouseMove, float(entity, vector));
-	ATTRIB(XonoticServerList, mouseOverIcons, bool, false)
-	METHOD(XonoticServerList, focusedItemChangeNotify, void(entity));
-
-	ATTRIB(XonoticServerList, realFontSize, vector, '0 0 0')
-	ATTRIB(XonoticServerList, realUpperMargin, float, 0)
-	ATTRIB(XonoticServerList, columnIconsOrigin, float, 0)
-	ATTRIB(XonoticServerList, columnIconsSize, float, 0)
-	ATTRIB(XonoticServerList, columnPingOrigin, float, 0)
-	ATTRIB(XonoticServerList, columnPingSize, float, 0)
-	ATTRIB(XonoticServerList, columnNameOrigin, float, 0)
-	ATTRIB(XonoticServerList, columnNameSize, float, 0)
-	ATTRIB(XonoticServerList, columnMapOrigin, float, 0)
-	ATTRIB(XonoticServerList, columnMapSize, float, 0)
-	ATTRIB(XonoticServerList, columnTypeOrigin, float, 0)
-	ATTRIB(XonoticServerList, columnTypeSize, float, 0)
-	ATTRIB(XonoticServerList, columnPlayersOrigin, float, 0)
-	ATTRIB(XonoticServerList, columnPlayersSize, float, 0)
-	ATTRIB(XonoticServerList, lockedSelectedItem, bool, true) // initially keep selected the first item of the list, avoiding an unwanted scrolling
-
-	ATTRIB(XonoticServerList, selectedServer, string, string_null) // to restore selected server when needed
-	METHOD(XonoticServerList, setSelected, void(entity, float));
-	METHOD(XonoticServerList, setSortOrder, void(entity, float, float));
-	ATTRIB(XonoticServerList, filterShowEmpty, float, 1)
-	ATTRIB(XonoticServerList, filterShowFull, float, 1)
-	ATTRIB(XonoticServerList, filterString, string, string_null)
-	ATTRIB(XonoticServerList, controlledTextbox, entity, NULL)
-	ATTRIB(XonoticServerList, ipAddressBox, entity, NULL)
-	ATTRIB(XonoticServerList, favoriteButton, entity, NULL)
-	ATTRIB(XonoticServerList, nextRefreshTime, float, 0)
-	METHOD(XonoticServerList, refreshServerList, void(entity, float)); // refresh mode: REFRESHSERVERLIST_*
-	ATTRIB(XonoticServerList, needsRefresh, float, 1)
-	METHOD(XonoticServerList, focusEnter, void(entity));
-	METHOD(XonoticServerList, positionSortButton, void(entity, entity, float, float, string, void(entity, entity)));
-	ATTRIB(XonoticServerList, sortButton1, entity, NULL)
-	ATTRIB(XonoticServerList, sortButton2, entity, NULL)
-	ATTRIB(XonoticServerList, sortButton3, entity, NULL)
-	ATTRIB(XonoticServerList, sortButton4, entity, NULL)
-	ATTRIB(XonoticServerList, sortButton5, entity, NULL)
-	ATTRIB(XonoticServerList, connectButton, entity, NULL)
-	ATTRIB(XonoticServerList, infoButton, entity, NULL)
-	ATTRIB(XonoticServerList, currentSortOrder, float, 0)
-	ATTRIB(XonoticServerList, currentSortField, float, -1)
-
-	ATTRIB(XonoticServerList, ipAddressBoxFocused, float, -1)
-
-	ATTRIB(XonoticServerList, seenIPv4, float, 0)
-	ATTRIB(XonoticServerList, seenIPv6, float, 0)
-	ATTRIB(XonoticServerList, categoriesHeight, float, 1.25)
-
-	METHOD(XonoticServerList, getTotalHeight, float(entity));
-	METHOD(XonoticServerList, getItemAtPos, float(entity, float));
-	METHOD(XonoticServerList, getItemStart, float(entity, float));
-	METHOD(XonoticServerList, getItemHeight, float(entity, float));
-ENDCLASS(XonoticServerList)
-entity makeXonoticServerList();
-
-#ifndef IMPLEMENTATION
-float autocvar_menu_slist_categories;
-float autocvar_menu_slist_categories_onlyifmultiple;
-float autocvar_menu_slist_purethreshold;
-float autocvar_menu_slist_modimpurity;
-float autocvar_menu_slist_recommendations;
-float autocvar_menu_slist_recommendations_maxping;
-float autocvar_menu_slist_recommendations_minfreeslots;
-float autocvar_menu_slist_recommendations_minhumans;
-float autocvar_menu_slist_recommendations_purethreshold;
-
-// server cache fields
-#define SLIST_FIELDS \
-	SLIST_FIELD(CNAME,       "cname") \
-	SLIST_FIELD(PING,        "ping") \
-	SLIST_FIELD(GAME,        "game") \
-	SLIST_FIELD(MOD,         "mod") \
-	SLIST_FIELD(MAP,         "map") \
-	SLIST_FIELD(NAME,        "name") \
-	SLIST_FIELD(MAXPLAYERS,  "maxplayers") \
-	SLIST_FIELD(NUMPLAYERS,  "numplayers") \
-	SLIST_FIELD(NUMHUMANS,   "numhumans") \
-	SLIST_FIELD(NUMBOTS,     "numbots") \
-	SLIST_FIELD(PROTOCOL,    "protocol") \
-	SLIST_FIELD(FREESLOTS,   "freeslots") \
-	SLIST_FIELD(PLAYERS,     "players") \
-	SLIST_FIELD(QCSTATUS,    "qcstatus") \
-	SLIST_FIELD(CATEGORY,    "category") \
-	SLIST_FIELD(ISFAVORITE,  "isfavorite")
-
-#define SLIST_FIELD(suffix,name) float SLIST_FIELD_##suffix;
-SLIST_FIELDS
-#undef SLIST_FIELD
-
-const float REFRESHSERVERLIST_RESORT = 0;    // sort the server list again to update for changes to e.g. favorite status, categories
-const float REFRESHSERVERLIST_REFILTER = 1;  // ..., also update filter and sort criteria
-const float REFRESHSERVERLIST_ASK = 2;       // ..., also suggest querying servers now
-const float REFRESHSERVERLIST_RESET = 3;     // ..., also clear the list first
-
-// function declarations
-float IsServerInList(string list, string srv);
-#define IsFavorite(srv) IsServerInList(cvar_string("net_slist_favorites"), srv)
-#define IsPromoted(srv) IsServerInList(_Nex_ExtResponseSystem_PromotedServers, srv)
-#define IsRecommended(srv) IsServerInList(_Nex_ExtResponseSystem_RecommendedServers, srv)
-
-entity RetrieveCategoryEnt(float catnum);
-
-float CheckCategoryOverride(float cat);
-float CheckCategoryForEntry(float entry);
-float m_gethostcachecategory(float entry) { return CheckCategoryOverride(CheckCategoryForEntry(entry)); }
-
-void RegisterSLCategories();
-
-void ServerList_Connect_Click(entity btn, entity me);
-void ServerList_Categories_Click(entity box, entity me);
-void ServerList_ShowEmpty_Click(entity box, entity me);
-void ServerList_ShowFull_Click(entity box, entity me);
-void ServerList_Filter_Change(entity box, entity me);
-void ServerList_Favorite_Click(entity btn, entity me);
-void ServerList_Info_Click(entity btn, entity me);
-void ServerList_Update_favoriteButton(entity btn, entity me);
-
-// fields for category entities
-const int MAX_CATEGORIES = 9;
-const int CATEGORY_FIRST = 1;
-entity categories[MAX_CATEGORIES];
-int category_ent_count;
-.string cat_name;
-.string cat_string;
-.string cat_enoverride_string;
-.string cat_dioverride_string;
-.float cat_enoverride;
-.float cat_dioverride;
-
-// fields for drawing categories
-int category_name[MAX_CATEGORIES];
-int category_item[MAX_CATEGORIES];
-int category_draw_count;
-
-#define SLIST_CATEGORIES \
-	SLIST_CATEGORY(CAT_FAVORITED,    "",            "",             CTX(_("SLCAT^Favorites"))) \
-	SLIST_CATEGORY(CAT_RECOMMENDED,  "",            "",             CTX(_("SLCAT^Recommended"))) \
-	SLIST_CATEGORY(CAT_NORMAL,       "",            "CAT_SERVERS",  CTX(_("SLCAT^Normal Servers"))) \
-	SLIST_CATEGORY(CAT_SERVERS,      "CAT_NORMAL",  "CAT_SERVERS",  CTX(_("SLCAT^Servers"))) \
-	SLIST_CATEGORY(CAT_XPM,          "CAT_NORMAL",  "CAT_SERVERS",  CTX(_("SLCAT^Competitive Mode"))) \
-	SLIST_CATEGORY(CAT_MODIFIED,     "",            "CAT_SERVERS",  CTX(_("SLCAT^Modified Servers"))) \
-	SLIST_CATEGORY(CAT_OVERKILL,     "",            "CAT_SERVERS",  CTX(_("SLCAT^Overkill Mode"))) \
-	SLIST_CATEGORY(CAT_INSTAGIB,     "",            "CAT_SERVERS",  CTX(_("SLCAT^InstaGib Mode"))) \
-	SLIST_CATEGORY(CAT_DEFRAG,       "",            "CAT_SERVERS",  CTX(_("SLCAT^Defrag Mode")))
-
-#define SLIST_CATEGORY_AUTOCVAR(name) autocvar_menu_slist_categories_##name##_override
-#define SLIST_CATEGORY(name,enoverride,dioverride,str) \
-	int name; \
-	string SLIST_CATEGORY_AUTOCVAR(name) = enoverride;
-SLIST_CATEGORIES
-#undef SLIST_CATEGORY
 
-#endif
-#endif
-#ifdef IMPLEMENTATION
+#include "checkbox.qh"
+#include "inputbox.qh"
+#include "mainwindow.qh"
+#include "dialog_multiplayer_join_serverinfo.qh"
+#include <common/mapinfo.qh>
 
 void RegisterSLCategories()
 {
@@ -1371,5 +1206,3 @@ float XonoticServerList_getItemHeight(entity me, int item)
 	}
 	return me.itemHeight;
 }
-
-#endif
diff --git a/qcsrc/menu/xonotic/serverlist.qh b/qcsrc/menu/xonotic/serverlist.qh
index 6f70f09be..ac726b222 100644
--- a/qcsrc/menu/xonotic/serverlist.qh
+++ b/qcsrc/menu/xonotic/serverlist.qh
@@ -1 +1,166 @@
 #pragma once
+
+#include "listbox.qh"
+CLASS(XonoticServerList, XonoticListBox)
+	METHOD(XonoticServerList, configureXonoticServerList, void(entity));
+	ATTRIB(XonoticServerList, rowsPerItem, float, 1)
+	METHOD(XonoticServerList, draw, void(entity));
+	METHOD(XonoticServerList, drawListBoxItem, void(entity, int, vector, bool, bool));
+	METHOD(XonoticServerList, doubleClickListBoxItem, void(entity, float, vector));
+	METHOD(XonoticServerList, resizeNotify, void(entity, vector, vector, vector, vector));
+	METHOD(XonoticServerList, keyDown, float(entity, float, float, float));
+	METHOD(XonoticServerList, toggleFavorite, void(entity, string));
+
+	ATTRIB(XonoticServerList, iconsSizeFactor, float, 0.85)
+	METHOD(XonoticServerList, mouseMove, float(entity, vector));
+	ATTRIB(XonoticServerList, mouseOverIcons, bool, false)
+	METHOD(XonoticServerList, focusedItemChangeNotify, void(entity));
+
+	ATTRIB(XonoticServerList, realFontSize, vector, '0 0 0')
+	ATTRIB(XonoticServerList, realUpperMargin, float, 0)
+	ATTRIB(XonoticServerList, columnIconsOrigin, float, 0)
+	ATTRIB(XonoticServerList, columnIconsSize, float, 0)
+	ATTRIB(XonoticServerList, columnPingOrigin, float, 0)
+	ATTRIB(XonoticServerList, columnPingSize, float, 0)
+	ATTRIB(XonoticServerList, columnNameOrigin, float, 0)
+	ATTRIB(XonoticServerList, columnNameSize, float, 0)
+	ATTRIB(XonoticServerList, columnMapOrigin, float, 0)
+	ATTRIB(XonoticServerList, columnMapSize, float, 0)
+	ATTRIB(XonoticServerList, columnTypeOrigin, float, 0)
+	ATTRIB(XonoticServerList, columnTypeSize, float, 0)
+	ATTRIB(XonoticServerList, columnPlayersOrigin, float, 0)
+	ATTRIB(XonoticServerList, columnPlayersSize, float, 0)
+	ATTRIB(XonoticServerList, lockedSelectedItem, bool, true)      // initially keep selected the first item of the list, avoiding an unwanted scrolling
+
+	ATTRIB(XonoticServerList, selectedServer, string, string_null) // to restore selected server when needed
+	METHOD(XonoticServerList, setSelected, void(entity, float));
+	METHOD(XonoticServerList, setSortOrder, void(entity, float, float));
+	ATTRIB(XonoticServerList, filterShowEmpty, float, 1)
+	ATTRIB(XonoticServerList, filterShowFull, float, 1)
+	ATTRIB(XonoticServerList, filterString, string, string_null)
+	ATTRIB(XonoticServerList, controlledTextbox, entity, NULL)
+	ATTRIB(XonoticServerList, ipAddressBox, entity, NULL)
+	ATTRIB(XonoticServerList, favoriteButton, entity, NULL)
+	ATTRIB(XonoticServerList, nextRefreshTime, float, 0)
+	METHOD(XonoticServerList, refreshServerList, void(entity, float));  // refresh mode: REFRESHSERVERLIST_*
+	ATTRIB(XonoticServerList, needsRefresh, float, 1)
+	METHOD(XonoticServerList, focusEnter, void(entity));
+	METHOD(XonoticServerList, positionSortButton, void(entity, entity, float, float, string, void(entity, entity)));
+	ATTRIB(XonoticServerList, sortButton1, entity, NULL)
+	ATTRIB(XonoticServerList, sortButton2, entity, NULL)
+	ATTRIB(XonoticServerList, sortButton3, entity, NULL)
+	ATTRIB(XonoticServerList, sortButton4, entity, NULL)
+	ATTRIB(XonoticServerList, sortButton5, entity, NULL)
+	ATTRIB(XonoticServerList, connectButton, entity, NULL)
+	ATTRIB(XonoticServerList, infoButton, entity, NULL)
+	ATTRIB(XonoticServerList, currentSortOrder, float, 0)
+	ATTRIB(XonoticServerList, currentSortField, float, -1)
+
+	ATTRIB(XonoticServerList, ipAddressBoxFocused, float, -1)
+
+	ATTRIB(XonoticServerList, seenIPv4, float, 0)
+	ATTRIB(XonoticServerList, seenIPv6, float, 0)
+	ATTRIB(XonoticServerList, categoriesHeight, float, 1.25)
+
+	METHOD(XonoticServerList, getTotalHeight, float(entity));
+	METHOD(XonoticServerList, getItemAtPos, float(entity, float));
+	METHOD(XonoticServerList, getItemStart, float(entity, float));
+	METHOD(XonoticServerList, getItemHeight, float(entity, float));
+ENDCLASS(XonoticServerList)
+entity makeXonoticServerList();
+
+void RegisterSLCategories();
+float CheckCategoryForEntry(float entry);
+void ServerList_Filter_Change(entity box, entity me);
+void ServerList_Categories_Click(entity box, entity me);
+void ServerList_ShowEmpty_Click(entity box, entity me);
+void ServerList_ShowFull_Click(entity box, entity me);
+void ServerList_Connect_Click(entity btn, entity me);
+void ServerList_Update_favoriteButton(entity btn, entity me);
+void ServerList_Favorite_Click(entity btn, entity me);
+void ServerList_Info_Click(entity btn, entity me);
+
+// server cache fields
+#define SLIST_FIELDS \
+	SLIST_FIELD(CNAME,       "cname") \
+	SLIST_FIELD(PING,        "ping") \
+	SLIST_FIELD(GAME,        "game") \
+	SLIST_FIELD(MOD,         "mod") \
+	SLIST_FIELD(MAP,         "map") \
+	SLIST_FIELD(NAME,        "name") \
+	SLIST_FIELD(MAXPLAYERS,  "maxplayers") \
+	SLIST_FIELD(NUMPLAYERS,  "numplayers") \
+	SLIST_FIELD(NUMHUMANS,   "numhumans") \
+	SLIST_FIELD(NUMBOTS,     "numbots") \
+	SLIST_FIELD(PROTOCOL,    "protocol") \
+	SLIST_FIELD(FREESLOTS,   "freeslots") \
+	SLIST_FIELD(PLAYERS,     "players") \
+	SLIST_FIELD(QCSTATUS,    "qcstatus") \
+	SLIST_FIELD(CATEGORY,    "category") \
+	SLIST_FIELD(ISFAVORITE,  "isfavorite")
+
+#define SLIST_FIELD(suffix,name) float SLIST_FIELD_##suffix;
+SLIST_FIELDS
+#undef SLIST_FIELD
+
+float autocvar_menu_slist_categories;
+float autocvar_menu_slist_categories_onlyifmultiple;
+float autocvar_menu_slist_purethreshold;
+float autocvar_menu_slist_modimpurity;
+float autocvar_menu_slist_recommendations;
+float autocvar_menu_slist_recommendations_maxping;
+float autocvar_menu_slist_recommendations_minfreeslots;
+float autocvar_menu_slist_recommendations_minhumans;
+float autocvar_menu_slist_recommendations_purethreshold;
+
+const float REFRESHSERVERLIST_RESORT = 0;    // sort the server list again to update for changes to e.g. favorite status, categories
+const float REFRESHSERVERLIST_REFILTER = 1;  // ..., also update filter and sort criteria
+const float REFRESHSERVERLIST_ASK = 2;       // ..., also suggest querying servers now
+const float REFRESHSERVERLIST_RESET = 3;     // ..., also clear the list first
+
+// function declarations
+float IsServerInList(string list, string srv);
+#define IsFavorite(srv) IsServerInList(cvar_string("net_slist_favorites"), srv)
+#define IsPromoted(srv) IsServerInList(_Nex_ExtResponseSystem_PromotedServers, srv)
+#define IsRecommended(srv) IsServerInList(_Nex_ExtResponseSystem_RecommendedServers, srv)
+
+entity RetrieveCategoryEnt(float catnum);
+
+float CheckCategoryOverride(float cat);
+float m_gethostcachecategory(float entry) { return CheckCategoryOverride(CheckCategoryForEntry(entry)); }
+
+
+// fields for category entities
+const int MAX_CATEGORIES = 9;
+const int CATEGORY_FIRST = 1;
+entity categories[MAX_CATEGORIES];
+int category_ent_count;
+.string cat_name;
+.string cat_string;
+.string cat_enoverride_string;
+.string cat_dioverride_string;
+.float cat_enoverride;
+.float cat_dioverride;
+
+// fields for drawing categories
+int category_name[MAX_CATEGORIES];
+int category_item[MAX_CATEGORIES];
+int category_draw_count;
+
+#define SLIST_CATEGORIES \
+	SLIST_CATEGORY(CAT_FAVORITED,    "",            "",             CTX(_("SLCAT^Favorites"))) \
+	SLIST_CATEGORY(CAT_RECOMMENDED,  "",            "",             CTX(_("SLCAT^Recommended"))) \
+	SLIST_CATEGORY(CAT_NORMAL,       "",            "CAT_SERVERS",  CTX(_("SLCAT^Normal Servers"))) \
+	SLIST_CATEGORY(CAT_SERVERS,      "CAT_NORMAL",  "CAT_SERVERS",  CTX(_("SLCAT^Servers"))) \
+	SLIST_CATEGORY(CAT_XPM,          "CAT_NORMAL",  "CAT_SERVERS",  CTX(_("SLCAT^Competitive Mode"))) \
+	SLIST_CATEGORY(CAT_MODIFIED,     "",            "CAT_SERVERS",  CTX(_("SLCAT^Modified Servers"))) \
+	SLIST_CATEGORY(CAT_OVERKILL,     "",            "CAT_SERVERS",  CTX(_("SLCAT^Overkill Mode"))) \
+	SLIST_CATEGORY(CAT_INSTAGIB,     "",            "CAT_SERVERS",  CTX(_("SLCAT^InstaGib Mode"))) \
+	SLIST_CATEGORY(CAT_DEFRAG,       "",            "CAT_SERVERS",  CTX(_("SLCAT^Defrag Mode")))
+
+#define SLIST_CATEGORY_AUTOCVAR(name) autocvar_menu_slist_categories_##name##_override
+#define SLIST_CATEGORY(name,enoverride,dioverride,str) \
+	int name; \
+	string SLIST_CATEGORY_AUTOCVAR(name) = enoverride;
+SLIST_CATEGORIES
+#undef SLIST_CATEGORY
diff --git a/qcsrc/menu/xonotic/skinlist.qc b/qcsrc/menu/xonotic/skinlist.qc
index 607888ec1..6e3f8a033 100644
--- a/qcsrc/menu/xonotic/skinlist.qc
+++ b/qcsrc/menu/xonotic/skinlist.qc
@@ -1,40 +1,4 @@
 #include "skinlist.qh"
-#ifndef SKINLIST_H
-#define SKINLIST_H
-#include "listbox.qc"
-CLASS(XonoticSkinList, XonoticListBox)
-	METHOD(XonoticSkinList, configureXonoticSkinList, void(entity));
-	ATTRIB(XonoticSkinList, rowsPerItem, float, 4)
-	METHOD(XonoticSkinList, resizeNotify, void(entity, vector, vector, vector, vector));
-	METHOD(XonoticSkinList, drawListBoxItem, void(entity, int, vector, bool, bool));
-	METHOD(XonoticSkinList, getSkins, void(entity));
-	METHOD(XonoticSkinList, setSkin, void(entity));
-	METHOD(XonoticSkinList, loadCvars, void(entity));
-	METHOD(XonoticSkinList, saveCvars, void(entity));
-	METHOD(XonoticSkinList, skinParameter, string(entity, float, float));
-	METHOD(XonoticSkinList, doubleClickListBoxItem, void(entity, float, vector));
-	METHOD(XonoticSkinList, keyDown, float(entity, float, float, float));
-	METHOD(XonoticSkinList, destroy, void(entity));
-
-	ATTRIB(XonoticSkinList, skinlist, float, -1)
-	ATTRIB(XonoticSkinList, realFontSize, vector, '0 0 0')
-	ATTRIB(XonoticSkinList, columnPreviewOrigin, float, 0)
-	ATTRIB(XonoticSkinList, columnPreviewSize, float, 0)
-	ATTRIB(XonoticSkinList, columnNameOrigin, float, 0)
-	ATTRIB(XonoticSkinList, columnNameSize, float, 0)
-	ATTRIB(XonoticSkinList, realUpperMargin1, float, 0)
-	ATTRIB(XonoticSkinList, realUpperMargin2, float, 0)
-	ATTRIB(XonoticSkinList, origin, vector, '0 0 0')
-	ATTRIB(XonoticSkinList, itemAbsSize, vector, '0 0 0')
-
-	ATTRIB(XonoticSkinList, name, string, "skinselector")
-ENDCLASS(XonoticSkinList)
-
-entity makeXonoticSkinList();
-void SetSkin_Click(entity btn, entity me);
-#endif
-
-#ifdef IMPLEMENTATION
 
 const float SKINPARM_NAME = 0;
 const float SKINPARM_TITLE = 1;
@@ -210,4 +174,3 @@ float XonoticSkinList_keyDown(entity me, float scan, float ascii, float shift)
 	else
 		return SUPER(XonoticSkinList).keyDown(me, scan, ascii, shift);
 }
-#endif
diff --git a/qcsrc/menu/xonotic/skinlist.qh b/qcsrc/menu/xonotic/skinlist.qh
index 6f70f09be..616fc233d 100644
--- a/qcsrc/menu/xonotic/skinlist.qh
+++ b/qcsrc/menu/xonotic/skinlist.qh
@@ -1 +1,33 @@
 #pragma once
+
+#include "listbox.qh"
+CLASS(XonoticSkinList, XonoticListBox)
+	METHOD(XonoticSkinList, configureXonoticSkinList, void(entity));
+	ATTRIB(XonoticSkinList, rowsPerItem, float, 4)
+	METHOD(XonoticSkinList, resizeNotify, void(entity, vector, vector, vector, vector));
+	METHOD(XonoticSkinList, drawListBoxItem, void(entity, int, vector, bool, bool));
+	METHOD(XonoticSkinList, getSkins, void(entity));
+	METHOD(XonoticSkinList, setSkin, void(entity));
+	METHOD(XonoticSkinList, loadCvars, void(entity));
+	METHOD(XonoticSkinList, saveCvars, void(entity));
+	METHOD(XonoticSkinList, skinParameter, string(entity, float, float));
+	METHOD(XonoticSkinList, doubleClickListBoxItem, void(entity, float, vector));
+	METHOD(XonoticSkinList, keyDown, float(entity, float, float, float));
+	METHOD(XonoticSkinList, destroy, void(entity));
+
+	ATTRIB(XonoticSkinList, skinlist, float, -1)
+	ATTRIB(XonoticSkinList, realFontSize, vector, '0 0 0')
+	ATTRIB(XonoticSkinList, columnPreviewOrigin, float, 0)
+	ATTRIB(XonoticSkinList, columnPreviewSize, float, 0)
+	ATTRIB(XonoticSkinList, columnNameOrigin, float, 0)
+	ATTRIB(XonoticSkinList, columnNameSize, float, 0)
+	ATTRIB(XonoticSkinList, realUpperMargin1, float, 0)
+	ATTRIB(XonoticSkinList, realUpperMargin2, float, 0)
+	ATTRIB(XonoticSkinList, origin, vector, '0 0 0')
+	ATTRIB(XonoticSkinList, itemAbsSize, vector, '0 0 0')
+
+	ATTRIB(XonoticSkinList, name, string, "skinselector")
+ENDCLASS(XonoticSkinList)
+
+entity makeXonoticSkinList();
+void SetSkin_Click(entity btn, entity me);
diff --git a/qcsrc/menu/xonotic/slider.qc b/qcsrc/menu/xonotic/slider.qc
index 149544aa3..fc4228cf9 100644
--- a/qcsrc/menu/xonotic/slider.qc
+++ b/qcsrc/menu/xonotic/slider.qc
@@ -1,35 +1,5 @@
 #include "slider.qh"
-#ifndef SLIDER_H
-#define SLIDER_H
-#include "../item/slider.qc"
-CLASS(XonoticSlider, Slider)
-	METHOD(XonoticSlider, configureXonoticSlider, void(entity, float, float, float, string, string));
-	METHOD(XonoticSlider, setValue, void(entity, float));
-	METHOD(XonoticSlider, setValue_noAnim, void(entity, float));
-	ATTRIB(XonoticSlider, fontSize, float, SKINFONTSIZE_NORMAL)
-	ATTRIB(XonoticSlider, valueSpace, float, SKINWIDTH_SLIDERTEXT)
-	ATTRIB(XonoticSlider, image, string, SKINGFX_SLIDER)
-	ATTRIB(XonoticSlider, tolerance, vector, SKINTOLERANCE_SLIDER)
-	ATTRIB(XonoticSlider, align, float, 0.5)
-	ATTRIB(XonoticSlider, color, vector, SKINCOLOR_SLIDER_N)
-	ATTRIB(XonoticSlider, colorC, vector, SKINCOLOR_SLIDER_C)
-	ATTRIB(XonoticSlider, colorF, vector, SKINCOLOR_SLIDER_F)
-	ATTRIB(XonoticSlider, colorD, vector, SKINCOLOR_SLIDER_D)
-	ATTRIB(XonoticSlider, color2, vector, SKINCOLOR_SLIDER_S)
 
-	ATTRIB(XonoticSlider, cvarName, string, string_null)
-	METHOD(XonoticSlider, loadCvars, void(entity));
-	METHOD(XonoticSlider, saveCvars, void(entity));
-	ATTRIB(XonoticSlider, sendCvars, float, 0)
-
-	ATTRIB(XonoticSlider, alpha, float, SKINALPHA_TEXT)
-	ATTRIB(XonoticSlider, disabledAlpha, float, SKINALPHA_DISABLED)
-ENDCLASS(XonoticSlider)
-entity makeXonoticSlider_T(float, float, float, string, string theTooltip);
-entity makeXonoticSlider(float, float, float, string);
-#endif
-
-#ifdef IMPLEMENTATION
 entity makeXonoticSlider_T(float theValueMin, float theValueMax, float theValueStep, string theCvar, string theTooltip)
 {
 	entity me;
@@ -92,4 +62,3 @@ void XonoticSlider_saveCvars(entity me)
 
 	CheckSendCvars(me, me.cvarName);
 }
-#endif
diff --git a/qcsrc/menu/xonotic/slider.qh b/qcsrc/menu/xonotic/slider.qh
index 6f70f09be..17287c428 100644
--- a/qcsrc/menu/xonotic/slider.qh
+++ b/qcsrc/menu/xonotic/slider.qh
@@ -1 +1,28 @@
 #pragma once
+
+#include "../item/slider.qh"
+CLASS(XonoticSlider, Slider)
+	METHOD(XonoticSlider, configureXonoticSlider, void(entity, float, float, float, string, string));
+	METHOD(XonoticSlider, setValue, void(entity, float));
+	METHOD(XonoticSlider, setValue_noAnim, void(entity, float));
+	ATTRIB(XonoticSlider, fontSize, float, SKINFONTSIZE_NORMAL)
+	ATTRIB(XonoticSlider, valueSpace, float, SKINWIDTH_SLIDERTEXT)
+	ATTRIB(XonoticSlider, image, string, SKINGFX_SLIDER)
+	ATTRIB(XonoticSlider, tolerance, vector, SKINTOLERANCE_SLIDER)
+	ATTRIB(XonoticSlider, align, float, 0.5)
+	ATTRIB(XonoticSlider, color, vector, SKINCOLOR_SLIDER_N)
+	ATTRIB(XonoticSlider, colorC, vector, SKINCOLOR_SLIDER_C)
+	ATTRIB(XonoticSlider, colorF, vector, SKINCOLOR_SLIDER_F)
+	ATTRIB(XonoticSlider, colorD, vector, SKINCOLOR_SLIDER_D)
+	ATTRIB(XonoticSlider, color2, vector, SKINCOLOR_SLIDER_S)
+
+	ATTRIB(XonoticSlider, cvarName, string, string_null)
+	METHOD(XonoticSlider, loadCvars, void(entity));
+	METHOD(XonoticSlider, saveCvars, void(entity));
+	ATTRIB(XonoticSlider, sendCvars, float, 0)
+
+	ATTRIB(XonoticSlider, alpha, float, SKINALPHA_TEXT)
+	ATTRIB(XonoticSlider, disabledAlpha, float, SKINALPHA_DISABLED)
+ENDCLASS(XonoticSlider)
+entity makeXonoticSlider_T(float, float, float, string, string theTooltip);
+entity makeXonoticSlider(float, float, float, string);
diff --git a/qcsrc/menu/xonotic/slider_decibels.qc b/qcsrc/menu/xonotic/slider_decibels.qc
index 345acf2b0..2b7814138 100644
--- a/qcsrc/menu/xonotic/slider_decibels.qc
+++ b/qcsrc/menu/xonotic/slider_decibels.qc
@@ -1,17 +1,4 @@
 #include "slider_decibels.qh"
-#ifndef SLIDER_DECIBELS_H
-#define SLIDER_DECIBELS_H
-#include "slider.qc"
-CLASS(XonoticDecibelsSlider, XonoticSlider)
-	METHOD(XonoticDecibelsSlider, loadCvars, void(entity));
-	METHOD(XonoticDecibelsSlider, saveCvars, void(entity));
-	METHOD(XonoticDecibelsSlider, valueToText, string(entity, float));
-ENDCLASS(XonoticDecibelsSlider)
-entity makeXonoticDecibelsSlider_T(float, float, float, string, string);
-entity makeXonoticDecibelsSlider(float, float, float, string);
-#endif
-
-#ifdef IMPLEMENTATION
 
 float toDecibelOfSquare(float f, float mi)
 {
@@ -110,5 +97,3 @@ TEST(XonoticDecibelsSlider, SoundTest)
 	}
 	SUCCEED();
 }
-
-#endif
diff --git a/qcsrc/menu/xonotic/slider_decibels.qh b/qcsrc/menu/xonotic/slider_decibels.qh
index 6f70f09be..887b58d24 100644
--- a/qcsrc/menu/xonotic/slider_decibels.qh
+++ b/qcsrc/menu/xonotic/slider_decibels.qh
@@ -1 +1,10 @@
 #pragma once
+
+#include "slider.qh"
+CLASS(XonoticDecibelsSlider, XonoticSlider)
+	METHOD(XonoticDecibelsSlider, loadCvars, void(entity));
+	METHOD(XonoticDecibelsSlider, saveCvars, void(entity));
+	METHOD(XonoticDecibelsSlider, valueToText, string(entity, float));
+ENDCLASS(XonoticDecibelsSlider)
+entity makeXonoticDecibelsSlider_T(float, float, float, string, string);
+entity makeXonoticDecibelsSlider(float, float, float, string);
diff --git a/qcsrc/menu/xonotic/slider_particles.qc b/qcsrc/menu/xonotic/slider_particles.qc
index 22fee95fa..e5982715e 100644
--- a/qcsrc/menu/xonotic/slider_particles.qc
+++ b/qcsrc/menu/xonotic/slider_particles.qc
@@ -1,16 +1,5 @@
 #include "slider_particles.qh"
-#ifndef SLIDER_PARTICLES_H
-#define SLIDER_PARTICLES_H
-#include "textslider.qc"
-CLASS(XonoticParticlesSlider, XonoticTextSlider)
-	METHOD(XonoticParticlesSlider, configureXonoticParticlesSlider, void(entity));
-	METHOD(XonoticParticlesSlider, loadCvars, void(entity));
-	METHOD(XonoticParticlesSlider, saveCvars, void(entity));
-ENDCLASS(XonoticParticlesSlider)
-entity makeXonoticParticlesSlider();
-#endif
 
-#ifdef IMPLEMENTATION
 entity makeXonoticParticlesSlider()
 {
 	entity me;
@@ -49,4 +38,3 @@ void XonoticParticlesSlider_saveCvars(entity me)
 		cvar_set("cl_damageeffect", argv(2));
 	}
 }
-#endif
diff --git a/qcsrc/menu/xonotic/slider_particles.qh b/qcsrc/menu/xonotic/slider_particles.qh
index 6f70f09be..47c1bff24 100644
--- a/qcsrc/menu/xonotic/slider_particles.qh
+++ b/qcsrc/menu/xonotic/slider_particles.qh
@@ -1 +1,9 @@
 #pragma once
+
+#include "textslider.qh"
+CLASS(XonoticParticlesSlider, XonoticTextSlider)
+	METHOD(XonoticParticlesSlider, configureXonoticParticlesSlider, void(entity));
+	METHOD(XonoticParticlesSlider, loadCvars, void(entity));
+	METHOD(XonoticParticlesSlider, saveCvars, void(entity));
+ENDCLASS(XonoticParticlesSlider)
+entity makeXonoticParticlesSlider();
diff --git a/qcsrc/menu/xonotic/slider_picmip.qc b/qcsrc/menu/xonotic/slider_picmip.qc
index 35c7ab7cb..226f4559c 100644
--- a/qcsrc/menu/xonotic/slider_picmip.qc
+++ b/qcsrc/menu/xonotic/slider_picmip.qc
@@ -1,17 +1,5 @@
 #include "slider_picmip.qh"
-#ifndef SLIDER_PICMIP_H
-#define SLIDER_PICMIP_H
-#include "textslider.qc"
-CLASS(XonoticPicmipSlider, XonoticTextSlider)
-	METHOD(XonoticPicmipSlider, configureXonoticPicmipSlider, void(entity));
-	METHOD(XonoticPicmipSlider, draw, void(entity));
-	METHOD(XonoticPicmipSlider, autofix, void(entity));
-	ATTRIB(XonoticPicmipSlider, have_s3tc, float, 0)
-ENDCLASS(XonoticPicmipSlider)
-entity makeXonoticPicmipSlider(); // note: you still need to call addValue and configureXonoticTextSliderValues!
-#endif
 
-#ifdef IMPLEMENTATION
 entity makeXonoticPicmipSlider()
 {
 	entity me;
@@ -54,4 +42,3 @@ void XonoticPicmipSlider_draw(entity me)
 	me.autofix(me);
 	SUPER(XonoticPicmipSlider).draw(me);
 }
-#endif
diff --git a/qcsrc/menu/xonotic/slider_picmip.qh b/qcsrc/menu/xonotic/slider_picmip.qh
index 6f70f09be..d25ba994b 100644
--- a/qcsrc/menu/xonotic/slider_picmip.qh
+++ b/qcsrc/menu/xonotic/slider_picmip.qh
@@ -1 +1,10 @@
 #pragma once
+
+#include "textslider.qh"
+CLASS(XonoticPicmipSlider, XonoticTextSlider)
+	METHOD(XonoticPicmipSlider, configureXonoticPicmipSlider, void(entity));
+	METHOD(XonoticPicmipSlider, draw, void(entity));
+	METHOD(XonoticPicmipSlider, autofix, void(entity));
+	ATTRIB(XonoticPicmipSlider, have_s3tc, float, 0)
+ENDCLASS(XonoticPicmipSlider)
+entity makeXonoticPicmipSlider();  // note: you still need to call addValue and configureXonoticTextSliderValues!
diff --git a/qcsrc/menu/xonotic/slider_resolution.qc b/qcsrc/menu/xonotic/slider_resolution.qc
index bfafaf2c4..762b216f9 100644
--- a/qcsrc/menu/xonotic/slider_resolution.qc
+++ b/qcsrc/menu/xonotic/slider_resolution.qc
@@ -1,23 +1,4 @@
 #include "slider_resolution.qh"
-#ifndef SLIDER_RESOLUTION_H
-#define SLIDER_RESOLUTION_H
-#include "textslider.qc"
-CLASS(XonoticResolutionSlider, XonoticTextSlider)
-	METHOD(XonoticResolutionSlider, configureXonoticResolutionSlider, void(entity));
-	METHOD(XonoticResolutionSlider, loadResolutions, void(entity, float));
-	METHOD(XonoticResolutionSlider, addResolution, void(entity, float, float, float));
-	METHOD(XonoticResolutionSlider, loadCvars, void(entity));
-	METHOD(XonoticResolutionSlider, saveCvars, void(entity));
-	METHOD(XonoticResolutionSlider, draw, void(entity));
-	ATTRIB(XonoticResolutionSlider, vid_fullscreen, float, -1)
-	ATTRIB(XonoticResolutionSlider, maxAllowedWidth, float, 0)
-	ATTRIB(XonoticResolutionSlider, maxAllowedHeight, float, 0)
-ENDCLASS(XonoticResolutionSlider)
-entity makeXonoticResolutionSlider();
-float updateConwidths(float width, float height, float pixelheight);
-#endif
-
-#ifdef IMPLEMENTATION
 
 /* private static */ float XonoticResolutionSlider_DataHasChanged;
 
@@ -244,4 +225,3 @@ void XonoticResolutionSlider_draw(entity me)
 	}
 	SUPER(XonoticResolutionSlider).draw(me);
 }
-#endif
diff --git a/qcsrc/menu/xonotic/slider_resolution.qh b/qcsrc/menu/xonotic/slider_resolution.qh
index 6f70f09be..40b7bbbc2 100644
--- a/qcsrc/menu/xonotic/slider_resolution.qh
+++ b/qcsrc/menu/xonotic/slider_resolution.qh
@@ -1 +1,16 @@
 #pragma once
+
+#include "textslider.qh"
+CLASS(XonoticResolutionSlider, XonoticTextSlider)
+	METHOD(XonoticResolutionSlider, configureXonoticResolutionSlider, void(entity));
+	METHOD(XonoticResolutionSlider, loadResolutions, void(entity, float));
+	METHOD(XonoticResolutionSlider, addResolution, void(entity, float, float, float));
+	METHOD(XonoticResolutionSlider, loadCvars, void(entity));
+	METHOD(XonoticResolutionSlider, saveCvars, void(entity));
+	METHOD(XonoticResolutionSlider, draw, void(entity));
+	ATTRIB(XonoticResolutionSlider, vid_fullscreen, float, -1)
+	ATTRIB(XonoticResolutionSlider, maxAllowedWidth, float, 0)
+	ATTRIB(XonoticResolutionSlider, maxAllowedHeight, float, 0)
+ENDCLASS(XonoticResolutionSlider)
+entity makeXonoticResolutionSlider();
+float updateConwidths(float width, float height, float pixelheight);
diff --git a/qcsrc/menu/xonotic/slider_sbfadetime.qc b/qcsrc/menu/xonotic/slider_sbfadetime.qc
index 386af7909..1e4bdbca2 100644
--- a/qcsrc/menu/xonotic/slider_sbfadetime.qc
+++ b/qcsrc/menu/xonotic/slider_sbfadetime.qc
@@ -1,16 +1,5 @@
 #include "slider_sbfadetime.qh"
-#ifndef SLIDER_SBFADETIME_H
-#define SLIDER_SBFADETIME_H
-#include "textslider.qc"
-CLASS(XonoticScoreboardFadeTimeSlider, XonoticTextSlider)
-	METHOD(XonoticScoreboardFadeTimeSlider, configureXonoticScoreboardFadeTimeSlider, void(entity));
-	METHOD(XonoticScoreboardFadeTimeSlider, loadCvars, void(entity));
-	METHOD(XonoticScoreboardFadeTimeSlider, saveCvars, void(entity));
-ENDCLASS(XonoticScoreboardFadeTimeSlider)
-entity makeXonoticScoreboardFadeTimeSlider();
-#endif
 
-#ifdef IMPLEMENTATION
 entity makeXonoticScoreboardFadeTimeSlider()
 {
 	entity me;
@@ -43,4 +32,3 @@ void XonoticScoreboardFadeTimeSlider_saveCvars(entity me)
 		cvar_set("scoreboard_fadeoutspeed", argv(1));
 	}
 }
-#endif
diff --git a/qcsrc/menu/xonotic/slider_sbfadetime.qh b/qcsrc/menu/xonotic/slider_sbfadetime.qh
index 6f70f09be..5597acc1b 100644
--- a/qcsrc/menu/xonotic/slider_sbfadetime.qh
+++ b/qcsrc/menu/xonotic/slider_sbfadetime.qh
@@ -1 +1,9 @@
 #pragma once
+
+#include "textslider.qh"
+CLASS(XonoticScoreboardFadeTimeSlider, XonoticTextSlider)
+	METHOD(XonoticScoreboardFadeTimeSlider, configureXonoticScoreboardFadeTimeSlider, void(entity));
+	METHOD(XonoticScoreboardFadeTimeSlider, loadCvars, void(entity));
+	METHOD(XonoticScoreboardFadeTimeSlider, saveCvars, void(entity));
+ENDCLASS(XonoticScoreboardFadeTimeSlider)
+entity makeXonoticScoreboardFadeTimeSlider();
diff --git a/qcsrc/menu/xonotic/soundlist.qc b/qcsrc/menu/xonotic/soundlist.qc
index 0dd568fef..13e6ba34c 100644
--- a/qcsrc/menu/xonotic/soundlist.qc
+++ b/qcsrc/menu/xonotic/soundlist.qc
@@ -1,42 +1,7 @@
 #include "soundlist.qh"
-#ifndef SOUNDLIST_H
-#define SOUNDLIST_H
-#include "listbox.qc"
-CLASS(XonoticSoundList, XonoticListBox)
-	METHOD(XonoticSoundList, configureXonoticSoundList, void(entity));
-	ATTRIB(XonoticSoundList, rowsPerItem, float, 1)
-	METHOD(XonoticSoundList, resizeNotify, void(entity, vector, vector, vector, vector));
-	METHOD(XonoticSoundList, drawListBoxItem, void(entity, int, vector, bool, bool));
-	METHOD(XonoticSoundList, getSounds, void(entity));
-	METHOD(XonoticSoundList, soundName, string(entity, int));
-	METHOD(XonoticSoundList, doubleClickListBoxItem, void(entity, int, vector));
-	METHOD(XonoticSoundList, keyDown, float(entity, float, float, float));
-	METHOD(XonoticSoundList, destroy, void(entity));
-	METHOD(XonoticSoundList, showNotify, void(entity));
-
-	ATTRIB(XonoticSoundList, listSound, int, -1)
-	ATTRIB(XonoticSoundList, realFontSize, vector, '0 0 0')
-	ATTRIB(XonoticSoundList, columnNameOrigin, float, 0)
-	ATTRIB(XonoticSoundList, columnNameSize, float, 0)
-	ATTRIB(XonoticSoundList, columnNumberOrigin, float, 0)
-	ATTRIB(XonoticSoundList, columnNumberSize, float, 0)
-	ATTRIB(XonoticSoundList, realUpperMargin, float, 0)
-	ATTRIB(XonoticSoundList, origin, vector, '0 0 0')
-	ATTRIB(XonoticSoundList, itemAbsSize, vector, '0 0 0')
-
-	ATTRIB(XonoticSoundList, filterString, string, string_null)
-	ATTRIB(XonoticSoundList, playlist, entity, NULL)
-ENDCLASS(XonoticSoundList)
-
-entity makeXonoticSoundList();
-void SoundList_Filter_Change(entity box, entity me);
-void SoundList_Add(entity box, entity me);
-void SoundList_Add_All(entity box, entity me);
-void SoundList_Menu_Track_Change(entity box, entity me);
-void SoundList_Menu_Track_Reset(entity box, entity me);
-#endif
-
-#ifdef IMPLEMENTATION
+
+#include "inputbox.qh"
+#include "playlist.qh"
 
 entity makeXonoticSoundList()
 {
@@ -176,5 +141,3 @@ float XonoticSoundList_keyDown(entity me, float scan, float ascii, float shift)
 	else
 		return SUPER(XonoticSoundList).keyDown(me, scan, ascii, shift);
 }
-#endif
-
diff --git a/qcsrc/menu/xonotic/soundlist.qh b/qcsrc/menu/xonotic/soundlist.qh
index 6f70f09be..86dc4c773 100644
--- a/qcsrc/menu/xonotic/soundlist.qh
+++ b/qcsrc/menu/xonotic/soundlist.qh
@@ -1 +1,35 @@
 #pragma once
+
+#include "listbox.qh"
+CLASS(XonoticSoundList, XonoticListBox)
+	METHOD(XonoticSoundList, configureXonoticSoundList, void(entity));
+	ATTRIB(XonoticSoundList, rowsPerItem, float, 1)
+	METHOD(XonoticSoundList, resizeNotify, void(entity, vector, vector, vector, vector));
+	METHOD(XonoticSoundList, drawListBoxItem, void(entity, int, vector, bool, bool));
+	METHOD(XonoticSoundList, getSounds, void(entity));
+	METHOD(XonoticSoundList, soundName, string(entity, int));
+	METHOD(XonoticSoundList, doubleClickListBoxItem, void(entity, int, vector));
+	METHOD(XonoticSoundList, keyDown, float(entity, float, float, float));
+	METHOD(XonoticSoundList, destroy, void(entity));
+	METHOD(XonoticSoundList, showNotify, void(entity));
+
+	ATTRIB(XonoticSoundList, listSound, int, -1)
+	ATTRIB(XonoticSoundList, realFontSize, vector, '0 0 0')
+	ATTRIB(XonoticSoundList, columnNameOrigin, float, 0)
+	ATTRIB(XonoticSoundList, columnNameSize, float, 0)
+	ATTRIB(XonoticSoundList, columnNumberOrigin, float, 0)
+	ATTRIB(XonoticSoundList, columnNumberSize, float, 0)
+	ATTRIB(XonoticSoundList, realUpperMargin, float, 0)
+	ATTRIB(XonoticSoundList, origin, vector, '0 0 0')
+	ATTRIB(XonoticSoundList, itemAbsSize, vector, '0 0 0')
+
+	ATTRIB(XonoticSoundList, filterString, string, string_null)
+	ATTRIB(XonoticSoundList, playlist, entity, NULL)
+ENDCLASS(XonoticSoundList)
+
+entity makeXonoticSoundList();
+void SoundList_Filter_Change(entity box, entity me);
+void SoundList_Add(entity box, entity me);
+void SoundList_Add_All(entity box, entity me);
+void SoundList_Menu_Track_Change(entity box, entity me);
+void SoundList_Menu_Track_Reset(entity box, entity me);
diff --git a/qcsrc/menu/xonotic/statslist.qc b/qcsrc/menu/xonotic/statslist.qc
index b8ced9010..7fdbf9c16 100644
--- a/qcsrc/menu/xonotic/statslist.qc
+++ b/qcsrc/menu/xonotic/statslist.qc
@@ -1,37 +1,6 @@
 #include "statslist.qh"
 #include <common/playerstats.qh>
 
-#ifndef STATSLIST_H
-#define STATSLIST_H
-#include "listbox.qc"
-CLASS(XonoticStatsList, XonoticListBox)
-	METHOD(XonoticStatsList, configureXonoticStatsList, void(entity));
-	ATTRIB(XonoticStatsList, rowsPerItem, float, 1.4)
-	METHOD(XonoticStatsList, resizeNotify, void(entity, vector, vector, vector, vector));
-	METHOD(XonoticStatsList, drawListBoxItem, void(entity, int, vector, bool, bool));
-	METHOD(XonoticStatsList, getStats, void(entity));
-	METHOD(XonoticStatsList, doubleClickListBoxItem, void(entity, float, vector));
-	METHOD(XonoticStatsList, keyDown, float(entity, float, float, float));
-	METHOD(XonoticStatsList, destroy, void(entity));
-	METHOD(XonoticStatsList, showNotify, void(entity));
-	ATTRIB(XonoticStatsList, selectionDoesntMatter, bool, true)
-
-	ATTRIB(XonoticStatsList, listStats, float, -1)
-	ATTRIB(XonoticStatsList, realFontSize, vector, '0 0 0')
-	ATTRIB(XonoticStatsList, realUpperMargin, float, 0)
-	ATTRIB(XonoticStatsList, columnNameOrigin, float, 0)
-	ATTRIB(XonoticStatsList, columnNameSize, float, 0)
-ENDCLASS(XonoticStatsList)
-
-#ifndef IMPLEMENTATION
-// public:
-entity statslist; // for reference elsewhere
-#endif
-entity makeXonoticStatsList();
-#endif
-
-#ifdef IMPLEMENTATION
-
 entity makeXonoticStatsList()
 {
 	entity me;
@@ -359,5 +328,3 @@ float XonoticStatsList_keyDown(entity me, float scan, float ascii, float shift)
 		return SUPER(XonoticStatsList).keyDown(me, scan, ascii, shift);
 	}
 }
-#endif
-
diff --git a/qcsrc/menu/xonotic/statslist.qh b/qcsrc/menu/xonotic/statslist.qh
index 6f70f09be..ebef28ac0 100644
--- a/qcsrc/menu/xonotic/statslist.qh
+++ b/qcsrc/menu/xonotic/statslist.qh
@@ -1 +1,24 @@
 #pragma once
+
+#include "listbox.qh"
+CLASS(XonoticStatsList, XonoticListBox)
+	METHOD(XonoticStatsList, configureXonoticStatsList, void(entity));
+	ATTRIB(XonoticStatsList, rowsPerItem, float, 1.4)
+	METHOD(XonoticStatsList, resizeNotify, void(entity, vector, vector, vector, vector));
+	METHOD(XonoticStatsList, drawListBoxItem, void(entity, int, vector, bool, bool));
+	METHOD(XonoticStatsList, getStats, void(entity));
+	METHOD(XonoticStatsList, doubleClickListBoxItem, void(entity, float, vector));
+	METHOD(XonoticStatsList, keyDown, float(entity, float, float, float));
+	METHOD(XonoticStatsList, destroy, void(entity));
+	METHOD(XonoticStatsList, showNotify, void(entity));
+	ATTRIB(XonoticStatsList, selectionDoesntMatter, bool, true)
+
+	ATTRIB(XonoticStatsList, listStats, float, -1)
+	ATTRIB(XonoticStatsList, realFontSize, vector, '0 0 0')
+	ATTRIB(XonoticStatsList, realUpperMargin, float, 0)
+	ATTRIB(XonoticStatsList, columnNameOrigin, float, 0)
+	ATTRIB(XonoticStatsList, columnNameSize, float, 0)
+ENDCLASS(XonoticStatsList)
+
+entity statslist;  // for reference elsewhere
+entity makeXonoticStatsList();
diff --git a/qcsrc/menu/xonotic/tab.qc b/qcsrc/menu/xonotic/tab.qc
index adcdd0bc7..9c5bcce8d 100644
--- a/qcsrc/menu/xonotic/tab.qc
+++ b/qcsrc/menu/xonotic/tab.qc
@@ -1,32 +1,7 @@
 #include "tab.qh"
-#ifndef TAB_H
-#define TAB_H
-#include "../item/tab.qc"
-CLASS(XonoticTab, Tab)
-	// still to be customized by user
-	/*
-	ATTRIB(XonoticTab, intendedWidth, float, 0)
-	ATTRIB(XonoticTab, rows, float, 3)
-	ATTRIB(XonoticTab, columns, float, 2)
-	*/
-	METHOD(XonoticTab, showNotify, void(entity));
 
-	ATTRIB(XonoticTab, marginTop, float, 0) // pixels
-	ATTRIB(XonoticTab, marginBottom, float, 0) // pixels
-	ATTRIB(XonoticTab, marginLeft, float, 0) // pixels
-	ATTRIB(XonoticTab, marginRight, float, 0) // pixels
-	ATTRIB(XonoticTab, columnSpacing, float, SKINMARGIN_COLUMNS) // pixels
-	ATTRIB(XonoticTab, rowSpacing, float, SKINMARGIN_ROWS) // pixels
-	ATTRIB(XonoticTab, rowHeight, float, SKINFONTSIZE_NORMAL * SKINHEIGHT_NORMAL) // pixels
-
-	ATTRIB(XonoticTab, backgroundImage, string, string_null)
-ENDCLASS(XonoticTab)
-#endif
-
-#ifdef IMPLEMENTATION
 void XonoticTab_showNotify(entity me)
 {
 	loadAllCvars(me);
 	SUPER(XonoticTab).showNotify(me);
 }
-#endif
diff --git a/qcsrc/menu/xonotic/tab.qh b/qcsrc/menu/xonotic/tab.qh
index 6f70f09be..26fe898bb 100644
--- a/qcsrc/menu/xonotic/tab.qh
+++ b/qcsrc/menu/xonotic/tab.qh
@@ -1 +1,22 @@
 #pragma once
+
+#include "../item/tab.qh"
+CLASS(XonoticTab, Tab)
+	// still to be customized by user
+	/*
+	ATTRIB(XonoticTab, intendedWidth, float, 0)
+	ATTRIB(XonoticTab, rows, float, 3)
+	ATTRIB(XonoticTab, columns, float, 2)
+	*/
+	METHOD(XonoticTab, showNotify, void(entity));
+
+	ATTRIB(XonoticTab, marginTop, float, 0)                                       // pixels
+	ATTRIB(XonoticTab, marginBottom, float, 0)                                    // pixels
+	ATTRIB(XonoticTab, marginLeft, float, 0)                                      // pixels
+	ATTRIB(XonoticTab, marginRight, float, 0)                                     // pixels
+	ATTRIB(XonoticTab, columnSpacing, float, SKINMARGIN_COLUMNS)                  // pixels
+	ATTRIB(XonoticTab, rowSpacing, float, SKINMARGIN_ROWS)                        // pixels
+	ATTRIB(XonoticTab, rowHeight, float, SKINFONTSIZE_NORMAL * SKINHEIGHT_NORMAL) // pixels
+
+	ATTRIB(XonoticTab, backgroundImage, string, string_null)
+ENDCLASS(XonoticTab)
diff --git a/qcsrc/menu/xonotic/tabcontroller.qc b/qcsrc/menu/xonotic/tabcontroller.qc
index b0f4fff30..fe6941723 100644
--- a/qcsrc/menu/xonotic/tabcontroller.qc
+++ b/qcsrc/menu/xonotic/tabcontroller.qc
@@ -1,19 +1,7 @@
 #include "tabcontroller.qh"
-#ifndef TABCONTROLLER_H
-#define TABCONTROLLER_H
-#include "../item/modalcontroller.qc"
-CLASS(XonoticTabController, ModalController)
-	METHOD(XonoticTabController, configureXonoticTabController, void(entity, float));
-	METHOD(XonoticTabController, makeTabButton_T, entity(entity, string, entity, string));
-	METHOD(XonoticTabController, makeTabButton, entity(entity, string, entity));
-	ATTRIB(XonoticTabController, rows, float, 0)
-	ATTRIB(XonoticTabController, fontSize, float, SKINFONTSIZE_NORMAL)
-	ATTRIB(XonoticTabController, image, string, SKINGFX_BUTTON)
-ENDCLASS(XonoticTabController)
-entity makeXonoticTabController(float theRows);
-#endif
 
-#ifdef IMPLEMENTATION
+#include "button.qh"
+
 entity makeXonoticTabController(float theRows)
 {
 	entity me;
@@ -39,4 +27,3 @@ entity XonoticTabController_makeTabButton(entity me, string theTitle, entity tab
 {
 	return XonoticTabController_makeTabButton_T(me, theTitle, tab, string_null);
 }
-#endif
diff --git a/qcsrc/menu/xonotic/tabcontroller.qh b/qcsrc/menu/xonotic/tabcontroller.qh
index 6f70f09be..eb4d48f8d 100644
--- a/qcsrc/menu/xonotic/tabcontroller.qh
+++ b/qcsrc/menu/xonotic/tabcontroller.qh
@@ -1 +1,12 @@
 #pragma once
+
+#include "../item/modalcontroller.qh"
+CLASS(XonoticTabController, ModalController)
+	METHOD(XonoticTabController, configureXonoticTabController, void(entity, float));
+	METHOD(XonoticTabController, makeTabButton_T, entity(entity, string, entity, string));
+	METHOD(XonoticTabController, makeTabButton, entity(entity, string, entity));
+	ATTRIB(XonoticTabController, rows, float, 0)
+	ATTRIB(XonoticTabController, fontSize, float, SKINFONTSIZE_NORMAL)
+	ATTRIB(XonoticTabController, image, string, SKINGFX_BUTTON)
+ENDCLASS(XonoticTabController)
+entity makeXonoticTabController(float theRows);
diff --git a/qcsrc/menu/xonotic/textlabel.qc b/qcsrc/menu/xonotic/textlabel.qc
index fa7751f3a..9af676ecf 100644
--- a/qcsrc/menu/xonotic/textlabel.qc
+++ b/qcsrc/menu/xonotic/textlabel.qc
@@ -1,19 +1,5 @@
 #include "textlabel.qh"
-#ifndef TEXTLABEL_H
-#define TEXTLABEL_H
-#include "../item/label.qc"
-CLASS(XonoticTextLabel, Label)
-	METHOD(XonoticTextLabel, configureXonoticTextLabel, void(entity, float, string));
-	METHOD(XonoticTextLabel, draw, void(entity));
-	ATTRIB(XonoticTextLabel, fontSize, float, SKINFONTSIZE_NORMAL)
-	ATTRIB(XonoticTextLabel, alpha, float, SKINALPHA_TEXT)
-	ATTRIB(XonoticTextLabel, disabledAlpha, float, SKINALPHA_DISABLED)
-ENDCLASS(XonoticTextLabel)
-entity makeXonoticTextLabel(float theAlign, string theText);
-entity makeXonoticHeaderLabel(string theText);
-#endif
 
-#ifdef IMPLEMENTATION
 entity makeXonoticTextLabel(float theAlign, string theText)
 {
 	entity me;
@@ -38,4 +24,3 @@ void XonoticTextLabel_draw(entity me)
 {
 	SUPER(XonoticTextLabel).draw(me);
 }
-#endif
diff --git a/qcsrc/menu/xonotic/textlabel.qh b/qcsrc/menu/xonotic/textlabel.qh
index 6f70f09be..fde05de8a 100644
--- a/qcsrc/menu/xonotic/textlabel.qh
+++ b/qcsrc/menu/xonotic/textlabel.qh
@@ -1 +1,12 @@
 #pragma once
+
+#include "../item/label.qh"
+CLASS(XonoticTextLabel, Label)
+	METHOD(XonoticTextLabel, configureXonoticTextLabel, void(entity, float, string));
+	METHOD(XonoticTextLabel, draw, void(entity));
+	ATTRIB(XonoticTextLabel, fontSize, float, SKINFONTSIZE_NORMAL)
+	ATTRIB(XonoticTextLabel, alpha, float, SKINALPHA_TEXT)
+	ATTRIB(XonoticTextLabel, disabledAlpha, float, SKINALPHA_DISABLED)
+ENDCLASS(XonoticTextLabel)
+entity makeXonoticTextLabel(float theAlign, string theText);
+entity makeXonoticHeaderLabel(string theText);
diff --git a/qcsrc/menu/xonotic/textslider.qc b/qcsrc/menu/xonotic/textslider.qc
index 40023e436..54c7e5fb1 100644
--- a/qcsrc/menu/xonotic/textslider.qc
+++ b/qcsrc/menu/xonotic/textslider.qc
@@ -1,36 +1,5 @@
 #include "textslider.qh"
-#ifndef TEXTSLIDER_H
-#define TEXTSLIDER_H
-#include "../item/textslider.qc"
-CLASS(XonoticTextSlider, TextSlider)
-	METHOD(XonoticTextSlider, configureXonoticTextSlider, void(entity, string, string));
-	METHOD(XonoticTextSlider, setValue, void(entity, float));
-	METHOD(XonoticTextSlider, setValue_noAnim, void(entity, float));
-	METHOD(XonoticTextSlider, configureXonoticTextSliderValues, void(entity));
-	ATTRIB(XonoticTextSlider, fontSize, float, SKINFONTSIZE_NORMAL)
-	ATTRIB(XonoticTextSlider, valueSpace, float, SKINWIDTH_SLIDERTEXT)
-	ATTRIB(XonoticTextSlider, image, string, SKINGFX_SLIDER)
-	ATTRIB(XonoticTextSlider, tolerance, vector, SKINTOLERANCE_SLIDER)
-	ATTRIB(XonoticTextSlider, align, float, 0.5)
-	ATTRIB(XonoticTextSlider, color, vector, SKINCOLOR_SLIDER_N)
-	ATTRIB(XonoticTextSlider, colorC, vector, SKINCOLOR_SLIDER_C)
-	ATTRIB(XonoticTextSlider, colorF, vector, SKINCOLOR_SLIDER_F)
-	ATTRIB(XonoticTextSlider, colorD, vector, SKINCOLOR_SLIDER_D)
-	ATTRIB(XonoticTextSlider, color2, vector, SKINCOLOR_SLIDER_S)
 
-	ATTRIB(XonoticTextSlider, cvarName, string, string_null)
-	METHOD(XonoticTextSlider, loadCvars, void(entity));
-	METHOD(XonoticTextSlider, saveCvars, void(entity));
-	ATTRIB(XonoticTextSlider, sendCvars, float, 0)
-
-	ATTRIB(XonoticTextSlider, alpha, float, SKINALPHA_TEXT)
-	ATTRIB(XonoticTextSlider, disabledAlpha, float, SKINALPHA_DISABLED)
-ENDCLASS(XonoticTextSlider)
-entity makeXonoticTextSlider_T(string, string theTooltip);
-entity makeXonoticTextSlider(string); // note: you still need to call addValue and configureXonoticTextSliderValues!
-#endif
-
-#ifdef IMPLEMENTATION
 entity makeXonoticTextSlider_T(string theCvar, string theTooltip)
 {
 	entity me;
@@ -131,4 +100,3 @@ void XonoticTextSlider_configureXonoticTextSliderValues(entity me)
 	me.configureTextSliderValues(me, string_null);
 	me.loadCvars(me);
 }
-#endif
diff --git a/qcsrc/menu/xonotic/textslider.qh b/qcsrc/menu/xonotic/textslider.qh
index 6f70f09be..ae81f36e8 100644
--- a/qcsrc/menu/xonotic/textslider.qh
+++ b/qcsrc/menu/xonotic/textslider.qh
@@ -1 +1,29 @@
 #pragma once
+
+#include "../item/textslider.qh"
+CLASS(XonoticTextSlider, TextSlider)
+	METHOD(XonoticTextSlider, configureXonoticTextSlider, void(entity, string, string));
+	METHOD(XonoticTextSlider, setValue, void(entity, float));
+	METHOD(XonoticTextSlider, setValue_noAnim, void(entity, float));
+	METHOD(XonoticTextSlider, configureXonoticTextSliderValues, void(entity));
+	ATTRIB(XonoticTextSlider, fontSize, float, SKINFONTSIZE_NORMAL)
+	ATTRIB(XonoticTextSlider, valueSpace, float, SKINWIDTH_SLIDERTEXT)
+	ATTRIB(XonoticTextSlider, image, string, SKINGFX_SLIDER)
+	ATTRIB(XonoticTextSlider, tolerance, vector, SKINTOLERANCE_SLIDER)
+	ATTRIB(XonoticTextSlider, align, float, 0.5)
+	ATTRIB(XonoticTextSlider, color, vector, SKINCOLOR_SLIDER_N)
+	ATTRIB(XonoticTextSlider, colorC, vector, SKINCOLOR_SLIDER_C)
+	ATTRIB(XonoticTextSlider, colorF, vector, SKINCOLOR_SLIDER_F)
+	ATTRIB(XonoticTextSlider, colorD, vector, SKINCOLOR_SLIDER_D)
+	ATTRIB(XonoticTextSlider, color2, vector, SKINCOLOR_SLIDER_S)
+
+	ATTRIB(XonoticTextSlider, cvarName, string, string_null)
+	METHOD(XonoticTextSlider, loadCvars, void(entity));
+	METHOD(XonoticTextSlider, saveCvars, void(entity));
+	ATTRIB(XonoticTextSlider, sendCvars, float, 0)
+
+	ATTRIB(XonoticTextSlider, alpha, float, SKINALPHA_TEXT)
+	ATTRIB(XonoticTextSlider, disabledAlpha, float, SKINALPHA_DISABLED)
+ENDCLASS(XonoticTextSlider)
+entity makeXonoticTextSlider_T(string, string theTooltip);
+entity makeXonoticTextSlider(string);  // note: you still need to call addValue and configureXonoticTextSliderValues!
diff --git a/qcsrc/menu/xonotic/util.qc b/qcsrc/menu/xonotic/util.qc
index c2a53db93..4d704606d 100644
--- a/qcsrc/menu/xonotic/util.qc
+++ b/qcsrc/menu/xonotic/util.qc
@@ -1,6 +1,6 @@
 #include "util.qh"
 
-#include "../item.qc"
+#include "../item.qh"
 
 #include "../menu.qh"
 #include <common/campaign_common.qh>
diff --git a/qcsrc/menu/xonotic/weaponarenacheckbox.qc b/qcsrc/menu/xonotic/weaponarenacheckbox.qc
index 942b1a4cc..fd4f51385 100644
--- a/qcsrc/menu/xonotic/weaponarenacheckbox.qc
+++ b/qcsrc/menu/xonotic/weaponarenacheckbox.qc
@@ -1,21 +1,5 @@
 #include "weaponarenacheckbox.qh"
-#ifndef WEAPONARENACHECKBOX_H
-#define WEAPONARENACHECKBOX_H
-#include "../item/checkbox.qc"
-CLASS(XonoticWeaponarenaCheckBox, CheckBox)
-	METHOD(XonoticWeaponarenaCheckBox, configureXonoticWeaponarenaCheckBox, void(entity, string, string));
-	METHOD(XonoticWeaponarenaCheckBox, setChecked, void(entity, float));
-	ATTRIB(XonoticWeaponarenaCheckBox, fontSize, float, SKINFONTSIZE_NORMAL)
-	ATTRIB(XonoticWeaponarenaCheckBox, image, string, SKINGFX_CHECKBOX)
-	ATTRIB(XonoticWeaponarenaCheckBox, netname, string, string_null)
 
-	METHOD(XonoticWeaponarenaCheckBox, loadCvars, void(entity));
-	METHOD(XonoticWeaponarenaCheckBox, saveCvars, void(entity));
-ENDCLASS(XonoticWeaponarenaCheckBox)
-entity makeXonoticWeaponarenaCheckBox(string, string);
-#endif
-
-#ifdef IMPLEMENTATION
 entity makeXonoticWeaponarenaCheckBox(string theWeapon, string theText)
 {
 	entity me;
@@ -57,4 +41,3 @@ void XonoticWeaponarenaCheckBox_saveCvars(entity me)
 		localcmd(strcat("\nmenu_cmd removefromlist menu_weaponarena ", me.netname, "\n"));
 	localcmd("\ng_weaponarena \"$menu_weaponarena\"\n");
 }
-#endif
diff --git a/qcsrc/menu/xonotic/weaponarenacheckbox.qh b/qcsrc/menu/xonotic/weaponarenacheckbox.qh
index 6f70f09be..0b8e214c8 100644
--- a/qcsrc/menu/xonotic/weaponarenacheckbox.qh
+++ b/qcsrc/menu/xonotic/weaponarenacheckbox.qh
@@ -1 +1,14 @@
 #pragma once
+
+#include "../item/checkbox.qh"
+CLASS(XonoticWeaponarenaCheckBox, CheckBox)
+	METHOD(XonoticWeaponarenaCheckBox, configureXonoticWeaponarenaCheckBox, void(entity, string, string));
+	METHOD(XonoticWeaponarenaCheckBox, setChecked, void(entity, float));
+	ATTRIB(XonoticWeaponarenaCheckBox, fontSize, float, SKINFONTSIZE_NORMAL)
+	ATTRIB(XonoticWeaponarenaCheckBox, image, string, SKINGFX_CHECKBOX)
+	ATTRIB(XonoticWeaponarenaCheckBox, netname, string, string_null)
+
+	METHOD(XonoticWeaponarenaCheckBox, loadCvars, void(entity));
+	METHOD(XonoticWeaponarenaCheckBox, saveCvars, void(entity));
+ENDCLASS(XonoticWeaponarenaCheckBox)
+entity makeXonoticWeaponarenaCheckBox(string, string);
diff --git a/qcsrc/menu/xonotic/weaponslist.qc b/qcsrc/menu/xonotic/weaponslist.qc
index 2f0f5d822..ed74631de 100644
--- a/qcsrc/menu/xonotic/weaponslist.qc
+++ b/qcsrc/menu/xonotic/weaponslist.qc
@@ -1,27 +1,9 @@
 #include "weaponslist.qh"
-#ifndef WEAPONSLIST_H
-#define WEAPONSLIST_H
-#include "listbox.qc"
-CLASS(XonoticWeaponsList, XonoticListBox)
-	METHOD(XonoticWeaponsList, configureXonoticWeaponsList, void(entity));
-	METHOD(XonoticWeaponsList, toString, string(entity));
-	ATTRIB(XonoticWeaponsList, rowsPerItem, float, 1)
-	METHOD(XonoticWeaponsList, draw, void(entity));
-	METHOD(XonoticWeaponsList, drawListBoxItem, void(entity, int, vector, bool, bool));
-	METHOD(XonoticWeaponsList, resizeNotify, void(entity, vector, vector, vector, vector));
-	METHOD(XonoticWeaponsList, keyDown, float(entity, float, float, float));
-	ATTRIB(XonoticWeaponsList, realFontSize, vector, '0 0 0')
-	ATTRIB(XonoticWeaponsList, realUpperMargin, float, 0)
-	METHOD(XonoticWeaponsList, mouseDrag, float(entity, vector));
 
-	ATTRIB(XonoticWeaponsList, applyButton, entity, NULL)
-ENDCLASS(XonoticWeaponsList)
-entity makeXonoticWeaponsList();
-void WeaponsList_MoveUp_Click(entity btn, entity me);
-void WeaponsList_MoveDown_Click(entity box, entity me);
-#endif
+#include <common/weapons/all.qh>
+
+.bool disabled;
 
-#ifdef IMPLEMENTATION
 entity makeXonoticWeaponsList()
 {
 	entity me;
@@ -139,4 +121,3 @@ float XonoticWeaponsList_keyDown(entity me, float scan, float ascii, float shift
 		return 1;
 	return 0;
 }
-#endif
diff --git a/qcsrc/menu/xonotic/weaponslist.qh b/qcsrc/menu/xonotic/weaponslist.qh
index 6f70f09be..953a40cc0 100644
--- a/qcsrc/menu/xonotic/weaponslist.qh
+++ b/qcsrc/menu/xonotic/weaponslist.qh
@@ -1 +1,20 @@
 #pragma once
+
+#include "listbox.qh"
+CLASS(XonoticWeaponsList, XonoticListBox)
+	METHOD(XonoticWeaponsList, configureXonoticWeaponsList, void(entity));
+	METHOD(XonoticWeaponsList, toString, string(entity));
+	ATTRIB(XonoticWeaponsList, rowsPerItem, float, 1)
+	METHOD(XonoticWeaponsList, draw, void(entity));
+	METHOD(XonoticWeaponsList, drawListBoxItem, void(entity, int, vector, bool, bool));
+	METHOD(XonoticWeaponsList, resizeNotify, void(entity, vector, vector, vector, vector));
+	METHOD(XonoticWeaponsList, keyDown, float(entity, float, float, float));
+	ATTRIB(XonoticWeaponsList, realFontSize, vector, '0 0 0')
+	ATTRIB(XonoticWeaponsList, realUpperMargin, float, 0)
+	METHOD(XonoticWeaponsList, mouseDrag, float(entity, vector));
+
+	ATTRIB(XonoticWeaponsList, applyButton, entity, NULL)
+ENDCLASS(XonoticWeaponsList)
+entity makeXonoticWeaponsList();
+void WeaponsList_MoveUp_Click(entity btn, entity me);
+void WeaponsList_MoveDown_Click(entity box, entity me);
diff --git a/qcsrc/uncrustify.cfg b/qcsrc/uncrustify.cfg
index b09403f95..98cdab9dd 100644
--- a/qcsrc/uncrustify.cfg
+++ b/qcsrc/uncrustify.cfg
@@ -1815,7 +1815,6 @@ type .string
 
 # QC OO
 macro-open CLASS
-macro-else EXTENDS
 macro-close ENDCLASS
 
 # translations