Files
bearstonem--openmohaa-vr/code/uilib/uifloatwnd.cpp
T
2025-07-19 23:30:20 +02:00

362 lines
9.7 KiB
C++

/*
===========================================================================
Copyright (C) 2023 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#include "ui_local.h"
CLASS_DECLARATION(UIWidget, UIChildSpaceWidget, NULL) {
{NULL, NULL}
};
UIChildSpaceWidget::UIChildSpaceWidget() {}
qboolean UIChildSpaceWidget::KeyEvent(int key, unsigned int time)
{
if (m_parent) {
//
// Transmit the key event to the parent
//
return m_parent->KeyEvent(key, 0);
}
return qfalse;
}
CLASS_DECLARATION(UIWidget, UIFloatingWindow, NULL) {
{&W_LeftMouseDown, &UIFloatingWindow::Pressed },
{&W_LeftMouseDragged, &UIFloatingWindow::Dragged },
{&W_LeftMouseUp, &UIFloatingWindow::Released },
{&UIFloatingWindow::W_ClosePressed, &UIFloatingWindow::ClosePressed },
{&UIFloatingWindow::W_MinimizePressed, &UIFloatingWindow::MinimizePressed},
{&W_SizeChanged, &UIFloatingWindow::SizeChanged },
{&W_Activated, &UIFloatingWindow::OnActivated },
{NULL, NULL }
};
Event UIFloatingWindow::W_ClosePressed(
"floatingwindow_close_pressed", EV_DEFAULT, NULL, NULL, "Signal that the window was closed"
);
Event UIFloatingWindow::W_MinimizePressed(
"floatingwindow_minimize_pressed", EV_DEFAULT, NULL, NULL, "Signal that the window was minimized"
);
UIFloatingWindow::UIFloatingWindow()
{
m_clickpoint = UIPoint2D(-20.0, -20.0);
m_isPressed = false;
m_minimized = false;
m_canactivate = true;
m_clicktime = -20000;
// create buttons that compose a window
m_closeButton = new UIButton();
m_minimizeButton = new UIButton();
m_childspace = new UIChildSpaceWidget();
}
UIFloatingWindow::~UIFloatingWindow() {}
void UIFloatingWindow::FrameInitialized(void)
{
FrameInitialized(true);
}
void UIFloatingWindow::FrameInitialized(bool bHasDragBar)
{
//
// Initialize the close button
//
m_closeButton->InitFrame(
this,
m_frame.size.width - 18.0 * getHighResScale()[0],
2.0,
16.0 * getHighResScale()[0],
16.0 * getHighResScale()[1],
-1,
"marlett"
);
m_closeButton->setTitle("r");
m_closeButton->setName("closebutton");
//
// Initialize the minimize button
//
m_minimizeButton->InitFrame(
this,
m_frame.size.width - 36.0 * getHighResScale()[0],
2.0,
16.0 * getHighResScale()[0],
16.0 * getHighResScale()[1],
-1,
"marlett"
);
m_minimizeButton->setTitle("0");
m_minimizeButton->setName("minimizebutton");
m_closeButton->Connect(this, W_Button_Pressed, UIFloatingWindow::W_ClosePressed);
m_minimizeButton->Connect(this, W_Button_Pressed, UIFloatingWindow::W_MinimizePressed);
//
// Size event
//
Connect(this, W_SizeChanged, W_SizeChanged);
Connect(this, W_Activated, W_Activated);
//
// Child space
//
if (bHasDragBar) {
m_childspace->InitFrame(
this,
UIRect2D(
2.0,
20.0 * getHighResScale()[1],
m_frame.size.width - 4.0,
m_frame.size.height - 22.0 * getHighResScale()[1]
),
0,
"verdana-12"
);
} else {
m_childspace->InitFrame(this, UIRect2D(UIPoint2D(0, 0), m_frame.size), 0, "verdana-12");
}
m_childspace->setTitle("Child space");
m_childspace->AllowActivate(true);
}
void UIFloatingWindow::ClosePressed(Event *ev)
{
PostEvent(EV_Remove, 0.0);
}
void UIFloatingWindow::MinimizePressed(Event *ev)
{
UISize2D size = getSize();
if (!m_minimized) {
m_minimized = true;
// save the hold height
// so the window can be restored later
m_restoredHeight = size.height;
size.height = 20.0 * getHighResScale()[1];
m_minimizeButton->setTitle("1");
} else {
m_minimized = false;
size.height = m_restoredHeight;
m_minimizeButton->setTitle("0");
}
setSize(size);
uWinMan.ActivateControl(this);
}
void UIFloatingWindow::Pressed(Event *ev)
{
UIPoint2D p = MouseEventToClientPoint(ev);
m_clickOffset.x = p.x;
m_clickOffset.y = p.y;
if (uid.time - 500 >= m_clicktime) {
m_clicktime = uid.time;
} else {
if (fabs(m_clickpoint.x - m_clickOffset.x) > 2.0 || fabs(m_clickpoint.y - m_clickOffset.y) > 2.0) {
m_clicktime = uid.time;
} else {
ProcessEvent(W_MinimizePressed);
m_clicktime = -20000;
}
}
m_clickpoint = m_clickOffset;
if (m_clickOffset.y < 18.0) {
uWinMan.setFirstResponder(this);
m_isPressed = true;
}
}
void UIFloatingWindow::Released(Event *ev)
{
if (!m_isPressed) {
return;
}
uWinMan.setFirstResponder(NULL);
m_isPressed = false;
OnActivated(NULL);
}
void UIFloatingWindow::Dragged(Event *ev)
{
if (!m_isPressed) {
return;
}
UIPoint2D point = MouseEventToClientPoint(ev);
UIPoint2D newpos;
newpos.x = point.x - m_clickOffset.x;
newpos.y = point.y - m_clickOffset.y;
newpos.x += m_frame.pos.x;
newpos.y += m_frame.pos.y;
setFrame(UIRect2D(newpos, getSize()));
}
void UIFloatingWindow::SizeChanged(Event *ev)
{
UIRect2D childRect;
childRect.pos.x = 2.0;
childRect.pos.y = 20.0 * getHighResScale()[1];
childRect.size.width = m_frame.size.width - 4.0 * getHighResScale()[0];
childRect.size.height = m_frame.size.height - 22.0 * getHighResScale()[1];
if (childRect.size.width <= 0.0 || childRect.size.height <= 0.0) {
return;
}
m_childspace->setFrame(childRect);
m_closeButton->setFrame(UIRect2D(
m_frame.size.width - 18.0 * getHighResScale()[0], 2.0, 16.0 * getHighResScale()[0], 16.0 * getHighResScale()[1]
));
m_minimizeButton->setFrame(UIRect2D(
m_frame.size.width - 36.0 * getHighResScale()[0], 2.0, 16.0 * getHighResScale()[0], 16.0 * getHighResScale()[1]
));
}
void UIFloatingWindow::OnActivated(Event *ev)
{
UIWidget *next;
if (!IsActive()) {
return;
}
for (next = m_childspace->getFirstChild(); next; next = m_childspace->getNextChild(next)) {
if (next->CanActivate()) {
uWinMan.ActivateControl(next);
break;
}
}
}
void UIFloatingWindow::OnDeactivated(Event *ev)
{
PostEvent(EV_Remove, 0.0);
}
void UIFloatingWindow::Create(
UIWidget *parent, const UIRect2D& rect, const char *title, const UColor& bgColor, const UColor& fgColor
)
{
m_titleColor = bgColor;
m_textColor = fgColor;
setTitle(title);
// actually create the window
InitFrame(parent, rect.pos.x, rect.pos.y, rect.size.width, rect.size.height, 0, "verdana-14");
}
void UIFloatingWindow::Draw(void)
{
UColor titleBar;
UColor textColor;
UBorderColor titleBorder;
UBorderColor windowBorder;
if (IsThisOrChildActive()) {
UColor newColor;
titleBar = m_titleColor;
textColor = m_textColor;
UColorHSV tmp(titleBar);
tmp.s *= 0.75;
tmp.v *= 1.333;
newColor = tmp;
titleBorder.dark = newColor;
titleBorder.reallydark = newColor;
titleBorder.light = newColor;
} else {
UColor newColor(0.1125, 0.147, 0.2085, 1.0);
titleBar = newColor;
textColor = UBlack;
titleBorder.CreateSolidBorder(newColor, DARK);
titleBorder.reallydark = newColor;
titleBorder.light = newColor;
}
UColor newColor(0.15, 0.196, 0.278, 1.0);
newColor.ScaleColor(0.666f);
windowBorder.dark = newColor;
windowBorder.reallydark = newColor;
windowBorder.light = newColor;
setForegroundColor(textColor);
m_closeButton->setForegroundColor(textColor);
m_closeButton->setBackgroundColor(titleBar, true);
m_minimizeButton->setForegroundColor(textColor);
m_minimizeButton->setBackgroundColor(titleBar, true);
if (!IsMinimized()) {
DrawBoxWithSolidBorder(
getClientFrame(), UColor(0.15, 0.195, 0.278, 1.0), UColor(0.075, 0.097, 0.139, 1.0), 2, 2, 1.0
);
}
const float maxTitleBarHeight = 20 * getHighResScale()[1];
DrawBox(
0.0,
0.0,
m_frame.size.width,
m_frame.size.height > maxTitleBarHeight ? maxTitleBarHeight : m_frame.size.height,
titleBar,
1.0
);
Draw3DBox(
0.0,
0.0,
m_frame.size.width,
m_frame.size.height > maxTitleBarHeight ? maxTitleBarHeight : m_frame.size.height,
false,
titleBorder,
1.0
);
DrawTitle(3.0, 3.0);
}
UIChildSpaceWidget *UIFloatingWindow::getChildSpace(void)
{
return m_childspace;
}
bool UIFloatingWindow::IsMinimized(void)
{
return m_minimized;
}