2016-03-27 11:49:47 +02:00
|
|
|
/*
|
|
|
|
===========================================================================
|
|
|
|
Copyright (C) 2015 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"
|
|
|
|
|
2024-01-01 15:01:23 +01:00
|
|
|
Event W_HScrollbar_Positioned
|
|
|
|
(
|
|
|
|
"hscrollbar_positioned",
|
|
|
|
EV_DEFAULT,
|
|
|
|
"i",
|
|
|
|
"new_position",
|
|
|
|
"Signaled when the user scrolls the view"
|
|
|
|
);
|
|
|
|
Event EV_HScrollbar_Scroll
|
|
|
|
(
|
|
|
|
"_hscrollbar_scroll",
|
|
|
|
EV_DEFAULT,
|
|
|
|
"ii",
|
|
|
|
"scrollrate autorepeat",
|
|
|
|
"scroll the scrollbar, at the specified rate.\n"
|
|
|
|
"The autorepeat is used for autoscrolling with the mouse button held down"
|
|
|
|
);
|
|
|
|
|
|
|
|
CLASS_DECLARATION(UIWidget, UIHorizScroll, NULL) {
|
|
|
|
{&W_LeftMouseDown, &UIHorizScroll::MouseDown },
|
|
|
|
{&W_LeftMouseUp, &UIHorizScroll::MouseUp },
|
|
|
|
{&W_LeftMouseDragged, &UIHorizScroll::MouseDragged},
|
|
|
|
{&W_MouseEntered, &UIHorizScroll::MouseEnter },
|
|
|
|
{&W_MouseExited, &UIHorizScroll::MouseLeave },
|
|
|
|
{&EV_HScrollbar_Scroll, &UIHorizScroll::Scroll },
|
|
|
|
{NULL, NULL }
|
2016-03-27 11:49:47 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
UIHorizScroll::UIHorizScroll()
|
2024-01-01 15:45:40 +01:00
|
|
|
: m_numitems(0)
|
|
|
|
, m_pagewidth(0)
|
|
|
|
, m_topitem(0)
|
|
|
|
, m_marlett("marlett")
|
|
|
|
, thumbRect(0, 0, 0, 0)
|
|
|
|
, m_pressed(VS_NONE)
|
|
|
|
, m_frameinitted(false)
|
|
|
|
, m_thumbcolor(UDarkGrey)
|
|
|
|
, m_solidbordercolor(UBlack)
|
|
|
|
{}
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2024-01-01 15:01:23 +01:00
|
|
|
void UIHorizScroll::DrawArrow(float top, const char *text, bool pressed)
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2024-01-01 15:45:40 +01:00
|
|
|
UIRect2D arrowRect(top, 0, m_frame.size.height, m_vVirtualScale[1] * 16.f);
|
|
|
|
UColor innerColor(m_background_color);
|
|
|
|
|
|
|
|
m_marlett.setColor(m_foreground_color);
|
|
|
|
|
|
|
|
if (pressed) {
|
|
|
|
if (!m_background_color.r && !m_background_color.g && !m_background_color.b) {
|
|
|
|
m_marlett.setColor(UGrey);
|
|
|
|
} else {
|
|
|
|
m_marlett.setColor(m_border_color.light);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
DrawBoxWithSolidBorder(arrowRect, innerColor, m_solidbordercolor, 1, 3, m_local_alpha);
|
|
|
|
if (m_numitems > m_pagewidth) {
|
|
|
|
DrawMac3DBox(arrowRect, pressed, m_border_color, 1, m_local_alpha);
|
|
|
|
}
|
|
|
|
|
|
|
|
m_marlett.PrintJustified(
|
|
|
|
arrowRect, m_iFontAlignmentHorizontal, m_iFontAlignmentVertical, text, m_bVirtual ? m_vVirtualScale : NULL
|
|
|
|
);
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2024-01-01 15:01:23 +01:00
|
|
|
void UIHorizScroll::DrawThumb(void)
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2024-01-01 15:45:40 +01:00
|
|
|
UIRect2D inbarrect;
|
|
|
|
float thumbWidth;
|
|
|
|
float thumbdiff;
|
|
|
|
UColor thumbInside;
|
|
|
|
|
|
|
|
thumbdiff = m_frame.size.width - m_vVirtualScale[1] * 32.f;
|
|
|
|
inbarrect.pos.x = m_vVirtualScale[1] * 16.0;
|
|
|
|
inbarrect.pos.y = 0;
|
|
|
|
inbarrect.size.width = thumbdiff;
|
|
|
|
inbarrect.size.height = m_frame.size.height;
|
|
|
|
|
|
|
|
thumbRect.pos.x = m_topitem * thumbdiff / m_numitems;
|
|
|
|
thumbRect.pos.y = 0.0;
|
|
|
|
thumbRect.size.width = m_pagewidth * thumbdiff / m_numitems;
|
|
|
|
if (thumbRect.size.width < 6.f) {
|
|
|
|
thumbRect.size.width = 6.f;
|
|
|
|
}
|
|
|
|
thumbRect.size.height = m_frame.size.height;
|
|
|
|
|
|
|
|
thumbInside = UDarkGrey;
|
|
|
|
thumbWidth = thumbRect.pos.x + thumbRect.size.width - thumbdiff;
|
|
|
|
|
|
|
|
if (m_pressed == VS_THUMB) {
|
|
|
|
thumbInside = UColor(-0.5f, -0.5f, -0.5f, thumbInside.a + 1.f);
|
|
|
|
|
|
|
|
if (thumbInside.r >= 0) {
|
|
|
|
thumbInside.r = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
thumbInside.g = Q_max(thumbInside.g, 0);
|
|
|
|
thumbInside.b = Q_max(thumbInside.b, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (thumbWidth > 0) {
|
|
|
|
thumbRect.pos.x -= thumbWidth;
|
|
|
|
}
|
|
|
|
thumbRect.pos.x += inbarrect.pos.x;
|
|
|
|
|
|
|
|
DrawBoxWithSolidBorder(thumbRect, thumbInside, m_solidbordercolor, 1, 3, m_local_alpha);
|
|
|
|
DrawMac3DBox(thumbRect, false, UBorderColor(thumbInside), true, m_local_alpha);
|
|
|
|
|
|
|
|
inbarrect.pos.x += 1;
|
|
|
|
inbarrect.pos.y += 1;
|
|
|
|
inbarrect.size.width += -2;
|
|
|
|
inbarrect.size.height += -2;
|
|
|
|
|
|
|
|
thumbRect.pos.x += -1;
|
|
|
|
thumbRect.pos.y += -1;
|
|
|
|
thumbRect.size.width += -2;
|
|
|
|
thumbRect.size.height += 2;
|
|
|
|
|
|
|
|
switch (m_pressed) {
|
|
|
|
case VS_PAGE_UP:
|
|
|
|
DrawBox(
|
|
|
|
inbarrect.pos.x,
|
|
|
|
0,
|
|
|
|
thumbRect.pos.x - inbarrect.pos.x,
|
|
|
|
m_frame.size.height,
|
|
|
|
m_border_color.dark,
|
|
|
|
m_local_alpha
|
|
|
|
);
|
|
|
|
break;
|
|
|
|
case VS_PAGE_DOWN:
|
|
|
|
DrawBox(
|
|
|
|
thumbRect.pos.x + thumbRect.size.width,
|
|
|
|
0,
|
|
|
|
inbarrect.pos.x + inbarrect.size.width - (thumbRect.pos.x + thumbRect.size.width),
|
|
|
|
m_frame.size.height,
|
|
|
|
m_border_color.dark,
|
|
|
|
m_local_alpha
|
|
|
|
);
|
|
|
|
break;
|
2024-06-07 20:34:13 +02:00
|
|
|
default:
|
|
|
|
break;
|
2024-01-01 15:45:40 +01:00
|
|
|
}
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2024-01-01 15:01:23 +01:00
|
|
|
void UIHorizScroll::Draw(void)
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2024-01-01 15:45:40 +01:00
|
|
|
UIRect2D arrowRect;
|
|
|
|
UColor innerColor(0, 0, 0, 1);
|
|
|
|
|
|
|
|
arrowRect = getClientFrame();
|
|
|
|
DrawBoxWithSolidBorder(arrowRect, m_background_color, m_solidbordercolor, 1, 3, m_local_alpha);
|
|
|
|
|
|
|
|
DrawArrow(0, "3", m_pressed == VS_UP_ARROW);
|
|
|
|
DrawArrow(m_frame.size.width - m_vVirtualScale[1] * 16.f, "4", m_pressed = VS_DOWN_ARROW);
|
|
|
|
if (m_numitems > m_pagewidth) {
|
|
|
|
DrawThumb();
|
|
|
|
}
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2024-01-01 15:01:23 +01:00
|
|
|
void UIHorizScroll::Scroll(Event *ev)
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2024-01-01 15:45:40 +01:00
|
|
|
if (!AttemptScrollTo(m_topitem + ev->GetInteger(1))) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
float delay = 0.2f;
|
|
|
|
if (ev->GetInteger(2)) {
|
|
|
|
delay = 0.1f;
|
|
|
|
}
|
|
|
|
|
|
|
|
Event event(EV_HScrollbar_Scroll);
|
|
|
|
event.AddInteger(ev->GetInteger(1));
|
|
|
|
event.AddInteger(0);
|
|
|
|
PostEvent(event, delay);
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2024-01-01 15:01:23 +01:00
|
|
|
bool UIHorizScroll::AttemptScrollTo(int to)
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2024-01-01 15:45:40 +01:00
|
|
|
int besttopitem;
|
|
|
|
|
|
|
|
if (to < 0) {
|
|
|
|
to = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
besttopitem = m_numitems - m_pagewidth;
|
|
|
|
if (besttopitem < 0) {
|
|
|
|
besttopitem = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (to > besttopitem) {
|
|
|
|
to = besttopitem;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (to == m_topitem) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
Event ev(W_HScrollbar_Positioned);
|
|
|
|
ev.AddInteger(m_topitem);
|
|
|
|
SendSignal(ev);
|
|
|
|
|
|
|
|
return true;
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2024-01-01 15:01:23 +01:00
|
|
|
void UIHorizScroll::MouseDown(Event *ev)
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2024-01-01 15:45:40 +01:00
|
|
|
UIPoint2D p;
|
|
|
|
int scrollrate = 0;
|
|
|
|
|
|
|
|
p.x = ev->GetFloat(1);
|
|
|
|
p.y = ev->GetFloat(2);
|
|
|
|
p.x -= m_screenframe.pos.x;
|
|
|
|
p.y -= m_screenframe.pos.y;
|
|
|
|
|
|
|
|
if (p.x < 0 || p.y < 0) {
|
|
|
|
// out of bounds
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (p.x > m_frame.size.width || p.y > m_frame.size.height) {
|
|
|
|
// out of bounds
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (m_numitems <= m_pagewidth) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (p.x < 16.f) {
|
|
|
|
scrollrate = -1;
|
|
|
|
m_pressed = VS_UP_ARROW;
|
|
|
|
} else if (p.x > m_frame.size.width - 16.f) {
|
|
|
|
scrollrate = 1;
|
|
|
|
m_pressed = VS_DOWN_ARROW;
|
|
|
|
} else if (p.x < thumbRect.pos.x) {
|
|
|
|
m_pressed = VS_PAGE_UP;
|
|
|
|
scrollrate = -m_pagewidth;
|
|
|
|
} else if (p.x >= (thumbRect.pos.x + thumbRect.size.width)) {
|
|
|
|
m_pressed = VS_PAGE_DOWN;
|
|
|
|
scrollrate = m_pagewidth;
|
|
|
|
} else {
|
|
|
|
m_pressed = VS_THUMB;
|
|
|
|
m_dragThumbState.itemOffset = m_topitem - getItemFromWidth(p.x);
|
|
|
|
m_dragThumbState.orgItem = m_topitem;
|
|
|
|
uWinMan.setFirstResponder(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (scrollrate) {
|
|
|
|
Event *event = new Event(EV_HScrollbar_Scroll);
|
|
|
|
event->AddInteger(scrollrate);
|
|
|
|
event->AddInteger(0);
|
|
|
|
CancelEventsOfType(EV_HScrollbar_Scroll);
|
|
|
|
PostEvent(event, 0);
|
|
|
|
|
|
|
|
uWinMan.setFirstResponder(this);
|
|
|
|
}
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2024-01-01 15:01:23 +01:00
|
|
|
int UIHorizScroll::getItemFromWidth(float height)
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2024-01-01 15:45:40 +01:00
|
|
|
return (int)((height - 16.0) * m_numitems / (m_frame.size.width - 32.0));
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2024-01-01 15:01:23 +01:00
|
|
|
void UIHorizScroll::MouseUp(Event *ev)
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2024-01-01 15:45:40 +01:00
|
|
|
CancelEventsOfType(EV_HScrollbar_Scroll);
|
|
|
|
|
|
|
|
if (uWinMan.getFirstResponder() == this) {
|
|
|
|
uWinMan.setFirstResponder(NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
m_pressed = VS_NONE;
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2024-01-01 15:01:23 +01:00
|
|
|
void UIHorizScroll::MouseDragged(Event *ev)
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2024-01-01 15:45:40 +01:00
|
|
|
UIPoint2D p;
|
|
|
|
|
|
|
|
if (m_pressed != VS_THUMB) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
p.x = ev->GetFloat(1);
|
|
|
|
p.y = ev->GetFloat(2);
|
|
|
|
|
|
|
|
if (p.y - m_screenframe.pos.y < -24 || m_frame.size.height + 24.0 < p.y - m_screenframe.pos.y) {
|
|
|
|
AttemptScrollTo(m_dragThumbState.orgItem);
|
|
|
|
} else {
|
|
|
|
AttemptScrollTo(m_dragThumbState.itemOffset + getItemFromWidth(p.x - m_screenframe.pos.x));
|
|
|
|
}
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2024-01-01 15:01:23 +01:00
|
|
|
void UIHorizScroll::InitFrameAlignRight(UIWidget *parent)
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2024-01-01 15:45:40 +01:00
|
|
|
UIRect2D frame, frameOut;
|
|
|
|
|
|
|
|
frame = parent->getClientFrame();
|
|
|
|
frameOut.pos.x = 0;
|
|
|
|
frameOut.pos.y = frame.pos.y + frame.size.height - m_vVirtualScale[0] * 16.f;
|
|
|
|
frameOut.size.width = frame.size.width - m_vVirtualScale[0] * 16.f;
|
|
|
|
frameOut.size.height = m_vVirtualScale[0] * 16.f;
|
|
|
|
|
|
|
|
if (m_frameinitted) {
|
|
|
|
setFrame(frameOut);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
InitFrame(parent, frameOut, -1);
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2024-01-01 15:01:23 +01:00
|
|
|
void UIHorizScroll::MouseEnter(Event *ev)
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2024-01-01 15:45:40 +01:00
|
|
|
uWinMan.ActivateControl(this);
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2024-01-01 15:45:40 +01:00
|
|
|
void UIHorizScroll::MouseLeave(Event *ev) {}
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2024-01-01 15:01:23 +01:00
|
|
|
bool UIHorizScroll::isEnoughItems(void)
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2024-01-01 15:45:40 +01:00
|
|
|
return m_numitems > m_pagewidth;
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2024-01-01 15:01:23 +01:00
|
|
|
void UIHorizScroll::setNumItems(int i)
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2024-01-01 15:45:40 +01:00
|
|
|
m_numitems = i;
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2024-01-01 15:01:23 +01:00
|
|
|
void UIHorizScroll::setPageWidth(int i)
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2024-01-01 15:45:40 +01:00
|
|
|
m_pagewidth = i;
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2024-01-01 15:01:23 +01:00
|
|
|
void UIHorizScroll::setTopItem(int i)
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2024-01-01 15:45:40 +01:00
|
|
|
m_topitem = i;
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2024-01-01 15:01:23 +01:00
|
|
|
int UIHorizScroll::getTopItem(void)
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2024-01-01 15:45:40 +01:00
|
|
|
return m_topitem;
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2024-01-01 15:01:23 +01:00
|
|
|
int UIHorizScroll::getPageWidth(void)
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2024-01-01 15:45:40 +01:00
|
|
|
return m_pagewidth;
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2024-01-01 15:01:23 +01:00
|
|
|
int UIHorizScroll::getNumItems(void)
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2024-01-01 15:45:40 +01:00
|
|
|
return m_numitems;
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2024-01-01 15:01:23 +01:00
|
|
|
void UIHorizScroll::setThumbColor(const UColor& thumb)
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2024-01-01 15:45:40 +01:00
|
|
|
m_thumbcolor = thumb;
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2024-01-01 15:01:23 +01:00
|
|
|
void UIHorizScroll::setSolidBorderColor(const UColor& col)
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2024-01-01 15:45:40 +01:00
|
|
|
m_solidbordercolor = col;
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|