VGUI: Redo the way input is handled, address focus changes between Windows etc.
This commit is contained in:
parent
5c5eedb665
commit
c1d6324153
2 changed files with 137 additions and 22 deletions
|
@ -53,6 +53,7 @@ Util_MouseAbove(vector vecMousePos, vector vecPos, vector vecSize)
|
|||
return (0);
|
||||
}
|
||||
|
||||
.bool isVGUI;
|
||||
/** @brief The base VGUI widget class.
|
||||
|
||||
Every VGUI widget is based off of this. */
|
||||
|
@ -62,7 +63,7 @@ public:
|
|||
void VGUIWidget(void);
|
||||
|
||||
/** Adds a widget into this one. */
|
||||
nonvirtual void Add(VGUIWidget);
|
||||
virtual void Add(VGUIWidget);
|
||||
/** Add a flag to the widget. */
|
||||
nonvirtual void FlagAdd(int);
|
||||
/** Remove a flag from the widget. */
|
||||
|
@ -116,6 +117,9 @@ public:
|
|||
/** Called when the size of the widget has changed in any capacity. */
|
||||
virtual void SizeChanged(vector, vector);
|
||||
|
||||
virtual void NowVisible(void);
|
||||
virtual void NowHidden(void);
|
||||
|
||||
/** Called in order to draw the widget. */
|
||||
virtual void Draw(void);
|
||||
/** Called whenever the physical properties of the display change. */
|
||||
|
@ -134,6 +138,7 @@ private:
|
|||
vector m_vecMaxSize;
|
||||
VGUIWidget m_next;
|
||||
VGUIWidget m_parent;
|
||||
VGUIWidget m_children;
|
||||
int m_iFlags;
|
||||
bool m_bVisible;
|
||||
VGUITheme m_theme;
|
||||
|
@ -150,6 +155,7 @@ VGUIWidget::VGUIWidget(void)
|
|||
m_parent = __NULL__;
|
||||
m_iFlags = 0i;
|
||||
m_bVisible = true;
|
||||
isVGUI = true;
|
||||
|
||||
Spawned();
|
||||
}
|
||||
|
@ -184,12 +190,26 @@ void
|
|||
VGUIWidget::Hide(void)
|
||||
{
|
||||
m_bVisible = false;
|
||||
NowHidden();
|
||||
}
|
||||
|
||||
void
|
||||
VGUIWidget::NowHidden(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
VGUIWidget::NowVisible(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
VGUIWidget::Show(void)
|
||||
{
|
||||
m_bVisible = true;
|
||||
NowVisible();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -343,38 +363,51 @@ bool
|
|||
VGUIWidget::Input(float flEVType, float flKey, float flChar, float flDevID)
|
||||
{
|
||||
VGUIWidget wNext = this;
|
||||
VGUIWidget wLast = __NULL__;
|
||||
VGUIWidget wLastBefore = __NULL__;
|
||||
|
||||
/* this is garbage, but it'll work */
|
||||
int c = 0;
|
||||
/* figure out the last window in the chain... */
|
||||
do {
|
||||
wLastBefore = wNext;
|
||||
wNext = wNext.m_next;
|
||||
c++;
|
||||
|
||||
if (wNext) {
|
||||
wLast = wNext;
|
||||
}
|
||||
} while (wNext);
|
||||
|
||||
/* we got the count of valid items */
|
||||
vgui_input_scene_t *tree = memalloc(sizeof(vgui_input_scene_t) * c);
|
||||
//print(sprintf("Last widget: %S\n", wLast.classname));
|
||||
|
||||
int i = 0;
|
||||
wNext = this;
|
||||
do {
|
||||
wNext = wNext.m_next;
|
||||
tree[i].member = wNext;
|
||||
i++;
|
||||
} while (wNext);
|
||||
/* we've found a window, let's test inputs backwards. */
|
||||
while (wLast.classname) {
|
||||
bool test = false;
|
||||
|
||||
/* traverse the list in reverse */
|
||||
for (int x = c-1; x >= 0; x--) {
|
||||
wNext = tree[x].member;
|
||||
if (wLast.Visible())
|
||||
test = wLast.Input(flEVType, flKey, flChar, flDevID);
|
||||
|
||||
if (wNext && wNext.Visible() && wNext.m_parent.Visible())
|
||||
if (wNext.Input(flEVType, flKey, flChar, flDevID) == true) {
|
||||
memfree(tree);
|
||||
return (true);
|
||||
//print(sprintf("Testing input for... widget: %S %d\n", wLast.classname, test));
|
||||
|
||||
/* input successful */
|
||||
if (test == true) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* select the former input */
|
||||
for (VGUIWidget a = this; a != __NULL__; a = a.m_next) {
|
||||
/* we've reached the end, take one from before */
|
||||
if (a == wLast) {
|
||||
wLast = wLastBefore;
|
||||
break;
|
||||
}
|
||||
wLastBefore = a;
|
||||
}
|
||||
|
||||
/* the end of the world. */
|
||||
if (wLast == this)
|
||||
return false;
|
||||
}
|
||||
|
||||
memfree(tree);
|
||||
return (false);
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -64,6 +64,9 @@ public:
|
|||
/** Called when the window has been repositioned by the user. */
|
||||
nonvirtual void CallOnMove(void(void) vFunc);
|
||||
|
||||
/** Will focus the window when called. */
|
||||
nonvirtual bool Focus(void);
|
||||
|
||||
/** Called when the VGUIWindow got moved successfully. */
|
||||
virtual void WindowDidMove(vector, vector);
|
||||
/** Called when the VGUIWindow got resized successfully. */
|
||||
|
@ -72,10 +75,12 @@ public:
|
|||
virtual void WindowDidClose(void);
|
||||
|
||||
/* overrides */
|
||||
virtual void Add(VGUIWidget);
|
||||
virtual void Draw(void);
|
||||
virtual void SizeChanged(vector, vector);
|
||||
virtual bool Input(float, float, float, float);
|
||||
virtual void Spawned(void);
|
||||
virtual void NowVisible();
|
||||
|
||||
private:
|
||||
vector m_vecColor;
|
||||
|
@ -96,6 +101,57 @@ VGUIWindow::VGUIWindow(void)
|
|||
m_styleMask = VGUIWindowStyleDefault;
|
||||
}
|
||||
|
||||
void
|
||||
VGUIWindow::NowVisible(void)
|
||||
{
|
||||
Focus();
|
||||
}
|
||||
|
||||
void
|
||||
VGUIWindow::Add(VGUIWidget wNew)
|
||||
{
|
||||
VGUIWidget wNext = this;
|
||||
VGUIWidget wParent;
|
||||
do {
|
||||
wParent = wNext;
|
||||
wNext = wNext.m_children;
|
||||
} while (wNext);
|
||||
wParent.m_children = wNew;
|
||||
wNew.m_parent = this;
|
||||
}
|
||||
|
||||
bool
|
||||
VGUIWindow::Focus(void)
|
||||
{
|
||||
VGUIWidget wLast = this;
|
||||
VGUIWidget wEdit = m_parent; /* start at parent */
|
||||
// error("Focusing!!!\n");
|
||||
|
||||
/* iterate through the main windows, we start at the parent of all windows... */
|
||||
do {
|
||||
//print(sprintf("At %S\n", wEdit.classname));
|
||||
wLast = wEdit;
|
||||
wEdit = wEdit.m_next; /* next window of parent */
|
||||
|
||||
/* skip over ourselves. */
|
||||
if (wEdit == this) {
|
||||
wEdit = this.m_next;
|
||||
wLast.m_next = this.m_next;
|
||||
// print("Skipping over ourselves...\n");
|
||||
//print(sprintf("At %S\n", wEdit.classname));
|
||||
}
|
||||
|
||||
/* if empty... mark ourselves as the last window */
|
||||
if (wEdit == __NULL__) {
|
||||
//print("Last window is us...\n");
|
||||
wLast.m_next = this;
|
||||
this.m_next = __NULL__;
|
||||
}
|
||||
} while (wEdit);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
VGUIWindow::SetStyleMask(vguiWindowStyle_t val)
|
||||
{
|
||||
|
@ -247,6 +303,16 @@ void VGUIWindow::Draw(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
VGUIWidget wNext = this;
|
||||
g_vguiWidgetCount = 0;
|
||||
do {
|
||||
wNext = wNext.m_children;
|
||||
if (wNext && wNext.Visible() && wNext.m_parent.Visible()) {
|
||||
g_vguiWidgetCount++;
|
||||
wNext.Draw();
|
||||
}
|
||||
} while (wNext);
|
||||
|
||||
#ifdef UI_DEVELOPER
|
||||
if (m_iFlags & WINDOW_DRAGGING) {
|
||||
Font_DrawText([8, video_res[1] - 18], sprintf("Window Position: %d, %d\n", m_vecOrigin[0], m_vecOrigin[1]), g_fntDefault);
|
||||
|
@ -265,9 +331,11 @@ bool VGUIWindow::Input (float flEVType, float flKey, float flChar, float flDevID
|
|||
if (flKey == K_MOUSE1) {
|
||||
if (m_styleMask & VGUIWindowResizeable && Util_MouseAbove(g_vecMousePos, m_vecOrigin + (m_vecSize - [16,16]), [16,16])) {
|
||||
m_iFlags |= WINDOW_RESIZING;
|
||||
return Focus();
|
||||
} else if (m_styleMask & VGUIWindowMovable && Util_MouseAbove(g_vecMousePos, m_vecOrigin, [m_vecSize[0] - 32, 16])) {
|
||||
m_iFlags |= WINDOW_DRAGGING;
|
||||
m_vecDragOffset = m_vecOrigin - g_vecMousePos;
|
||||
return Focus();
|
||||
}
|
||||
}
|
||||
} else if (flEVType == IE_KEYUP) {
|
||||
|
@ -300,5 +368,19 @@ bool VGUIWindow::Input (float flEVType, float flKey, float flChar, float flDevID
|
|||
}
|
||||
ret = true;
|
||||
}
|
||||
|
||||
if (ret == false) {
|
||||
VGUIWidget wNext = this;
|
||||
do {
|
||||
wNext = wNext.m_children;
|
||||
if (wNext && wNext.Visible() && wNext.m_parent.Visible()) {
|
||||
ret = wNext.Input(flEVType, flKey, flChar, flDevID);
|
||||
}
|
||||
|
||||
if (ret == true)
|
||||
return true;
|
||||
} while (wNext);
|
||||
}
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue