316 lines
8.7 KiB
C++
316 lines
8.7 KiB
C++
/* ScummVM - Graphic Adventure Engine
|
|
*
|
|
* ScummVM is the legal property of its developers, whose names
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
* file distributed with this source distribution.
|
|
*
|
|
* This program 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 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
#include "ultima/shared/std/string.h"
|
|
#include "ultima/nuvie/core/nuvie_defs.h"
|
|
#include "ultima/nuvie/misc/u6_misc.h"
|
|
#include "ultima/nuvie/gui/gui.h"
|
|
#include "ultima/nuvie/gui/gui_button.h"
|
|
#include "ultima/nuvie/gui/gui_scroll_bar.h"
|
|
|
|
namespace Ultima {
|
|
namespace Nuvie {
|
|
|
|
// Colours
|
|
|
|
#define SLIDER_HIGHLIGHT_R 245
|
|
#define SLIDER_HIGHLIGHT_G 247
|
|
#define SLIDER_HIGHLIGHT_B 201
|
|
|
|
#define SLIDER_SHADOW_R 115
|
|
#define SLIDER_SHADOW_G 116
|
|
#define SLIDER_SHADOW_B 94
|
|
|
|
#define SLIDER_BASE_R 183
|
|
#define SLIDER_BASE_G 185
|
|
#define SLIDER_BASE_B 150
|
|
|
|
#define TRACK_BORDER_R 76
|
|
#define TRACK_BORDER_G 75
|
|
#define TRACK_BORDER_B 71
|
|
|
|
#define TRACK_BASE_R 137
|
|
#define TRACK_BASE_G 139
|
|
#define TRACK_BASE_B 113
|
|
|
|
|
|
GUI_ScrollBar::GUI_ScrollBar(int x, int y, int h, GUI_CallBack *callback)
|
|
: GUI_Widget(nullptr, x, y, SCROLLBAR_WIDTH, h), callback_object(callback),
|
|
drag(false), slider_highlight_c(0), slider_shadow_c(0), slider_base_c(0),
|
|
track_border_c(0), track_base_c(0), slider_click_offset(0) {
|
|
|
|
loadButtons();
|
|
|
|
track_length = area.height() - 2 * button_height;
|
|
slider_length = track_length / 2;
|
|
slider_y = 5;
|
|
|
|
}
|
|
|
|
|
|
void GUI_ScrollBar::loadButtons() {
|
|
Common::Path datadir = GUI::get_gui()->get_data_dir();
|
|
Common::Path imagefile;
|
|
Graphics::ManagedSurface *image, *image1;
|
|
|
|
build_path(datadir, "ScrollBarUp_1.bmp", imagefile);
|
|
image = SDL_LoadBMP(imagefile);
|
|
build_path(datadir, "ScrollBarUp_2.bmp", imagefile);
|
|
image1 = SDL_LoadBMP(imagefile);
|
|
|
|
up_button = new GUI_Button(nullptr, 0, 0, image, image1, this);
|
|
this->AddWidget(up_button);
|
|
|
|
build_path(datadir, "ScrollBarDown_1.bmp", imagefile);
|
|
image = SDL_LoadBMP(imagefile);
|
|
build_path(datadir, "ScrollBarDown_2.bmp", imagefile);
|
|
image1 = SDL_LoadBMP(imagefile);
|
|
|
|
button_height = image->h;
|
|
|
|
down_button = new GUI_Button(nullptr, 0, area.height() - button_height, image, image1, this);
|
|
this->AddWidget(down_button);
|
|
|
|
return;
|
|
}
|
|
|
|
/* Map the color to the display */
|
|
void GUI_ScrollBar::SetDisplay(Screen *s) {
|
|
GUI_Widget::SetDisplay(s);
|
|
|
|
slider_highlight_c = surface->format.RGBToColor(SLIDER_HIGHLIGHT_R, SLIDER_HIGHLIGHT_G, SLIDER_HIGHLIGHT_B);
|
|
slider_shadow_c = surface->format.RGBToColor(SLIDER_SHADOW_R, SLIDER_SHADOW_G, SLIDER_SHADOW_B);
|
|
slider_base_c = surface->format.RGBToColor(SLIDER_BASE_R, SLIDER_BASE_G, SLIDER_BASE_B);
|
|
|
|
track_border_c = surface->format.RGBToColor(TRACK_BORDER_R, TRACK_BORDER_G, TRACK_BORDER_B);
|
|
track_base_c = surface->format.RGBToColor(TRACK_BASE_R, TRACK_BASE_G, TRACK_BASE_B);
|
|
}
|
|
|
|
void GUI_ScrollBar::set_slider_length(float percentage) {
|
|
slider_length = (int)((float)track_length * percentage);
|
|
}
|
|
|
|
void GUI_ScrollBar::set_slider_position(float percentage) {
|
|
move_slider((int)((float)track_length * percentage));
|
|
}
|
|
|
|
|
|
/* Show the widget */
|
|
void GUI_ScrollBar::Display(bool full_redraw) {
|
|
Common::Rect framerect;
|
|
// Common::Rect src, dst;
|
|
|
|
if (slider_y > 0) {
|
|
framerect.left = area.left;
|
|
framerect.top = area.top + button_height;
|
|
framerect.setWidth(SCROLLBAR_WIDTH);
|
|
framerect.setHeight(slider_y);
|
|
SDL_FillRect(surface, &framerect, track_base_c);
|
|
|
|
// Draw Border
|
|
framerect.left = area.left;
|
|
framerect.top = area.top + button_height;
|
|
framerect.setHeight(SCROLLBAR_WIDTH);
|
|
framerect.setHeight(1);
|
|
SDL_FillRect(surface, &framerect, track_border_c);
|
|
|
|
framerect.left = area.left;
|
|
framerect.top = area.top + button_height;
|
|
framerect.setWidth(1);
|
|
framerect.setHeight(slider_y);
|
|
SDL_FillRect(surface, &framerect, track_border_c);
|
|
|
|
framerect.left = area.left + SCROLLBAR_WIDTH - 1;
|
|
framerect.top = area.top + button_height;
|
|
framerect.setWidth(1);
|
|
framerect.setHeight(slider_y);
|
|
SDL_FillRect(surface, &framerect, track_border_c);
|
|
|
|
}
|
|
|
|
DisplaySlider();
|
|
|
|
if (slider_y + slider_length < track_length) {
|
|
framerect.left = area.left;
|
|
framerect.top = area.top + button_height + slider_y + slider_length;
|
|
framerect.setWidth(SCROLLBAR_WIDTH);
|
|
framerect.setHeight(track_length - (slider_y + slider_length));
|
|
SDL_FillRect(surface, &framerect, track_base_c);
|
|
|
|
// Draw Border
|
|
framerect.left = area.left;
|
|
framerect.top = area.top + area.height() - button_height - 1;
|
|
framerect.setWidth(SCROLLBAR_WIDTH);
|
|
framerect.setHeight(1);
|
|
SDL_FillRect(surface, &framerect, track_border_c);
|
|
|
|
framerect.left = area.left;
|
|
framerect.top = area.top + button_height + slider_y + slider_length;
|
|
framerect.setWidth(1);
|
|
framerect.setHeight(track_length - slider_y - slider_length);
|
|
SDL_FillRect(surface, &framerect, track_border_c);
|
|
|
|
framerect.left = area.left + SCROLLBAR_WIDTH - 1;
|
|
framerect.top = area.top + button_height + slider_y + slider_length;
|
|
framerect.setWidth(1);
|
|
framerect.setHeight(track_length - slider_y - slider_length);
|
|
SDL_FillRect(surface, &framerect, track_border_c);
|
|
|
|
}
|
|
|
|
DisplayChildren();
|
|
|
|
screen->update(area.left, area.top, area.width(), area.height());
|
|
|
|
return;
|
|
}
|
|
|
|
inline void GUI_ScrollBar::DisplaySlider() {
|
|
Common::Rect rect;
|
|
|
|
rect.left = area.left;
|
|
rect.top = area.top + button_height + slider_y;
|
|
rect.setWidth(SCROLLBAR_WIDTH);
|
|
rect.setHeight(slider_length);
|
|
SDL_FillRect(surface, &rect, slider_base_c);
|
|
|
|
rect.left = area.left;
|
|
rect.top = area.top + button_height + slider_y;
|
|
rect.setWidth(1);
|
|
rect.setHeight(slider_length - 1);
|
|
SDL_FillRect(surface, &rect, slider_highlight_c);
|
|
|
|
rect.left = area.left + 1;
|
|
rect.top = area.top + button_height + slider_y;
|
|
rect.setWidth(SCROLLBAR_WIDTH - 1);
|
|
rect.setHeight(1);
|
|
SDL_FillRect(surface, &rect, slider_highlight_c);
|
|
|
|
rect.left = area.left + SCROLLBAR_WIDTH - 1;
|
|
rect.top = area.top + button_height + slider_y;
|
|
rect.setWidth(1);
|
|
rect.setHeight(slider_length);
|
|
SDL_FillRect(surface, &rect, slider_shadow_c);
|
|
|
|
rect.left = area.left;
|
|
rect.top = area.top + button_height + slider_y + slider_length - 1;
|
|
rect.setWidth(SCROLLBAR_WIDTH - 1);
|
|
rect.setHeight(1);
|
|
SDL_FillRect(surface, &rect, slider_shadow_c);
|
|
|
|
}
|
|
GUI_status GUI_ScrollBar::MouseWheel(sint32 x, sint32 y) {
|
|
if (y > 0) {
|
|
send_up_button_msg();
|
|
} else if (y < 0) {
|
|
send_down_button_msg();
|
|
}
|
|
|
|
return GUI_YUM;
|
|
}
|
|
|
|
GUI_status GUI_ScrollBar::MouseDown(int x, int y, Events::MouseButton button) {
|
|
if (y >= area.top + button_height + slider_y && y <= area.top + button_height + slider_y + slider_length) {
|
|
drag = true;
|
|
slider_click_offset = y - area.top - button_height - slider_y;
|
|
grab_focus();
|
|
} else if (y < area.top + button_height + slider_y)
|
|
callback_object->callback(SCROLLBAR_CB_PAGE_UP, this, nullptr);
|
|
else
|
|
callback_object->callback(SCROLLBAR_CB_PAGE_DOWN, this, nullptr);
|
|
|
|
return GUI_YUM;
|
|
}
|
|
|
|
GUI_status GUI_ScrollBar::MouseUp(int x, int y, Events::MouseButton button) {
|
|
drag = false;
|
|
|
|
release_focus();
|
|
|
|
return GUI_YUM;
|
|
}
|
|
|
|
GUI_status GUI_ScrollBar::MouseMotion(int x, int y, uint8 state) {
|
|
int new_slider_y;
|
|
|
|
if (!drag)
|
|
return GUI_PASS;
|
|
|
|
new_slider_y = y - slider_click_offset - (area.top + button_height);
|
|
|
|
if (move_slider(new_slider_y)) {
|
|
send_slider_moved_msg();
|
|
}
|
|
// Redraw();
|
|
|
|
return GUI_YUM;
|
|
}
|
|
|
|
inline bool GUI_ScrollBar::move_slider(int new_slider_y) {
|
|
if (new_slider_y < 0 || new_slider_y + slider_length > track_length) { //new slider position is out of bounds.
|
|
if (new_slider_y < 0)
|
|
new_slider_y = 0;
|
|
else
|
|
new_slider_y = track_length - slider_length;
|
|
}
|
|
|
|
if (slider_y == new_slider_y)
|
|
return false;
|
|
|
|
slider_y = new_slider_y;
|
|
|
|
return true;
|
|
}
|
|
|
|
void GUI_ScrollBar::send_slider_moved_msg() {
|
|
float slider_percentage;
|
|
|
|
slider_percentage = slider_y / (float)track_length;
|
|
|
|
callback_object->callback(SCROLLBAR_CB_SLIDER_MOVED, this, &slider_percentage);
|
|
|
|
return;
|
|
}
|
|
|
|
void GUI_ScrollBar::send_up_button_msg() {
|
|
callback_object->callback(SCROLLBAR_CB_UP_BUTTON, this, nullptr);
|
|
}
|
|
|
|
void GUI_ScrollBar::send_down_button_msg() {
|
|
callback_object->callback(SCROLLBAR_CB_DOWN_BUTTON, this, nullptr);
|
|
}
|
|
|
|
GUI_status GUI_ScrollBar::callback(uint16 msg, GUI_CallBack *caller, void *data) {
|
|
if (msg == BUTTON_CB) {
|
|
if (caller == up_button)
|
|
send_up_button_msg();
|
|
|
|
if (caller == down_button)
|
|
send_down_button_msg();
|
|
}
|
|
|
|
return GUI_YUM;
|
|
}
|
|
|
|
} // End of namespace Nuvie
|
|
} // End of namespace Ultima
|
|
|