Initial commit
This commit is contained in:
414
engines/ultima/nuvie/gui/gui.cpp
Normal file
414
engines/ultima/nuvie/gui/gui.cpp
Normal file
@@ -0,0 +1,414 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/* This is a C++ class for handling a GUI, and associated widgets */
|
||||
|
||||
#include "ultima/nuvie/core/nuvie_defs.h"
|
||||
#include "ultima/nuvie/conf/configuration.h"
|
||||
#include "ultima/nuvie/gui/gui.h"
|
||||
#include "ultima/nuvie/gui/gui_types.h"
|
||||
#include "ultima/nuvie/keybinding/keys.h"
|
||||
#include "common/system.h"
|
||||
|
||||
#include "backends/keymapper/keymapper.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
const int GUI::mouseclick_delay = 300; /* SB-X */
|
||||
|
||||
|
||||
/* Number of widget elements to allocate at once */
|
||||
#define WIDGET_ARRAYCHUNK 32
|
||||
|
||||
GUI *GUI::gui = nullptr;
|
||||
|
||||
GUI::GUI(const Configuration *c, Screen *s) : config(c), screen(s), numwidgets(0),
|
||||
maxwidgets(0), widgets(nullptr), display(1), running(0), dragging(false),
|
||||
full_redraw(true), focused_widget(nullptr), locked_widget(nullptr),
|
||||
block_input(false) {
|
||||
gui = this;
|
||||
selected_color = new GUI_Color(10, 10, 50);
|
||||
selected_color->map_color(screen->get_sdl_surface()->format);
|
||||
|
||||
gui_font = new GUI_Font();
|
||||
gui_drag_manager = new GUI_DragManager(screen);
|
||||
}
|
||||
|
||||
GUI::~GUI() {
|
||||
if (widgets != nullptr) {
|
||||
for (int i = 0; i < numwidgets; ++i) {
|
||||
delete widgets[i];
|
||||
}
|
||||
free(widgets);
|
||||
}
|
||||
|
||||
delete selected_color;
|
||||
|
||||
delete gui_font;
|
||||
delete gui_drag_manager;
|
||||
}
|
||||
|
||||
/* Add a widget to the GUI.
|
||||
The widget will be automatically deleted when the GUI is deleted.
|
||||
*/
|
||||
int GUI::AddWidget(GUI_Widget *widget) {
|
||||
int i = numwidgets;
|
||||
|
||||
// This is commented out because it makes it unsafe to call AddWidget
|
||||
// from a widget's event handler: It could delete the calling widget
|
||||
// if it was marked for deletion during event handling.
|
||||
/* Look for deleted widgets */
|
||||
// for (i = 0; i < numwidgets; ++i) {
|
||||
// if (widgets[i]->Status() == WIDGET_DELETED) {
|
||||
// delete widgets[i];
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// if (i == numwidgets) {
|
||||
/* Expand the widgets array if necessary */
|
||||
if (numwidgets == maxwidgets) {
|
||||
GUI_Widget **newarray;
|
||||
int maxarray;
|
||||
|
||||
maxarray = maxwidgets + WIDGET_ARRAYCHUNK;
|
||||
if ((newarray = (GUI_Widget **)realloc(widgets,
|
||||
maxarray * sizeof(*newarray))) == nullptr) {
|
||||
return -1;
|
||||
}
|
||||
widgets = newarray;
|
||||
maxwidgets = maxarray;
|
||||
}
|
||||
++numwidgets;
|
||||
// }
|
||||
widgets[i] = widget;
|
||||
widget->PlaceOnScreen(screen, gui_drag_manager, 0, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* remove widget from gui system but don't delete it */
|
||||
bool GUI::removeWidget(GUI_Widget *widget) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < numwidgets; ++i) {
|
||||
if (widgets[i] == widget) {
|
||||
for (int j = i + 1; j < numwidgets; ++j) { //shuffle remaining widgets down.
|
||||
widgets[j - 1] = widgets[j];
|
||||
}
|
||||
|
||||
--numwidgets;
|
||||
force_full_redraw();
|
||||
Display();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void GUI::CleanupDeletedWidgets(bool redraw) {
|
||||
/* Garbage collection */
|
||||
if (locked_widget && locked_widget->Status() == WIDGET_DELETED) {
|
||||
locked_widget = nullptr;
|
||||
// Re-enable the global keymapper
|
||||
g_system->getEventManager()->getKeymapper()->setEnabled(true);
|
||||
}
|
||||
if (focused_widget && focused_widget->Status() == WIDGET_DELETED)
|
||||
focused_widget = nullptr;
|
||||
|
||||
for (int i = 0; i < numwidgets;) {
|
||||
if (widgets[i]->Status() == WIDGET_DELETED) {
|
||||
delete widgets[i];
|
||||
|
||||
for (int j = i + 1; j < numwidgets; ++j) //shuffle remaining widgets down.
|
||||
widgets[j - 1] = widgets[j];
|
||||
|
||||
--numwidgets;
|
||||
if (redraw) {
|
||||
// CHECKME: is it really necessary to redraw after each deletion?
|
||||
force_full_redraw();
|
||||
Display();
|
||||
}
|
||||
} else
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
bool GUI::moveWidget(GUI_Widget *widget, uint32 dx, uint32 dy) {
|
||||
if (!widget)
|
||||
return false;
|
||||
|
||||
widget->MoveRelative(dx, dy);
|
||||
|
||||
if (widget->Status() == WIDGET_VISIBLE)
|
||||
widget->Redraw();//force_full_redraw();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void GUI::force_full_redraw() {
|
||||
full_redraw = true;
|
||||
}
|
||||
|
||||
void GUI::Display() {
|
||||
int i;
|
||||
bool complete_redraw = false;
|
||||
|
||||
// hack for now to make everyhing under the cursor draw until I find a better
|
||||
// way of doing this...
|
||||
if (dragging || full_redraw)
|
||||
complete_redraw = true;
|
||||
|
||||
for (i = 0; i < numwidgets; ++i) {
|
||||
if (widgets[i]->Status() == WIDGET_VISIBLE) {
|
||||
widgets[i]->Display(complete_redraw);
|
||||
//screen->update(widgets[i]->area.left,widgets[i]->area.top,widgets[i]->area.width(),widgets[i]->area.height());
|
||||
}
|
||||
}
|
||||
//SDL_UpdateRect(screen, 0, 0, 0, 0);
|
||||
|
||||
int mx, my;
|
||||
screen->get_mouse_location(&mx, &my);
|
||||
|
||||
gui_drag_manager->draw(mx, my);
|
||||
|
||||
if (full_redraw)
|
||||
full_redraw = false;
|
||||
}
|
||||
|
||||
/* Function to handle a GUI status */
|
||||
void
|
||||
GUI::HandleStatus(GUI_status status) {
|
||||
switch (status) {
|
||||
case GUI_QUIT:
|
||||
running = 0;
|
||||
break;
|
||||
case GUI_REDRAW:
|
||||
display = 1;
|
||||
break;
|
||||
case GUI_DRAG_AND_DROP:
|
||||
dragging = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle an event, passing it to widgets until they return a status */
|
||||
GUI_status GUI::HandleEvent(Common::Event *event) {
|
||||
int i;
|
||||
int hit;
|
||||
GUI_status status = GUI_PASS;
|
||||
|
||||
if (dragging) { //&& !block_input)
|
||||
if (event->type == Common::EVENT_LBUTTONUP ||
|
||||
event->type == Common::EVENT_MBUTTONUP ||
|
||||
event->type == Common::EVENT_RBUTTONUP) { //FIX for button up that doesn't hit a widget.
|
||||
for (hit = false, i = numwidgets - 1; (i >= 0) && (hit == false); --i) {
|
||||
if (widgets[i]->Status() == WIDGET_VISIBLE && widgets[i]->is_drop_target() && widgets[i]->HitRect(event->mouse.x, event->mouse.y)) {
|
||||
gui_drag_manager->drop((GUI_DragArea *)widgets[i], event->mouse.x, event->mouse.y);
|
||||
dragging = false;
|
||||
Display(); // redraw the widget to get rid of the drop graphic.
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (!block_input) {
|
||||
if (event->type == Common::EVENT_JOYAXIS_MOTION ||
|
||||
event->type == Common::EVENT_JOYBUTTON_DOWN ||
|
||||
event->type == Common::EVENT_JOYBUTTON_UP) {
|
||||
event->kbd.keycode = Game::get_game()->get_keybinder()->get_key_from_joy_events(event);
|
||||
if (event->kbd.keycode == Common::KEYCODE_INVALID) { // isn't mapped, is in deadzone, or axis didn't return to center before moving again
|
||||
HandleStatus(status);
|
||||
CleanupDeletedWidgets(status != GUI_QUIT);
|
||||
return status; // pretend nothing happened
|
||||
}
|
||||
event->type = Common::EVENT_KEYDOWN;
|
||||
event->kbd.flags = 0;
|
||||
}
|
||||
|
||||
switch (event->type) {
|
||||
/* SDL_QUIT events quit the GUI */
|
||||
// case SDL_QUIT:
|
||||
// status = GUI_QUIT;
|
||||
// break;
|
||||
|
||||
/* Keyboard and mouse events go to widgets */
|
||||
|
||||
case Common::EVENT_MOUSEMOVE:
|
||||
case Common::EVENT_LBUTTONDOWN:
|
||||
case Common::EVENT_RBUTTONDOWN:
|
||||
case Common::EVENT_MBUTTONDOWN:
|
||||
case Common::EVENT_LBUTTONUP:
|
||||
case Common::EVENT_RBUTTONUP:
|
||||
case Common::EVENT_MBUTTONUP:
|
||||
case Common::EVENT_KEYDOWN:
|
||||
case Common::EVENT_KEYUP:
|
||||
case Common::EVENT_WHEELDOWN:
|
||||
case Common::EVENT_WHEELUP:
|
||||
// /* Go through widgets, topmost first */
|
||||
// status = GUI_PASS;
|
||||
// for (i=numwidgets-1; (i>=0)&&(status==GUI_PASS); --i) {
|
||||
// if ( widgets[i]->Status() == WIDGET_VISIBLE ) {
|
||||
// status = widgets[i]->HandleEvent(event);
|
||||
// }
|
||||
// }
|
||||
// break;
|
||||
/* Send everything to locked widget. */
|
||||
if (locked_widget && locked_widget->Status() == WIDGET_VISIBLE) {
|
||||
status = locked_widget->HandleEvent(event);
|
||||
if (status == GUI_PASS) // can't bypass the lock
|
||||
status = GUI_YUM;
|
||||
}
|
||||
/* Go through widgets, focused first, then from the
|
||||
top.*/
|
||||
else {
|
||||
status = GUI_PASS;
|
||||
if (focused_widget && focused_widget->Status() == WIDGET_VISIBLE) {
|
||||
status = focused_widget->HandleEvent(event);
|
||||
}
|
||||
for (i = numwidgets - 1; (i >= 0) && (status == GUI_PASS); --i) {
|
||||
if (widgets[i]->Status() == WIDGET_VISIBLE
|
||||
&& widgets[i] != focused_widget) { // don't send to focused twice
|
||||
status = widgets[i]->HandleEvent(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
/* Ignore unhandled events */
|
||||
default:
|
||||
status = GUI_PASS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
HandleStatus(status);
|
||||
|
||||
CleanupDeletedWidgets(status != GUI_QUIT);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Run the GUI.
|
||||
This returns when either a widget requests a quit, the idle
|
||||
function requests a quit, or the SDL window has been closed.
|
||||
*/
|
||||
void GUI::Run(GUI_IdleProc idle, int once, int multitaskfriendly) {
|
||||
int i;
|
||||
Common::Event event;
|
||||
|
||||
/* If there's nothing to do, return immediately */
|
||||
if ((numwidgets == 0) && (idle == nullptr)) {
|
||||
return;
|
||||
}
|
||||
|
||||
running = 1;
|
||||
if (! once) {
|
||||
display = 1;
|
||||
}
|
||||
do {
|
||||
CleanupDeletedWidgets();
|
||||
|
||||
/* Display widgets if necessary */
|
||||
if (display) {
|
||||
Display();
|
||||
display = 0;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////// Polling is time consuming - instead:
|
||||
if (multitaskfriendly && (idle == nullptr)) {
|
||||
while (!Events::get()->pollEvent(event))
|
||||
g_system->delayMillis(5);
|
||||
HandleEvent(&event);
|
||||
} else
|
||||
/////////////////////////////////////////////////////////////////
|
||||
/* Handle events, or run idle functions */
|
||||
if (Events::get()->pollEvent(event)) {
|
||||
/* Handle all pending events */
|
||||
do {
|
||||
HandleEvent(&event);
|
||||
} while (Events::get()->pollEvent(event));
|
||||
} else {
|
||||
if (idle != nullptr) {
|
||||
HandleStatus(idle());
|
||||
}
|
||||
for (i = numwidgets - 1; i >= 0; --i) {
|
||||
HandleStatus(widgets[i]->Idle());
|
||||
}
|
||||
}
|
||||
//ERIC SDL_Delay(10);
|
||||
} while (running && ! once);
|
||||
}
|
||||
|
||||
GUI_Font *GUI::get_font() {
|
||||
return gui_font;
|
||||
}
|
||||
|
||||
|
||||
// SB-X
|
||||
void GUI::Idle() {
|
||||
if (locked_widget) {
|
||||
locked_widget->Idle();
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = numwidgets - 1; i >= 0; --i) {
|
||||
HandleStatus(widgets[i]->Idle());
|
||||
}
|
||||
}
|
||||
|
||||
bool GUI::set_focus(GUI_Widget *widget) {
|
||||
/*
|
||||
for(int i = 0; i < numwidgets; ++i)
|
||||
{
|
||||
if(!widget || (widgets[i] == widget)) // must be managed by GUI
|
||||
{
|
||||
*/
|
||||
focused_widget = widget;
|
||||
return true;
|
||||
// }
|
||||
// }
|
||||
|
||||
// return false;
|
||||
}
|
||||
|
||||
void GUI::lock_input(GUI_Widget *widget) {
|
||||
for (int i = 0; i < numwidgets; ++i) {
|
||||
if (!widget || (widgets[i] == widget)) {// must be managed by GUI
|
||||
locked_widget = widget;
|
||||
// Disable the keymapper so direct keys can go into the input
|
||||
g_system->getEventManager()->getKeymapper()->setEnabled(locked_widget == nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Common::Path GUI::get_data_dir() const {
|
||||
Std::string datadir;
|
||||
|
||||
config->value("config/datadir", datadir, "");
|
||||
|
||||
return Common::Path(datadir);
|
||||
}
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
187
engines/ultima/nuvie/gui/gui.h
Normal file
187
engines/ultima/nuvie/gui/gui.h
Normal file
@@ -0,0 +1,187 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/* This is a C++ class for handling a GUI, and associated widgets */
|
||||
|
||||
#ifndef NUVIE_GUI_GUI_H
|
||||
#define NUVIE_GUI_GUI_H
|
||||
|
||||
#include "ultima/nuvie/gui/gui_status.h"
|
||||
#include "ultima/nuvie/gui/gui_drag_manager.h"
|
||||
#include "ultima/nuvie/gui/widgets/gui_widget.h"
|
||||
#include "ultima/nuvie/gui/gui_font.h"
|
||||
#include "common/events.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
class Configuration;
|
||||
class Screen;
|
||||
class GUI_Color;
|
||||
|
||||
#define GUI_FULL_REDRAW true
|
||||
|
||||
class GUI {
|
||||
|
||||
protected:
|
||||
|
||||
static GUI *gui;
|
||||
const Configuration *config;
|
||||
|
||||
/* The display surface */
|
||||
Screen *screen;
|
||||
|
||||
GUI_Font *gui_font;
|
||||
GUI_DragManager *gui_drag_manager;
|
||||
|
||||
/* Pointers for an array of widgets */
|
||||
int maxwidgets;
|
||||
int numwidgets;
|
||||
GUI_Widget **widgets;
|
||||
|
||||
/* All input will go to this widget first. */
|
||||
GUI_Widget *focused_widget; // SB-X
|
||||
/* All input will go to this widget ONLY. */
|
||||
GUI_Widget *locked_widget; // SB-X
|
||||
/* All input will be ignored. */
|
||||
bool block_input; // SB-X
|
||||
|
||||
/* Flag - whether or not the GUI is currently running */
|
||||
int running;
|
||||
|
||||
/* Flag - whether or not the GUI needs to be displayed */
|
||||
int display;
|
||||
|
||||
/* Flag - whether we are performing a drag and drop */
|
||||
bool dragging;
|
||||
|
||||
bool full_redraw; // this forces all widgets to redraw on the next call to Display()
|
||||
|
||||
// some default colours
|
||||
GUI_Color *selected_color;
|
||||
|
||||
public:
|
||||
static const int mouseclick_delay; /* SB-X */
|
||||
|
||||
GUI(const Configuration *c, Screen *s);
|
||||
~GUI();
|
||||
|
||||
/* Add a widget to the GUI.
|
||||
The widget will be automatically deleted when the GUI is deleted.
|
||||
This function returns 0, or -1 if the function ran out of memory.
|
||||
*/
|
||||
int AddWidget(GUI_Widget *widget);
|
||||
|
||||
/* remove widget from gui system but don't delete it */
|
||||
bool removeWidget(GUI_Widget *widget);
|
||||
|
||||
bool moveWidget(GUI_Widget *widget, uint32 dx, uint32 dy);
|
||||
|
||||
/* force everything to redraw */
|
||||
void force_full_redraw();
|
||||
|
||||
/* Display the GUI manually */
|
||||
void Display();
|
||||
|
||||
/* Returns will return true if the GUI is still ready to handle
|
||||
events after a call to Run(), and false if a widget or idle
|
||||
function requested a quit.
|
||||
*/
|
||||
int Running(void) {
|
||||
return running;
|
||||
}
|
||||
|
||||
/* Run the GUI.
|
||||
This returns when either a widget requests a quit, the idle
|
||||
function requests a quit, or the SDL window has been closed.
|
||||
If 'once' is non-zero, you need to display the GUI yourself,
|
||||
and the GUI event loop will run once and then return.
|
||||
If 'multitaskfriendly' is non-zero AND idle is nullptr,
|
||||
a 'WaitEvent' will be used instead of the CPU time
|
||||
consuming 'PollEvent'. CAVE: Any widget-'idle'-procs WON'T
|
||||
be executed then.
|
||||
*/
|
||||
void Run(GUI_IdleProc idle = nullptr, int once = 0, int multitaskfriendly = 0);
|
||||
|
||||
/* Run Idle() on all widgets. */
|
||||
void Idle(); // SB-X
|
||||
|
||||
static GUI *get_gui() {
|
||||
return gui;
|
||||
}
|
||||
GUI_Font *get_font();
|
||||
Screen *get_screen() {
|
||||
return screen;
|
||||
}
|
||||
GUI_Widget *get_focused_widget() {
|
||||
return focused_widget;
|
||||
}
|
||||
GUI_Widget *get_locked_widget() {
|
||||
return locked_widget;
|
||||
}
|
||||
bool get_block_input() {
|
||||
return block_input;
|
||||
}
|
||||
|
||||
//colors
|
||||
GUI_Color *get_selected_color() {
|
||||
return selected_color;
|
||||
}
|
||||
|
||||
/* Function to pass an event to the GUI widgets */
|
||||
GUI_status HandleEvent(Common::Event *event);
|
||||
|
||||
bool set_focus(GUI_Widget *widget);
|
||||
void clear_focus() {
|
||||
set_focus(nullptr);
|
||||
}
|
||||
void lock_input(GUI_Widget *widget);
|
||||
void unlock_input() {
|
||||
lock_input(nullptr);
|
||||
unblock();
|
||||
}
|
||||
void block() {
|
||||
block_input = true;
|
||||
}
|
||||
void unblock() {
|
||||
block_input = false;
|
||||
}
|
||||
Common::Path get_data_dir() const;
|
||||
|
||||
uint16 get_width() const {
|
||||
return screen->get_width();
|
||||
}
|
||||
uint16 get_height() const {
|
||||
return screen->get_height();
|
||||
}
|
||||
protected:
|
||||
|
||||
/* Function to handle a GUI status */
|
||||
void HandleStatus(GUI_status status);
|
||||
|
||||
void CleanupDeletedWidgets(bool redraw = false);
|
||||
|
||||
};
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
121
engines/ultima/nuvie/gui/gui_area.cpp
Normal file
121
engines/ultima/nuvie/gui/gui_area.cpp
Normal file
@@ -0,0 +1,121 @@
|
||||
/* 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/nuvie/core/nuvie_defs.h"
|
||||
#include "ultima/nuvie/gui/gui.h"
|
||||
#include "ultima/nuvie/gui/gui_area.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
GUI_Area:: GUI_Area(int x, int y, int w, int h, uint8 r, uint8 g, uint8 b, int aShape)
|
||||
: GUI_Widget(nullptr, x, y, w, h), R(r), G(g), B(b), color(0), useFrame(0), shape(aShape),
|
||||
frameThickness(0), fB(0), fG(0), fR(0), frameColor(0) {
|
||||
}
|
||||
|
||||
GUI_Area:: GUI_Area(int x, int y, int w, int h, uint8 r, uint8 g, uint8 b,
|
||||
uint8 fr, uint8 fg, uint8 fb, int fthick, int aShape)
|
||||
: GUI_Widget(nullptr, x, y, w, h), R(r), G(g), B(b), color(0), useFrame(1),
|
||||
fR(fr), fG(fg), fB(fb), frameColor(0), frameThickness(fthick), shape(aShape) {
|
||||
}
|
||||
|
||||
/* Map the color to the display */
|
||||
void
|
||||
GUI_Area:: SetDisplay(Screen *s) {
|
||||
GUI_Widget::SetDisplay(s);
|
||||
color = surface->format.RGBToColor(R, G, B);
|
||||
if (useFrame)
|
||||
frameColor = surface->format.RGBToColor(fR, fG, fB);
|
||||
}
|
||||
|
||||
/* Show the widget */
|
||||
void GUI_Area::Display(bool full_redraw) {
|
||||
Common::Rect framerect;
|
||||
int x, dy, r1, r2, x0, y0;
|
||||
|
||||
switch (shape) {
|
||||
case AREA_ROUND:
|
||||
|
||||
r1 = area.width() >> 1;
|
||||
r2 = area.height() >> 1;
|
||||
x0 = area.left + r1;
|
||||
y0 = area.top + r2;
|
||||
for (x = area.left; x < area.left + area.width(); x++) {
|
||||
dy = (int)((double) r2 * sin(acos((double)(x - x0) / (double) r1)));
|
||||
framerect.left = x;
|
||||
framerect.top = y0 - dy;
|
||||
framerect.setWidth(1);
|
||||
framerect.setHeight(dy << 1);
|
||||
SDL_FillRect(surface, &framerect, color);
|
||||
if (useFrame) {
|
||||
if ((x == area.left) || (x == area.left + area.width() - 1)) {
|
||||
SDL_FillRect(surface, &framerect, frameColor);
|
||||
}
|
||||
framerect.setHeight(frameThickness);
|
||||
SDL_FillRect(surface, &framerect, frameColor);
|
||||
framerect.top = y0 + dy - frameThickness;
|
||||
SDL_FillRect(surface, &framerect, frameColor);
|
||||
}
|
||||
}
|
||||
/*
|
||||
******** GUI_FillEllipse is not ready yet, GUI_BoundaryFill either *****
|
||||
framerect=area;
|
||||
if (useFrame)
|
||||
{
|
||||
GUI_FillEllipse(screen,&framerect,frameColor);
|
||||
area.left+=frameThickness; area.width()-=frameThickness << 1;
|
||||
area.top+=frameThickness; area.height()-=frameThickness << 1;
|
||||
}
|
||||
GUI_FillEllipse(screen,&framerect,color);
|
||||
*/
|
||||
break;
|
||||
|
||||
case AREA_ANGULAR:
|
||||
framerect = area;
|
||||
SDL_FillRect(surface, &framerect, color);
|
||||
|
||||
/* draw frame */
|
||||
if (useFrame) {
|
||||
framerect = area;
|
||||
framerect.setHeight(frameThickness);
|
||||
SDL_FillRect(surface, &framerect, frameColor);
|
||||
framerect = area;
|
||||
framerect.top = framerect.bottom - frameThickness;
|
||||
SDL_FillRect(surface, &framerect, frameColor);
|
||||
framerect = area;
|
||||
framerect.setWidth(frameThickness);
|
||||
SDL_FillRect(surface, &framerect, frameColor);
|
||||
framerect = area;
|
||||
framerect.left = framerect.right - frameThickness;
|
||||
SDL_FillRect(surface, &framerect, frameColor);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
DisplayChildren();
|
||||
|
||||
screen->update(area.left, area.top, area.width(), area.height());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
73
engines/ultima/nuvie/gui/gui_area.h
Normal file
73
engines/ultima/nuvie/gui/gui_area.h
Normal file
@@ -0,0 +1,73 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/* This is a simple colored area widget -- rectangular or round */
|
||||
|
||||
#ifndef NUVIE_GUI_GUI_AREA_H
|
||||
#define NUVIE_GUI_GUI_AREA_H
|
||||
|
||||
#include "ultima/nuvie/gui/widgets/gui_widget.h"
|
||||
#include "ultima/nuvie/screen/screen.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
#define AREA_ROUND 1
|
||||
#define AREA_ANGULAR 2
|
||||
|
||||
class GUI_Area : public GUI_Widget {
|
||||
|
||||
public:
|
||||
/* Passed the area, color and shape */
|
||||
GUI_Area(int x, int y, int w, int h, uint8 r, uint8 g, uint8 b, int aShape = AREA_ANGULAR);
|
||||
|
||||
/* Passed the area, color, frame color, frame thickness and shape */
|
||||
GUI_Area(int x, int y, int w, int h, uint8 r, uint8 g, uint8 b,
|
||||
uint8 fr, uint8 fg, uint8 fb, int fthick, int aShape = AREA_ANGULAR);
|
||||
|
||||
/* Map the color to the display */
|
||||
void SetDisplay(Screen *s) override;
|
||||
|
||||
/* Show the widget */
|
||||
void Display(bool full_redraw) override;
|
||||
|
||||
|
||||
protected:
|
||||
uint8 R, G, B;
|
||||
uint32 color;
|
||||
|
||||
/* flag */
|
||||
int useFrame;
|
||||
|
||||
/* frame color values */
|
||||
uint8 fR, fG, fB;
|
||||
uint32 frameColor;
|
||||
|
||||
/* remember me */
|
||||
int frameThickness;
|
||||
int shape;
|
||||
|
||||
};
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
337
engines/ultima/nuvie/gui/gui_button.cpp
Normal file
337
engines/ultima/nuvie/gui/gui_button.cpp
Normal file
@@ -0,0 +1,337 @@
|
||||
/* 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/nuvie/core/nuvie_defs.h"
|
||||
#include "ultima/nuvie/gui/gui_button.h"
|
||||
#include "ultima/nuvie/gui/gui_load_image.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
/* the check marks bitmap */
|
||||
Graphics::ManagedSurface *checkmarks = nullptr;
|
||||
|
||||
|
||||
GUI_Button:: GUI_Button(void *data, int x, int y, Graphics::ManagedSurface *image,
|
||||
Graphics::ManagedSurface *image2, GUI_CallBack *callback, bool free_surfaces)
|
||||
: GUI_Widget(data, x, y, image->w, image->h), callback_object(callback), button(image),
|
||||
button2(image2), freebutton(free_surfaces), enabled(true), buttonFont(nullptr),
|
||||
freefont(false), flatbutton(false), is_checkable(false), checked(0), is_highlighted(false) {
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
pressed[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
GUI_Button::GUI_Button(void *data, int x, int y, int w, int h,
|
||||
GUI_CallBack *callback)
|
||||
: GUI_Widget(data, x, y, w, h), callback_object(callback), button(nullptr),
|
||||
button2(nullptr), freebutton(false), enabled(true), buttonFont(nullptr),
|
||||
freefont(false), flatbutton(false), is_checkable(false), checked(0), is_highlighted(false) {
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
pressed[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
GUI_Button::GUI_Button(void *data, int x, int y, int w, int h, const char *text,
|
||||
GUI_Font *font, ButtonTextAlign alignment, bool is_checkbutton,
|
||||
GUI_CallBack *callback, bool flat)
|
||||
: GUI_Widget(data, x, y, w, h) {
|
||||
callback_object = callback;
|
||||
|
||||
if (font != nullptr) {
|
||||
buttonFont = font;
|
||||
freefont = false;
|
||||
} else {
|
||||
buttonFont = new GUI_Font();
|
||||
freefont = true;
|
||||
}
|
||||
flatbutton = flat;
|
||||
freebutton = true;
|
||||
button = nullptr;
|
||||
button2 = nullptr;
|
||||
|
||||
is_checkable = is_checkbutton;
|
||||
checked = 0;
|
||||
is_highlighted = false;
|
||||
/*
|
||||
if (is_checkable &&(checkmarks==nullptr))
|
||||
{
|
||||
checkmarks=GUI_LoadImage(checker_w,checker_h,checker_pal,checker_data);
|
||||
SDL_SetColorKey(checkmarks,SDL_SRCCOLORKEY,0);
|
||||
}
|
||||
*/
|
||||
ChangeTextButton(-1, -1, -1, -1, text, alignment);
|
||||
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
pressed[i] = 0;
|
||||
}
|
||||
enabled = true;
|
||||
}
|
||||
|
||||
GUI_Button::~GUI_Button() {
|
||||
if (freebutton) {
|
||||
if (button)
|
||||
delete button;
|
||||
if (button2)
|
||||
delete button2;
|
||||
}
|
||||
if (freefont)
|
||||
delete buttonFont;
|
||||
}
|
||||
|
||||
/* Resize/reposition/change text */
|
||||
void GUI_Button::ChangeTextButton(int x, int y, int w, int h, const char *text, ButtonTextAlign alignment) {
|
||||
if (x != -1 || y != -1) {
|
||||
assert(x >= 0 && y >= 0);
|
||||
area.moveTo(x, y);
|
||||
}
|
||||
|
||||
if (w != -1 || h != -1) {
|
||||
assert(w >= 0 && h >= 0);
|
||||
area.setWidth(w);
|
||||
area.setHeight(h);
|
||||
}
|
||||
|
||||
if (freebutton) {
|
||||
if (button)
|
||||
delete button;
|
||||
if (button2)
|
||||
delete button2;
|
||||
if (flatbutton) {
|
||||
button = CreateTextButtonImage(BUTTON2D_UP, text, alignment);
|
||||
button2 = CreateTextButtonImage(BUTTON2D_DOWN, text, alignment);
|
||||
} else {
|
||||
button = CreateTextButtonImage(BUTTON3D_UP, text, alignment);
|
||||
button2 = CreateTextButtonImage(BUTTON3D_DOWN, text, alignment);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Show the widget */
|
||||
void GUI_Button:: Display(bool full_redraw) {
|
||||
Common::Rect src, dest = area;
|
||||
|
||||
if (button) {
|
||||
if ((button2 != nullptr) && ((pressed[0]) == 1 || is_highlighted))
|
||||
SDL_BlitSurface(button2, nullptr, surface, &dest);
|
||||
else
|
||||
SDL_BlitSurface(button, nullptr, surface, &dest);
|
||||
}
|
||||
if (is_checkable) {
|
||||
src.left = 8 - (checked * 8);
|
||||
src.top = 0;
|
||||
src.setWidth(8);
|
||||
src.setHeight(10);
|
||||
dest.left += 4;
|
||||
dest.top += 4;
|
||||
dest.setWidth(8);
|
||||
dest.setHeight(10);
|
||||
SDL_BlitSurface(checkmarks, &src, surface, &dest);
|
||||
}
|
||||
if (!enabled) {
|
||||
uint8 *pointer;
|
||||
int pixel = surface->format.RGBToColor(0, 0, 0);
|
||||
uint8 bytepp = surface->format.bytesPerPixel;
|
||||
|
||||
for (int y = 0; y < area.height(); y += 2) {
|
||||
pointer = (uint8 *)surface->getPixels() + surface->pitch * (area.top + y) + (area.left * bytepp);
|
||||
for (int x = 0; x<area.width() >> 1; x++) {
|
||||
switch (bytepp) {
|
||||
case 1:
|
||||
*((uint8 *)(pointer)) = (uint8)pixel;
|
||||
pointer += 2;
|
||||
break;
|
||||
case 2:
|
||||
*((uint16 *)(pointer)) = (uint16)pixel;
|
||||
pointer += 4;
|
||||
break;
|
||||
case 3: /* Format/endian independent */
|
||||
uint8 r, g, b;
|
||||
|
||||
r = (pixel >> surface->format.rShift) & 0xFF;
|
||||
g = (pixel >> surface->format.gShift) & 0xFF;
|
||||
b = (pixel >> surface->format.bShift) & 0xFF;
|
||||
*((pointer) + surface->format.rShift / 8) = r;
|
||||
*((pointer) + surface->format.gShift / 8) = g;
|
||||
*((pointer) + surface->format.bShift / 8) = b;
|
||||
pointer += 6;
|
||||
break;
|
||||
case 4:
|
||||
*((uint32 *)(pointer)) = (uint32)pixel;
|
||||
pointer += 8;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DisplayChildren();
|
||||
}
|
||||
|
||||
/* Mouse hits activate us */
|
||||
GUI_status GUI_Button:: MouseDown(int x, int y, Events::MouseButton btn) {
|
||||
// if(btn == SDL_BUTTON_WHEELUP || btn == SDL_BUTTON_WHEELDOWN)
|
||||
// return GUI_PASS;
|
||||
if (enabled && (btn == Events::BUTTON_LEFT || btn == Events::BUTTON_RIGHT)) {
|
||||
pressed[0] = 1;
|
||||
Redraw();
|
||||
}
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
GUI_status GUI_Button::MouseUp(int x, int y, Events::MouseButton btn) {
|
||||
// if (btn==SDL_BUTTON_WHEELUP || btn==SDL_BUTTON_WHEELDOWN)
|
||||
// return GUI_PASS;
|
||||
if ((btn == Events::BUTTON_LEFT || btn == Events::BUTTON_RIGHT) && (pressed[0])) {
|
||||
pressed[0] = 0;
|
||||
return Activate_button(x, y, btn);
|
||||
}
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
GUI_status GUI_Button::Activate_button(int x, int y, Events::MouseButton btn) {
|
||||
if (x >= 0 && y >= 0) {
|
||||
if (callback_object && callback_object->callback(BUTTON_CB, this, widget_data) == GUI_QUIT)
|
||||
return GUI_QUIT;
|
||||
}
|
||||
Redraw();
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
GUI_status GUI_Button::MouseMotion(int x, int y, uint8 state) {
|
||||
if ((pressed[0] == 1) && ((x < 0) || (y < 0))) {
|
||||
pressed[0] = 2;
|
||||
Redraw();
|
||||
}
|
||||
if ((pressed[0] == 2) && (x >= 0) && (y >= 0)) {
|
||||
pressed[0] = 1;
|
||||
Redraw();
|
||||
}
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
void GUI_Button::Disable() {
|
||||
enabled = false;
|
||||
Redraw();
|
||||
}
|
||||
|
||||
void GUI_Button::Enable(bool flag) {
|
||||
enabled = flag;
|
||||
Redraw();
|
||||
}
|
||||
|
||||
Graphics::ManagedSurface *GUI_Button::CreateTextButtonImage(int style, const char *text, ButtonTextAlign alignment) {
|
||||
Common::Rect fillrect;
|
||||
int th, tw;
|
||||
int tx = 0, ty = 0;
|
||||
char *duptext = nullptr;
|
||||
|
||||
Graphics::ManagedSurface *img = new Graphics::ManagedSurface(area.width(), area.height(),
|
||||
Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0));
|
||||
|
||||
if (img == nullptr)
|
||||
return nullptr;
|
||||
|
||||
uint32 color1 = img->format.RGBToColor(BL_R, BL_G, BL_B);
|
||||
uint32 color2 = img->format.RGBToColor(BS_R, BS_G, BS_B);
|
||||
uint32 color3 = img->format.RGBToColor(BF_R, BF_G, BF_B);
|
||||
uint32 color4 = img->format.RGBToColor(BI2_R, BI2_G, BI2_B);
|
||||
|
||||
|
||||
buttonFont->setColoring(0, 0, 0);
|
||||
buttonFont->setTransparency(true);
|
||||
buttonFont->textExtent(text, &tw, &th);
|
||||
int checkable = (is_checkable ? 1 : 0);
|
||||
if (tw > (area.width() - (4 + checkable * 16))) {
|
||||
int n = (area.width() - (4 + checkable * 16)) / buttonFont->charWidth();
|
||||
duptext = new char[n + 1];
|
||||
strncpy(duptext, text, n);
|
||||
duptext[n] = 0;
|
||||
text = duptext;
|
||||
buttonFont->textExtent(text, &tw, &th);
|
||||
}
|
||||
if (th > (area.height() - 4)) {
|
||||
text = "";
|
||||
}
|
||||
switch (alignment) {
|
||||
case BUTTON_TEXTALIGN_LEFT:
|
||||
tx = 4 + (checkable * 16);
|
||||
break;
|
||||
case BUTTON_TEXTALIGN_CENTER:
|
||||
tx = (area.width() - tw) >> 1;
|
||||
break;
|
||||
case BUTTON_TEXTALIGN_RIGHT:
|
||||
tx = area.width() - 5 - tw;
|
||||
break;
|
||||
}
|
||||
ty = (area.height() - th) >> 1;
|
||||
|
||||
if (!area.isEmpty()) {
|
||||
switch (style) {
|
||||
case BUTTON3D_UP:
|
||||
fillrect = Common::Rect(area.width(), 2);
|
||||
SDL_FillRect(img, &fillrect, color1);
|
||||
fillrect.moveTo(0, area.height() - 2);
|
||||
SDL_FillRect(img, &fillrect, color2);
|
||||
|
||||
fillrect = Common::Rect(2, area.height());
|
||||
SDL_FillRect(img, &fillrect, color1);
|
||||
fillrect.moveTo(area.width() - 2, 0);
|
||||
SDL_FillRect(img, &fillrect, color2);
|
||||
|
||||
fillrect.setHeight(1);
|
||||
fillrect.setWidth(1);
|
||||
SDL_FillRect(img, &fillrect, color1);
|
||||
fillrect.moveTo(1, area.height() - 1);
|
||||
SDL_FillRect(img, &fillrect, color2);
|
||||
|
||||
fillrect = Common::Rect(2, 2, area.width() - 2, area.height() - 2);
|
||||
SDL_FillRect(img, &fillrect, color3);
|
||||
|
||||
buttonFont->textOut(img, tx, ty, text);
|
||||
break;
|
||||
case BUTTON3D_DOWN:
|
||||
fillrect = Common::Rect(area.width(), area.height());
|
||||
SDL_FillRect(img, &fillrect, color3);
|
||||
buttonFont->textOut(img, tx + 1, ty + 1, text);
|
||||
break;
|
||||
case BUTTON2D_UP:
|
||||
fillrect = Common::Rect(area.width(), area.height());
|
||||
SDL_FillRect(img, &fillrect, color3);
|
||||
buttonFont->textOut(img, tx, ty, text);
|
||||
break;
|
||||
case BUTTON2D_DOWN:
|
||||
fillrect = Common::Rect(area.width(), area.height());
|
||||
SDL_FillRect(img, &fillrect, color4);
|
||||
buttonFont->setTransparency(false);
|
||||
buttonFont->setColoring(BI1_R, BI1_G, BI1_B, BI2_R, BI2_G, BI2_B);
|
||||
buttonFont->textOut(img, tx, ty, text);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
delete[] duptext;
|
||||
|
||||
return img;
|
||||
}
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
147
engines/ultima/nuvie/gui/gui_button.h
Normal file
147
engines/ultima/nuvie/gui/gui_button.h
Normal file
@@ -0,0 +1,147 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/* This is a very generic button widget - NOT ANY LONGER*/
|
||||
|
||||
#ifndef NUVIE_GUI_GUI_BUTTON_H
|
||||
#define NUVIE_GUI_GUI_BUTTON_H
|
||||
|
||||
#include "ultima/nuvie/gui/widgets/gui_widget.h"
|
||||
#include "ultima/nuvie/gui/gui_font.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
class GUI_CallBack;
|
||||
|
||||
/* design constants */
|
||||
#define BUTTON3D_UP 1
|
||||
#define BUTTON3D_DOWN 2
|
||||
#define BUTTON2D_UP 3
|
||||
#define BUTTON2D_DOWN 4
|
||||
|
||||
/* alignment constants */
|
||||
enum ButtonTextAlign {
|
||||
BUTTON_TEXTALIGN_LEFT = 1,
|
||||
BUTTON_TEXTALIGN_CENTER = 2,
|
||||
BUTTON_TEXTALIGN_RIGHT = 3,
|
||||
};
|
||||
|
||||
// Callback message types
|
||||
|
||||
static const uint16 BUTTON_CB = 0x1;
|
||||
|
||||
/* color constants */
|
||||
|
||||
// Button face color
|
||||
static const uint8 BF_R = 183, BF_G = 185, BF_B = 150;
|
||||
// Button light color
|
||||
static const uint8 BL_R = 245, BL_G = 247, BL_B = 201;
|
||||
// Button shadow color
|
||||
static const uint8 BS_R = 115, BS_G = 116, BS_B = 94;
|
||||
// 2D Button inverse text color
|
||||
static const uint8 BI1_R = 255, BI1_G = 255, BI1_B = 255;
|
||||
// 2D Button inverse background color
|
||||
static const uint8 BI2_R = 0, BI2_G = 0, BI2_B = 0;
|
||||
|
||||
#define GUI_BUTTON_DONT_FREE_SURFACES false
|
||||
|
||||
/* This is the definition of the "I've been activated" callback */
|
||||
typedef GUI_status(*GUI_ActiveProc)(void *data);
|
||||
|
||||
class GUI_Button : public GUI_Widget {
|
||||
|
||||
public:
|
||||
/* Passed the button data, position, images (pressed/unpressed) and callback */
|
||||
GUI_Button(void *data, int x, int y, Graphics::ManagedSurface *image,
|
||||
Graphics::ManagedSurface *image2, GUI_CallBack *callback, bool free_surfaces = true);
|
||||
|
||||
/* I don't know what this one is for */
|
||||
GUI_Button(void *data, int x, int y, int w, int h,
|
||||
GUI_CallBack *callback);
|
||||
|
||||
/* Passed the button data, position, width, height, a caption, a font,
|
||||
an alignment (enum above), if it should be a checkbutton (1/0),
|
||||
the callback and a flag if it should be 2D (1) or 3D (0) */
|
||||
GUI_Button(void *data, int x, int y, int w, int h, const char *text,
|
||||
GUI_Font *font, ButtonTextAlign alignment, bool is_checkbutton,
|
||||
GUI_CallBack *callback, bool flat = false);
|
||||
|
||||
~GUI_Button() override;
|
||||
|
||||
/* change features of a text button (if one of the dimensions is negativ, it's ignored) */
|
||||
virtual void ChangeTextButton(int x, int y, int w, int h, const char *text, ButtonTextAlign alignment);
|
||||
|
||||
/* Show the widget */
|
||||
void Display(bool full_redraw) override;
|
||||
|
||||
/* Mouse hits activate us */
|
||||
GUI_status MouseDown(int x, int y, Events::MouseButton button) override;
|
||||
GUI_status MouseUp(int x, int y, Events::MouseButton button) override;
|
||||
GUI_status MouseMotion(int x, int y, uint8 state) override;
|
||||
|
||||
/* Clickable or not ... */
|
||||
virtual void Disable();
|
||||
virtual void Enable(bool flag = true);
|
||||
|
||||
/* yields current state */
|
||||
virtual bool Enabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
/* yields flag if button is a checkbutton */
|
||||
virtual bool IsCheckButton() {
|
||||
return is_checkable;
|
||||
}
|
||||
virtual void set_highlighted(bool val) {
|
||||
is_highlighted = val;
|
||||
}
|
||||
virtual GUI_status Activate_button(int x = 0, int y = 0, Events::MouseButton button = Events::BUTTON_LEFT);
|
||||
|
||||
protected:
|
||||
/* yields an appropriate image */
|
||||
virtual Graphics::ManagedSurface *CreateTextButtonImage(int style, const char *text, ButtonTextAlign alignment);
|
||||
|
||||
/* The button font */
|
||||
GUI_Font *buttonFont;
|
||||
|
||||
/* The button images */
|
||||
Graphics::ManagedSurface *button, *button2;
|
||||
|
||||
/* The activation callback */
|
||||
GUI_CallBack *callback_object;
|
||||
|
||||
/* remember me! - flags */
|
||||
bool enabled;
|
||||
bool flatbutton;
|
||||
bool freebutton;
|
||||
bool freefont;
|
||||
|
||||
/* Checkbutton flags */
|
||||
bool is_checkable;
|
||||
int checked;
|
||||
bool is_highlighted;
|
||||
};
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
51
engines/ultima/nuvie/gui/gui_callback.h
Normal file
51
engines/ultima/nuvie/gui/gui_callback.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NUVIE_GUI_GUI_CALLBACK_H
|
||||
#define NUVIE_GUI_GUI_CALLBACK_H
|
||||
|
||||
#include "ultima/nuvie/gui/gui_status.h"
|
||||
#include "ultima/nuvie/core/nuvie_defs.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
class GUI_CallBack {
|
||||
|
||||
public:
|
||||
|
||||
GUI_CallBack() {
|
||||
return;
|
||||
}
|
||||
virtual ~GUI_CallBack() {
|
||||
return;
|
||||
}
|
||||
virtual GUI_status callback(uint16 msg, GUI_CallBack *caller, void *data) {
|
||||
DEBUG(false, LEVEL_WARNING, "Unhandled callback. msg (%x)\n", msg);
|
||||
return GUI_PASS;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
109
engines/ultima/nuvie/gui/gui_console.cpp
Normal file
109
engines/ultima/nuvie/gui/gui_console.cpp
Normal file
@@ -0,0 +1,109 @@
|
||||
/* 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/widgets/gui_widget.h"
|
||||
#include "ultima/nuvie/gui/gui_console.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
GUI_Console::GUI_Console(uint16 x, uint16 y, uint16 w, uint16 h)
|
||||
: GUI_Widget(nullptr, x, y, w, h) {
|
||||
bg_color = new GUI_Color(0, 0, 0);
|
||||
font = new GUI_Font(1);
|
||||
font->setColoring(0xff, 0xff, 0xff, 0, 0, 0);
|
||||
num_rows = (uint16)(h / font->charHeight());
|
||||
num_cols = (uint16)(w / font->charWidth());
|
||||
}
|
||||
|
||||
GUI_Console::~GUI_Console() {
|
||||
delete bg_color;
|
||||
delete font;
|
||||
}
|
||||
|
||||
/* Map the color to the display */
|
||||
void GUI_Console::SetDisplay(Screen *s) {
|
||||
GUI_Widget::SetDisplay(s);
|
||||
bg_color->map_color(surface->format);
|
||||
}
|
||||
|
||||
/* Show the widget */
|
||||
void GUI_Console:: Display(bool full_redraw) {
|
||||
SDL_FillRect(surface, &area, bg_color->sdl_color);
|
||||
|
||||
uint16 i = 0;
|
||||
for (const Std::string &s : data) {
|
||||
font->textOut(surface, area.left, area.top + i * font->charHeight(), s.c_str(), false);
|
||||
i++;
|
||||
}
|
||||
screen->update(area.left, area.top, area.width(), area.height());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void GUI_Console::AddLine(const Std::string &line) {
|
||||
uint16 len = line.size();
|
||||
uint16 i;
|
||||
|
||||
if (len > num_cols) {
|
||||
for (i = 0; i + num_cols < len; i += num_cols)
|
||||
data.push_back(Std::string(line.substr(i, num_cols)));
|
||||
|
||||
if (i < len)
|
||||
data.push_back(Std::string(line.substr(i, len - i)));
|
||||
} else
|
||||
data.push_back(line);
|
||||
|
||||
|
||||
for (i = data.size(); i > num_rows; i--)
|
||||
data.pop_front();
|
||||
}
|
||||
|
||||
GUI_status GUI_Console::MouseDown(int x, int y, Events::MouseButton button) {
|
||||
|
||||
|
||||
//grab_focus();
|
||||
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
GUI_status GUI_Console::MouseUp(int x, int y, Events::MouseButton button) {
|
||||
|
||||
// release_focus();
|
||||
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
GUI_status GUI_Console::MouseMotion(int x, int y, uint8 state) {
|
||||
|
||||
|
||||
//GUI::get_gui()->moveWidget(this,dx,dy);
|
||||
// Redraw();
|
||||
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
64
engines/ultima/nuvie/gui/gui_console.h
Normal file
64
engines/ultima/nuvie/gui/gui_console.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NUVIE_GUI_GUI_CONSOLE_H
|
||||
#define NUVIE_GUI_GUI_CONSOLE_H
|
||||
|
||||
|
||||
|
||||
#include "ultima/nuvie/gui/widgets/gui_widget.h"
|
||||
#include "ultima/nuvie/gui/gui_types.h"
|
||||
#include "ultima/nuvie/gui/gui_font.h"
|
||||
#include "ultima/nuvie/screen/screen.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
class GUI_Console : public GUI_Widget {
|
||||
|
||||
GUI_Color *bg_color;
|
||||
GUI_Font *font;
|
||||
uint16 num_cols;
|
||||
uint16 num_rows;
|
||||
Std::list<Std::string> data;
|
||||
|
||||
public:
|
||||
GUI_Console(uint16 x, uint16 y, uint16 w, uint16 h);
|
||||
~GUI_Console() override;
|
||||
|
||||
/* Map the color to the display */
|
||||
void SetDisplay(Screen *s) override;
|
||||
|
||||
/* Show the widget */
|
||||
void Display(bool full_redraw) override;
|
||||
|
||||
/* events, used for dragging the area. */
|
||||
GUI_status MouseDown(int x, int y, Events::MouseButton button) override;
|
||||
GUI_status MouseUp(int x, int y, Events::MouseButton button) override;
|
||||
GUI_status MouseMotion(int x, int y, uint8 state) override;
|
||||
|
||||
virtual void AddLine(const Std::string &line);
|
||||
};
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
254
engines/ultima/nuvie/gui/gui_dialog.cpp
Normal file
254
engines/ultima/nuvie/gui/gui_dialog.cpp
Normal file
@@ -0,0 +1,254 @@
|
||||
/* 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_dialog.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
GUI_Dialog::GUI_Dialog(int x, int y, int w, int h, uint8 r, uint8 g, uint8 b, bool is_moveable)
|
||||
: GUI_Widget(nullptr, x, y, w, h), R(r), G(g), B(b), bg_color(0), drag(false),
|
||||
can_drag(is_moveable), button_x(0), button_y(0), old_x(-1), old_y(-1),
|
||||
backingstore(nullptr) {
|
||||
backingstore_rect.setWidth(w);
|
||||
backingstore_rect.setHeight(h);
|
||||
loadBorderImages();
|
||||
}
|
||||
|
||||
GUI_Dialog::~GUI_Dialog() {
|
||||
if (backingstore)
|
||||
free(backingstore);
|
||||
|
||||
for (int i = 0; i < ARRAYSIZE(border); i++)
|
||||
delete border[i];
|
||||
}
|
||||
|
||||
void GUI_Dialog::loadBorderImages() {
|
||||
char filename[15]; // BorderU6_x.bmp\0
|
||||
Common::Path datadir = GUI::get_gui()->get_data_dir();
|
||||
Common::Path imagefile;
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
Common::sprintf_s(filename, "Border%s_%d.bmp", "U6", i + 1);
|
||||
build_path(datadir, filename, imagefile);
|
||||
border[i] = SDL_LoadBMP(imagefile);
|
||||
if (border[i] == nullptr) {
|
||||
DEBUG(0, LEVEL_ERROR, "Failed to load %s from '%s' directory\n", filename, datadir.toString().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Map the color to the display */
|
||||
void GUI_Dialog::SetDisplay(Screen *s) {
|
||||
GUI_Widget::SetDisplay(s);
|
||||
bg_color = surface->format.RGBToColor(R, G, B);
|
||||
}
|
||||
|
||||
/* Show the widget */
|
||||
void
|
||||
GUI_Dialog::Display(bool full_redraw) {
|
||||
int i;
|
||||
if (old_x != area.left || old_y != area.top) {
|
||||
if (backingstore) {
|
||||
screen->restore_area(backingstore, &backingstore_rect, nullptr, nullptr, false);
|
||||
screen->update(backingstore_rect.left, backingstore_rect.top,
|
||||
backingstore_rect.width(), backingstore_rect.height());
|
||||
}
|
||||
|
||||
backingstore_rect.moveTo(area.left, area.top);
|
||||
backingstore = screen->copy_area(&backingstore_rect, backingstore);
|
||||
|
||||
old_x = area.left;
|
||||
old_y = area.top;
|
||||
}
|
||||
|
||||
Common::Rect framerect = area;
|
||||
framerect.grow(-8);
|
||||
SDL_FillRect(surface, &framerect, bg_color);
|
||||
|
||||
// Draw border corners
|
||||
|
||||
Common::Rect dst;
|
||||
dst = area;
|
||||
dst.setWidth(8);
|
||||
dst.setHeight(8);
|
||||
SDL_BlitSurface(border[0], nullptr, surface, &dst);
|
||||
|
||||
dst.left = area.left + area.width() - 8;
|
||||
dst.top = area.top;
|
||||
dst.setWidth(8);
|
||||
dst.setHeight(8);
|
||||
SDL_BlitSurface(border[2], nullptr, surface, &dst);
|
||||
|
||||
dst.left = area.left + area.width() - 8;
|
||||
dst.top = area.top + area.height() - 8;
|
||||
dst.setWidth(8);
|
||||
dst.setHeight(8);
|
||||
SDL_BlitSurface(border[4], nullptr, surface, &dst);
|
||||
|
||||
dst.left = area.left;
|
||||
dst.top = area.top + area.height() - 8;
|
||||
dst.setWidth(8);
|
||||
dst.setHeight(8);
|
||||
SDL_BlitSurface(border[6], nullptr, surface, &dst);
|
||||
|
||||
// Draw top and bottom border lines
|
||||
|
||||
for (i = area.left + 8; i < area.left + area.width() - 24; i += 16) {
|
||||
dst.left = i;
|
||||
dst.top = area.top;
|
||||
dst.setWidth(16);
|
||||
dst.setHeight(8);
|
||||
SDL_BlitSurface(border[1], nullptr, surface, &dst);
|
||||
|
||||
dst.left = i;
|
||||
dst.top = area.top + area.height() - 8;
|
||||
dst.setWidth(16);
|
||||
dst.setHeight(8);
|
||||
SDL_BlitSurface(border[5], nullptr, surface, &dst);
|
||||
}
|
||||
|
||||
if (i < area.left + area.width() - 8) { // draw partial border images
|
||||
Common::Rect src;
|
||||
src.left = 0;
|
||||
src.top = 0;
|
||||
src.setWidth(area.left + area.width() - 8 - i);
|
||||
src.setHeight(8);
|
||||
|
||||
dst.left = i;
|
||||
dst.top = area.top;
|
||||
dst.setWidth(src.width());
|
||||
dst.setHeight(8);
|
||||
SDL_BlitSurface(border[1], &src, surface, &dst);
|
||||
|
||||
dst.left = i;
|
||||
dst.top = area.top + area.height() - 8;
|
||||
dst.setWidth(src.width());
|
||||
dst.setHeight(8);
|
||||
SDL_BlitSurface(border[5], &src, surface, &dst);
|
||||
}
|
||||
|
||||
// Draw left and right sides
|
||||
|
||||
|
||||
for (i = area.top + 8; i < area.top + area.height() - 24; i += 16) {
|
||||
dst.left = area.left;
|
||||
dst.top = i;
|
||||
dst.setWidth(8);
|
||||
dst.setHeight(16);
|
||||
SDL_BlitSurface(border[7], nullptr, surface, &dst);
|
||||
|
||||
dst.left = area.left + area.width() - 8;
|
||||
dst.top = i;
|
||||
dst.setWidth(8);
|
||||
dst.setHeight(16);
|
||||
SDL_BlitSurface(border[3], nullptr, surface, &dst);
|
||||
}
|
||||
|
||||
if (i < area.top + area.height() - 8) { // draw partial border images
|
||||
Common::Rect src;
|
||||
src.left = 0;
|
||||
src.top = 0;
|
||||
src.setWidth(8);
|
||||
src.setHeight(area.top + area.height() - 8 - i);
|
||||
|
||||
dst.left = area.left;
|
||||
dst.top = i;
|
||||
dst.setWidth(8);
|
||||
dst.setHeight(src.height());
|
||||
SDL_BlitSurface(border[7], &src, surface, &dst);
|
||||
|
||||
dst.left = area.left + area.width() - 8;
|
||||
dst.top = i;
|
||||
dst.setWidth(8);
|
||||
dst.setHeight(src.height());
|
||||
SDL_BlitSurface(border[3], &src, surface, &dst);
|
||||
}
|
||||
|
||||
DisplayChildren();
|
||||
|
||||
screen->update(area.left, area.top, area.width(), area.height());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
GUI_status GUI_Dialog::MouseDown(int x, int y, Events::MouseButton button) {
|
||||
drag = can_drag;
|
||||
button_x = x;
|
||||
button_y = y;
|
||||
|
||||
grab_focus();
|
||||
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
GUI_status GUI_Dialog::MouseUp(int x, int y, Events::MouseButton button) {
|
||||
drag = false;
|
||||
|
||||
release_focus();
|
||||
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
GUI_status GUI_Dialog::MouseMotion(int x, int y, uint8 state) {
|
||||
if (!drag)
|
||||
return GUI_PASS;
|
||||
|
||||
int dx = x - button_x;
|
||||
int dy = y - button_y;
|
||||
|
||||
button_x = x;
|
||||
button_y = y;
|
||||
|
||||
GUI::get_gui()->moveWidget(this, dx, dy);
|
||||
// Redraw();
|
||||
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
void GUI_Dialog::MoveRelative(int dx, int dy) {
|
||||
int new_x = area.left + dx;
|
||||
|
||||
if (new_x < 0) {
|
||||
dx = -area.left;
|
||||
} else if (new_x + area.width() > screen->get_width()) {
|
||||
dx = screen->get_width() - (area.left + area.width());
|
||||
}
|
||||
|
||||
int new_y = area.top + dy;
|
||||
|
||||
if (new_y < 0) {
|
||||
dy = -area.top;
|
||||
} else if (new_y + area.height() > screen->get_height()) {
|
||||
dy = screen->get_height() - (area.top + area.height());
|
||||
}
|
||||
|
||||
GUI_Widget::MoveRelative(dx, dy);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
72
engines/ultima/nuvie/gui/gui_dialog.h
Normal file
72
engines/ultima/nuvie/gui/gui_dialog.h
Normal file
@@ -0,0 +1,72 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NUVIE_GUI_GUI_DIALOG_H
|
||||
#define NUVIE_GUI_GUI_DIALOG_H
|
||||
|
||||
|
||||
|
||||
#include "ultima/nuvie/gui/widgets/gui_widget.h"
|
||||
#include "ultima/nuvie/screen/screen.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
#define GUI_DIALOG_MOVABLE true
|
||||
#define GUI_DIALOG_UNMOVABLE false
|
||||
|
||||
class GUI_Dialog : public GUI_Widget {
|
||||
|
||||
int old_x, old_y;
|
||||
int button_x, button_y;
|
||||
uint8 R, G, B;
|
||||
uint32 bg_color;
|
||||
|
||||
bool drag;
|
||||
Graphics::ManagedSurface *border[8];
|
||||
|
||||
unsigned char *backingstore;
|
||||
|
||||
Common::Rect backingstore_rect;
|
||||
public:
|
||||
/* Passed the area, color and shape */
|
||||
GUI_Dialog(int x, int y, int w, int h, uint8 r, uint8 g, uint8 b, bool is_moveable);
|
||||
~GUI_Dialog() override;
|
||||
/* Map the color to the display */
|
||||
void SetDisplay(Screen *s) override;
|
||||
|
||||
/* Show the widget */
|
||||
void Display(bool full_redraw) override;
|
||||
|
||||
/* events, used for dragging the area. */
|
||||
GUI_status MouseDown(int x, int y, Events::MouseButton button) override;
|
||||
GUI_status MouseUp(int x, int y, Events::MouseButton button) override;
|
||||
GUI_status MouseMotion(int x, int y, uint8 state) override;
|
||||
void MoveRelative(int dx, int dy) override;
|
||||
protected:
|
||||
bool can_drag;
|
||||
void loadBorderImages();
|
||||
};
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
68
engines/ultima/nuvie/gui/gui_drag_area.h
Normal file
68
engines/ultima/nuvie/gui/gui_drag_area.h
Normal file
@@ -0,0 +1,68 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NUVIE_GUI_GUI_DRAG_AREA_H
|
||||
#define NUVIE_GUI_GUI_DRAG_AREA_H
|
||||
|
||||
#include "ultima/nuvie/gui/gui_callback.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
class GUI_DragArea : public GUI_CallBack {
|
||||
|
||||
protected:
|
||||
bool drop_target;
|
||||
bool dragging;
|
||||
|
||||
public:
|
||||
|
||||
GUI_DragArea() {
|
||||
dragging = false;
|
||||
drop_target = true;
|
||||
}
|
||||
|
||||
bool is_drop_target() {
|
||||
return drop_target;
|
||||
}
|
||||
|
||||
virtual bool drag_accept_drop(int x, int y, int message, void *data) {
|
||||
return false;
|
||||
}
|
||||
virtual void drag_perform_drop(int x, int y, int message, void *data) {
|
||||
return;
|
||||
}
|
||||
virtual void drag_drop_failed(int x, int y, int message, void *data) {
|
||||
return;
|
||||
}
|
||||
virtual void drag_drop_success(int x, int y, int message, void *data) {
|
||||
return;
|
||||
}
|
||||
virtual void drag_draw(int x, int y, int message, void *data) {
|
||||
return;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
84
engines/ultima/nuvie/gui/gui_drag_manager.cpp
Normal file
84
engines/ultima/nuvie/gui/gui_drag_manager.cpp
Normal file
@@ -0,0 +1,84 @@
|
||||
/* 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/nuvie/core/nuvie_defs.h"
|
||||
#include "ultima/nuvie/gui/gui_drag_area.h"
|
||||
#include "ultima/nuvie/gui/gui_drag_manager.h"
|
||||
#include "ultima/nuvie/core/game.h" // -+- Included so we can set WAIT_MODE while dragging.
|
||||
#include "ultima/nuvie/core/events.h" // /
|
||||
#include "ultima/nuvie/gui/widgets/msg_scroll.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
GUI_DragManager::GUI_DragManager(Screen *s): screen(s), message(0),
|
||||
data(nullptr), drag_source(nullptr), is_out_of_range(false) {
|
||||
}
|
||||
|
||||
GUI_status GUI_DragManager::start_drag(GUI_DragArea *src, int msg, void *d, unsigned char *icon_buf, uint16 w, uint16 h, uint8 bpp, bool out_of_range) {
|
||||
DEBUG(false, LEVEL_DEBUGGING, "Start Drag\n");
|
||||
|
||||
drag_source = src;
|
||||
message = msg;
|
||||
data = d;
|
||||
is_out_of_range = out_of_range;
|
||||
//Game::get_game()->get_event()->set_mode(WAIT_MODE);
|
||||
Game::get_game()->pause_user();
|
||||
return GUI_DRAG_AND_DROP;
|
||||
}
|
||||
|
||||
void GUI_DragManager::drop(GUI_DragArea *drag_target, int x, int y) {
|
||||
DEBUG(0, LEVEL_DEBUGGING, "Drop\n");
|
||||
|
||||
//Game::get_game()->get_event()->endAction(); // WAIT_MODE
|
||||
Game::get_game()->unpause_user();
|
||||
if (is_out_of_range) {
|
||||
MsgScroll *scroll = Game::get_game()->get_scroll();
|
||||
scroll->display_string("Move-");
|
||||
scroll->display_string(Game::get_game()->get_obj_manager()->look_obj((Obj *)data)); // getting obj name
|
||||
scroll->message(".\n\nOut of range!\n\n");
|
||||
drag_source->drag_drop_failed(x, y, message, data);
|
||||
} else if (drag_target->drag_accept_drop(x, y, message, data)) {
|
||||
//inform the source of the success so it can perform operations before the drop takes place.
|
||||
drag_source->drag_drop_success(x, y, message, data);
|
||||
drag_target->drag_perform_drop(x, y, message, data);
|
||||
} else
|
||||
drag_source->drag_drop_failed(x, y, message, data);
|
||||
|
||||
|
||||
drag_source = nullptr;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void GUI_DragManager::draw(int x, int y) {
|
||||
if (!drag_source)
|
||||
return;
|
||||
|
||||
drag_source->drag_draw(x, y, message, data);
|
||||
}
|
||||
|
||||
GUI_DragArea *GUI_DragManager::get_source() {
|
||||
return drag_source;
|
||||
}
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
65
engines/ultima/nuvie/gui/gui_drag_manager.h
Normal file
65
engines/ultima/nuvie/gui/gui_drag_manager.h
Normal file
@@ -0,0 +1,65 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NUVIE_GUI_GUI_DRAG_MANAGER_H
|
||||
#define NUVIE_GUI_GUI_DRAG_MANAGER_H
|
||||
|
||||
#include "ultima/nuvie/gui/gui_status.h"
|
||||
#include "ultima/nuvie/gui/gui_drag_area.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
// Drag Messages.
|
||||
#define GUI_DRAG_OBJ 0
|
||||
|
||||
class Screen;
|
||||
|
||||
class GUI_DragManager {
|
||||
|
||||
protected:
|
||||
|
||||
Screen *screen;
|
||||
|
||||
GUI_DragArea *drag_source;
|
||||
int message;
|
||||
void *data;
|
||||
bool is_out_of_range;
|
||||
|
||||
public:
|
||||
|
||||
GUI_DragManager(Screen *s);
|
||||
|
||||
GUI_status start_drag(GUI_DragArea *src, int msg, void *d, unsigned char *icon_buf, uint16 w, uint16 h, uint8 bpp, bool out_of_range = false);
|
||||
void drop(GUI_DragArea *drag_target, int x, int y);
|
||||
|
||||
// let us find out where the drag originated, because we might
|
||||
// need to do something different depending on where a dragged
|
||||
// object is coming from.
|
||||
GUI_DragArea *get_source();
|
||||
|
||||
void draw(int x, int y);
|
||||
};
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
177
engines/ultima/nuvie/gui/gui_font.cpp
Normal file
177
engines/ultima/nuvie/gui/gui_font.cpp
Normal file
@@ -0,0 +1,177 @@
|
||||
/* 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/nuvie/misc/u6_misc.h"
|
||||
#include "ultima/nuvie/files/utils.h"
|
||||
#include "ultima/nuvie/gui/gui_font.h"
|
||||
#include "ultima/nuvie/gui/gui_load_image.h"
|
||||
#include "common/textconsole.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
/* use default 8x8 font */
|
||||
GUI_Font::GUI_Font(uint8 fontType) : _wData(nullptr) {
|
||||
Graphics::ManagedSurface *temp;
|
||||
|
||||
if (fontType == GUI_FONT_6X8)
|
||||
temp = GUI_Font6x8();
|
||||
else if (fontType == GUI_FONT_GUMP) {
|
||||
temp = GUI_FontGump();
|
||||
_wData = GUI_FontGumpWData();
|
||||
} else
|
||||
temp = GUI_DefaultFont();
|
||||
|
||||
_fontStore = new Graphics::ManagedSurface(temp->w, temp->h, temp->format);
|
||||
_fontStore->blitFrom(*temp);
|
||||
|
||||
_charH = _fontStore->h / 16;
|
||||
_charW = _fontStore->w / 16;
|
||||
_disposeFont = DisposeAfterUse::YES;
|
||||
setTransparency(true);
|
||||
}
|
||||
|
||||
/* open named BMP file */
|
||||
GUI_Font::GUI_Font(const char *name) {
|
||||
_fontStore = SDL_LoadBMP(name);
|
||||
if (_fontStore != nullptr) {
|
||||
_charH = _fontStore->h / 16;
|
||||
_charW = _fontStore->w / 16;
|
||||
_disposeFont = DisposeAfterUse::YES;
|
||||
} else {
|
||||
::error("Could not load font");
|
||||
}
|
||||
|
||||
setTransparency(true);
|
||||
_wData = nullptr;
|
||||
}
|
||||
|
||||
/* use given YxY surface */
|
||||
GUI_Font::GUI_Font(Graphics::ManagedSurface *bitmap) {
|
||||
if (bitmap == nullptr)
|
||||
_fontStore = GUI_DefaultFont();
|
||||
else
|
||||
_fontStore = bitmap;
|
||||
_charH = _fontStore->h / 16;
|
||||
_charW = _fontStore->w / 16;
|
||||
_disposeFont = DisposeAfterUse::NO;
|
||||
setTransparency(true);
|
||||
_wData = nullptr;
|
||||
}
|
||||
|
||||
GUI_Font::~GUI_Font() {
|
||||
if (_disposeFont == DisposeAfterUse::YES)
|
||||
delete _fontStore;
|
||||
}
|
||||
|
||||
/* determine drawing style */
|
||||
void GUI_Font::setTransparency(bool on) {
|
||||
_transparent = on;
|
||||
|
||||
if (_transparent)
|
||||
_fontStore->setTransparentColor(0);
|
||||
else
|
||||
_fontStore->clearTransparentColor();
|
||||
}
|
||||
|
||||
/* determine foreground and background color values RGB*/
|
||||
void GUI_Font::setColoring(uint8 fr, uint8 fg, uint8 fb, uint8 br, uint8 bg, uint8 bb) {
|
||||
const uint8 colors[2 * 3] = {
|
||||
br, bg, bb,
|
||||
fr, fg, fb
|
||||
};
|
||||
_fontStore->setPalette(colors, 0, 2);
|
||||
}
|
||||
|
||||
void GUI_Font::setColoring(uint8 fr, uint8 fg, uint8 fb, uint8 fr1, uint8 fg1, uint8 fb1, uint8 br, uint8 bg, uint8 bb) {
|
||||
const uint8 colors[3 * 3] = {
|
||||
br, bg, bb,
|
||||
fr, fg, fb,
|
||||
fr1, fg1, fb1
|
||||
};
|
||||
_fontStore->setPalette(colors, 0, 3);
|
||||
}
|
||||
|
||||
/* put the text onto the given surface using the preset mode and colors */
|
||||
void GUI_Font::textOut(Graphics::ManagedSurface *context, int x, int y, const char *text, int line_wrap) {
|
||||
uint8 ch;
|
||||
Common::Rect src(_charW, _charH - 1);
|
||||
Common::Rect dst(_charW, _charH - 1);
|
||||
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
while ((ch = text[i])) { // single "=" is correct!
|
||||
if (line_wrap && j == line_wrap) {
|
||||
j = 0;
|
||||
y += _charH;
|
||||
}
|
||||
|
||||
src.moveTo((ch % 16) * _charW, (ch / 16) * _charH);
|
||||
if (_wData) {
|
||||
dst.left = x;
|
||||
dst.right = x + _wData[ch];
|
||||
x += dst.width();
|
||||
|
||||
} else {
|
||||
dst.moveTo(x + (j * _charW), dst.top);
|
||||
}
|
||||
|
||||
dst.moveTo(dst.left, y);
|
||||
SDL_BlitSurface(_fontStore, &src, context, &dst);
|
||||
i++;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
void GUI_Font:: textExtent(const char *text, int *w, int *h, int line_wrap) {
|
||||
int len = strlen(text);
|
||||
if (_wData) { //variable width font.
|
||||
//FIXME we're not handling line_wrap properly for variable width fonts!
|
||||
*w = 0;
|
||||
for (int i = 0; i < len; i++) {
|
||||
*w += _wData[(byte)text[i]];
|
||||
}
|
||||
} else {
|
||||
if (line_wrap && len > line_wrap)
|
||||
*w = line_wrap * _charW;
|
||||
else
|
||||
*w = len * _charW;
|
||||
}
|
||||
|
||||
if (line_wrap && len > line_wrap) {
|
||||
*h = (int)ceil((float)len / (float)line_wrap);
|
||||
*h *= _charH - 1;
|
||||
} else
|
||||
*h = _charH - 1;
|
||||
return;
|
||||
}
|
||||
|
||||
uint16 GUI_Font::getCenter(const char *text, uint16 width) {
|
||||
int w, h;
|
||||
textExtent(text, &w, &h);
|
||||
if (w < width)
|
||||
return ((width - w) / 2);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
94
engines/ultima/nuvie/gui/gui_font.h
Normal file
94
engines/ultima/nuvie/gui/gui_font.h
Normal file
@@ -0,0 +1,94 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NUVIE_GUI_GUI_FONT_H
|
||||
#define NUVIE_GUI_GUI_FONT_H
|
||||
|
||||
#include "ultima/nuvie/core/nuvie_defs.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
enum GuiFont {
|
||||
GUI_FONT_DEFAULT = 0,
|
||||
GUI_FONT_6X8 = 1,
|
||||
GUI_FONT_GUMP = 2
|
||||
};
|
||||
|
||||
class GUI_Font {
|
||||
protected:
|
||||
/* the font source surface */
|
||||
Graphics::ManagedSurface *_fontStore;
|
||||
|
||||
/* flags */
|
||||
bool _transparent;
|
||||
DisposeAfterUse::Flag _disposeFont;
|
||||
|
||||
/* dimensions */
|
||||
int _charH, _charW;
|
||||
|
||||
const byte *_wData;
|
||||
public:
|
||||
/* use default 8x8 font */
|
||||
GUI_Font(uint8 fontType = GUI_FONT_DEFAULT);
|
||||
|
||||
/* open named BMP file */
|
||||
GUI_Font(const char *name);
|
||||
|
||||
/* use given YxY surface */
|
||||
GUI_Font(Graphics::ManagedSurface *bitmap);
|
||||
|
||||
GUI_Font(const GUI_Font &font) = delete;
|
||||
|
||||
virtual ~GUI_Font();
|
||||
|
||||
/* determine drawing style */
|
||||
virtual void setTransparency(bool on);
|
||||
|
||||
/* determine foreground and background color values RGB*/
|
||||
virtual void setColoring(uint8 fr, uint8 fg, uint8 fb, uint8 br = 255, uint8 bg = 255, uint8 bb = 255);
|
||||
/* Two color font */
|
||||
virtual void setColoring(uint8 fr, uint8 fg, uint8 fb, uint8 fr1, uint8 fg1, uint8 fb1, uint8 br, uint8 bg, uint8 bb);
|
||||
|
||||
/* yields the pixel height of a single character */
|
||||
inline virtual int charHeight() const {
|
||||
return _charH - 1;
|
||||
}
|
||||
|
||||
/* yields the pixel width of a single character */
|
||||
inline virtual int charWidth() const {
|
||||
return _charW;
|
||||
}
|
||||
|
||||
/* put the text onto the given surface using the preset mode and colors */
|
||||
virtual void textOut(Graphics::ManagedSurface *context, int x, int y, const char *text, int line_wrap = 0);
|
||||
|
||||
/* yields pixel width and height of a string when printed with this font */
|
||||
void textExtent(const char *text, int *w, int *h, int line_wrap = 0);
|
||||
|
||||
/* yields the center (of width) where the text should be placed or 0 if larger than width */
|
||||
uint16 getCenter(const char *text, uint16 width);
|
||||
};
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
85
engines/ultima/nuvie/gui/gui_load_image.cpp
Normal file
85
engines/ultima/nuvie/gui/gui_load_image.cpp
Normal file
@@ -0,0 +1,85 @@
|
||||
/* 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/nuvie/core/nuvie_defs.h"
|
||||
#include "ultima/nuvie/gui/gui_load_image.h"
|
||||
#include "ultima/nuvie/gui/the_font.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
/************************************************************************/
|
||||
/* C functions for image loading */
|
||||
/* */
|
||||
/************************************************************************/
|
||||
|
||||
Graphics::ManagedSurface *GUI_LoadImage(int w, int h, const uint8 *pal, const uint8 *data) {
|
||||
Graphics::ManagedSurface *image = new Graphics::ManagedSurface(w, h,
|
||||
Graphics::PixelFormat::createFormatCLUT8());
|
||||
|
||||
if (image) {
|
||||
for (int row = 0; row < h; ++row) {
|
||||
memcpy((uint8 *)image->getBasePtr(0, row), data, w);
|
||||
data += w;
|
||||
}
|
||||
|
||||
image->setPalette(pal, 0, 256);
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* C functions for default font support */
|
||||
/* */
|
||||
/************************************************************************/
|
||||
|
||||
static Graphics::ManagedSurface *the_font = nullptr;
|
||||
static Graphics::ManagedSurface *the_font_6x8 = nullptr;
|
||||
static Graphics::ManagedSurface *the_font_gump = nullptr;
|
||||
|
||||
Graphics::ManagedSurface *GUI_DefaultFont(void) {
|
||||
if (the_font == nullptr) {
|
||||
the_font = GUI_LoadImage(font_w, font_h, font_pal, font_data);
|
||||
}
|
||||
return the_font;
|
||||
}
|
||||
|
||||
Graphics::ManagedSurface *GUI_Font6x8(void) {
|
||||
if (the_font_6x8 == nullptr) {
|
||||
the_font_6x8 = GUI_LoadImage(font_6x8_w, font_6x8_h, font_pal, font_6x8_data);
|
||||
}
|
||||
return the_font_6x8;
|
||||
}
|
||||
|
||||
Graphics::ManagedSurface *GUI_FontGump(void) {
|
||||
if (the_font_gump == nullptr) {
|
||||
the_font_gump = GUI_LoadImage(font_gump_w, font_gump_h, font_pal, font_gump_data);
|
||||
}
|
||||
return the_font_gump;
|
||||
}
|
||||
|
||||
const uint8 *GUI_FontGumpWData(void) {
|
||||
return font_gump_w_data;
|
||||
}
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
53
engines/ultima/nuvie/gui/gui_load_image.h
Normal file
53
engines/ultima/nuvie/gui/gui_load_image.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NUVIE_GUI_GUI_LOAD_IMAGE_H
|
||||
#define NUVIE_GUI_GUI_LOAD_IMAGE_H
|
||||
|
||||
#include "graphics/managed_surface.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
/************************************************************************/
|
||||
/* C functions for C image loading support:
|
||||
Use 'genimage' to turn an 8-bit BMP file into a C image, and include
|
||||
the output in your application, either directly or as a header file.
|
||||
Create an SDL surface in your program:
|
||||
surface = GUI_LoadImage(image_w, image_h, image_pal, image_data);
|
||||
*/
|
||||
/************************************************************************/
|
||||
|
||||
extern Graphics::ManagedSurface *GUI_LoadImage(int w, int h, const uint8 *pal, const uint8 *data);
|
||||
|
||||
/* Load the internal 8x8 font and return the associated font surface */
|
||||
extern Graphics::ManagedSurface *GUI_DefaultFont(void);
|
||||
|
||||
extern Graphics::ManagedSurface *GUI_Font6x8(void);
|
||||
|
||||
extern Graphics::ManagedSurface *GUI_FontGump(void);
|
||||
|
||||
extern const uint8 *GUI_FontGumpWData(void);
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
315
engines/ultima/nuvie/gui/gui_scroll_bar.cpp
Normal file
315
engines/ultima/nuvie/gui/gui_scroll_bar.cpp
Normal file
@@ -0,0 +1,315 @@
|
||||
/* 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
|
||||
|
||||
101
engines/ultima/nuvie/gui/gui_scroll_bar.h
Normal file
101
engines/ultima/nuvie/gui/gui_scroll_bar.h
Normal file
@@ -0,0 +1,101 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NUVIE_GUI_GUI_SCROLLBAR_H
|
||||
#define NUVIE_GUI_GUI_SCROLLBAR_H
|
||||
|
||||
|
||||
|
||||
#include "ultima/nuvie/gui/widgets/gui_widget.h"
|
||||
#include "ultima/nuvie/screen/screen.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
#define GUI_DIALOG_MOVABLE true
|
||||
|
||||
#define SCROLLBAR_WIDTH 14
|
||||
|
||||
// Callback message types
|
||||
|
||||
#define SCROLLBAR_CB_DOWN_BUTTON 0x1
|
||||
#define SCROLLBAR_CB_UP_BUTTON 0x2
|
||||
#define SCROLLBAR_CB_SLIDER_MOVED 0x3
|
||||
#define SCROLLBAR_CB_PAGE_DOWN 0x4
|
||||
#define SCROLLBAR_CB_PAGE_UP 0x5
|
||||
|
||||
class GUI_Button;
|
||||
|
||||
class GUI_ScrollBar : public GUI_Widget {
|
||||
GUI_CallBack *callback_object;
|
||||
GUI_Button *up_button, *down_button;
|
||||
|
||||
bool drag;
|
||||
uint16 button_height;
|
||||
|
||||
// Various colours.
|
||||
|
||||
uint32 slider_highlight_c;
|
||||
uint32 slider_shadow_c;
|
||||
uint32 slider_base_c;
|
||||
uint32 track_border_c;
|
||||
uint32 track_base_c;
|
||||
|
||||
uint16 track_length;
|
||||
uint16 slider_length;
|
||||
uint16 slider_y;
|
||||
uint16 slider_click_offset; // where on the slider were we clicked?
|
||||
|
||||
public:
|
||||
/* Passed the area, color and shape */
|
||||
GUI_ScrollBar(int x, int y, int h, GUI_CallBack *callback);
|
||||
|
||||
void set_slider_length(float percentage);
|
||||
void set_slider_position(float percentage);
|
||||
|
||||
/* Map the color to the display */
|
||||
void SetDisplay(Screen *s) override;
|
||||
|
||||
/* Show the widget */
|
||||
void Display(bool full_redraw) override;
|
||||
|
||||
/* events, used for dragging the area. */
|
||||
GUI_status MouseDown(int x, int y, Events::MouseButton button) override;
|
||||
GUI_status MouseUp(int x, int y, Events::MouseButton button) override;
|
||||
GUI_status MouseMotion(int x, int y, uint8 state) override;
|
||||
GUI_status MouseWheel(sint32 x, sint32 y) override;
|
||||
|
||||
protected:
|
||||
void loadButtons();
|
||||
void DisplaySlider();
|
||||
|
||||
void send_slider_moved_msg();
|
||||
bool move_slider(int new_slider_y);
|
||||
GUI_status callback(uint16 msg, GUI_CallBack *caller, void *data) override;
|
||||
|
||||
void send_up_button_msg();
|
||||
void send_down_button_msg();
|
||||
};
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
222
engines/ultima/nuvie/gui/gui_scroller.cpp
Normal file
222
engines/ultima/nuvie/gui/gui_scroller.cpp
Normal file
@@ -0,0 +1,222 @@
|
||||
/* 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/widgets/gui_widget.h"
|
||||
#include "ultima/nuvie/gui/gui_scroll_bar.h"
|
||||
#include "ultima/nuvie/gui/gui_scroller.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
GUI_Scroller::GUI_Scroller(int x, int y, int w, int h, uint8 r, uint8 g, uint8 b, uint16 r_height)
|
||||
: GUI_Widget(nullptr, x, y, w, h), R(r), G(g), B(b), bg_color(0),
|
||||
row_height(r_height), num_rows(0), disp_offset(0) {
|
||||
rows_per_page = h / row_height;
|
||||
scroll_bar = new GUI_ScrollBar(area.width() - SCROLLBAR_WIDTH, 0, area.height(), this);
|
||||
|
||||
GUI_Widget::AddWidget(scroll_bar); // we call the GUI_Widget::AddWidget method our method is for scroller container items.
|
||||
}
|
||||
|
||||
/* Map the color to the display */
|
||||
void GUI_Scroller::SetDisplay(Screen *s) {
|
||||
GUI_Widget::SetDisplay(s);
|
||||
bg_color = surface->format.RGBToColor(R, G, B);
|
||||
}
|
||||
|
||||
int GUI_Scroller::AddWidget(GUI_Widget *widget) {
|
||||
GUI_Widget::AddWidget(widget);
|
||||
num_rows++;
|
||||
update_viewport(true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void GUI_Scroller::PlaceOnScreen(Screen *s, GUI_DragManager *dm, int x, int y) {
|
||||
GUI_Widget::PlaceOnScreen(s, dm, x, y);
|
||||
|
||||
update_viewport(true);
|
||||
}
|
||||
|
||||
void GUI_Scroller::update_viewport(bool update_slider) {
|
||||
uint16 i;
|
||||
float s_len = 1.0;
|
||||
float s_pos = 0.0;
|
||||
|
||||
if (update_slider) {
|
||||
if (rows_per_page < num_rows)
|
||||
s_len = (float)rows_per_page / (float)num_rows;
|
||||
|
||||
scroll_bar->set_slider_length(s_len);
|
||||
|
||||
if (disp_offset > 0)
|
||||
s_pos = (float)disp_offset / (float)num_rows;
|
||||
|
||||
scroll_bar->set_slider_position(s_pos);
|
||||
}
|
||||
|
||||
Std::list<GUI_Widget *>::iterator child = children.begin();
|
||||
child++; // skip the scroll_bar widget. This is a bit evil.
|
||||
|
||||
for (i = 0; child != children.end(); child++, i++) {
|
||||
if (i < disp_offset || i >= disp_offset + rows_per_page)
|
||||
(*child)->Hide();
|
||||
else {
|
||||
(*child)->Move(area.left, area.top + (i - disp_offset) * row_height);
|
||||
(*child)->Show();
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Show the widget */
|
||||
void GUI_Scroller:: Display(bool full_redraw) {
|
||||
Common::Rect framerect;
|
||||
|
||||
framerect = area;
|
||||
framerect.right -= SCROLLBAR_WIDTH;
|
||||
|
||||
SDL_FillRect(surface, &framerect, bg_color);
|
||||
|
||||
DisplayChildren();
|
||||
|
||||
// screen->update(area.left,area.top,area.width(),area.height());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
GUI_status GUI_Scroller::MouseDown(int x, int y, Events::MouseButton button) {
|
||||
//grab_focus();
|
||||
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
GUI_status GUI_Scroller::MouseUp(int x, int y, Events::MouseButton button) {
|
||||
|
||||
// release_focus();
|
||||
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
GUI_status GUI_Scroller::MouseMotion(int x, int y, uint8 state) {
|
||||
|
||||
|
||||
//GUI::get_gui()->moveWidget(this,dx,dy);
|
||||
// Redraw();
|
||||
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
GUI_status GUI_Scroller::MouseWheel(sint32 x, sint32 y) {
|
||||
if (y > 0)
|
||||
move_up();
|
||||
else if (y < 0)
|
||||
move_down();
|
||||
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
void GUI_Scroller::move_up() {
|
||||
if (disp_offset > 0) {
|
||||
disp_offset--;
|
||||
update_viewport(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void GUI_Scroller::move_down() {
|
||||
if (num_rows - disp_offset > rows_per_page) {
|
||||
disp_offset++;
|
||||
update_viewport(true);
|
||||
}
|
||||
}
|
||||
|
||||
void GUI_Scroller::page_up(bool all) {
|
||||
if (disp_offset == 0)
|
||||
return;
|
||||
if (all)
|
||||
disp_offset = 0;
|
||||
else {
|
||||
for (int i = 0; i < rows_per_page; i++) {
|
||||
if (disp_offset > 0)
|
||||
disp_offset--;
|
||||
}
|
||||
}
|
||||
update_viewport(true);
|
||||
}
|
||||
|
||||
void GUI_Scroller::page_down(bool all) {
|
||||
if (num_rows - disp_offset < rows_per_page)
|
||||
return;
|
||||
if (all)
|
||||
disp_offset = num_rows - rows_per_page;
|
||||
else {
|
||||
for (int i = 0; i < rows_per_page; i++) {
|
||||
if (num_rows - disp_offset > rows_per_page)
|
||||
disp_offset++;
|
||||
}
|
||||
}
|
||||
update_viewport(true);
|
||||
}
|
||||
|
||||
void GUI_Scroller::move_percentage(float offset_percentage) {
|
||||
// DEBUG(0,LEVEL_DEBUGGING,"offset_percentage = %f\n", offset_percentage);
|
||||
|
||||
disp_offset = (int)((float)num_rows * offset_percentage);
|
||||
update_viewport(false);
|
||||
|
||||
}
|
||||
|
||||
GUI_status GUI_Scroller::callback(uint16 msg, GUI_CallBack *caller, void *data) {
|
||||
|
||||
switch (msg) {
|
||||
case SCROLLBAR_CB_SLIDER_MOVED :
|
||||
move_percentage(*(float *)data);
|
||||
break;
|
||||
|
||||
case SCROLLBAR_CB_UP_BUTTON :
|
||||
move_up();
|
||||
break;
|
||||
|
||||
case SCROLLBAR_CB_DOWN_BUTTON :
|
||||
move_down();
|
||||
break;
|
||||
case SCROLLBAR_CB_PAGE_DOWN:
|
||||
page_down();
|
||||
break;
|
||||
case SCROLLBAR_CB_PAGE_UP:
|
||||
page_up();
|
||||
break;
|
||||
|
||||
default :
|
||||
DEBUG(0, LEVEL_ERROR, "Unhandled callback!\n");
|
||||
break;
|
||||
}
|
||||
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
77
engines/ultima/nuvie/gui/gui_scroller.h
Normal file
77
engines/ultima/nuvie/gui/gui_scroller.h
Normal file
@@ -0,0 +1,77 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NUVIE_GUI_GUI_SCROLLER_H
|
||||
#define NUVIE_GUI_GUI_SCROLLER_H
|
||||
|
||||
|
||||
|
||||
#include "ultima/nuvie/gui/widgets/gui_widget.h"
|
||||
#include "ultima/nuvie/screen/screen.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
class GUI_ScrollBar;
|
||||
|
||||
class GUI_Scroller : public GUI_Widget {
|
||||
|
||||
uint8 R, G, B;
|
||||
uint32 bg_color;
|
||||
uint16 row_height;
|
||||
uint16 rows_per_page;
|
||||
uint16 num_rows;
|
||||
GUI_ScrollBar *scroll_bar;
|
||||
uint16 disp_offset;
|
||||
|
||||
public:
|
||||
/* Passed the area, color and shape */
|
||||
GUI_Scroller(int x, int y, int w, int h, uint8 r, uint8 g, uint8 b, uint16 r_height);
|
||||
|
||||
/* Map the color to the display */
|
||||
void SetDisplay(Screen *s) override;
|
||||
void PlaceOnScreen(Screen *s, GUI_DragManager *dm, int x, int y) override;
|
||||
void move_up();
|
||||
void move_down();
|
||||
void page_up(bool all = false);
|
||||
void page_down(bool all = false);
|
||||
|
||||
int AddWidget(GUI_Widget *widget);
|
||||
|
||||
/* Show the widget */
|
||||
void Display(bool full_redraw) override;
|
||||
|
||||
/* events, used for dragging the area. */
|
||||
GUI_status MouseDown(int x, int y, Events::MouseButton button) override;
|
||||
GUI_status MouseUp(int x, int y, Events::MouseButton button) override;
|
||||
GUI_status MouseMotion(int x, int y, uint8 state) override;
|
||||
GUI_status MouseWheel(sint32 x, sint32 y) override;
|
||||
|
||||
protected:
|
||||
void update_viewport(bool update_slider);
|
||||
void move_percentage(float offset_percentage);
|
||||
GUI_status callback(uint16 msg, GUI_CallBack *caller, void *data) override;
|
||||
};
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
50
engines/ultima/nuvie/gui/gui_status.h
Normal file
50
engines/ultima/nuvie/gui/gui_status.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/* These are return codes for widget event functions */
|
||||
|
||||
#ifndef NUVIE_GUI_GUI_STATUS_H
|
||||
#define NUVIE_GUI_GUI_STATUS_H
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
typedef enum {
|
||||
GUI_QUIT, /* Close the GUI */
|
||||
GUI_REDRAW, /* The GUI needs to be redrawn */
|
||||
GUI_YUM, /* The event was eaten by the widget */
|
||||
GUI_PASS, /* The event should be passed on */
|
||||
GUI_DRAG_AND_DROP /* Drag and Drop sequence initiated by GUI */
|
||||
} GUI_status;
|
||||
|
||||
typedef enum {
|
||||
WIDGET_VISIBLE,
|
||||
WIDGET_HIDDEN,
|
||||
WIDGET_DELETED
|
||||
} WIDGET_status;
|
||||
|
||||
/* GUI idle function -- run when no events pending */
|
||||
typedef GUI_status(*GUI_IdleProc)(void);
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
76
engines/ultima/nuvie/gui/gui_text.cpp
Normal file
76
engines/ultima/nuvie/gui/gui_text.cpp
Normal file
@@ -0,0 +1,76 @@
|
||||
/* 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/nuvie/core/nuvie_defs.h"
|
||||
#include "ultima/nuvie/gui/gui_text.h"
|
||||
#include "ultima/nuvie/gui/gui_font.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
GUI_Text::GUI_Text(int x, int y, uint8 r, uint8 g, uint8 b, GUI_Font *gui_font, uint16 line_length)
|
||||
: GUI_Widget(nullptr, x, y, 0, 0) {
|
||||
R = r;
|
||||
G = g;
|
||||
B = b;
|
||||
text = nullptr;
|
||||
max_width = line_length;
|
||||
|
||||
font = gui_font;
|
||||
}
|
||||
|
||||
|
||||
GUI_Text::GUI_Text(int x, int y, uint8 r, uint8 g, uint8 b, const char *str, GUI_Font *gui_font, uint16 line_length)
|
||||
: GUI_Widget(nullptr, x, y, 0, 0), R(r), G(g), B(b), max_width(line_length),
|
||||
font(gui_font), text(nullptr) {
|
||||
setText(str);
|
||||
}
|
||||
|
||||
GUI_Text::~GUI_Text() {
|
||||
free(text);
|
||||
}
|
||||
|
||||
|
||||
/* Show the widget */
|
||||
void GUI_Text::Display(bool full_redraw) {
|
||||
font->setTransparency(true);
|
||||
font->setColoring(R, G, B);
|
||||
font->textOut(surface, area.left, area.top, text, max_width);
|
||||
|
||||
DisplayChildren();
|
||||
}
|
||||
|
||||
void GUI_Text::setText(const char *txt) {
|
||||
if (text)
|
||||
free(text);
|
||||
text = scumm_strdup(txt);
|
||||
if (text == nullptr)
|
||||
error("GUI_Text: failed to allocate memory for text");
|
||||
|
||||
int w, h;
|
||||
font->textExtent(text, &w, &h, max_width);
|
||||
|
||||
area.setWidth(w);
|
||||
area.setHeight(h);
|
||||
}
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
53
engines/ultima/nuvie/gui/gui_text.h
Normal file
53
engines/ultima/nuvie/gui/gui_text.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NUVIE_GUI_GUI_TEXT_H
|
||||
#define NUVIE_GUI_GUI_TEXT_H
|
||||
|
||||
#include "ultima/nuvie/gui/widgets/gui_widget.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
class GUI_Font;
|
||||
|
||||
class GUI_Text : public GUI_Widget {
|
||||
protected:
|
||||
uint8 R, G, B;
|
||||
char *text;
|
||||
GUI_Font *font;
|
||||
uint16 max_width; //max line width. No limit if set to 0
|
||||
|
||||
public:
|
||||
GUI_Text(int x, int y, uint8 r, uint8 g, uint8 b, GUI_Font *gui_font, uint16 line_length);
|
||||
GUI_Text(int x, int y, uint8 r, uint8 g, uint8 b, const char *str, GUI_Font *gui_font, uint16 line_length = 0);
|
||||
~GUI_Text() override;
|
||||
|
||||
/* Show the widget */
|
||||
void Display(bool full_redraw) override;
|
||||
|
||||
void setText(const char *txt);
|
||||
};
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
314
engines/ultima/nuvie/gui/gui_text_input.cpp
Normal file
314
engines/ultima/nuvie/gui/gui_text_input.cpp
Normal file
@@ -0,0 +1,314 @@
|
||||
/* 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/nuvie/core/nuvie_defs.h"
|
||||
|
||||
#include "ultima/nuvie/gui/gui_text_input.h"
|
||||
#include "ultima/nuvie/gui/gui_font.h"
|
||||
#include "ultima/nuvie/keybinding/keys.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
GUI_TextInput:: GUI_TextInput(int x, int y, uint8 r, uint8 g, uint8 b, const char *str,
|
||||
GUI_Font *gui_font, uint16 width, uint16 height, GUI_CallBack *callback)
|
||||
: GUI_Text(x, y, r, g, b, gui_font, width), max_height(height), callback_object(callback),
|
||||
cursor_color(0), selected_bgcolor(0) {
|
||||
text = (char *)malloc(max_width * max_height + 1);
|
||||
if (text == nullptr)
|
||||
error("GUI_TextInput failed to allocate memory for text");
|
||||
|
||||
strncpy(text, str, max_width * max_height);
|
||||
|
||||
pos = strlen(text);
|
||||
length = pos;
|
||||
|
||||
area.setWidth(max_width * font->charWidth());
|
||||
area.setHeight(max_height * font->charHeight());
|
||||
}
|
||||
|
||||
GUI_TextInput::~GUI_TextInput() {
|
||||
return;
|
||||
}
|
||||
|
||||
void GUI_TextInput::release_focus() {
|
||||
GUI_Widget::release_focus();
|
||||
|
||||
// SDL_EnableUNICODE(0); //disable unicode.
|
||||
}
|
||||
|
||||
GUI_status GUI_TextInput::MouseUp(int x, int y, Events::MouseButton button) {
|
||||
// if(button == SDL_BUTTON_WHEELUP || button == SDL_BUTTON_WHEELDOWN)
|
||||
// return GUI_PASS;
|
||||
//release focus if we click outside the text box.
|
||||
if (focused && !HitRect(x, y))
|
||||
release_focus();
|
||||
else {
|
||||
if (!focused) {
|
||||
grab_focus();
|
||||
// FIXME SDL2 SDL_EnableUNICODE(1); //turn on unicode processing.
|
||||
}
|
||||
}
|
||||
|
||||
return GUI_PASS;
|
||||
}
|
||||
|
||||
GUI_status GUI_TextInput::KeyDown(const Common::KeyState &keyState) {
|
||||
Common::KeyState key = keyState;
|
||||
char ascii = get_ascii_char_from_keysym(key);
|
||||
|
||||
if (!focused)
|
||||
return GUI_PASS;
|
||||
|
||||
|
||||
if (!Common::isPrint(ascii) && key.keycode != Common::KEYCODE_BACKSPACE) {
|
||||
KeyBinder *keybinder = Game::get_game()->get_keybinder();
|
||||
ActionType a = keybinder->get_ActionType(key);
|
||||
switch (keybinder->GetActionKeyType(a)) {
|
||||
case NORTH_KEY:
|
||||
key.keycode = Common::KEYCODE_UP;
|
||||
break;
|
||||
case SOUTH_KEY:
|
||||
key.keycode = Common::KEYCODE_DOWN;
|
||||
break;
|
||||
case WEST_KEY:
|
||||
key.keycode = Common::KEYCODE_LEFT;
|
||||
break;
|
||||
case EAST_KEY:
|
||||
key.keycode = Common::KEYCODE_RIGHT;
|
||||
break;
|
||||
case TOGGLE_CURSOR_KEY:
|
||||
release_focus();
|
||||
return GUI_PASS; // can tab through to SaveDialog
|
||||
case DO_ACTION_KEY:
|
||||
key.keycode = Common::KEYCODE_RETURN;
|
||||
break;
|
||||
case CANCEL_ACTION_KEY:
|
||||
key.keycode = Common::KEYCODE_ESCAPE;
|
||||
break;
|
||||
case HOME_KEY:
|
||||
key.keycode = Common::KEYCODE_HOME;
|
||||
break;
|
||||
case END_KEY:
|
||||
key.keycode = Common::KEYCODE_END;
|
||||
break;
|
||||
default :
|
||||
if (keybinder->handle_always_available_keys(a)) return GUI_YUM;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (key.keycode) {
|
||||
case Common::KEYCODE_LSHIFT:
|
||||
case Common::KEYCODE_RSHIFT:
|
||||
case Common::KEYCODE_LCTRL:
|
||||
case Common::KEYCODE_RCTRL:
|
||||
case Common::KEYCODE_CAPSLOCK:
|
||||
break;
|
||||
|
||||
case Common::KEYCODE_KP_ENTER:
|
||||
case Common::KEYCODE_RETURN:
|
||||
if (callback_object)
|
||||
callback_object->callback(TEXTINPUT_CB_TEXT_READY, this, text);
|
||||
// falls through
|
||||
case Common::KEYCODE_ESCAPE :
|
||||
release_focus();
|
||||
break;
|
||||
|
||||
case Common::KEYCODE_HOME:
|
||||
pos = 0;
|
||||
break;
|
||||
case Common::KEYCODE_END:
|
||||
pos = length;
|
||||
break;
|
||||
|
||||
case Common::KEYCODE_KP4:
|
||||
case Common::KEYCODE_LEFT:
|
||||
if (pos > 0)
|
||||
pos--;
|
||||
break;
|
||||
|
||||
case Common::KEYCODE_KP6:
|
||||
case Common::KEYCODE_RIGHT:
|
||||
if (pos < length)
|
||||
pos++;
|
||||
break;
|
||||
|
||||
case Common::KEYCODE_DELETE :
|
||||
if (pos < length) { //delete the character to the right of the cursor
|
||||
pos++;
|
||||
remove_char();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case Common::KEYCODE_BACKSPACE :
|
||||
remove_char();
|
||||
break; //delete the character to the left of the cursor
|
||||
|
||||
case Common::KEYCODE_UP:
|
||||
case Common::KEYCODE_KP8:
|
||||
if (pos == length) {
|
||||
if (length + 1 > max_width * max_height)
|
||||
break;
|
||||
length++;
|
||||
if (pos == 0 || text[pos - 1] == ' ')
|
||||
text[pos] = 'A';
|
||||
else
|
||||
text[pos] = 'a';
|
||||
break;
|
||||
}
|
||||
text[pos]++;
|
||||
// We want alphanumeric characters or space
|
||||
if (text[pos] < ' ' || text[pos] > 'z') {
|
||||
text[pos] = ' ';
|
||||
break;
|
||||
}
|
||||
while (!Common::isAlnum(text[pos]))
|
||||
text[pos]++;
|
||||
break;
|
||||
|
||||
case Common::KEYCODE_KP2:
|
||||
case Common::KEYCODE_DOWN:
|
||||
if (pos == length) {
|
||||
if (length + 1 > max_width * max_height)
|
||||
break;
|
||||
length++;
|
||||
if (pos == 0 || text[pos - 1] == ' ')
|
||||
text[pos] = 'Z';
|
||||
else
|
||||
text[pos] = 'z';
|
||||
break;
|
||||
}
|
||||
text[pos]--;
|
||||
// We want alphanumeric characters or space
|
||||
if (text[pos] < ' ' || text[pos] > 'z') {
|
||||
text[pos] = 'z';
|
||||
break;
|
||||
} else if (text[pos] < '0') {
|
||||
text[pos] = ' ';
|
||||
break;
|
||||
}
|
||||
while (!Common::isAlnum(text[pos]))
|
||||
text[pos]--;
|
||||
break;
|
||||
|
||||
default :
|
||||
if (Common::isPrint(ascii))
|
||||
add_char(ascii);
|
||||
break;
|
||||
}
|
||||
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
void GUI_TextInput::add_char(char c) {
|
||||
uint16 i;
|
||||
|
||||
if (length + 1 > max_width * max_height)
|
||||
return;
|
||||
|
||||
if (pos < length) { //shuffle chars to the right if required.
|
||||
for (i = length; i > pos; i--)
|
||||
text[i] = text[i - 1];
|
||||
}
|
||||
|
||||
length++;
|
||||
|
||||
text[pos] = c;
|
||||
pos++;
|
||||
|
||||
text[length] = '\0';
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void GUI_TextInput::remove_char() {
|
||||
uint16 i;
|
||||
|
||||
if (pos == 0)
|
||||
return;
|
||||
|
||||
for (i = pos - 1; i < length; i++)
|
||||
text[i] = text[i + 1];
|
||||
|
||||
pos--;
|
||||
length--;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void GUI_TextInput::set_text(const char *new_text) {
|
||||
if (new_text) {
|
||||
strncpy(text, new_text, max_width * max_height);
|
||||
|
||||
pos = strlen(text);
|
||||
length = pos;
|
||||
}
|
||||
}
|
||||
|
||||
/* Map the color to the display */
|
||||
void GUI_TextInput::SetDisplay(Screen *s) {
|
||||
GUI_Widget::SetDisplay(s);
|
||||
cursor_color = surface->format.RGBToColor(0xff, 0, 0);
|
||||
selected_bgcolor = surface->format.RGBToColor(0x5a, 0x6e, 0x91);
|
||||
}
|
||||
|
||||
|
||||
/* Show the widget */
|
||||
void GUI_TextInput:: Display(bool full_redraw) {
|
||||
Common::Rect r;
|
||||
|
||||
if (full_redraw && focused) {
|
||||
r = area;
|
||||
SDL_FillRect(surface, &r, selected_bgcolor);
|
||||
}
|
||||
|
||||
GUI_Text::Display(full_redraw);
|
||||
|
||||
if (focused)
|
||||
display_cursor();
|
||||
|
||||
}
|
||||
|
||||
void GUI_TextInput::display_cursor() {
|
||||
Common::Rect r;
|
||||
uint16 x, y;
|
||||
uint16 cw, ch;
|
||||
|
||||
x = pos % max_width;
|
||||
y = pos / max_width;
|
||||
|
||||
cw = font->charWidth();
|
||||
ch = font->charHeight();
|
||||
|
||||
r.left = area.left + x * cw;
|
||||
r.top = area.top + y * ch;
|
||||
r.setWidth(1);
|
||||
r.setHeight(ch);
|
||||
|
||||
SDL_FillRect(surface, &r, cursor_color);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
74
engines/ultima/nuvie/gui/gui_text_input.h
Normal file
74
engines/ultima/nuvie/gui/gui_text_input.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NUVIE_GUI_GUI_TEXT_INPUT_H
|
||||
#define NUVIE_GUI_GUI_TEXT_INPUT_H
|
||||
|
||||
#include "ultima/nuvie/gui/gui_text.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
class GUI_Font;
|
||||
|
||||
|
||||
#define TEXTINPUT_CB_TEXT_READY 0x1
|
||||
|
||||
class GUI_TextInput : public GUI_Text {
|
||||
protected:
|
||||
uint16 max_height;
|
||||
uint16 pos;
|
||||
uint16 length;
|
||||
|
||||
GUI_CallBack *callback_object;
|
||||
|
||||
uint32 cursor_color;
|
||||
uint32 selected_bgcolor;
|
||||
|
||||
public:
|
||||
|
||||
GUI_TextInput(int x, int y, uint8 r, uint8 g, uint8 b,
|
||||
const char *str, GUI_Font *gui_font, uint16 width, uint16 height, GUI_CallBack *callback);
|
||||
~GUI_TextInput() override;
|
||||
|
||||
void release_focus() override;
|
||||
|
||||
GUI_status MouseUp(int x, int y, Events::MouseButton button) override;
|
||||
GUI_status KeyDown(const Common::KeyState &key) override;
|
||||
|
||||
void add_char(char c);
|
||||
void remove_char();
|
||||
void set_text(const char *new_text);
|
||||
const char *get_text() {
|
||||
return text;
|
||||
}
|
||||
void SetDisplay(Screen *s) override;
|
||||
void display_cursor();
|
||||
|
||||
/* Show the widget */
|
||||
void Display(bool full_redraw) override;
|
||||
|
||||
};
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
83
engines/ultima/nuvie/gui/gui_text_toggle_button.cpp
Normal file
83
engines/ultima/nuvie/gui/gui_text_toggle_button.cpp
Normal file
@@ -0,0 +1,83 @@
|
||||
/* 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/nuvie/core/nuvie_defs.h"
|
||||
#include "ultima/nuvie/gui/gui_text_toggle_button.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
GUI_TextToggleButton::GUI_TextToggleButton(void *data, int x, int y, int w, int h,
|
||||
const char *const *texts_, int count_, int selection_,
|
||||
GUI_Font *font, ButtonTextAlign alignment_,
|
||||
GUI_CallBack *callback, int flat)
|
||||
: GUI_Button(data, x, y, w, h, "", font, alignment_, false, callback, flat), count(count_),
|
||||
selection(selection_), alignment(alignment_) {
|
||||
assert(count > 0);
|
||||
assert(selection >= 0 && selection < count);
|
||||
|
||||
texts = new char *[count];
|
||||
for (int i = 0; i < count; ++i) {
|
||||
int l = strlen(texts_[i]) + 1;
|
||||
texts[i] = new char[l];
|
||||
Common::strcpy_s(texts[i], l, texts_[i]);
|
||||
}
|
||||
|
||||
ChangeTextButton(-1, -1, -1, -1, texts[selection], alignment);
|
||||
}
|
||||
|
||||
GUI_TextToggleButton::~GUI_TextToggleButton() {
|
||||
for (int i = 0; i < count; ++i)
|
||||
delete[] texts[i];
|
||||
delete[] texts;
|
||||
texts = 0;
|
||||
}
|
||||
|
||||
GUI_status GUI_TextToggleButton::MouseUp(int x, int y, Events::MouseButton button_) {
|
||||
if ((button_ == 1 || button_ == 3) && (pressed[0])) {
|
||||
pressed[0] = 0;
|
||||
return Activate_button(x, y, button_);
|
||||
}
|
||||
return GUI_Button::MouseUp(x, y, button_);
|
||||
}
|
||||
|
||||
GUI_status GUI_TextToggleButton::Activate_button(int x, int y, Events::MouseButton button_) {
|
||||
selection = (selection + (button_ == Events::BUTTON_LEFT ? 1 : -1)) % count;
|
||||
if (selection < 0)
|
||||
selection = count - 1;
|
||||
|
||||
if (x >= 0 && y >= 0) {
|
||||
if (callback_object && callback_object->callback(BUTTON_CB, this, widget_data) == GUI_QUIT)
|
||||
return GUI_QUIT;
|
||||
}
|
||||
|
||||
ChangeTextButton(-1, -1, -1, -1, texts[selection], alignment);
|
||||
Redraw();
|
||||
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
int GUI_TextToggleButton::GetSelection() const {
|
||||
return selection;
|
||||
}
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
62
engines/ultima/nuvie/gui/gui_text_toggle_button.h
Normal file
62
engines/ultima/nuvie/gui/gui_text_toggle_button.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NUVIE_GUI_TEXT_TOGGLE_BUTTON_H
|
||||
#define NUVIE_GUI_TEXT_TOGGLE_BUTTON_H
|
||||
|
||||
#include "ultima/nuvie/gui/gui_button.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
// A button that cycles through a set of captions when clicked
|
||||
|
||||
class GUI_TextToggleButton : public GUI_Button {
|
||||
public:
|
||||
/* Passed the button data, position, width, height,
|
||||
captions, number of captions, initial selection,
|
||||
a font, an alignment (see GUI_Button),
|
||||
the callback and a flag if it should be 2D (1) or 3D (0).
|
||||
|
||||
The captions are copied into the class. */
|
||||
GUI_TextToggleButton(void *data, int x, int y, int w, int h,
|
||||
const char *const *texts, int count, int selection,
|
||||
GUI_Font *font, ButtonTextAlign alignment,
|
||||
GUI_CallBack *callback, int flat = 0);
|
||||
|
||||
~GUI_TextToggleButton() override;
|
||||
|
||||
virtual int GetSelection() const;
|
||||
|
||||
GUI_status MouseUp(int x, int y, Events::MouseButton button) override;
|
||||
GUI_status Activate_button(int x = 0, int y = 0, Events::MouseButton button = Events::BUTTON_LEFT) override;
|
||||
|
||||
protected:
|
||||
int selection;
|
||||
char **texts;
|
||||
int count;
|
||||
ButtonTextAlign alignment;
|
||||
};
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
74
engines/ultima/nuvie/gui/gui_types.h
Normal file
74
engines/ultima/nuvie/gui/gui_types.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NUVIE_GUI_GUI_TYPES_H
|
||||
#define NUVIE_GUI_GUI_TYPES_H
|
||||
|
||||
/* Basic GUI data types and classes */
|
||||
|
||||
#include "ultima/nuvie/misc/sdl_compat.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
class GUI_image {
|
||||
|
||||
public:
|
||||
/* Load an image from a BMP file */
|
||||
GUI_image(char *file);
|
||||
|
||||
/* Use a Graphics::ManagedSurface as the image
|
||||
The surface shouldn't be freed while the miage object exists.
|
||||
*/
|
||||
GUI_image(Graphics::ManagedSurface *picture, int shouldfree = 0);
|
||||
|
||||
private:
|
||||
Graphics::ManagedSurface *image;
|
||||
};
|
||||
|
||||
class GUI_Color {
|
||||
public:
|
||||
|
||||
uint8 r;
|
||||
uint8 g;
|
||||
uint8 b;
|
||||
//uint8 a;
|
||||
|
||||
uint32 sdl_color;
|
||||
|
||||
public:
|
||||
|
||||
GUI_Color(uint8 red, uint8 green, uint8 blue)
|
||||
: r(red), g(green), b(blue), sdl_color(0) {
|
||||
};
|
||||
GUI_Color()
|
||||
: r(0), g(0), b(0), sdl_color(0) {
|
||||
};
|
||||
void map_color(const Graphics::PixelFormat &format) {
|
||||
sdl_color = format.RGBToColor(r, g, b);
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
99
engines/ultima/nuvie/gui/gui_yes_no_dialog.cpp
Normal file
99
engines/ultima/nuvie/gui/gui_yes_no_dialog.cpp
Normal file
@@ -0,0 +1,99 @@
|
||||
/* 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/nuvie/core/nuvie_defs.h"
|
||||
|
||||
#include "ultima/nuvie/gui/gui.h"
|
||||
#include "ultima/nuvie/gui/gui_button.h"
|
||||
#include "ultima/nuvie/gui/gui_text.h"
|
||||
|
||||
#include "ultima/nuvie/gui/gui_dialog.h"
|
||||
#include "ultima/nuvie/gui/gui_yes_no_dialog.h"
|
||||
#include "ultima/nuvie/keybinding/keys.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
GUI_YesNoDialog::GUI_YesNoDialog(GUI *gui, int x, int y, int w, int h, const char *msg,
|
||||
CallBack *yesCallback, CallBack *noCallback)
|
||||
: GUI_Dialog(x, y, w, h, 244, 216, 131, GUI_DIALOG_MOVABLE), b_index_num(-1),
|
||||
yes_callback_object(yesCallback), no_callback_object(noCallback) {
|
||||
GUI_Widget *widget;
|
||||
|
||||
yes_button = new GUI_Button(this, 100, 50, 40, 18, "Yes", gui->get_font(), BUTTON_TEXTALIGN_CENTER, false, this, false);
|
||||
AddWidget(yes_button);
|
||||
button_index[0] = yes_button;
|
||||
|
||||
no_button = new GUI_Button(this, 30, 50, 40, 18, "No", gui->get_font(), BUTTON_TEXTALIGN_CENTER, false, this, false);
|
||||
AddWidget(no_button);
|
||||
button_index[1] = no_button;
|
||||
|
||||
widget = new GUI_Text(10, 25, 0, 0, 0, msg, gui->get_font());
|
||||
AddWidget(widget);
|
||||
}
|
||||
|
||||
|
||||
GUI_YesNoDialog::~GUI_YesNoDialog() {
|
||||
}
|
||||
|
||||
GUI_status GUI_YesNoDialog::KeyDown(const Common::KeyState &key) {
|
||||
if (key.keycode == Common::KEYCODE_y)
|
||||
return (GUI_status)yes_callback_object->callback(YESNODIALOG_CB_YES, nullptr);
|
||||
|
||||
KeyBinder *keybinder = Game::get_game()->get_keybinder();
|
||||
ActionType a = keybinder->get_ActionType(key);
|
||||
|
||||
switch (keybinder->GetActionKeyType(a)) {
|
||||
case EAST_KEY:
|
||||
case WEST_KEY:
|
||||
if (b_index_num != -1)
|
||||
button_index[b_index_num]->set_highlighted(false);
|
||||
|
||||
if (b_index_num == 0)
|
||||
b_index_num = 1;
|
||||
else
|
||||
b_index_num = 0;
|
||||
button_index[b_index_num]->set_highlighted(true);
|
||||
return GUI_YUM;
|
||||
case DO_ACTION_KEY:
|
||||
if (b_index_num != -1)
|
||||
return button_index[b_index_num]->Activate_button();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return (GUI_status)no_callback_object->callback(YESNODIALOG_CB_NO, nullptr, this);
|
||||
}
|
||||
|
||||
GUI_status GUI_YesNoDialog::callback(uint16 msg, GUI_CallBack *caller, void *data) {
|
||||
if (caller == yes_button)
|
||||
return (GUI_status)yes_callback_object->callback(YESNODIALOG_CB_YES, nullptr);
|
||||
|
||||
if (caller == no_button)
|
||||
return (GUI_status)no_callback_object->callback(YESNODIALOG_CB_NO, nullptr, this);
|
||||
|
||||
return GUI_PASS;
|
||||
}
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
59
engines/ultima/nuvie/gui/gui_yes_no_dialog.h
Normal file
59
engines/ultima/nuvie/gui/gui_yes_no_dialog.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NUVIE_GUI_GUI_YES_NO_DIALOG_H
|
||||
#define NUVIE_GUI_GUI_YES_NO_DIALOG_H
|
||||
|
||||
#include "ultima/nuvie/gui/gui_dialog.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
class GUI;
|
||||
class GUI_CallBack;
|
||||
class GUI_Button;
|
||||
|
||||
// Callback message types
|
||||
|
||||
#define YESNODIALOG_CB_YES 0x1
|
||||
#define YESNODIALOG_CB_NO 0x2
|
||||
|
||||
class GUI_YesNoDialog : public GUI_Dialog {
|
||||
private:
|
||||
sint8 b_index_num;
|
||||
GUI_Button *yes_button, *no_button;
|
||||
CallBack *yes_callback_object, *no_callback_object;
|
||||
GUI_Button *button_index[2];
|
||||
|
||||
public:
|
||||
GUI_YesNoDialog(GUI *gui, int x, int y, int w, int h, const char *msg,
|
||||
CallBack *yesCallback, CallBack *noCallback);
|
||||
~GUI_YesNoDialog() override;
|
||||
|
||||
GUI_status KeyDown(const Common::KeyState &key) override;
|
||||
|
||||
GUI_status callback(uint16 msg, GUI_CallBack *caller, void *data) override;
|
||||
};
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
1908
engines/ultima/nuvie/gui/the_font.h
Normal file
1908
engines/ultima/nuvie/gui/the_font.h
Normal file
File diff suppressed because it is too large
Load Diff
162
engines/ultima/nuvie/gui/widgets/background.cpp
Normal file
162
engines/ultima/nuvie/gui/widgets/background.cpp
Normal file
@@ -0,0 +1,162 @@
|
||||
/* 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/conf/configuration.h"
|
||||
#include "ultima/nuvie/misc/u6_misc.h"
|
||||
#include "ultima/nuvie/files/u6_lib_n.h"
|
||||
#include "ultima/nuvie/files/u6_bmp.h"
|
||||
#include "ultima/nuvie/screen/dither.h"
|
||||
#include "ultima/nuvie/gui/widgets/background.h"
|
||||
#include "ultima/nuvie/gui/widgets/map_window.h"
|
||||
#include "ultima/nuvie/gui/gui.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
Background::Background(const Configuration *cfg) : GUI_Widget(nullptr), config(cfg),
|
||||
bg_w(0), bg_h(0), border_width(0), background(nullptr), right_bg_x_off(0),
|
||||
left_bg_x_off(0) {
|
||||
config->value("config/GameType", game_type);
|
||||
x_off = Game::get_game()->get_game_x_offset();
|
||||
y_off = Game::get_game()->get_game_y_offset();
|
||||
|
||||
Init(nullptr, 0, 0, Game::get_game()->get_screen()->get_width(), Game::get_game()->get_screen()->get_height());
|
||||
}
|
||||
|
||||
Background::~Background() {
|
||||
if (background)
|
||||
delete background;
|
||||
}
|
||||
|
||||
bool Background::init() {
|
||||
Common::Path filename;
|
||||
|
||||
if (!Game::get_game()->is_new_style()) {
|
||||
switch (game_type) {
|
||||
case NUVIE_GAME_U6 :
|
||||
config_get_path(config, "paper.bmp", filename);
|
||||
background = (U6Shape *) new U6Bmp();
|
||||
if (background->load(filename) == false)
|
||||
return false;
|
||||
if (Game::get_game()->is_original_plus()) {
|
||||
border_width = 158;
|
||||
right_bg_x_off = x_off + Game::get_game()->get_game_width() - 152;
|
||||
left_bg_x_off = x_off + Game::get_game()->get_game_width() - border_width;
|
||||
}
|
||||
break;
|
||||
|
||||
case NUVIE_GAME_MD :
|
||||
background = new U6Shape();
|
||||
background->load_WoU_background(config, game_type);
|
||||
if (Game::get_game()->is_original_plus()) {
|
||||
border_width = 144;
|
||||
left_bg_x_off = x_off + Game::get_game()->get_game_width() - border_width;
|
||||
}
|
||||
break;
|
||||
|
||||
case NUVIE_GAME_SE :
|
||||
background = new U6Shape();
|
||||
background->load_WoU_background(config, game_type);
|
||||
if (Game::get_game()->is_original_plus()) {
|
||||
border_width = 142;
|
||||
left_bg_x_off = x_off + Game::get_game()->get_game_width() - border_width;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
background->get_size(&bg_w, &bg_h);
|
||||
|
||||
Game::get_game()->get_dither()->dither_bitmap(background->get_data(), bg_w, bg_h, DITHER_NO_TRANSPARENCY);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void Background::Display(bool full_redraw) {
|
||||
if (full_redraw || update_display || Game::get_game()->is_original_plus_full_map()) {
|
||||
if (Game::get_game()->is_original_plus()) {
|
||||
if (Game::get_game()->is_original_plus_cutoff_map())
|
||||
screen->clear(area.left, area.top, area.width(), area.height(), nullptr);
|
||||
else if (full_redraw || update_display) { // need to clear null background when we have a game size smaller than the screen
|
||||
uint16 game_width = Game::get_game()->get_game_width();
|
||||
uint16 game_height = Game::get_game()->get_game_height();
|
||||
if (x_off > 0) { // centered
|
||||
screen->clear(area.left, area.top, x_off, area.height(), nullptr); // left side
|
||||
screen->clear(x_off + game_width, area.top, x_off, area.height(), nullptr); // right side
|
||||
} else if (area.width() > game_width) { // upper_left position
|
||||
screen->clear(game_width, area.top, area.width() - game_width, area.height(), nullptr); // right side
|
||||
}
|
||||
if (y_off > 0) { // centered
|
||||
screen->clear(area.left, area.top, area.width(), y_off, nullptr); // top
|
||||
screen->clear(area.left, y_off + game_height, area.width(), y_off, nullptr); // bottom
|
||||
} else if (area.height() > game_height) { // upper_left position
|
||||
screen->clear(area.left, game_height, area.width(), area.height() - game_height, nullptr); // bottom
|
||||
}
|
||||
}
|
||||
const unsigned char *ptr = background->get_data();
|
||||
if (game_type == NUVIE_GAME_U6) {
|
||||
ptr += (bg_w - 152);
|
||||
screen->blit(right_bg_x_off, y_off, ptr, 8, 152, bg_h, bg_w, true);
|
||||
screen->blit(left_bg_x_off, y_off, background->get_data(), 8, 6, bg_h, bg_w, true);
|
||||
} else {
|
||||
if (game_type == NUVIE_GAME_MD)
|
||||
screen->fill(0, left_bg_x_off, y_off, border_width, bg_h); // background has transparent parts that should be black
|
||||
ptr += (bg_w - border_width);
|
||||
screen->blit(left_bg_x_off, y_off, ptr, 8, border_width, bg_h, bg_w, true);
|
||||
}
|
||||
} else {
|
||||
screen->clear(area.left, area.top, area.width(), area.height(), nullptr);
|
||||
if (Game::get_game()->is_orig_style())
|
||||
screen->blit(x_off, y_off, background->get_data(), 8, bg_w, bg_h, bg_w, true);
|
||||
}
|
||||
update_display = false;
|
||||
screen->update(0, 0, area.width(), area.height());
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
bool Background::drag_accept_drop(int x, int y, int message, void *data) {
|
||||
GUI::get_gui()->force_full_redraw();
|
||||
DEBUG(0, LEVEL_DEBUGGING, "Background::drag_accept_drop()\n");
|
||||
if (Game::get_game()->is_original_plus_full_map() && message == GUI_DRAG_OBJ) { // added to gui before the map window so we need to redirect
|
||||
MapWindow *map_window = Game::get_game()->get_map_window();
|
||||
if (!map_window) // should be initialized before drops occur but we will play it safe
|
||||
return false;
|
||||
if (Game::get_game()->get_game_width() > x - x_off && x >= x_off // make sure we are on the map window
|
||||
&& Game::get_game()->get_game_height() > y - y_off && y >= y_off) {
|
||||
if (x >= left_bg_x_off && y <= 200 + y_off) // over background image
|
||||
return false;
|
||||
return map_window->drag_accept_drop(x, y, message, data);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Background::drag_perform_drop(int x, int y, int message, void *data) {
|
||||
DEBUG(0, LEVEL_DEBUGGING, "Background::drag_perform_drop()\n");
|
||||
if (message == GUI_DRAG_OBJ) // should only happen with original_plus_full_map
|
||||
Game::get_game()->get_map_window()->drag_perform_drop(x, y, message, data);
|
||||
}
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
64
engines/ultima/nuvie/gui/widgets/background.h
Normal file
64
engines/ultima/nuvie/gui/widgets/background.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NUVIE_CORE_BACKGROUND_H
|
||||
#define NUVIE_CORE_BACKGROUND_H
|
||||
|
||||
#include "ultima/nuvie/gui/widgets/gui_widget.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
class Configuration;
|
||||
class U6Shape;
|
||||
|
||||
class Background: public GUI_Widget {
|
||||
const Configuration *config;
|
||||
int game_type;
|
||||
|
||||
U6Shape *background;
|
||||
uint16 bg_w, bg_h;
|
||||
uint16 x_off, y_off, right_bg_x_off, left_bg_x_off, border_width;
|
||||
|
||||
public:
|
||||
|
||||
Background(const Configuration *cfg);
|
||||
~Background() override;
|
||||
|
||||
bool init();
|
||||
uint16 get_border_width() const {
|
||||
return border_width;
|
||||
}
|
||||
void Display(bool full_redraw) override;
|
||||
bool drag_accept_drop(int x, int y, int message, void *data) override; // needed for original+_full_map
|
||||
void drag_perform_drop(int x, int y, int message, void *data) override; // needed for original+_full_map
|
||||
U6Shape *get_bg_shape() {
|
||||
return background;
|
||||
}
|
||||
uint16 get_bg_w() const {
|
||||
return bg_w;
|
||||
}
|
||||
};
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
520
engines/ultima/nuvie/gui/widgets/command_bar.cpp
Normal file
520
engines/ultima/nuvie/gui/widgets/command_bar.cpp
Normal file
@@ -0,0 +1,520 @@
|
||||
/* 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/nuvie/conf/configuration.h"
|
||||
#include "ultima/nuvie/core/nuvie_defs.h"
|
||||
#include "ultima/nuvie/misc/u6_misc.h"
|
||||
#include "ultima/nuvie/core/game.h"
|
||||
#include "ultima/nuvie/screen/screen.h"
|
||||
#include "ultima/nuvie/core/events.h"
|
||||
#include "ultima/nuvie/core/tile_manager.h"
|
||||
#include "ultima/nuvie/fonts/font.h"
|
||||
#include "ultima/nuvie/fonts/font_manager.h"
|
||||
#include "ultima/nuvie/core/game_clock.h"
|
||||
#include "ultima/nuvie/screen/game_palette.h"
|
||||
#include "ultima/nuvie/gui/widgets/command_bar.h"
|
||||
#include "ultima/nuvie/core/weather.h"
|
||||
#include "ultima/nuvie/core/party.h"
|
||||
#include "ultima/nuvie/core/player.h"
|
||||
#include "ultima/nuvie/save/obj_list.h"
|
||||
#include "ultima/nuvie/files/nuvie_io.h"
|
||||
#include "ultima/nuvie/files/u6_shape.h"
|
||||
#include "ultima/nuvie/gui/widgets/map_window.h"
|
||||
#include "ultima/nuvie/gui/gui.h"
|
||||
#include "ultima/nuvie/nuvie.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
using Std::string;
|
||||
|
||||
static const Tile placeholder_tile = {
|
||||
0,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
0,
|
||||
//uint8 qty;
|
||||
//uint8 flags;
|
||||
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
|
||||
{
|
||||
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
|
||||
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
|
||||
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
|
||||
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
|
||||
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
|
||||
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
|
||||
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
|
||||
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
|
||||
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
|
||||
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
|
||||
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
|
||||
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
|
||||
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
|
||||
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
|
||||
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
|
||||
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15
|
||||
}
|
||||
};
|
||||
|
||||
CommandBar::CommandBar() : GUI_Widget(nullptr), game(nullptr), event(nullptr),
|
||||
background(nullptr), font(nullptr), selected_action(-1), offset(0),
|
||||
combat_mode(false), bg_color(0), font_color(0), active_action_num(-1),
|
||||
lever_up(nullptr), lever_down(nullptr) {
|
||||
for (int i = 0; i < ARRAYSIZE(icon); i++)
|
||||
icon[i] = nullptr;
|
||||
}
|
||||
|
||||
CommandBar::CommandBar(Game *g) : GUI_Widget(nullptr), game(g),
|
||||
background(nullptr), combat_mode(false), bg_color(0), active_action_num(-1),
|
||||
font_color(0), lever_up(nullptr), lever_down(nullptr) {
|
||||
Weather *weather;
|
||||
uint16 x_off = game->get_game_x_offset();
|
||||
uint16 y_off = game->get_game_y_offset();
|
||||
bool right_pos_cb = false;
|
||||
const Configuration *cfg = nullptr;
|
||||
|
||||
if (!game->is_orig_style()) {
|
||||
cfg = game->get_config();
|
||||
Std::string pos_str;
|
||||
cfg->value(config_get_game_key(cfg) + "/cb_position", pos_str, "default");
|
||||
if (pos_str == "default")
|
||||
right_pos_cb = !game->is_new_style();
|
||||
else
|
||||
right_pos_cb = pos_str != "left";
|
||||
}
|
||||
|
||||
if (game->get_game_type() == NUVIE_GAME_U6) {
|
||||
offset = OBJLIST_OFFSET_U6_COMMAND_BAR;
|
||||
if (!game->is_orig_style()) {
|
||||
|
||||
int value;
|
||||
cfg->value(config_get_game_key(cfg) + "/cb_text_color", value, 115); // light blue so that it stands out most of the time and isn't too bold
|
||||
font_color = value;
|
||||
y_off += game->get_game_height() - 29;
|
||||
if (right_pos_cb && (game->get_game_height() > 228 || game->is_new_style())) // bottom right
|
||||
Init(nullptr, x_off + 159 + game->get_game_width() - 320, y_off, 0, 0);
|
||||
else // bottom left
|
||||
Init(nullptr, x_off, y_off, 0, 0);
|
||||
} else {
|
||||
font_color = FONT_COLOR_U6_NORMAL;
|
||||
Init(nullptr, 8 + x_off, 168 + y_off, 0, 0);
|
||||
}
|
||||
area.setWidth(16 * 10); // space for 10 icons
|
||||
area.setHeight(24 + 1); // extra space for the underlined default action
|
||||
} else if (game->get_game_type() == NUVIE_GAME_MD) {
|
||||
if (!game->is_orig_style()) {
|
||||
background = new U6Shape();
|
||||
background->load_WoU_background(game->get_config(), game->get_game_type());
|
||||
y_off += game->get_game_height() - 34;
|
||||
if (right_pos_cb && (game->get_game_height() > 233 || game->is_new_style()))
|
||||
Init(nullptr, x_off + game->get_game_width() - 320 + 174, y_off, 146, 34);
|
||||
else
|
||||
Init(nullptr, 16 + x_off, y_off - 3, 146, 34);
|
||||
} else
|
||||
Init(nullptr, 16 + x_off, 163 + y_off, 146, 34);
|
||||
offset = OBJLIST_OFFSET_MD_COMMAND_BAR;
|
||||
} else { // SE
|
||||
if (!game->is_orig_style()) {
|
||||
background = new U6Shape();
|
||||
background->load_WoU_background(game->get_config(), game->get_game_type());
|
||||
y_off += game->get_game_height() - 22;
|
||||
if (right_pos_cb && (game->get_game_height() > 221 || game->is_new_style())) // bottom right
|
||||
Init(nullptr, x_off + 156 + game->get_game_width() - 320, y_off, 163, 19);
|
||||
else
|
||||
Init(nullptr, 8 + x_off, y_off, 1643, 19);
|
||||
} else
|
||||
Init(nullptr, 8 + x_off, 178 + y_off, 163, 19);
|
||||
offset = OBJLIST_OFFSET_SE_COMMAND_BAR;
|
||||
}
|
||||
|
||||
event = nullptr; // it's not set yet
|
||||
font = game->get_font_manager()->get_font(0);
|
||||
|
||||
weather = game->get_weather();
|
||||
|
||||
selected_action = -1;
|
||||
combat_mode = false;
|
||||
wind = "?";
|
||||
|
||||
bg_color = game->get_palette()->get_bg_color();
|
||||
init_buttons();
|
||||
|
||||
weather->add_wind_change_notification_callback((CallBack *)this); //we want to know when the wind direction changes.
|
||||
}
|
||||
|
||||
CommandBar::~CommandBar() {
|
||||
if (background)
|
||||
delete background;
|
||||
if (lever_up)
|
||||
delete lever_up;
|
||||
if (lever_down)
|
||||
delete lever_down;
|
||||
}
|
||||
|
||||
bool CommandBar::init_buttons() {
|
||||
if (game->get_game_type() == NUVIE_GAME_U6) {
|
||||
TileManager *tile_man = game->get_tile_manager();
|
||||
for (uint32 i = 0; i < 9; i++)
|
||||
icon[i] = tile_man->get_tile(i + 400);
|
||||
// NOTE: combat button has two states
|
||||
icon[9] = tile_man->get_tile(combat_mode ? 415 : 414);
|
||||
icon[10] = tile_man->get_tile(409); //save icon used by CommandBarNewUI
|
||||
icon[11] = tile_man->get_tile(409); // quick save
|
||||
icon[12] = tile_man->get_tile(409); // quick load
|
||||
} else if (game->get_game_type() == NUVIE_GAME_MD) {
|
||||
icon[0] = &placeholder_tile; // attack
|
||||
icon[1] = &placeholder_tile; // talk
|
||||
icon[2] = &placeholder_tile; // look
|
||||
icon[3] = &placeholder_tile; // get
|
||||
icon[4] = &placeholder_tile; // drop
|
||||
icon[5] = &placeholder_tile; // move
|
||||
icon[6] = &placeholder_tile; // use
|
||||
icon[7] = &placeholder_tile; // combat mode
|
||||
icon[8] = &placeholder_tile; // load/save
|
||||
icon[9] = &placeholder_tile; // quick save
|
||||
icon[10] = &placeholder_tile; // quick load
|
||||
|
||||
Common::Path filename;
|
||||
Configuration *config = Game::get_game()->get_config();
|
||||
config_get_path(config, "mdscreen.lzc", filename);
|
||||
lever_up = new U6Shape();
|
||||
lever_down = new U6Shape();
|
||||
lever_up->load_from_lzc(filename, 2, 1);
|
||||
lever_down->load_from_lzc(filename, 2, 0);
|
||||
} else { // SE
|
||||
icon[0] = &placeholder_tile; // move
|
||||
icon[1] = &placeholder_tile; // get
|
||||
icon[2] = &placeholder_tile; // drop
|
||||
icon[3] = &placeholder_tile; // use
|
||||
icon[4] = &placeholder_tile; // talk
|
||||
icon[5] = &placeholder_tile; // look
|
||||
icon[6] = &placeholder_tile; // attack
|
||||
icon[7] = &placeholder_tile; // rest
|
||||
icon[8] = &placeholder_tile; // combat mode
|
||||
icon[9] = &placeholder_tile; // load/save
|
||||
icon[10] = &placeholder_tile; // quick save
|
||||
icon[11] = &placeholder_tile; // quick load
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CommandBar::load(NuvieIO *objlist) {
|
||||
objlist->seek(offset);
|
||||
uint8 action = objlist->read1();
|
||||
selected_action = (action == 0xff ? -1 : action - 0x81);
|
||||
|
||||
sint8 max_action;
|
||||
if (game->get_game_type() == NUVIE_GAME_U6)
|
||||
max_action = 9;
|
||||
else if (game->get_game_type() == NUVIE_GAME_SE)
|
||||
max_action = 8;
|
||||
else // MD
|
||||
max_action = 7;
|
||||
|
||||
if (selected_action > max_action || selected_action < 0)
|
||||
selected_action = -1;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CommandBar::save(NuvieIO *objlist) {
|
||||
objlist->seek(offset);
|
||||
objlist->write1(selected_action > 0 ? selected_action + 0x81 : 0xff);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CommandBar::fill_square(uint8 pal_index) {
|
||||
screen->fill(pal_index, area.left + selected_action * 18, area.top, 19, 1); // top row
|
||||
screen->fill(pal_index, area.left + selected_action * 18, area.top + 18, 19, 1); // bottom row
|
||||
screen->fill(pal_index, area.left + selected_action * 18, area.top + 1, 1, 17); // left side
|
||||
screen->fill(pal_index, area.left + selected_action * 18 + 18, area.top + 1, 1, 17); // right side
|
||||
}
|
||||
|
||||
void CommandBar::select_action(sint8 activate) {
|
||||
if (!game->is_new_style() && game->get_game_type() == NUVIE_GAME_SE) // black out previous setting
|
||||
fill_square(0);
|
||||
if (selected_action == activate) // clear if already selected
|
||||
set_selected_action(-1);
|
||||
else
|
||||
set_selected_action(activate);
|
||||
}
|
||||
|
||||
GUI_status CommandBar::MouseDown(int x, int y, Events::MouseButton button) {
|
||||
x -= area.left;
|
||||
y -= area.top;
|
||||
|
||||
if (game->get_game_type() != NUVIE_GAME_U6 ||
|
||||
(y >= 8 && y <= 24)) {
|
||||
uint8 activate = x / 16; // icon selected
|
||||
if (game->get_game_type() == NUVIE_GAME_SE)
|
||||
activate = x / 18;
|
||||
else if (game->get_game_type() == NUVIE_GAME_MD) {
|
||||
activate = (x) / 18;
|
||||
if (activate > 7)
|
||||
activate = 7;
|
||||
}
|
||||
if (button == COMMANDBAR_USE_BUTTON)
|
||||
return hit(activate);
|
||||
else if (button == COMMANDBAR_ACTION_BUTTON) {
|
||||
select_action(activate);
|
||||
}
|
||||
} else if (!game->is_orig_style())
|
||||
return GUI_PASS;
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
GUI_status CommandBar::hit(uint8 num) {
|
||||
if (!event) event = game->get_event();
|
||||
|
||||
if (event->get_mode() != MOVE_MODE && event->get_mode() != EQUIP_MODE)
|
||||
return GUI_PASS;
|
||||
|
||||
try_selected_action(num);
|
||||
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
static const EventMode U6_mode_tbl[] = { ATTACK_MODE, CAST_MODE, TALK_MODE, LOOK_MODE, GET_MODE,
|
||||
DROP_MODE, PUSH_MODE, USE_MODE, REST_MODE, COMBAT_MODE
|
||||
};
|
||||
static const EventMode MD_mode_tbl[] = { ATTACK_MODE, TALK_MODE, LOOK_MODE, GET_MODE,
|
||||
DROP_MODE, PUSH_MODE, USE_MODE, COMBAT_MODE
|
||||
};
|
||||
static const EventMode SE_mode_tbl[] = { PUSH_MODE, GET_MODE, DROP_MODE, USE_MODE, TALK_MODE,
|
||||
LOOK_MODE, ATTACK_MODE, REST_MODE, COMBAT_MODE
|
||||
};
|
||||
|
||||
/*
|
||||
* return true if target is needed (only used for original CommandBar commands)
|
||||
*/
|
||||
bool CommandBar::try_selected_action(sint8 command_num) {
|
||||
if (!event) event = game->get_event();
|
||||
|
||||
if (command_num == -1)
|
||||
command_num = selected_action;
|
||||
|
||||
if (command_num == -1) // might happen if changing selected action when in EQUIP_MODE
|
||||
return false;
|
||||
|
||||
EventMode mode;
|
||||
|
||||
sint8 save_num, quick_save_num, quick_load_num;
|
||||
if (game->get_game_type() == NUVIE_GAME_U6) {
|
||||
save_num = 10;
|
||||
quick_save_num = 11;
|
||||
quick_load_num = 12;
|
||||
} else if (game->get_game_type() == NUVIE_GAME_MD) {
|
||||
save_num = 8;
|
||||
quick_save_num = 9;
|
||||
quick_load_num = 10;
|
||||
} else { // SE
|
||||
save_num = 9;
|
||||
quick_save_num = 10;
|
||||
quick_load_num = 11;
|
||||
}
|
||||
|
||||
// CommandBarNewUI only commands
|
||||
if (command_num == save_num) {
|
||||
g_engine->openMainMenuDialog();
|
||||
return false;
|
||||
} else if (command_num == quick_save_num)
|
||||
return g_engine->quickSave(0, true);
|
||||
else if (command_num == quick_load_num)
|
||||
return g_engine->quickSave(0, false);
|
||||
else if (command_num >= save_num)
|
||||
return false;
|
||||
|
||||
// original CommandBar commands (also used in CommandBarNewUI)
|
||||
if (game->get_game_type() == NUVIE_GAME_U6)
|
||||
mode = U6_mode_tbl[command_num];
|
||||
else if (game->get_game_type() == NUVIE_GAME_MD)
|
||||
mode = MD_mode_tbl[command_num];
|
||||
else // SE
|
||||
mode = SE_mode_tbl[command_num];
|
||||
|
||||
switch (mode) {
|
||||
case CAST_MODE:
|
||||
case GET_MODE:
|
||||
case DROP_MODE:
|
||||
case PUSH_MODE:
|
||||
if (game->get_player()->is_in_vehicle()) {
|
||||
event->display_not_aboard_vehicle();
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
event->newAction(mode);
|
||||
|
||||
if (mode < REST_MODE) // needs target
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void CommandBar::set_combat_mode(bool mode) {
|
||||
TileManager *tile_man = game->get_tile_manager();
|
||||
if (combat_mode != mode) {
|
||||
combat_mode = mode;
|
||||
if (game->get_game_type() == NUVIE_GAME_U6) {
|
||||
icon[9] = tile_man->get_tile(combat_mode ? 415 : 414);
|
||||
update_display = true;
|
||||
}
|
||||
}
|
||||
|
||||
//FIXME this probably should be moved else where. I think this was added to get party to fight first. It may not be needed now.
|
||||
if (combat_mode) { // make sure party attacks
|
||||
Player *player = game->get_player();
|
||||
Party *party = player->get_party();
|
||||
party->follow(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void CommandBar::Display(bool full_redraw) {
|
||||
Screen *scr = game->get_screen();
|
||||
|
||||
if (full_redraw || update_display || !game->is_orig_style()) {
|
||||
update_display = false;
|
||||
if (game->get_game_type() == NUVIE_GAME_U6) {
|
||||
if (game->is_orig_style())
|
||||
scr->fill(bg_color, area.left, area.top, area.width(), area.height());
|
||||
else if (game->is_original_plus_cutoff_map() && area.left != game->get_game_x_offset()) // over null background so clear area where text is displayed
|
||||
scr->clear(area.left + 2, area.top, area.width() - 2, area.height() - 16, nullptr);
|
||||
|
||||
display_information();
|
||||
for (uint32 i = 0; i < 10; i++)
|
||||
scr->blit(area.left + i * 16, area.top + 8, icon[i]->data, 8, 16, 16, 16);
|
||||
|
||||
if (selected_action >= 0 && selected_action <= 9)
|
||||
scr->fill(9, area.left + selected_action * 16, area.top + 24, 16, 1);
|
||||
} else if (game->get_game_type() == NUVIE_GAME_SE) {
|
||||
if (!game->is_orig_style()) {
|
||||
const unsigned char *se_ptr = background->get_data();
|
||||
se_ptr += ((320 * 178) + 8); // ((bg_w * image_y_off) + image_x_off)
|
||||
scr->blit(area.left, area.top, se_ptr, 8, 163, 19, 320, true); // drawing command bar icons from background
|
||||
}
|
||||
if (selected_action >= 0 && selected_action <= 8)
|
||||
fill_square(6);
|
||||
} else { // MD
|
||||
if (!game->is_orig_style()) {
|
||||
const unsigned char *md_bg_ptr = background->get_data();
|
||||
md_bg_ptr += ((320 * 163) + 15); // ((bg_w * image_y_off) + image_x_off)
|
||||
scr->fill(0, area.left, area.top, area.width(), area.height()); // lever slots, text, top, and bottom have transparency so we need to fill in black first
|
||||
scr->blit(area.left, area.top, md_bg_ptr, 8, area.width(), area.height(), 320, true); // drawing command bar icons from background
|
||||
scr->fill(0, area.left, area.top, 1, area.height()); // make left black so it looks better
|
||||
scr->fill(0, area.left + area.width() - 1, area.top, 1, area.height()); // make right black so it looks better
|
||||
}
|
||||
|
||||
//
|
||||
// Display the switched levers. Original MD has lever down for:
|
||||
// * the right-click action (left click is move)
|
||||
// * a current action pressed via lever or keyboard (eg, drop)
|
||||
// * combat lever if in combat mode
|
||||
//
|
||||
// TODO: Switch the right-click action down to match original.
|
||||
//
|
||||
const U6Shape *lever;
|
||||
uint16 w, h;
|
||||
lever_up->get_size(&w, &h);
|
||||
for (int i = 0; i < 7; i++) {
|
||||
lever = (i == active_action_num) ? lever_down : lever_up;
|
||||
scr->blit(area.left + 18 * i + 6, area.top + 6, lever->get_data(), 8, w, h, w);
|
||||
}
|
||||
lever = (combat_mode ? lever_down : lever_up);
|
||||
scr->blit(area.left + 18 * 7 + 6, area.top + 6, lever->get_data(), 8, w, h, w);
|
||||
}
|
||||
|
||||
scr->update(area.left, area.top, area.width(), area.height());
|
||||
}
|
||||
}
|
||||
|
||||
void CommandBar::display_information() {
|
||||
string infostring(game->get_clock()->get_date_string());
|
||||
infostring += " Wind:";
|
||||
infostring += wind;
|
||||
font->drawString(screen, infostring.c_str(), area.left + 8, area.top, font_color, font_color);
|
||||
}
|
||||
|
||||
void CommandBar::on_new_action(EventMode action) {
|
||||
// This is only really needed on MD, but keep track on others too.
|
||||
const EventMode *modetbl;
|
||||
int modetblsz;
|
||||
if (game->get_game_type() == NUVIE_GAME_U6) {
|
||||
modetbl = U6_mode_tbl;
|
||||
modetblsz = ARRAYSIZE(U6_mode_tbl);
|
||||
} else if (game->get_game_type() == NUVIE_GAME_MD) {
|
||||
modetbl = MD_mode_tbl;
|
||||
modetblsz = ARRAYSIZE(MD_mode_tbl);
|
||||
} else { // SE
|
||||
modetbl = SE_mode_tbl;
|
||||
modetblsz = ARRAYSIZE(SE_mode_tbl);
|
||||
}
|
||||
|
||||
active_action_num = -1;
|
||||
for (int i = 0; i < modetblsz; i++) {
|
||||
if (action == modetbl[i])
|
||||
active_action_num = i;
|
||||
}
|
||||
update_display = true;
|
||||
}
|
||||
|
||||
uint16 CommandBar::callback(uint16 msg, CallBack *caller, void *data) {
|
||||
Weather *weather = game->get_weather();
|
||||
|
||||
if (caller == (CallBack *)weather && msg == WEATHER_CB_CHANGE_WIND_DIR) {
|
||||
wind = weather->get_wind_dir_str();
|
||||
update_display = true;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool CommandBar::drag_accept_drop(int x, int y, int message, void *data) {
|
||||
GUI::get_gui()->force_full_redraw();
|
||||
DEBUG(0, LEVEL_DEBUGGING, "CommandBar::drag_accept_drop()\n");
|
||||
if (game->get_game_type() == NUVIE_GAME_U6 && !Game::get_game()->is_orig_style()
|
||||
&& message == GUI_DRAG_OBJ) {
|
||||
if (y < area.top + 8) // over text
|
||||
return Game::get_game()->get_map_window()->drag_accept_drop(x, y, message, data);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void CommandBar::drag_perform_drop(int x, int y, int message, void *data) {
|
||||
DEBUG(0, LEVEL_DEBUGGING, "CommandBar::drag_perform_drop()\n");
|
||||
if (message == GUI_DRAG_OBJ) // should only happen with !orig_style in U6
|
||||
Game::get_game()->get_map_window()->drag_perform_drop(x, y, message, data);
|
||||
}
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
113
engines/ultima/nuvie/gui/widgets/command_bar.h
Normal file
113
engines/ultima/nuvie/gui/widgets/command_bar.h
Normal file
@@ -0,0 +1,113 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NUVIE_CORE_COMMAND_BAR_H
|
||||
#define NUVIE_CORE_COMMAND_BAR_H
|
||||
|
||||
#include "ultima/shared/std/string.h"
|
||||
#include "ultima/nuvie/gui/widgets/gui_widget.h"
|
||||
#include "ultima/nuvie/misc/call_back.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
class NuvieIO;
|
||||
class Events;
|
||||
class Game;
|
||||
class GUI_Button;
|
||||
class GUI_CallBack;
|
||||
class Font;
|
||||
class U6Shape;
|
||||
|
||||
#define COMMANDBAR_USE_BUTTON 1
|
||||
#define COMMANDBAR_ACTION_BUTTON 3
|
||||
|
||||
/* U6 command buttons.
|
||||
* [Attack][Cast][Talk][Look][Get][Drop][Move][Use][Rest][Combat]
|
||||
* Left click: New action if none is pending.
|
||||
* Right click: Set default action.
|
||||
* Information: [A]M-DD-YYYY Wind: W[B]
|
||||
*/
|
||||
class CommandBar: public GUI_Widget, public CallBack {
|
||||
protected:
|
||||
Game *game;
|
||||
Events *event;
|
||||
Font *font;
|
||||
const Tile *icon[13];
|
||||
U6Shape *background; // used to display the WoU command bar backgrounds
|
||||
|
||||
U6Shape *lever_up; // The lever in the up state (MD only)
|
||||
U6Shape *lever_down; // The lever in the down state (MD only)
|
||||
|
||||
sint8 selected_action; // underlined icon (-1 = none)
|
||||
sint8 active_action_num; // the last action that was activated (for MD levers)
|
||||
bool combat_mode; // state of combat icon
|
||||
Std::string wind; // wind direction
|
||||
void fill_square(uint8 pal_index);
|
||||
|
||||
uint8 bg_color, font_color;
|
||||
uint16 offset;
|
||||
|
||||
virtual void display_information();
|
||||
virtual GUI_status hit(uint8 num);
|
||||
|
||||
public:
|
||||
CommandBar();
|
||||
CommandBar(Game *g);
|
||||
~CommandBar() override;
|
||||
virtual bool init_buttons();
|
||||
|
||||
void Display(bool full_redraw) override;
|
||||
GUI_status MouseDown(int x, int y, Events::MouseButton button) override;
|
||||
void update() {
|
||||
update_display = true;
|
||||
}
|
||||
|
||||
void select_action(sint8 activate);
|
||||
void set_combat_mode(bool mode);
|
||||
// void set_wind(Std::string dir) { wind = dir; update_display = true; }
|
||||
void set_selected_action(sint8 action) {
|
||||
selected_action = action;
|
||||
update_display = true;
|
||||
}
|
||||
bool try_selected_action(sint8 command_num = -1);
|
||||
sint8 get_selected_action() const {
|
||||
return selected_action;
|
||||
}
|
||||
|
||||
// Called when a mode is being changed from here
|
||||
// *or* keyboard - so MD can update levers
|
||||
void on_new_action(EventMode action);
|
||||
|
||||
GUI_status callback(uint16 msg, GUI_CallBack *caller, void *data) override {
|
||||
return GUI_PASS;
|
||||
}
|
||||
uint16 callback(uint16 msg, CallBack *caller, void *data) override;
|
||||
bool load(NuvieIO *objlist);
|
||||
bool save(NuvieIO *objlist);
|
||||
bool drag_accept_drop(int x, int y, int message, void *data) override; // needed for !orig_style
|
||||
void drag_perform_drop(int x, int y, int message, void *data) override; // needed for !orig_style
|
||||
};
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
284
engines/ultima/nuvie/gui/widgets/command_bar_new_ui.cpp
Normal file
284
engines/ultima/nuvie/gui/widgets/command_bar_new_ui.cpp
Normal file
@@ -0,0 +1,284 @@
|
||||
/* 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/nuvie/conf/configuration.h"
|
||||
|
||||
#include "ultima/nuvie/core/nuvie_defs.h"
|
||||
#include "ultima/nuvie/misc/u6_misc.h"
|
||||
#include "ultima/nuvie/core/game.h"
|
||||
#include "ultima/nuvie/screen/screen.h"
|
||||
#include "ultima/nuvie/core/events.h"
|
||||
#include "ultima/nuvie/core/tile_manager.h"
|
||||
#include "ultima/nuvie/fonts/font.h"
|
||||
#include "ultima/nuvie/fonts/font_manager.h"
|
||||
#include "ultima/nuvie/core/game_clock.h"
|
||||
#include "ultima/nuvie/screen/game_palette.h"
|
||||
#include "ultima/nuvie/gui/widgets/command_bar_new_ui.h"
|
||||
#include "ultima/nuvie/core/weather.h"
|
||||
#include "ultima/nuvie/core/party.h"
|
||||
#include "ultima/nuvie/core/player.h"
|
||||
#include "ultima/nuvie/save/obj_list.h"
|
||||
#include "ultima/nuvie/files/nuvie_io.h"
|
||||
#include "ultima/nuvie/gui/widgets/background.h"
|
||||
#include "ultima/nuvie/keybinding/keys.h"
|
||||
#include "common/events.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
using Std::string;
|
||||
|
||||
#define btn_size 17
|
||||
#define SELECTED_COLOR 248
|
||||
#define table_size_U6 13
|
||||
#define table_size_SE 12
|
||||
#define table_size_MD 11
|
||||
|
||||
static const char *U6_mode_name_tbl[table_size_U6] = {"Attack", "Cast", "Talk", "Look", "Get", "Drop", "Move", "Use", "Rest", "Combat mode", "Load/Save", "Quick save", "Quick load"};
|
||||
static const char *SE_mode_name_tbl[table_size_SE] = {"Move", "Get", "Drop", "Use", "Talk", "Look", "Attack", "Rest", "Combat mode", "Load/Save", "Quick save", "Quick load"};
|
||||
static const char *MD_mode_name_tbl[table_size_MD] = {"Attack", "Talk", "Look", "Get", "Drop", "Move", "Use", "Combat mode", "Load/Save", "Quick save", "Quick load"};
|
||||
static const char *mode_name_tbl[table_size_U6];
|
||||
|
||||
CommandBarNewUI::CommandBarNewUI(Game *g) : CommandBar() {
|
||||
game = g;
|
||||
background = nullptr;
|
||||
Weather *weather;
|
||||
uint16 x_off = game->get_game_x_offset();
|
||||
uint16 y_off = game->get_game_y_offset();
|
||||
|
||||
icon_w = 5;
|
||||
icon_h = 3;
|
||||
uint8 text_height;
|
||||
uint16 map_width;
|
||||
uint16 map_height;
|
||||
|
||||
offset = OBJLIST_OFFSET_U6_COMMAND_BAR;
|
||||
|
||||
if (game->get_game_type() == NUVIE_GAME_U6) {
|
||||
num_icons = table_size_U6;
|
||||
for (uint8 i = 0; i < table_size_U6; i++)
|
||||
mode_name_tbl[i] = U6_mode_name_tbl[i];
|
||||
} else if (game->get_game_type() == NUVIE_GAME_SE) {
|
||||
num_icons = table_size_SE;
|
||||
for (uint8 i = 0; i < table_size_SE; i++)
|
||||
mode_name_tbl[i] = SE_mode_name_tbl[i];
|
||||
} else { // MD
|
||||
num_icons = table_size_MD;
|
||||
for (uint8 i = 0; i < table_size_MD; i++)
|
||||
mode_name_tbl[i] = MD_mode_name_tbl[i];
|
||||
}
|
||||
|
||||
if (game->is_orig_style()) {
|
||||
text_height = 8;
|
||||
icon_y_offset = 0;
|
||||
map_width = 176;
|
||||
map_height = 176;
|
||||
} else {
|
||||
if (game->get_game_type() == NUVIE_GAME_U6) {
|
||||
text_height = 17;
|
||||
icon_y_offset = 9;
|
||||
} else {
|
||||
text_height = 8;
|
||||
icon_y_offset = 0;
|
||||
}
|
||||
if (game->is_original_plus())
|
||||
map_width = game->get_game_width() - game->get_background()->get_border_width();
|
||||
else
|
||||
map_width = game->get_game_width();
|
||||
map_height = game->get_game_height();
|
||||
}
|
||||
uint8 command_width = btn_size * icon_w;
|
||||
uint8 command_height = btn_size * icon_h + text_height;
|
||||
|
||||
Init(nullptr, (map_width - command_width) / 2 + x_off, (map_height - command_height) / 2 + y_off, 0, 0);
|
||||
area.setWidth(command_width); // space for 5x3 icons
|
||||
area.setHeight(command_height);
|
||||
|
||||
event = nullptr; // it's not set yet
|
||||
|
||||
weather = game->get_weather();
|
||||
|
||||
selected_action = -1;
|
||||
combat_mode = false;
|
||||
wind = weather->get_wind_dir_str();
|
||||
|
||||
bg_color = game->get_palette()->get_bg_color();
|
||||
|
||||
init_buttons();
|
||||
if (game->get_game_type() == NUVIE_GAME_U6 && !game->is_orig_style())
|
||||
weather->add_wind_change_notification_callback((CallBack *)this); //we want to know when the wind direction changes.
|
||||
|
||||
cur_pos = 0;
|
||||
|
||||
font = game->get_font_manager()->get_conv_font();
|
||||
}
|
||||
|
||||
CommandBarNewUI::~CommandBarNewUI() {
|
||||
}
|
||||
|
||||
|
||||
|
||||
GUI_status CommandBarNewUI::MouseDown(int x, int y, Events::MouseButton button) {
|
||||
if (HitRect(x, y)) {
|
||||
x -= area.left;
|
||||
y -= area.right;
|
||||
|
||||
if (y >= icon_y_offset) {
|
||||
uint8 pos = ((y - icon_y_offset) / btn_size) * icon_w;
|
||||
pos += x / btn_size;
|
||||
|
||||
if (pos < num_icons) {
|
||||
cur_pos = pos;
|
||||
hit((sint8)cur_pos);
|
||||
Game::get_game()->get_keybinder()->set_enable_joy_repeat(true);
|
||||
Hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
GUI_status CommandBarNewUI::MouseUp(int x, int y, Events::MouseButton button) {
|
||||
/*
|
||||
if(HitRect(x, y))
|
||||
{
|
||||
x -= area.left;
|
||||
y -= area.top;
|
||||
|
||||
if(y >= icon_y_offset && y < icon_y_offset + icon_h * btn_size)
|
||||
{
|
||||
hit((sint8)cur_pos);
|
||||
Hide();
|
||||
}
|
||||
}
|
||||
*/
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
GUI_status CommandBarNewUI::KeyDown(const Common::KeyState &key) {
|
||||
KeyBinder *keybinder = Game::get_game()->get_keybinder();
|
||||
ActionType a = keybinder->get_ActionType(key);
|
||||
|
||||
switch (keybinder->GetActionKeyType(a)) {
|
||||
case NORTH_KEY:
|
||||
do {
|
||||
if (cur_pos - icon_w < 0)
|
||||
cur_pos = icon_w * icon_h - (icon_w - cur_pos % icon_w);
|
||||
else
|
||||
cur_pos -= icon_w;
|
||||
} while (cur_pos >= num_icons);
|
||||
break;
|
||||
case SOUTH_KEY:
|
||||
do {
|
||||
cur_pos = (cur_pos + icon_w) % (icon_w * icon_h);
|
||||
} while (cur_pos >= num_icons);
|
||||
break;
|
||||
case WEST_KEY:
|
||||
do {
|
||||
if (cur_pos % icon_w == 0)
|
||||
cur_pos = (cur_pos / icon_w) * icon_w + icon_w - 1;
|
||||
else
|
||||
cur_pos--;
|
||||
} while (cur_pos >= num_icons);
|
||||
break;
|
||||
case EAST_KEY:
|
||||
do {
|
||||
cur_pos = (cur_pos / icon_w) * icon_w + (cur_pos + 1) % icon_w;
|
||||
} while (cur_pos >= num_icons);
|
||||
break;
|
||||
case DO_ACTION_KEY:
|
||||
if (cur_pos < num_icons) {
|
||||
hit((sint8)cur_pos);
|
||||
keybinder->set_enable_joy_repeat(true);
|
||||
Hide();
|
||||
}
|
||||
break;
|
||||
case CANCEL_ACTION_KEY:
|
||||
case NEW_COMMAND_BAR_KEY:
|
||||
keybinder->set_enable_joy_repeat(true);
|
||||
Hide();
|
||||
break;
|
||||
|
||||
default :
|
||||
keybinder->handle_always_available_keys(a);
|
||||
break;
|
||||
}
|
||||
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
void CommandBarNewUI::Display(bool full_redraw) {
|
||||
Screen *scr = game->get_screen();
|
||||
|
||||
//if(full_redraw || update_display)
|
||||
// {
|
||||
update_display = false;
|
||||
if (game->get_game_type() == NUVIE_GAME_U6) {
|
||||
//scr->fill(bg_color, area.left, area.top, area.width(), area.height());
|
||||
if (!game->is_orig_style()) {
|
||||
//display_information();
|
||||
string infostring(game->get_clock()->get_date_string());
|
||||
infostring += " Wind:";
|
||||
infostring += wind;
|
||||
font->drawString(scr, infostring.c_str(), area.left - 13, area.top); // sort of center
|
||||
}
|
||||
}
|
||||
uint8 i = 0;
|
||||
for (uint8 y = 0; y < icon_h; y++) {
|
||||
for (uint8 x = 0; x < icon_w && i < num_icons; x++, i++) {
|
||||
scr->blit(area.left + x * btn_size, icon_y_offset + area.top + y * btn_size, icon[i]->data, 8, 16, 16, 16);
|
||||
if (i == cur_pos) {
|
||||
scr->stipple_8bit(SELECTED_COLOR, area.left + x * btn_size, icon_y_offset + area.top + y * btn_size, 16, 16);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (game->get_game_type() == NUVIE_GAME_U6) { // FIXME use new icon instead
|
||||
font->drawString(scr, "QS", area.left + 2 + btn_size, icon_y_offset + area.top + 2 * btn_size + 4);
|
||||
font->drawString(scr, "QL", area.left + 2 + 2 * btn_size, icon_y_offset + area.top + 2 * btn_size + 4);
|
||||
}
|
||||
font->drawString(scr, get_command_name(cur_pos), area.left, area.top + icon_y_offset + icon_h * btn_size);
|
||||
if (game->get_game_type() == NUVIE_GAME_U6 && !game->is_orig_style())
|
||||
scr->update(area.left - 13, area.top, area.width() + 26, area.height()); // need to have edges of text update
|
||||
else
|
||||
scr->update(area.left, area.top, area.width(), area.height());
|
||||
// }
|
||||
}
|
||||
|
||||
const char *CommandBarNewUI::get_command_name(sint8 command_num) const {
|
||||
if (command_num < 0 || command_num >= num_icons)
|
||||
return "";
|
||||
|
||||
return mode_name_tbl[command_num];
|
||||
}
|
||||
|
||||
/*
|
||||
void CommandBarNewUI::display_information()
|
||||
{
|
||||
string infostring(game->get_clock()->get_date_string());
|
||||
infostring += " Wind:";
|
||||
infostring += wind;
|
||||
text->drawString(screen, infostring.c_str(), area.left + 8, area.top, 0);
|
||||
}
|
||||
*/
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
66
engines/ultima/nuvie/gui/widgets/command_bar_new_ui.h
Normal file
66
engines/ultima/nuvie/gui/widgets/command_bar_new_ui.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NUVIE_CORE_COMMAND_BAR_NEW_UI_H
|
||||
#define NUVIE_CORE_COMMAND_BAR_NEW_UI_H
|
||||
|
||||
#include "ultima/shared/std/string.h"
|
||||
#include "ultima/nuvie/gui/widgets/gui_widget.h"
|
||||
#include "ultima/nuvie/misc/call_back.h"
|
||||
#include "ultima/nuvie/gui/widgets/command_bar.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
class NuvieIO;
|
||||
class Events;
|
||||
class Game;
|
||||
class GUI_Button;
|
||||
class GUI_CallBack;
|
||||
class Text;
|
||||
class Font;
|
||||
|
||||
class CommandBarNewUI: public CommandBar {
|
||||
protected:
|
||||
uint8 cur_pos;
|
||||
uint8 icon_w;
|
||||
uint8 icon_h;
|
||||
uint8 icon_y_offset;
|
||||
uint16 num_icons;
|
||||
|
||||
Font *font;
|
||||
public:
|
||||
CommandBarNewUI(Game *g);
|
||||
~CommandBarNewUI() override;
|
||||
|
||||
void Display(bool full_redraw) override;
|
||||
GUI_status KeyDown(const Common::KeyState &key) override;
|
||||
GUI_status MouseDown(int x, int y, Events::MouseButton button) override;
|
||||
GUI_status MouseUp(int x, int y, Events::MouseButton button) override;
|
||||
|
||||
private:
|
||||
const char *get_command_name(sint8 command_num) const;
|
||||
};
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
129
engines/ultima/nuvie/gui/widgets/console.cpp
Normal file
129
engines/ultima/nuvie/gui/widgets/console.cpp
Normal file
@@ -0,0 +1,129 @@
|
||||
/* 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/widgets/console.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
static Console *g_console = nullptr;
|
||||
|
||||
Console::Console(const Configuration *c, Screen *s, GUI *g, uint16 x, uint16 y, uint16 w, uint16 h)
|
||||
: GUI_Console(x, y, w, h), config(c), screen(s), gui(g), displayConsole(true) {
|
||||
config->value("config/general/show_console", displayConsole, true);
|
||||
|
||||
if (displayConsole == false)
|
||||
Hide();
|
||||
|
||||
gui->AddWidget(this);
|
||||
}
|
||||
|
||||
Console::~Console() {
|
||||
|
||||
}
|
||||
|
||||
void Console::AddLine(const Std::string &line) {
|
||||
GUI_Console::AddLine(line);
|
||||
|
||||
if (status == WIDGET_VISIBLE) {
|
||||
gui->Display();
|
||||
screen->performUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
void ConsoleInit(const Configuration *c, Screen *s, GUI *gui, uint16 w, uint16 h) {
|
||||
assert(g_console == nullptr);
|
||||
|
||||
//uint16 x_off = config_get_video_x_offset(c);
|
||||
//uint16 y_off = config_get_video_y_offset(c);
|
||||
|
||||
g_console = new Console(c, s, gui, 0, 0, s->get_width(), s->get_height());//x_off, y_off, w, h);
|
||||
}
|
||||
|
||||
void ConsoleDelete() {
|
||||
if (g_console != nullptr) {
|
||||
g_console->Delete();
|
||||
g_console = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void ConsoleAddInfo(const char *format, ...) {
|
||||
char buf[1024];
|
||||
memset(buf, 0, 1024);
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
vsnprintf(buf, 1024, format, args);
|
||||
va_end(args);
|
||||
|
||||
if (g_console != nullptr) {
|
||||
DEBUG(0, LEVEL_INFORMATIONAL, "%s\n", buf);
|
||||
g_console->AddLine(buf);
|
||||
}
|
||||
}
|
||||
|
||||
void ConsoleAddError(const Std::string &s) {
|
||||
if (g_console != nullptr) {
|
||||
DEBUG(0, LEVEL_ERROR, "%s\n", s.c_str());
|
||||
g_console->Show();
|
||||
g_console->AddLine("Error: " + s);
|
||||
}
|
||||
}
|
||||
|
||||
void ConsoleAddWarning(const Std::string &s) {
|
||||
if (g_console != nullptr) {
|
||||
DEBUG(0, LEVEL_WARNING, "%s\n", s.c_str());
|
||||
g_console->AddLine("Warning: " + s);
|
||||
}
|
||||
}
|
||||
|
||||
void ConsolePause() {
|
||||
if (g_console == nullptr)
|
||||
return;
|
||||
|
||||
//pause here.
|
||||
Common::Event event;
|
||||
bool waiting = true;
|
||||
for (; waiting;) {
|
||||
while (!Events::get()->pollEvent(event)) {
|
||||
if (event.type == Common::EVENT_KEYDOWN || event.type == Common::EVENT_QUIT) {
|
||||
waiting = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ConsoleShow() {
|
||||
if (g_console)
|
||||
g_console->Show();
|
||||
}
|
||||
|
||||
void ConsoleHide() {
|
||||
if (g_console)
|
||||
g_console->Hide();
|
||||
}
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
60
engines/ultima/nuvie/gui/widgets/console.h
Normal file
60
engines/ultima/nuvie/gui/widgets/console.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NUVIE_CORE_CONSOLE_H
|
||||
#define NUVIE_CORE_CONSOLE_H
|
||||
|
||||
#include "ultima/nuvie/gui/gui_console.h"
|
||||
#include "ultima/nuvie/screen/screen.h"
|
||||
#include "ultima/nuvie/conf/configuration.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
class Console : public GUI_Console {
|
||||
|
||||
protected:
|
||||
GUI *gui;
|
||||
Screen *screen;
|
||||
const Configuration *config;
|
||||
|
||||
bool displayConsole;
|
||||
|
||||
public:
|
||||
Console(const Configuration *c, Screen *s, GUI *g, uint16 x, uint16 y, uint16 w, uint16 h);
|
||||
~Console() override;
|
||||
|
||||
void AddLine(const Std::string &line) override;
|
||||
};
|
||||
|
||||
void ConsoleInit(const Configuration *c, Screen *s, GUI *gui, uint16 w, uint16 h);
|
||||
void ConsoleDelete();
|
||||
void ConsoleAddInfo(const char *s, ...);
|
||||
void ConsoleAddError(const Std::string &s);
|
||||
void ConsoleAddWarning(const Std::string &s);
|
||||
void ConsolePause();
|
||||
void ConsoleShow();
|
||||
void ConsoleHide();
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
757
engines/ultima/nuvie/gui/widgets/converse_gump.cpp
Normal file
757
engines/ultima/nuvie/gui/widgets/converse_gump.cpp
Normal file
@@ -0,0 +1,757 @@
|
||||
/* 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/conf/configuration.h"
|
||||
#include "ultima/nuvie/misc/u6_misc.h"
|
||||
#include "ultima/nuvie/fonts/font_manager.h"
|
||||
#include "ultima/nuvie/fonts/font.h"
|
||||
#include "ultima/nuvie/screen/game_palette.h"
|
||||
#include "ultima/nuvie/gui/gui.h"
|
||||
#include "ultima/nuvie/gui/widgets/msg_scroll.h"
|
||||
#include "ultima/nuvie/portraits/portrait.h"
|
||||
#include "ultima/nuvie/core/player.h"
|
||||
#include "ultima/nuvie/gui/widgets/converse_gump.h"
|
||||
#include "ultima/nuvie/actors/actor_manager.h"
|
||||
#include "ultima/nuvie/actors/actor.h"
|
||||
#include "ultima/nuvie/keybinding/keys.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
static const int CURSOR_COLOR = 248;
|
||||
|
||||
// ConverseGump Class
|
||||
|
||||
ConverseGump::ConverseGump(const Configuration *cfg, Font *f, Screen *s) {
|
||||
// uint16 x, y;
|
||||
|
||||
init(cfg, f);
|
||||
Game *game = Game::get_game();
|
||||
game_type = game->get_game_type();
|
||||
|
||||
scroll_width = 30;
|
||||
scroll_height = 8;
|
||||
|
||||
// x = 8;
|
||||
// y = 8;
|
||||
int gump_h;
|
||||
uint8 min_h, default_c;
|
||||
Std::string height_str;
|
||||
min_w = game->get_min_converse_gump_width();
|
||||
uint16 x_off = game->get_game_x_offset();
|
||||
uint16 y_off = game->get_game_y_offset();
|
||||
int game_h = game->get_game_height();
|
||||
|
||||
if (game_type == NUVIE_GAME_SE) {
|
||||
default_c = 216;
|
||||
min_h = 185;
|
||||
} else if (game_type == NUVIE_GAME_MD) {
|
||||
default_c = 136;
|
||||
min_h = 181;
|
||||
} else {// U6
|
||||
default_c = 218;
|
||||
min_h = 152;
|
||||
}
|
||||
cfg->value(config_get_game_key(cfg) + "/converse_height", height_str, "default");
|
||||
|
||||
if (game->is_orig_style()) {
|
||||
gump_h = game_h;
|
||||
} else {
|
||||
if (height_str == "default") {
|
||||
if (game_h > min_h * 1.5) // big enough that we probably don't want to take up the whole screen
|
||||
gump_h = min_h;
|
||||
else
|
||||
gump_h = game_h;
|
||||
} else {
|
||||
cfg->value(config_get_game_key(cfg) + "/converse_height", gump_h, game_h);
|
||||
if (gump_h < min_h)
|
||||
gump_h = min_h;
|
||||
else if (gump_h > game_h)
|
||||
gump_h = game_h;
|
||||
}
|
||||
}
|
||||
|
||||
GUI_Widget::Init(nullptr, x_off, y_off, game->get_converse_gump_width(), (uint16)gump_h);
|
||||
npc_portrait = nullptr;
|
||||
avatar_portrait = nullptr;
|
||||
keyword_list = nullptr;
|
||||
|
||||
font = game->get_font_manager()->get_conv_font();
|
||||
|
||||
found_break_char = false;
|
||||
cursor_wait = 0;
|
||||
|
||||
if (game->is_forcing_solid_converse_bg()) {
|
||||
solid_bg = true;
|
||||
force_solid_bg = true;
|
||||
} else {
|
||||
force_solid_bg = false;
|
||||
cfg->value(config_get_game_key(config) + "/converse_solid_bg", solid_bg, false);
|
||||
}
|
||||
|
||||
int c;
|
||||
cfg->value(config_get_game_key(config) + "/converse_bg_color", c, default_c);
|
||||
if (c < 256)
|
||||
converse_bg_color = (uint8)c;
|
||||
else
|
||||
converse_bg_color = 0;
|
||||
|
||||
cursor_position = 0;
|
||||
|
||||
portrait_width = frame_w = game->get_portrait()->get_portrait_width();
|
||||
portrait_height = frame_h = game->get_portrait()->get_portrait_height();
|
||||
if (game_type == NUVIE_GAME_U6) {
|
||||
frame_w = portrait_width + 8;
|
||||
frame_h = portrait_height + 9;
|
||||
}
|
||||
//DEBUG(0, LEVEL_DEBUGGING, "\nMin w = %d\n", frame_w + 12 + 210);
|
||||
}
|
||||
|
||||
ConverseGump::~ConverseGump() {
|
||||
if (npc_portrait)
|
||||
free(npc_portrait);
|
||||
if (avatar_portrait)
|
||||
free(avatar_portrait);
|
||||
conv_keywords.clear();
|
||||
permitted_input_keywords.clear();
|
||||
}
|
||||
|
||||
void ConverseGump::set_talking(bool state, Actor *actor) {
|
||||
if (state == true) {
|
||||
Game::get_game()->get_keybinder()->set_enable_joy_repeat(false);
|
||||
found_break_char = true;
|
||||
conv_keywords.clear();
|
||||
permitted_input_keywords.clear();
|
||||
Show();
|
||||
set_input_mode(false);
|
||||
clear_scroll();
|
||||
set_found_break_char(true);
|
||||
bool altar = (game_type == NUVIE_GAME_U6 // Singularity is excluded on purpose
|
||||
&& actor->get_actor_num() >= 192 && actor->get_actor_num() <= 199);
|
||||
if (!altar) {
|
||||
add_keyword("name");
|
||||
add_keyword("job");
|
||||
add_keyword("bye");
|
||||
}
|
||||
bool cant_join = (game_type == NUVIE_GAME_U6 // statues and altars
|
||||
&& actor->get_actor_num() >= 189 && actor->get_actor_num() <= 200);
|
||||
if (actor->is_in_party())
|
||||
add_keyword("leave");
|
||||
else if (!cant_join)
|
||||
add_keyword("join");
|
||||
if (game_type == NUVIE_GAME_U6 && !altar) {
|
||||
add_keyword("rune");
|
||||
add_keyword("mantra");
|
||||
}
|
||||
keyword_list = &conv_keywords;
|
||||
|
||||
if (avatar_portrait) {
|
||||
free(avatar_portrait);
|
||||
avatar_portrait = nullptr;
|
||||
}
|
||||
|
||||
cursor_position = 0;
|
||||
} else {
|
||||
Game::get_game()->get_keybinder()->set_enable_joy_repeat(true);
|
||||
}
|
||||
|
||||
MsgScroll::set_talking(state);
|
||||
}
|
||||
|
||||
void ConverseGump::set_actor_portrait(Actor *a) {
|
||||
if (npc_portrait)
|
||||
free(npc_portrait);
|
||||
|
||||
if (Game::get_game()->get_portrait()->has_portrait(a))
|
||||
npc_portrait = get_portrait_data(a);
|
||||
else
|
||||
npc_portrait = nullptr;
|
||||
|
||||
if (avatar_portrait == nullptr) {
|
||||
Actor *p = Game::get_game()->get_player()->get_actor();
|
||||
Actor *p1 = Game::get_game()->get_actor_manager()->get_actor(1);
|
||||
avatar_portrait = get_portrait_data(p->get_actor_num() != 0 ? p : p1); // don't use portrait 0 when in a vehicle
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char *ConverseGump::get_portrait_data(Actor *a) {
|
||||
if (game_type == NUVIE_GAME_U6) {
|
||||
return create_framed_portrait(a);
|
||||
}
|
||||
|
||||
Portrait *p = Game::get_game()->get_portrait();
|
||||
return p->get_portrait_data(a);
|
||||
}
|
||||
|
||||
unsigned char *ConverseGump::create_framed_portrait(Actor *a) { //FIXME U6 specific.
|
||||
//uint8 FRAME_W = portrait_width + 8;
|
||||
uint16 i;
|
||||
Portrait *p = Game::get_game()->get_portrait();
|
||||
unsigned char *portrait_data = p->get_portrait_data(a);
|
||||
unsigned char *framed_data = (unsigned char *)malloc(frame_w * frame_h);
|
||||
|
||||
memset(framed_data, 255, frame_w * frame_h);
|
||||
|
||||
memset(framed_data, 0, frame_w);
|
||||
memset(framed_data + (frame_h - 1)*frame_w, 0, frame_w);
|
||||
memset(framed_data + 1 * frame_w + 2, 53, 57);
|
||||
memset(framed_data + 2 * frame_w + 2, 57, 59);
|
||||
|
||||
memset(framed_data + 3 * frame_w + 4, 0, 57);
|
||||
|
||||
//top left corner
|
||||
framed_data[1 * frame_w] = 0;
|
||||
framed_data[1 * frame_w + 1] = 138;
|
||||
framed_data[2 * frame_w] = 0;
|
||||
framed_data[2 * frame_w + 1] = 139;
|
||||
framed_data[3 * frame_w] = 0;
|
||||
framed_data[3 * frame_w + 1] = 139;
|
||||
framed_data[3 * frame_w + 2] = 57;
|
||||
framed_data[3 * frame_w + 3] = 143;
|
||||
|
||||
for (i = 0; i < portrait_height; i++) {
|
||||
framed_data[(i + 4)*frame_w] = 0;
|
||||
framed_data[(i + 4)*frame_w + 1] = 139;
|
||||
framed_data[(i + 4)*frame_w + 2] = 57;
|
||||
framed_data[(i + 4)*frame_w + 3] = 142;
|
||||
|
||||
memcpy(&framed_data[(i + 4)*frame_w + 4], &portrait_data[i * p->get_portrait_width()], portrait_width);
|
||||
|
||||
framed_data[(i + 4)*frame_w + 4 + portrait_width] = 0;
|
||||
framed_data[(i + 4)*frame_w + 4 + portrait_width + 1] = 57;
|
||||
framed_data[(i + 4)*frame_w + 4 + portrait_width + 2] = 53;
|
||||
framed_data[(i + 4)*frame_w + 4 + portrait_width + 3] = 0;
|
||||
}
|
||||
|
||||
memset(framed_data + (frame_h - 5)*frame_w + 3, 142, 57);
|
||||
memset(framed_data + (frame_h - 4)*frame_w + 2, 57, 60);
|
||||
memset(framed_data + (frame_h - 3)*frame_w + 1, 139, 61);
|
||||
memset(framed_data + (frame_h - 2)*frame_w + 1, 142, 62);
|
||||
|
||||
//bottom left
|
||||
framed_data[(frame_h - 5)*frame_w] = 0;
|
||||
framed_data[(frame_h - 5)*frame_w + 1] = 139;
|
||||
framed_data[(frame_h - 5)*frame_w + 2] = 57;
|
||||
framed_data[(frame_h - 4)*frame_w] = 0;
|
||||
framed_data[(frame_h - 4)*frame_w + 1] = 139;
|
||||
framed_data[(frame_h - 3)*frame_w] = 0;
|
||||
framed_data[(frame_h - 2)*frame_w] = 0;
|
||||
|
||||
//top right
|
||||
framed_data[1 * frame_w + 59] = 50;
|
||||
framed_data[1 * frame_w + 59 + 1] = 49;
|
||||
framed_data[1 * frame_w + 59 + 2] = 49;
|
||||
framed_data[1 * frame_w + 59 + 3] = 15;
|
||||
framed_data[1 * frame_w + 59 + 4] = 0;
|
||||
framed_data[2 * frame_w + 59 + 2] = 15;
|
||||
framed_data[2 * frame_w + 59 + 3] = 49;
|
||||
framed_data[2 * frame_w + 59 + 4] = 0;
|
||||
framed_data[3 * frame_w + 59 + 2] = 57;
|
||||
framed_data[3 * frame_w + 59 + 3] = 49;
|
||||
framed_data[3 * frame_w + 59 + 4] = 0;
|
||||
framed_data[4 * frame_w + 59 + 3] = 50;
|
||||
|
||||
//bottom right
|
||||
framed_data[(frame_h - 5)*frame_w + 60] = 143;
|
||||
framed_data[(frame_h - 5)*frame_w + 61] = 57;
|
||||
framed_data[(frame_h - 5)*frame_w + 62] = 53;
|
||||
framed_data[(frame_h - 5)*frame_w + 63] = 0;
|
||||
framed_data[(frame_h - 4)*frame_w + 62] = 53;
|
||||
framed_data[(frame_h - 4)*frame_w + 63] = 0;
|
||||
framed_data[(frame_h - 3)*frame_w + 62] = 173;
|
||||
framed_data[(frame_h - 3)*frame_w + 63] = 0;
|
||||
framed_data[(frame_h - 2)*frame_w + 63] = 0;
|
||||
|
||||
free(portrait_data);
|
||||
|
||||
return framed_data;
|
||||
}
|
||||
|
||||
void ConverseGump::set_permitted_input(const char *allowed) {
|
||||
permitted_input_keywords.clear();
|
||||
keyword_list = &permitted_input_keywords;
|
||||
MsgScroll::set_permitted_input(allowed);
|
||||
|
||||
if (yes_no_only) {
|
||||
add_keyword("yes");
|
||||
add_keyword("no");
|
||||
} else if (aye_nay_only) {
|
||||
add_keyword("aye");
|
||||
add_keyword("nay");
|
||||
} else if (numbers_only) {
|
||||
add_keyword("0");
|
||||
add_keyword("1");
|
||||
add_keyword("2");
|
||||
add_keyword("3");
|
||||
add_keyword("4");
|
||||
add_keyword("5");
|
||||
add_keyword("6");
|
||||
add_keyword("7");
|
||||
add_keyword("8");
|
||||
add_keyword("9");
|
||||
}
|
||||
|
||||
cursor_position = 0;
|
||||
}
|
||||
|
||||
void ConverseGump::clear_permitted_input() {
|
||||
keyword_list = &conv_keywords;
|
||||
MsgScroll::clear_permitted_input();
|
||||
}
|
||||
|
||||
/*
|
||||
void ConverseGump::add_token(MsgText *token)
|
||||
{
|
||||
DEBUG(0,LEVEL_ALERT, "TOKEN: %s\n", token->s.c_str());
|
||||
|
||||
display_text.push_back(*token);
|
||||
}
|
||||
*/
|
||||
|
||||
void ConverseGump::display_string(const Std::string &s, Font *f, bool include_on_map_window) {
|
||||
if (s.empty())
|
||||
return;
|
||||
|
||||
MsgScroll::display_string(strip_whitespace_after_break(s), f, include_on_map_window);//, MSGSCROLL_NO_MAP_DISPLAY);
|
||||
}
|
||||
|
||||
Std::string ConverseGump::strip_whitespace_after_break(Std::string s) {
|
||||
Std::string::iterator iter;
|
||||
for (iter = s.begin(); iter != s.end();) {
|
||||
if (found_break_char == true) {
|
||||
char c = *iter;
|
||||
if (c == ' ' || c == '\t' || c == '\n' || c == '*') {
|
||||
iter = s.erase(iter);
|
||||
} else {
|
||||
found_break_char = false;
|
||||
iter++;
|
||||
}
|
||||
} else {
|
||||
char c = *iter;
|
||||
if (c == '*') {
|
||||
found_break_char = true;
|
||||
}
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
bool ConverseGump::parse_token(MsgText *token) {
|
||||
int at_idx = token->s.findFirstOf('@', 0);
|
||||
int i = 0;
|
||||
int len = (int)token->s.size();
|
||||
while (at_idx != -1 && i < len) {
|
||||
Std::string keyword = "";
|
||||
for (i = at_idx + 1; i < len; i++) {
|
||||
char c = token->s[i];
|
||||
if (Common::isAlpha(c)) {
|
||||
keyword.push_back(c);
|
||||
}
|
||||
|
||||
if (!Common::isAlpha(c) || i == len - 1) {
|
||||
token->s.erase(at_idx, 1);
|
||||
i--;
|
||||
at_idx = token->s.findFirstOf('@', i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
DEBUG(0, LEVEL_WARNING, "%s", keyword.c_str());
|
||||
add_keyword(keyword);
|
||||
}
|
||||
|
||||
parse_fm_towns_token(token);
|
||||
return MsgScroll::parse_token(token);
|
||||
}
|
||||
|
||||
// Add FM-Towns keywords which take the form. +actor_numKeyword+ eg. +5runes+
|
||||
// Only add keyword if the player has met the actor given by the actor_num
|
||||
void ConverseGump::parse_fm_towns_token(MsgText *token) {
|
||||
int at_idx = token->s.findFirstOf('+', 0);
|
||||
int i = 0;
|
||||
int len = (int)token->s.size();
|
||||
bool has_met = false;
|
||||
while (at_idx != -1 && i < len) {
|
||||
i = at_idx + 1;
|
||||
char c = token->s[i];
|
||||
if (i < len && Common::isDigit(c)) {
|
||||
const char *c_str = token->s.c_str();
|
||||
uint16 actor_num = (int)strtol(&c_str[i], nullptr, 10);
|
||||
if (actor_num < 256) {
|
||||
Actor *actor = Game::get_game()->get_actor_manager()->get_actor(actor_num);
|
||||
if (actor) {
|
||||
has_met = actor->is_met();
|
||||
}
|
||||
}
|
||||
for (; Common::isDigit(c_str[i]);)
|
||||
i++;
|
||||
}
|
||||
|
||||
Std::string keyword = "";
|
||||
for (; i < len; i++) {
|
||||
char ch = token->s[i];
|
||||
|
||||
if (Common::isAlpha(ch)) {
|
||||
keyword.push_back(ch);
|
||||
}
|
||||
|
||||
if (!Common::isAlpha(ch) || i == len - 1) {
|
||||
token->s.erase(at_idx, (i - at_idx) + 1);
|
||||
i -= i - at_idx;
|
||||
at_idx = token->s.findFirstOf('+', i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
DEBUG(0, LEVEL_WARNING, "%s", keyword.c_str());
|
||||
if (has_met) { //only add keyword if the player has met the actor in question.
|
||||
add_keyword(keyword);
|
||||
has_met = false;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void ConverseGump::add_keyword(const Std::string keyword_) {
|
||||
string keyword = " *" + keyword_;
|
||||
|
||||
for (const MsgText &txt : *keyword_list) {
|
||||
if (string_i_compare(txt.s, keyword)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
MsgText m_text;
|
||||
m_text.s = keyword;
|
||||
m_text.font = font;
|
||||
keyword_list->push_back(m_text);
|
||||
}
|
||||
|
||||
Std::string ConverseGump::get_token_string_at_pos(uint16 x, uint16 y) {
|
||||
uint16 total_length = 0;
|
||||
uint16 tmp_y = area.top + portrait_height + 8 + 3 + 4;
|
||||
Std::list<MsgText>::iterator iter;
|
||||
for (iter = keyword_list->begin(); iter != keyword_list->end(); iter++) {
|
||||
MsgText t = *iter;
|
||||
uint16 token_len = font->getStringWidth(t.s.c_str());
|
||||
|
||||
// if(token_len + total_length >= (26 * 8))
|
||||
if (portrait_width / 2 + portrait_width + token_len + total_length + 8 >= min_w - 4) {
|
||||
total_length = 0;
|
||||
tmp_y += 10;
|
||||
}
|
||||
//t.font->drawString(screen, t.s.c_str(), area.left + portrait_width / 2 + portrait_width + 8 + total_length * 8, y + portrait_height + 8, 0);
|
||||
if (x > area.left + portrait_width / 2 + portrait_width + 8 + total_length && x < area.left + portrait_width / 2 + portrait_width + 8 + total_length + token_len) {
|
||||
if (y > tmp_y && y < tmp_y + 8) {
|
||||
if (!is_permanent_keyword(t.s))
|
||||
keyword_list->erase(iter);
|
||||
return t.s;
|
||||
}
|
||||
}
|
||||
total_length += token_len;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
Std::string ConverseGump::get_token_at_cursor() {
|
||||
uint16 i = 0;
|
||||
Std::list<MsgText>::iterator iter;
|
||||
for (iter = keyword_list->begin(); iter != keyword_list->end(); i++, iter++) {
|
||||
if (i == cursor_position) {
|
||||
Std::string keyword = (*iter).s;
|
||||
if (!is_permanent_keyword(keyword)) {
|
||||
keyword_list->erase(iter);
|
||||
if (permit_input)
|
||||
keyword = Std::string(keyword.at(2)); // only return first char after " *"
|
||||
}
|
||||
return keyword;
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
bool ConverseGump::input_buf_add_char(char c) {
|
||||
input_char = 0;
|
||||
if (permit_input != nullptr)
|
||||
input_buf_remove_char();
|
||||
input_buf.push_back(c);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ConverseGump::input_buf_remove_char() {
|
||||
if (!input_buf.empty()) {
|
||||
input_buf.deleteLastChar();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void ConverseGump::Display(bool full_redraw) {
|
||||
uint16 total_length = 0;
|
||||
uint16 y = area.top + portrait_height + 8 + 3;
|
||||
|
||||
if (converse_bg_color != 255 || force_solid_bg) {
|
||||
if (solid_bg)
|
||||
screen->fill(converse_bg_color, area.left, area.top, area.width(), area.height());
|
||||
else
|
||||
screen->stipple_8bit(converse_bg_color, area.left, area.top, area.width(), area.height());
|
||||
}
|
||||
|
||||
bool use_transparency = (game_type == NUVIE_GAME_U6) ? false : true;
|
||||
|
||||
if (npc_portrait) {
|
||||
screen->blit(area.left + 4, area.top + 4, npc_portrait, 8, frame_w, frame_h, frame_w, use_transparency);
|
||||
}
|
||||
|
||||
if (!page_break && input_mode && avatar_portrait && is_talking()) {
|
||||
screen->blit(area.left + portrait_width / 2 + 4, y, avatar_portrait, 8, frame_w, frame_h, frame_w, use_transparency);
|
||||
sint16 i = 0;
|
||||
for (const MsgText &t : *keyword_list) {
|
||||
uint16 token_len = font->getStringWidth(t.s.c_str());
|
||||
// if(token_len + total_length >= (26 * 8))
|
||||
if (portrait_width / 2 + portrait_width + token_len + total_length + 8 >= min_w - 4) {
|
||||
total_length = 0;
|
||||
y += 10;
|
||||
}
|
||||
t.font->drawString(screen, t.s.c_str(), area.left + portrait_width / 2 + portrait_width + 8 + total_length, y + 4, 0, 0);
|
||||
if (cursor_position == i) {
|
||||
screen->fill(CURSOR_COLOR, area.left + portrait_width / 2 + portrait_width + 16 + total_length, y + 4 + 8, token_len - 8, 1);
|
||||
}
|
||||
total_length += token_len;
|
||||
//total_length += t.s.size();
|
||||
}
|
||||
y += 16;
|
||||
font->drawString(screen, " *", area.left + portrait_width / 2 + portrait_width + 8, y, 0, 0);
|
||||
font->drawString(screen, input_buf.c_str(), area.left + portrait_width / 2 + portrait_width + 8 + font->getStringWidth(" *"), y, 0, 0);
|
||||
drawCursor(area.left + portrait_width / 2 + portrait_width + 8 + font->getStringWidth(" *") + font->getStringWidth(input_buf.c_str()), y);
|
||||
if (cursor_position == keyword_list->size()) {
|
||||
screen->fill(CURSOR_COLOR, area.left + portrait_width / 2 + portrait_width + 16, y + 8, font->getStringWidth(input_buf.c_str()) + 8, 1);
|
||||
}
|
||||
}
|
||||
|
||||
y = area.top + 4;
|
||||
total_length = 0;
|
||||
for (const MsgLine *line : msg_buf) {
|
||||
for (const MsgText *token : line->text) {
|
||||
total_length += token->font->drawString(screen, token->s.c_str(), area.left + 4 + frame_w + 4 + total_length, y + 4, 0, 0); //FIX for hardcoded font height
|
||||
|
||||
//token->s.size();
|
||||
//token->font->drawChar(screen, ' ', area.left + portrait_width + 8 + total_length * 8, y, 0);
|
||||
//total_length += 1;
|
||||
|
||||
}
|
||||
y += 10;
|
||||
total_length = 0;
|
||||
}
|
||||
|
||||
//font->drawString(screen, conv_str.c_str(), area.left, area.top);
|
||||
screen->update(area.left, area.top, area.width(), area.height());
|
||||
}
|
||||
|
||||
|
||||
GUI_status ConverseGump::KeyDown(const Common::KeyState &keyState) {
|
||||
Common::KeyState key = keyState;
|
||||
char ascii = get_ascii_char_from_keysym(key);
|
||||
|
||||
if (page_break || !is_talking()) {
|
||||
page_break = false;
|
||||
just_finished_page_break = true;
|
||||
if (!input_mode)
|
||||
Game::get_game()->get_gui()->unlock_input();
|
||||
if (!is_holding_buffer_empty() || !input_mode || !is_talking()) {
|
||||
clear_scroll();
|
||||
process_holding_buffer(); // Process any text in the holding buffer.
|
||||
}
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
if (!input_mode || !Common::isPrint(ascii)) {
|
||||
KeyBinder *keybinder = Game::get_game()->get_keybinder();
|
||||
ActionType a = keybinder->get_ActionType(key);
|
||||
switch (keybinder->GetActionKeyType(a)) {
|
||||
case WEST_KEY:
|
||||
key.keycode = Common::KEYCODE_LEFT;
|
||||
break;
|
||||
case EAST_KEY:
|
||||
key.keycode = Common::KEYCODE_RIGHT;
|
||||
break;
|
||||
case SOUTH_KEY:
|
||||
key.keycode = Common::KEYCODE_DOWN;
|
||||
break;
|
||||
case NORTH_KEY:
|
||||
key.keycode = Common::KEYCODE_UP;
|
||||
break;
|
||||
case CANCEL_ACTION_KEY:
|
||||
key.keycode = Common::KEYCODE_ESCAPE;
|
||||
break;
|
||||
case DO_ACTION_KEY:
|
||||
key.keycode = Common::KEYCODE_RETURN;
|
||||
break;
|
||||
default:
|
||||
if (keybinder->handle_always_available_keys(a)) return GUI_YUM;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (key.keycode) {
|
||||
case Common::KEYCODE_LEFT:
|
||||
if (cursor_at_input_section() && input_char != 0)
|
||||
input_char = 0;
|
||||
else {
|
||||
if (!cursor_at_input_section() || !input_buf_remove_char()) {
|
||||
if (cursor_position == 0) {
|
||||
cursor_position = keyword_list->size();
|
||||
} else {
|
||||
cursor_position--;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Common::KEYCODE_RIGHT:
|
||||
if (cursor_at_input_section() && input_char != 0 && permit_input == nullptr)
|
||||
input_buf_add_char(get_char_from_input_char());
|
||||
else
|
||||
cursor_position = (cursor_position + 1) % (keyword_list->size() + 1);
|
||||
break;
|
||||
case Common::KEYCODE_DOWN:
|
||||
cursor_move_to_input();
|
||||
increase_input_char();
|
||||
break;
|
||||
case Common::KEYCODE_UP:
|
||||
cursor_move_to_input();
|
||||
decrease_input_char();
|
||||
break;
|
||||
case Common::KEYCODE_ESCAPE:
|
||||
if (permit_inputescape) {
|
||||
// reset input buffer
|
||||
permit_input = nullptr;
|
||||
if (input_mode)
|
||||
set_input_mode(false);
|
||||
}
|
||||
return GUI_YUM;
|
||||
case Common::KEYCODE_KP_ENTER:
|
||||
case Common::KEYCODE_RETURN:
|
||||
if (permit_inputescape || !cursor_at_input_section()
|
||||
|| input_char != 0) { // input_char should only be permit_input
|
||||
if (!cursor_at_input_section())
|
||||
input_add_string(get_token_at_cursor());
|
||||
else {
|
||||
if (input_char != 0)
|
||||
input_buf_add_char(get_char_from_input_char());
|
||||
}
|
||||
//if(input_mode)
|
||||
set_input_mode(false);
|
||||
clear_scroll();
|
||||
found_break_char = true; //strip leading whitespace.
|
||||
cursor_reset();
|
||||
}
|
||||
|
||||
return GUI_YUM;
|
||||
case Common::KEYCODE_BACKSPACE :
|
||||
if (input_mode)
|
||||
input_buf_remove_char();
|
||||
break;
|
||||
default: // alphanumeric characters
|
||||
if (input_mode && Common::isPrint(ascii)) {
|
||||
cursor_move_to_input();
|
||||
if (permit_input == nullptr) {
|
||||
if (!numbers_only || Common::isDigit(ascii))
|
||||
if (input_char != 0)
|
||||
input_buf_add_char(get_char_from_input_char());
|
||||
input_buf_add_char(ascii);
|
||||
} else if (strchr(permit_input, ascii) || strchr(permit_input, tolower(ascii))) {
|
||||
input_buf_add_char(toupper(ascii));
|
||||
set_input_mode(false);
|
||||
clear_scroll();
|
||||
found_break_char = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
GUI_status ConverseGump::MouseUp(int x, int y, Events::MouseButton button) {
|
||||
Std::string token_str;
|
||||
|
||||
if (page_break || !is_talking()) { // any click == scroll-to-end
|
||||
page_break = false;
|
||||
just_finished_page_break = true;
|
||||
if (!input_mode)
|
||||
Game::get_game()->get_gui()->unlock_input();
|
||||
|
||||
if (!is_holding_buffer_empty() || !input_mode || !is_talking()) {
|
||||
clear_scroll();
|
||||
process_holding_buffer(); // Process any text in the holding buffer.
|
||||
}
|
||||
return GUI_YUM;
|
||||
} else if (button == 1) { // left click == select word
|
||||
if (input_mode) {
|
||||
token_str = get_token_string_at_pos(x, y);
|
||||
if (!token_str.empty()) {
|
||||
input_add_string(token_str);
|
||||
set_input_mode(false);
|
||||
clear_scroll();
|
||||
found_break_char = true; //strip leading whitespace.
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
else if(button == 3) // right click == send input
|
||||
if(permit_inputescape && input_mode)
|
||||
{
|
||||
set_input_mode(false);
|
||||
return(GUI_YUM);
|
||||
}
|
||||
*/
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
void ConverseGump::input_add_string(Std::string token_str) {
|
||||
input_buf.clear();
|
||||
for (uint16 i = 0; i < token_str.size(); i++) {
|
||||
if (Common::isAlnum(token_str[i]) && (!permit_input || strchr(permit_input, token_str[i])
|
||||
|| strchr(permit_input, tolower(token_str[i]))))
|
||||
input_buf_add_char(token_str[i]);
|
||||
}
|
||||
}
|
||||
|
||||
bool ConverseGump::is_permanent_keyword(const Std::string &keyword) {
|
||||
return (string_i_compare(keyword, " *buy") || string_i_compare(keyword, " *sell")
|
||||
|| string_i_compare(keyword, " *bye") || string_i_compare(keyword, " *spells")
|
||||
|| string_i_compare(keyword, " *reagents"));
|
||||
}
|
||||
|
||||
void ConverseGump::drawCursor(uint16 x, uint16 y) {
|
||||
if (input_char != 0) {
|
||||
font->drawChar(screen, get_char_from_input_char(), x, y);
|
||||
} else {
|
||||
MsgScroll::drawCursor(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
156
engines/ultima/nuvie/gui/widgets/converse_gump.h
Normal file
156
engines/ultima/nuvie/gui/widgets/converse_gump.h
Normal file
@@ -0,0 +1,156 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NUVIE_CORE_CONVERSE_GUMP_H
|
||||
#define NUVIE_CORE_CONVERSE_GUMP_H
|
||||
|
||||
#include "ultima/nuvie/misc/call_back.h"
|
||||
#include "ultima/nuvie/gui/widgets/gui_widget.h"
|
||||
#include "ultima/shared/std/containers.h"
|
||||
#include "ultima/shared/std/string.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
using Std::list;
|
||||
|
||||
|
||||
class Configuration;
|
||||
class Font;
|
||||
class MsgScroll;
|
||||
class Actor;
|
||||
|
||||
class ConverseGump: public MsgScroll {
|
||||
Std::list<MsgText> conv_keywords;
|
||||
Std::list<MsgText> permitted_input_keywords;
|
||||
|
||||
Std::list<MsgText> *keyword_list;
|
||||
|
||||
unsigned char *npc_portrait;
|
||||
unsigned char *avatar_portrait;
|
||||
|
||||
bool found_break_char;
|
||||
bool solid_bg;
|
||||
bool force_solid_bg;
|
||||
uint8 converse_bg_color;
|
||||
|
||||
uint16 cursor_position;
|
||||
|
||||
uint8 portrait_width;
|
||||
uint8 portrait_height;
|
||||
uint8 frame_w;
|
||||
uint8 frame_h;
|
||||
uint16 min_w;
|
||||
|
||||
nuvie_game_t game_type;
|
||||
|
||||
public:
|
||||
|
||||
ConverseGump(const Configuration *cfg, Font *f, Screen *s);
|
||||
~ConverseGump() override;
|
||||
|
||||
void set_actor_portrait(Actor *a);
|
||||
unsigned char *create_framed_portrait(Actor *a);
|
||||
bool parse_token(MsgText *token) override;
|
||||
Std::string get_token_string_at_pos(uint16 x, uint16 y) override;
|
||||
void display_string(const Std::string &s, Font *f, bool include_on_map_window) override;
|
||||
void set_talking(bool state, Actor *actor = nullptr) override;
|
||||
void set_font(uint8 font_type) override {}
|
||||
//bool get_solid_bg() { return solid_bg; }
|
||||
void set_solid_bg(bool val) {
|
||||
solid_bg = val;
|
||||
}
|
||||
|
||||
void Display(bool full_redraw) override;
|
||||
|
||||
GUI_status KeyDown(const Common::KeyState &key) override;
|
||||
GUI_status MouseUp(int x, int y, Events::MouseButton button) override;
|
||||
|
||||
GUI_status MouseDown(int x, int y, Events::MouseButton button) override {
|
||||
return GUI_YUM;
|
||||
}
|
||||
GUI_status MouseMotion(int x, int y, uint8 state) override {
|
||||
return GUI_YUM;
|
||||
}
|
||||
GUI_status MouseEnter(uint8 state) override {
|
||||
return GUI_YUM;
|
||||
}
|
||||
GUI_status MouseLeave(uint8 state) override {
|
||||
return GUI_YUM;
|
||||
}
|
||||
GUI_status MouseClick(int x, int y, Events::MouseButton button) override {
|
||||
return GUI_YUM;
|
||||
}
|
||||
GUI_status MouseDouble(int x, int y, Events::MouseButton button) override {
|
||||
return GUI_YUM;
|
||||
}
|
||||
GUI_status MouseDelayed(int x, int y, Events::MouseButton button) override {
|
||||
return GUI_YUM;
|
||||
}
|
||||
GUI_status MouseHeld(int x, int y, Events::MouseButton button) override {
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
void set_found_break_char(bool val) {
|
||||
found_break_char = val;
|
||||
}
|
||||
|
||||
bool input_buf_add_char(char c) override;
|
||||
bool input_buf_remove_char() override;
|
||||
|
||||
bool is_converse_finished() override {
|
||||
return (is_holding_buffer_empty() && msg_buf.size() == 1 && msg_buf.back()->total_length == 0);
|
||||
}
|
||||
|
||||
void drawCursor(uint16 x, uint16 y) override;
|
||||
|
||||
protected:
|
||||
Std::string strip_whitespace_after_break(Std::string s);
|
||||
void add_keyword(Std::string keyword);
|
||||
|
||||
void set_permitted_input(const char *allowed) override;
|
||||
void clear_permitted_input() override;
|
||||
|
||||
bool cursor_at_input_section() const {
|
||||
return (keyword_list && cursor_position == keyword_list->size());
|
||||
}
|
||||
void cursor_reset() {
|
||||
cursor_position = 0;
|
||||
}
|
||||
void cursor_move_to_input() {
|
||||
cursor_position = keyword_list ? keyword_list->size() : 0;
|
||||
}
|
||||
|
||||
void input_add_string(Std::string token_str);
|
||||
|
||||
Std::string get_token_at_cursor();
|
||||
|
||||
bool is_permanent_keyword(const Std::string &keyword);
|
||||
void parse_fm_towns_token(MsgText *token);
|
||||
|
||||
private:
|
||||
unsigned char *get_portrait_data(Actor *a);
|
||||
};
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
187
engines/ultima/nuvie/gui/widgets/converse_gump_wou.cpp
Normal file
187
engines/ultima/nuvie/gui/widgets/converse_gump_wou.cpp
Normal file
@@ -0,0 +1,187 @@
|
||||
/* 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/conf/configuration.h"
|
||||
#include "ultima/nuvie/misc/u6_misc.h"
|
||||
#include "ultima/nuvie/fonts/font_manager.h"
|
||||
#include "ultima/nuvie/fonts/font.h"
|
||||
#include "ultima/nuvie/screen/game_palette.h"
|
||||
#include "ultima/nuvie/gui/gui.h"
|
||||
#include "ultima/nuvie/misc/sdl_compat.h"
|
||||
#include "ultima/nuvie/gui/widgets/msg_scroll.h"
|
||||
#include "ultima/nuvie/portraits/portrait.h"
|
||||
#include "ultima/nuvie/core/player.h"
|
||||
#include "ultima/nuvie/gui/widgets/converse_gump_wou.h"
|
||||
#include "ultima/nuvie/actors/actor_manager.h"
|
||||
#include "ultima/nuvie/keybinding/keys.h"
|
||||
#include "ultima/nuvie/gui/widgets/map_window.h"
|
||||
#include "ultima/nuvie/gui/widgets/background.h"
|
||||
#include "ultima/nuvie/files/u6_shape.h"
|
||||
#include "ultima/nuvie/files/nuvie_bmp_file.h"
|
||||
#include "ultima/nuvie/views/view_manager.h"
|
||||
#include "ultima/nuvie/views/md_sky_strip_widget.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
#define INPUT_FONT_COLOR 1
|
||||
|
||||
// ConverseGumpWOU Class
|
||||
|
||||
ConverseGumpWOU::ConverseGumpWOU(const Configuration *cfg, Font *f, Screen *s)
|
||||
: found_break_char(false), frame_h(0), frame_w(0), min_w(0) {
|
||||
// uint16 x, y;
|
||||
|
||||
init(cfg, f);
|
||||
Game *game = Game::get_game();
|
||||
game_type = game->get_game_type();
|
||||
|
||||
//scroll_width = 20;
|
||||
//scroll_height = 18;
|
||||
|
||||
set_scroll_dimensions(18, 18);
|
||||
|
||||
Std::string height_str;
|
||||
uint16 x_off = game->get_game_x_offset();
|
||||
uint16 y_off = game->get_game_y_offset();
|
||||
|
||||
if (game_type == NUVIE_GAME_U6) {
|
||||
GUI_Widget::Init(nullptr, x_off + 8, y_off + 8, 160, 160);
|
||||
bg_color = converse_bg_color = 0x31; //17;
|
||||
if (game->get_game_width() >= 335) {
|
||||
Common::Path imagefile;
|
||||
Common::Path datadir = GUI::get_gui()->get_data_dir();
|
||||
build_path(datadir, "U6_WOU_Scroll_bg.bmp", imagefile);
|
||||
NuvieBmpFile bmp;
|
||||
bg_image = bmp.getSdlSurface32(imagefile);
|
||||
} else
|
||||
bg_image = nullptr;
|
||||
} else { //MD and SE
|
||||
bg_image = nullptr;
|
||||
GUI_Widget::Init(nullptr, x_off + 8, y_off + 16, 160, 144);
|
||||
bg_color = converse_bg_color = Game::get_game()->get_palette()->get_bg_color();
|
||||
}
|
||||
|
||||
left_margin = 8;
|
||||
add_new_line();
|
||||
//DEBUG(0, LEVEL_DEBUGGING, "\nMin w = %d\n", frame_w + 12 + 210);
|
||||
}
|
||||
|
||||
ConverseGumpWOU::~ConverseGumpWOU() {
|
||||
if (bg_image)
|
||||
delete bg_image;
|
||||
}
|
||||
|
||||
void ConverseGumpWOU::set_talking(bool state, Actor *actor) {
|
||||
if (state) {
|
||||
found_break_char = true;
|
||||
clear_scroll();
|
||||
Show();
|
||||
if (Game::get_game()->get_view_manager()->get_mdSkyWidget() && Game::get_game()->is_original_plus())
|
||||
Game::get_game()->get_view_manager()->get_mdSkyWidget()->Show();
|
||||
} else {
|
||||
if (talking) {
|
||||
MsgScroll::display_string("\nPress any key...*", MSGSCROLL_NO_MAP_DISPLAY);
|
||||
} else {
|
||||
if (Game::get_game()->get_view_manager()->get_mdSkyWidget() && Game::get_game()->is_original_plus())
|
||||
Game::get_game()->get_view_manager()->get_mdSkyWidget()->Hide();
|
||||
}
|
||||
}
|
||||
MsgScroll::set_talking(state);
|
||||
}
|
||||
|
||||
void ConverseGumpWOU::process_page_break() {
|
||||
page_break = false;
|
||||
just_finished_page_break = true;
|
||||
if (!input_mode)
|
||||
Game::get_game()->get_gui()->unlock_input();
|
||||
if (!input_mode) {
|
||||
//clear_scroll();
|
||||
|
||||
process_holding_buffer(); // Process any text in the holding buffer.
|
||||
}
|
||||
}
|
||||
|
||||
void ConverseGumpWOU::display_converse_prompt() {
|
||||
MsgScroll::display_string("\nyou say:", INPUT_FONT_COLOR, MSGSCROLL_NO_MAP_DISPLAY);
|
||||
}
|
||||
|
||||
void ConverseGumpWOU::display_bg() {
|
||||
Game *game = Game::get_game();
|
||||
U6Shape *background = game->get_background()->get_bg_shape();
|
||||
unsigned char *ptr = background->get_data();
|
||||
uint16 bg_w = game->get_background()->get_bg_w();
|
||||
uint16 x_off = game->get_game_x_offset();
|
||||
uint16 y_off = game->get_game_y_offset();
|
||||
uint16 game_w = game->get_game_width();
|
||||
|
||||
if (game_type == NUVIE_GAME_U6) {
|
||||
if (game_w >= 335) { // get right size
|
||||
Common::Rect dst;
|
||||
dst.left = x_off;
|
||||
dst.top = y_off;
|
||||
dst.setWidth(176);
|
||||
dst.setHeight(176);
|
||||
SDL_BlitSurface(bg_image, nullptr, game->get_screen()->get_sdl_surface(), &dst);
|
||||
screen->update(x_off, y_off, 176, 176);
|
||||
} else {
|
||||
screen->blit(x_off, y_off, ptr, 8, 171, 200, bg_w, true); // main bg
|
||||
if (game_w > 323) { // add filler to the right
|
||||
ptr += 5;
|
||||
screen->blit(x_off + 171, y_off, ptr, 8, game_w - 323, 200, bg_w, true);
|
||||
screen->fill(game->get_palette()->get_bg_color(), x_off + 171, y_off + 8, game_w - 323, 184); // ovewrite center
|
||||
screen->update(x_off, y_off, 171 + game_w - 323, 200);
|
||||
} else
|
||||
screen->update(x_off, y_off, 171, 200);
|
||||
}
|
||||
} else if (game_type == NUVIE_GAME_SE) {
|
||||
ptr += bg_w + 1;
|
||||
screen->fill(0, x_off + 172, y_off, 4, 1); // upper right corner
|
||||
screen->blit(x_off + 1, y_off + 1, ptr, 8, 176, 173, bg_w, true); // main bg
|
||||
// FIXME: will need to add time strip to top once it is coded
|
||||
screen->update(x_off + 1, y_off, 177, 174);
|
||||
} else { // MD
|
||||
screen->fill(0, x_off, y_off, 176, 164); // background has transparent parts that should be black - also adding border to bottom
|
||||
if (game_w == 321)
|
||||
screen->fill(4, x_off + 176, y_off, 1, 1); // overwrite black pixel on top that looks bad
|
||||
else if (game_w > 321) // add right border
|
||||
screen->fill(0, x_off + 176, y_off, 1, 164);
|
||||
screen->blit(x_off, y_off, ptr, 8, 176, 163, bg_w, true); // main bg
|
||||
if (game->get_view_manager()->get_mdSkyWidget())
|
||||
game->get_view_manager()->get_mdSkyWidget()->Display(true);
|
||||
screen->update(x_off, y_off, 177, 164);
|
||||
}
|
||||
}
|
||||
|
||||
void ConverseGumpWOU::Display(bool full_redraw) {
|
||||
if (Game::get_game()->is_original_plus())
|
||||
display_bg(); // do first so that the text will be displayed on top
|
||||
MsgScroll::Display(true);
|
||||
if (game_type == NUVIE_GAME_U6) {
|
||||
Game::get_game()->get_map_window()->drawBorder();
|
||||
screen->update(area.left, area.top, area.width(), area.height());
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
112
engines/ultima/nuvie/gui/widgets/converse_gump_wou.h
Normal file
112
engines/ultima/nuvie/gui/widgets/converse_gump_wou.h
Normal file
@@ -0,0 +1,112 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NUVIE_CORE_CONVERSE_GUMP_WOU_H
|
||||
#define NUVIE_CORE_CONVERSE_GUMP_WOU_H
|
||||
|
||||
#include "ultima/nuvie/misc/call_back.h"
|
||||
#include "ultima/nuvie/gui/widgets/gui_widget.h"
|
||||
#include "ultima/nuvie/fonts/font.h"
|
||||
#include "ultima/shared/std/containers.h"
|
||||
#include "ultima/shared/std/string.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
using Std::list;
|
||||
|
||||
class Configuration;
|
||||
class Font;
|
||||
class MsgScroll;
|
||||
class Actor;
|
||||
|
||||
class ConverseGumpWOU: public MsgScroll {
|
||||
|
||||
uint8 converse_bg_color;
|
||||
|
||||
uint8 frame_w;
|
||||
uint8 frame_h;
|
||||
uint16 min_w;
|
||||
|
||||
nuvie_game_t game_type;
|
||||
bool found_break_char;
|
||||
public:
|
||||
|
||||
ConverseGumpWOU(const Configuration *cfg, Font *f, Screen *s);
|
||||
~ConverseGumpWOU() override;
|
||||
|
||||
void set_talking(bool state, Actor *actor = nullptr) override;
|
||||
void set_font(uint8 font_type) override {}
|
||||
void display_converse_prompt() override;
|
||||
|
||||
void Display(bool full_redraw) override;
|
||||
|
||||
GUI_status MouseUp(int x, int y, Events::MouseButton button) override {
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
GUI_status MouseDown(int x, int y, Events::MouseButton button) override {
|
||||
return GUI_YUM;
|
||||
}
|
||||
GUI_status MouseMotion(int x, int y, uint8 state) override {
|
||||
return GUI_YUM;
|
||||
}
|
||||
GUI_status MouseEnter(uint8 state) override {
|
||||
return GUI_YUM;
|
||||
}
|
||||
GUI_status MouseLeave(uint8 state) override {
|
||||
return GUI_YUM;
|
||||
}
|
||||
GUI_status MouseClick(int x, int y, Events::MouseButton button) override {
|
||||
return GUI_YUM;
|
||||
}
|
||||
GUI_status MouseDouble(int x, int y, Events::MouseButton button) override {
|
||||
return GUI_YUM;
|
||||
}
|
||||
GUI_status MouseDelayed(int x, int y, Events::MouseButton button) override {
|
||||
return GUI_YUM;
|
||||
}
|
||||
GUI_status MouseHeld(int x, int y, Events::MouseButton button) override {
|
||||
return GUI_YUM;
|
||||
}
|
||||
|
||||
bool is_converse_finished() override {
|
||||
return (is_holding_buffer_empty() && !page_break);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
void input_add_string(Std::string token_str);
|
||||
void process_page_break() override;
|
||||
uint8 get_input_font_color() const override {
|
||||
return FONT_COLOR_WOU_CONVERSE_INPUT;
|
||||
}
|
||||
void display_bg();
|
||||
|
||||
private:
|
||||
|
||||
Graphics::ManagedSurface *bg_image;
|
||||
};
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
69
engines/ultima/nuvie/gui/widgets/fps_counter.cpp
Normal file
69
engines/ultima/nuvie/gui/widgets/fps_counter.cpp
Normal file
@@ -0,0 +1,69 @@
|
||||
/* 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/nuvie/conf/configuration.h"
|
||||
#include "ultima/nuvie/core/nuvie_defs.h"
|
||||
#include "ultima/nuvie/misc/u6_misc.h"
|
||||
#include "ultima/nuvie/core/game.h"
|
||||
#include "ultima/nuvie/screen/screen.h"
|
||||
#include "ultima/nuvie/fonts/font_manager.h"
|
||||
#include "ultima/nuvie/fonts/font.h"
|
||||
#include "ultima/nuvie/gui/widgets/fps_counter.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
using Std::string;
|
||||
|
||||
FpsCounter::FpsCounter(Game *g) : GUI_Widget(nullptr) {
|
||||
game = g;
|
||||
font = game->get_font_manager()->get_conv_font();
|
||||
|
||||
uint16 x_off = game->get_game_x_offset();
|
||||
uint16 y_off = game->get_game_y_offset();
|
||||
|
||||
Init(nullptr, x_off + 280, y_off, 40, 10);
|
||||
|
||||
Common::strcpy_s(fps_string, "000.00");
|
||||
}
|
||||
|
||||
FpsCounter::~FpsCounter() {
|
||||
}
|
||||
|
||||
void FpsCounter::setFps(float fps) {
|
||||
snprintf(fps_string, sizeof(fps_string), "%3.02f", fps);
|
||||
}
|
||||
|
||||
void FpsCounter::Display(bool full_redraw) {
|
||||
Screen *scr = game->get_screen();
|
||||
|
||||
// if(full_redraw || update_display || game->is_new_style())
|
||||
{
|
||||
// update_display = false;
|
||||
scr->fill(0, area.left, area.top, area.width(), area.height());
|
||||
font->drawString(scr, fps_string, area.left, area.top);
|
||||
|
||||
scr->update(area.left, area.top, area.width(), area.height());
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
57
engines/ultima/nuvie/gui/widgets/fps_counter.h
Normal file
57
engines/ultima/nuvie/gui/widgets/fps_counter.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NUVIE_CORE_FPS_COUNTER_H
|
||||
#define NUVIE_CORE_FPS_COUNTER_H
|
||||
|
||||
#include "ultima/nuvie/gui/widgets/gui_widget.h"
|
||||
#include "ultima/nuvie/fonts/font.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
class Game;
|
||||
|
||||
class FpsCounter: public GUI_Widget {
|
||||
protected:
|
||||
|
||||
Game *game;
|
||||
Font *font;
|
||||
|
||||
char fps_string[7]; // "000.00\0"
|
||||
|
||||
public:
|
||||
FpsCounter(Game *g);
|
||||
~FpsCounter() override;
|
||||
|
||||
void setFps(float fps);
|
||||
|
||||
void Display(bool full_redraw) override;
|
||||
|
||||
void update() {
|
||||
update_display = true;
|
||||
}
|
||||
};
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
578
engines/ultima/nuvie/gui/widgets/gui_widget.cpp
Normal file
578
engines/ultima/nuvie/gui/widgets/gui_widget.cpp
Normal file
@@ -0,0 +1,578 @@
|
||||
/* 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/nuvie/core/nuvie_defs.h"
|
||||
#include "ultima/nuvie/gui/gui.h"
|
||||
#include "ultima/nuvie/gui/widgets/gui_widget.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
/* Widget constructors */
|
||||
GUI_Widget::GUI_Widget(void *data) {
|
||||
Init(data, 0, 0, 0, 0);
|
||||
}
|
||||
GUI_Widget::GUI_Widget(void *data, int x, int y, int w, int h) {
|
||||
Init(data, x, y, w, h);
|
||||
}
|
||||
|
||||
GUI_Widget::~GUI_Widget() {
|
||||
for (; !children.empty();) {
|
||||
GUI_Widget *child = children.front();
|
||||
|
||||
children.pop_front();
|
||||
delete child;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void GUI_Widget::Init(void *data, int x, int y, int w, int h) {
|
||||
focused = false;
|
||||
gui_drag_manager = nullptr; //set from placeOnScreen method
|
||||
widget_data = data;
|
||||
screen = nullptr;
|
||||
surface = nullptr;
|
||||
SetRect(0, 0, w, h);
|
||||
offset_x = x;
|
||||
offset_y = y;
|
||||
Show();
|
||||
errorptr = nullptr;
|
||||
for (int n = 0; n < 3; ++n) {
|
||||
pressed[n] = 0;
|
||||
}
|
||||
parent = nullptr;
|
||||
|
||||
update_display = true;
|
||||
set_accept_mouseclick(false); // initializes mouseclick time; SB-X
|
||||
delayed_button = Events::BUTTON_NONE; // optional mouseclick-delay; SB-X
|
||||
held_button = Events::BUTTON_NONE; // optional mousedown-delay; SB-X
|
||||
mouse_moved = false;
|
||||
|
||||
int mx = 0, my = 0;
|
||||
if (screen)
|
||||
screen->get_mouse_location(&mx, &my);
|
||||
mouse_over = HitRect(mx, my);
|
||||
}
|
||||
|
||||
int GUI_Widget::AddWidget(GUI_Widget *widget) {
|
||||
children.push_back(widget);
|
||||
widget->setParent(this);
|
||||
|
||||
return 0; //success.
|
||||
}
|
||||
|
||||
|
||||
/* Mark the widget as visible -- this is the default state */
|
||||
void GUI_Widget::Show(void) {
|
||||
status = WIDGET_VISIBLE;
|
||||
}
|
||||
|
||||
/* Mark the widget as hidden; no display, no events */
|
||||
void GUI_Widget::Hide(void) {
|
||||
if (has_focus()) {
|
||||
release_focus();
|
||||
}
|
||||
status = WIDGET_HIDDEN;
|
||||
}
|
||||
|
||||
/* Mark the widget as free, so it will be deleted by the GUI */
|
||||
void GUI_Widget::Delete(void) {
|
||||
status = WIDGET_DELETED;
|
||||
}
|
||||
|
||||
void GUI_Widget::MoveRelative(int dx, int dy) {
|
||||
area.translate(dx, dy);
|
||||
|
||||
for (GUI_Widget *child : children)
|
||||
child->MoveRelative(dx, dy);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void GUI_Widget::Move(int32 new_x, int32 new_y) {
|
||||
area.moveTo(new_x + offset_x, new_y + offset_y);
|
||||
|
||||
for (GUI_Widget *child : children)
|
||||
child->Move(area.left, area.top);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void GUI_Widget::MoveRelativeToParent(int dx, int dy) {
|
||||
area.left = (area.left - offset_x) + dx;
|
||||
area.top = (area.top - offset_y) + dy;
|
||||
|
||||
offset_x = dx;
|
||||
offset_y = dy;
|
||||
|
||||
for (GUI_Widget *child : children)
|
||||
child->Move(area.left, area.top);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void GUI_Widget::grab_focus() {
|
||||
if (GUI::get_gui()->set_focus(this))
|
||||
focused = true;
|
||||
}
|
||||
|
||||
void GUI_Widget::release_focus() {
|
||||
GUI::get_gui()->clear_focus();
|
||||
focused = false;
|
||||
}
|
||||
|
||||
void GUI_Widget::moveToFront() {
|
||||
GUI *gui = GUI::get_gui();
|
||||
if (gui) {
|
||||
gui->removeWidget(this);
|
||||
gui->AddWidget(this);
|
||||
}
|
||||
}
|
||||
|
||||
void GUI_Widget::PlaceOnScreen(Screen *s, GUI_DragManager *dm, int x, int y) {
|
||||
if (screen != nullptr)
|
||||
return;
|
||||
|
||||
area.moveTo(x + offset_x, y + offset_y);
|
||||
|
||||
gui_drag_manager = dm;
|
||||
|
||||
SetDisplay(s);
|
||||
|
||||
/* place our children relative to ourself */
|
||||
for (GUI_Widget *child : children)
|
||||
child->PlaceOnScreen(screen, dm, area.left, area.top);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Report status to GUI */
|
||||
WIDGET_status GUI_Widget::Status(void) const {
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Set the bounds of the widget.
|
||||
If 'w' or 'h' is -1, that parameter will not be changed.
|
||||
*/
|
||||
void GUI_Widget::SetRect(int x, int y, int w, int h) {
|
||||
area = Common::Rect(x, y, x + w, y + h);
|
||||
}
|
||||
|
||||
void GUI_Widget::SetRect(Common::Rect **bounds) {
|
||||
int minx, maxx;
|
||||
int miny, maxy;
|
||||
int i, v;
|
||||
|
||||
maxx = 0;
|
||||
maxy = 0;
|
||||
for (i = 0; bounds[i]; ++i) {
|
||||
v = (bounds[i]->right - 1);
|
||||
if (maxx < v) {
|
||||
maxx = v;
|
||||
}
|
||||
v = (bounds[i]->bottom - 1);
|
||||
if (maxy < v) {
|
||||
maxy = v;
|
||||
}
|
||||
}
|
||||
minx = maxx;
|
||||
miny = maxy;
|
||||
for (i = 0; bounds[i]; ++i) {
|
||||
v = bounds[i]->left;
|
||||
if (minx > v) {
|
||||
minx = v;
|
||||
}
|
||||
v = bounds[i]->top;
|
||||
if (miny > v) {
|
||||
miny = v;
|
||||
}
|
||||
}
|
||||
SetRect(minx, miny, (maxx - minx + 1), (maxy - miny + 1));
|
||||
}
|
||||
|
||||
/* Check to see if a point intersects the bounds of the widget.
|
||||
*/
|
||||
int GUI_Widget::HitRect(int x, int y) {
|
||||
return HitRect(x, y, area);
|
||||
}
|
||||
|
||||
int GUI_Widget::HitRect(int x, int y, const Common::Rect &rect) {
|
||||
int hit;
|
||||
|
||||
hit = 1;
|
||||
if ((x < rect.left) || (x >= rect.right) ||
|
||||
(y < rect.top) || (y >= rect.bottom)) {
|
||||
hit = 0;
|
||||
}
|
||||
return hit;
|
||||
}
|
||||
|
||||
/* Set the display surface for this widget */
|
||||
void GUI_Widget::SetDisplay(Screen *s) {
|
||||
screen = s;
|
||||
surface = screen->get_sdl_surface();
|
||||
}
|
||||
|
||||
void GUI_Widget::setParent(GUI_Widget *widget) {
|
||||
parent = widget;
|
||||
}
|
||||
|
||||
/* Show the widget.
|
||||
If the surface needs to be locked, it will be locked
|
||||
before this call, and unlocked after it returns.
|
||||
|
||||
****************NO, NOT AT ALL IF I'M NOT TOO DUMB TO LOOK******
|
||||
******OTHERWISE YOU COULDN'T FILLRECT in Display(), ETC!!!! ***********
|
||||
*/
|
||||
void GUI_Widget::Display(bool full_redraw) {
|
||||
DisplayChildren(full_redraw);
|
||||
}
|
||||
|
||||
void GUI_Widget::DisplayChildren(bool full_redraw) {
|
||||
if (update_display)
|
||||
full_redraw = true;
|
||||
|
||||
if (children.empty() == false) {
|
||||
/* display our children */
|
||||
for (GUI_Widget *child : children) {
|
||||
if (child->Status() == WIDGET_VISIBLE)
|
||||
child->Display(full_redraw);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Redraw the widget and only the widget */
|
||||
void GUI_Widget::Redraw(void) {
|
||||
|
||||
if (status == WIDGET_VISIBLE) {
|
||||
update_display = true;
|
||||
if (parent != nullptr)
|
||||
parent->Redraw();
|
||||
//Display();
|
||||
//SDL_UpdateRects(screen,1,&area);
|
||||
}
|
||||
}
|
||||
|
||||
/* GUI idle function -- run when no events pending */
|
||||
// Idle and HandleEvent produce delayed clicks. Don't override if using those. -- SB-X
|
||||
GUI_status GUI_Widget::Idle(void) {
|
||||
if (children.empty() == false) {
|
||||
/* idle our children */
|
||||
for (GUI_Widget *child : children) {
|
||||
GUI_status idleStatus = child->Idle();
|
||||
if (idleStatus != GUI_PASS)
|
||||
return idleStatus;
|
||||
}
|
||||
}
|
||||
if (delayed_button != 0 || held_button != 0)
|
||||
return try_mouse_delayed();
|
||||
return GUI_PASS;
|
||||
}
|
||||
|
||||
/* Widget event handlers.
|
||||
These functions should return a status telling the GUI whether
|
||||
or not the event should be passed on to other widgets.
|
||||
These are called by the default HandleEvent function.
|
||||
*/
|
||||
GUI_status GUI_Widget::KeyDown(const Common::KeyState &key) {
|
||||
return GUI_PASS;
|
||||
}
|
||||
|
||||
GUI_status GUI_Widget::KeyUp(Common::KeyState key) {
|
||||
return GUI_PASS;
|
||||
}
|
||||
|
||||
GUI_status GUI_Widget::MouseDown(int x, int y, Events::MouseButton button) {
|
||||
return GUI_PASS;
|
||||
}
|
||||
|
||||
GUI_status GUI_Widget::MouseUp(int x, int y, Events::MouseButton button) {
|
||||
return GUI_PASS;
|
||||
}
|
||||
|
||||
|
||||
GUI_status GUI_Widget::MouseMotion(int x, int y, uint8 state) {
|
||||
return GUI_PASS;
|
||||
}
|
||||
|
||||
GUI_status GUI_Widget::MouseWheel(sint32 x, sint32 y) {
|
||||
return GUI_PASS;
|
||||
}
|
||||
|
||||
/* Main event handler function.
|
||||
This function gets raw SDL events from the GUI.
|
||||
*/
|
||||
// Idle and HandleEvent produce delayed clicks. Don't override if using those. -- SB-X
|
||||
GUI_status GUI_Widget::HandleEvent(const Common::Event *event) {
|
||||
if (status == WIDGET_HIDDEN) //we don't care for events if we are hidden.
|
||||
return GUI_PASS;
|
||||
|
||||
if (children.empty() == false) {
|
||||
/* handle our children */
|
||||
for (GUI_Widget *child : children) {
|
||||
GUI_status status_ = child->HandleEvent(event);
|
||||
if (status_ != GUI_PASS)
|
||||
return status_;
|
||||
}
|
||||
}
|
||||
|
||||
if (delayed_button != 0 || held_button != 0) {
|
||||
GUI_status status_ = try_mouse_delayed();
|
||||
if (status_ != GUI_PASS)
|
||||
return status_;
|
||||
}
|
||||
|
||||
switch (event->type) {
|
||||
case Common::EVENT_KEYDOWN:
|
||||
return KeyDown(event->kbd.keycode);
|
||||
break;
|
||||
case Common::EVENT_KEYUP:
|
||||
return KeyUp(event->kbd.keycode);
|
||||
break;
|
||||
case Common::EVENT_LBUTTONDOWN:
|
||||
case Common::EVENT_RBUTTONDOWN:
|
||||
case Common::EVENT_MBUTTONDOWN: {
|
||||
int x, y;
|
||||
Events::MouseButton button;
|
||||
x = event->mouse.x;
|
||||
y = event->mouse.y;
|
||||
button = Events::whichButton(event->type);
|
||||
if (focused || HitRect(x, y)) {
|
||||
set_mousedown(SDL_GetTicks(), button);
|
||||
return(MouseDown(x, y, button));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Common::EVENT_LBUTTONUP:
|
||||
case Common::EVENT_RBUTTONUP:
|
||||
case Common::EVENT_MBUTTONUP: {
|
||||
int x, y;
|
||||
Events::MouseButton button;
|
||||
x = event->mouse.x;
|
||||
y = event->mouse.y;
|
||||
button = Events::whichButton(event->type);
|
||||
if (focused || HitRect(x, y)) {
|
||||
int rel_time = SDL_GetTicks();
|
||||
int last_rel_time = get_mouseup(button);
|
||||
bool do_mouseclick = get_mousedown(button);
|
||||
set_mouseup(rel_time, button);
|
||||
if (do_mouseclick && accept_mouseclick[button - 1] && (rel_time - last_rel_time < GUI::mouseclick_delay)) {
|
||||
// before a Double or Delayed click, mouseup_time is reset so another click isn't possible
|
||||
set_mouseup(0, button);
|
||||
return MouseDouble(x, y, button);
|
||||
} else if (do_mouseclick && accept_mouseclick[button - 1])
|
||||
return MouseClick(x, y, button);
|
||||
else
|
||||
return MouseUp(x, y, button);
|
||||
}
|
||||
/* if widget was clicked before we must let it deactivate itself*/
|
||||
else if (ClickState(1)) {
|
||||
set_mouseup(0, button);
|
||||
return MouseUp(-1, -1, button);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case Common::EVENT_MOUSEMOVE: {
|
||||
int x, y;
|
||||
uint8 state;
|
||||
x = event->mouse.x;
|
||||
y = event->mouse.y;
|
||||
state = Events::get()->getButtonState();
|
||||
if (state > 0) // mousemotion resets Click
|
||||
mouse_moved = true;
|
||||
if (focused || HitRect(x, y)) {
|
||||
if (!mouse_over) {
|
||||
mouse_over = true;
|
||||
MouseEnter(state);
|
||||
}
|
||||
return MouseMotion(x, y, state);
|
||||
} else {
|
||||
if (mouse_over) {
|
||||
mouse_over = false;
|
||||
MouseLeave(state);
|
||||
}
|
||||
/* if widget was clicked before we must let it react*/
|
||||
if (ClickState(1))
|
||||
return MouseMotion(-1, -1, state);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case Common::EVENT_WHEELUP:
|
||||
return MouseWheel(0, 1);
|
||||
|
||||
case Common::EVENT_WHEELDOWN:
|
||||
return MouseWheel(0, -1);
|
||||
|
||||
default: {
|
||||
/* Pass it along.. */;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return GUI_PASS;
|
||||
}
|
||||
|
||||
// iterate through children if present to hit the correct drag area.
|
||||
bool GUI_Widget::drag_accept_drop(int x, int y, int message, void *data) {
|
||||
if (children.empty() == false) {
|
||||
for (GUI_Widget *child : children) {
|
||||
if (child->HitRect(x, y)) {
|
||||
if (child->drag_accept_drop(x, y, message, data))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GUI::get_gui()->force_full_redraw();
|
||||
return false;
|
||||
}
|
||||
|
||||
void GUI_Widget::drag_perform_drop(int x, int y, int message, void *data) {
|
||||
if (children.empty() == false) {
|
||||
for (GUI_Widget *child : children) {
|
||||
if (child->HitRect(x, y)) {
|
||||
child->drag_perform_drop(x, y, message, data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Mouse button was pressed and released over the widget.
|
||||
*/
|
||||
GUI_status GUI_Widget::MouseClick(int x, int y, Events::MouseButton button) {
|
||||
return GUI_PASS;
|
||||
}
|
||||
|
||||
/* Mouse button was clicked twice over the widget, within a certain time period.
|
||||
*/
|
||||
GUI_status GUI_Widget::MouseDouble(int x, int y, Events::MouseButton button) {
|
||||
return GUI_PASS;
|
||||
}
|
||||
|
||||
/* Mouse cursor passed out of the widget area.
|
||||
*/
|
||||
GUI_status GUI_Widget::MouseEnter(uint8 state) {
|
||||
return GUI_PASS;
|
||||
}
|
||||
|
||||
/* Mouse cursor passed into the widget area.
|
||||
*/
|
||||
GUI_status GUI_Widget::MouseLeave(uint8 state) {
|
||||
return GUI_PASS;
|
||||
}
|
||||
|
||||
/* Returns false if any widget but this one is focused or locked.
|
||||
*/
|
||||
bool GUI_Widget::widget_has_focus() {
|
||||
GUI_Widget *focused_widget = GUI::get_gui()->get_focused_widget();
|
||||
GUI_Widget *locked_widget = GUI::get_gui()->get_locked_widget();
|
||||
|
||||
if (GUI::get_gui()->get_block_input())
|
||||
return false;
|
||||
if (locked_widget != nullptr && locked_widget != this)
|
||||
return false;
|
||||
if (focused_widget != nullptr && focused_widget != this)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// button 0 = all
|
||||
void GUI_Widget::set_accept_mouseclick(bool set, int button) {
|
||||
if (button <= 0)
|
||||
accept_mouseclick[0] = accept_mouseclick[1] = accept_mouseclick[2] = set;
|
||||
else if (button < 4)
|
||||
accept_mouseclick[button - 1] = set;
|
||||
set_mouseup(0, button);
|
||||
set_mousedown(0, button);
|
||||
}
|
||||
|
||||
// time 0 = reset; button 0 = all
|
||||
// mousedown is always cleared
|
||||
void GUI_Widget::set_mouseup(int set, int button) {
|
||||
mouse_moved = false;
|
||||
if (button <= 0) {
|
||||
mouseup[0] = mouseup[1] = mouseup[2] = set;
|
||||
mousedown[0] = mousedown[1] = mousedown[2] = 0;
|
||||
} else if (button < 4) {
|
||||
mouseup[button - 1] = set;
|
||||
mousedown[button - 1] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// time 0 = reset; button 0 = all
|
||||
// mouseup is not cleared because two mouseup times are compared for mouseclicks
|
||||
void GUI_Widget::set_mousedown(int set, int button) {
|
||||
if (button <= 0) {
|
||||
// mouseup[0]=mouseup[1]=mouseup[2] = 0;
|
||||
mousedown[0] = mousedown[1] = mousedown[2] = set;
|
||||
} else if (button < 4) {
|
||||
// mouseup[button-1] = 0;
|
||||
mousedown[button - 1] = set;
|
||||
}
|
||||
}
|
||||
|
||||
// check to see if time has passed for a MouseDelayed or MouseHeld
|
||||
GUI_status GUI_Widget::try_mouse_delayed() {
|
||||
int mousedown_time = get_mousedown(held_button);
|
||||
int mouseup_time = get_mouseup(delayed_button);
|
||||
int time_to_hold = SDL_GetTicks() - mousedown_time;
|
||||
int time_to_click = SDL_GetTicks() - mouseup_time;
|
||||
|
||||
if (mousedown_time != 0 && time_to_hold >= GUI::mouseclick_delay) {
|
||||
Events::MouseButton button = held_button;
|
||||
int x, y; // position isn't saved anywhere so we get it here
|
||||
screen->get_mouse_location(&x, &y); // hopefully it hasn't changed since MouseDown
|
||||
held_button = Events::BUTTON_NONE; // no need to clear mousedown time, MouseUp does that
|
||||
return (MouseHeld(x, y, button));
|
||||
}
|
||||
|
||||
if (mouseup_time != 0 && time_to_click >= GUI::mouseclick_delay) {
|
||||
Events::MouseButton button = delayed_button;
|
||||
int x, y; // position isn't saved anywhere so we get it here
|
||||
screen->get_mouse_location(&x, &y); // hopefully it hasn't changed since MouseClick/MouseUp
|
||||
delayed_button = Events::BUTTON_NONE;
|
||||
// before a Double or Delayed click, mouseup time is reset
|
||||
set_mouseup(0, button);
|
||||
return (MouseDelayed(x, y, button));
|
||||
}
|
||||
return GUI_PASS;
|
||||
}
|
||||
|
||||
// like a MouseClick but called only after waiting for MouseDouble, if
|
||||
// wait_for_mouseclick(button) was called
|
||||
GUI_status GUI_Widget::MouseDelayed(int x, int y, Events::MouseButton button) {
|
||||
return GUI_PASS;
|
||||
}
|
||||
|
||||
// like a MouseDown but called only after waiting for MouseUp, if
|
||||
// wait_for_mousedown(button) was called
|
||||
GUI_status GUI_Widget::MouseHeld(int x, int y, Events::MouseButton button) {
|
||||
return GUI_PASS;
|
||||
}
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
251
engines/ultima/nuvie/gui/widgets/gui_widget.h
Normal file
251
engines/ultima/nuvie/gui/widgets/gui_widget.h
Normal file
@@ -0,0 +1,251 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/* Base class for all widgets -- the GUI operates on this class */
|
||||
|
||||
#ifndef NUVIE_GUI_GUI_WIDGET_H
|
||||
#define NUVIE_GUI_GUI_WIDGET_H
|
||||
|
||||
#include "ultima/nuvie/gui/gui_status.h"
|
||||
#include "ultima/nuvie/gui/gui_drag_area.h"
|
||||
#include "ultima/nuvie/gui/gui_drag_manager.h"
|
||||
#include "ultima/nuvie/screen/screen.h"
|
||||
#include "ultima/nuvie/core/events.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
typedef GUI_status(*GUI_CallbackProc)(void *data);
|
||||
|
||||
class GUI_Widget : public GUI_DragArea {
|
||||
|
||||
protected:
|
||||
/* A generic pointer to user-specified data for the widget.
|
||||
*/
|
||||
void *widget_data;
|
||||
|
||||
Screen *screen;
|
||||
/* The display surface for the widget */
|
||||
Graphics::ManagedSurface *surface;
|
||||
|
||||
int offset_x, offset_y; /* original offsets to parent */
|
||||
|
||||
/* Flag -- whether or not the widget should be freed */
|
||||
WIDGET_status status;
|
||||
|
||||
/* should we redraw this widget */
|
||||
bool update_display;
|
||||
|
||||
/* the button states for theoretically 3 buttons */
|
||||
int pressed[3];
|
||||
|
||||
bool focused;
|
||||
|
||||
Std::list<GUI_Widget *>children;
|
||||
GUI_Widget *parent;
|
||||
|
||||
char *errorptr;
|
||||
char errbuf[BUFSIZ];
|
||||
|
||||
GUI_DragManager *gui_drag_manager;
|
||||
|
||||
// SB-X
|
||||
/* The time of the last mouse click (SDL_GetTicks()). */
|
||||
unsigned int mouseup[3]; /* for 3 buttons */
|
||||
unsigned int mousedown[3]; /* waiting for MouseUp */
|
||||
bool accept_mouseclick[3]; /* which buttons can be [double]clicked */
|
||||
Events::MouseButton delayed_button; /* a MouseClick can be delayed on one button; 0=none */
|
||||
Events::MouseButton held_button; /* a MouseDown can be delayed on one button; 0=none */
|
||||
bool mouse_moved; /* true if mouse moves while button is pressed */
|
||||
|
||||
bool mouse_over; // initialized here; toggled by GUI
|
||||
|
||||
public:
|
||||
/* The area covered by the widget */
|
||||
Common::Rect area;
|
||||
|
||||
GUI_Widget(void *data);
|
||||
GUI_Widget(void *data, int x, int y, int w, int h);
|
||||
~GUI_Widget() override;
|
||||
|
||||
int AddWidget(GUI_Widget *widget);
|
||||
|
||||
/* Mark the widget as visible -- this is the default state */
|
||||
virtual void Show(void);
|
||||
|
||||
/* Mark the widget as hidden; no display, no events */
|
||||
virtual void Hide(void);
|
||||
|
||||
/* Mark the widget as free, so it will be deleted by the GUI */
|
||||
virtual void Delete(void);
|
||||
|
||||
virtual void MoveRelative(int dx, int dy);
|
||||
virtual void Move(int32 new_x, int32 new_y);
|
||||
void MoveRelativeToParent(int dx, int dy);
|
||||
bool has_focus() const {
|
||||
return focused;
|
||||
}
|
||||
void grab_focus();
|
||||
virtual void release_focus();
|
||||
void moveToFront();
|
||||
virtual void PlaceOnScreen(Screen *s, GUI_DragManager *dm, int x, int y);
|
||||
|
||||
virtual WIDGET_status Status(void) const; /* Reports status to GUI */
|
||||
|
||||
/* Set the bounds of the widget.
|
||||
If 'w' or 'h' is -1, that parameter will not be changed.
|
||||
*/
|
||||
virtual void SetRect(int x, int y, int w, int h);
|
||||
virtual void SetRect(Common::Rect **bounds);
|
||||
|
||||
/* Return the whole area */
|
||||
virtual Common::Rect GetRect() {
|
||||
return area;
|
||||
}
|
||||
|
||||
/* Return the bounds of the widget */
|
||||
virtual int X() const {
|
||||
return area.left;
|
||||
}
|
||||
virtual int Y() const {
|
||||
return area.top;
|
||||
}
|
||||
virtual int W() const {
|
||||
return area.width();
|
||||
}
|
||||
virtual int H() const {
|
||||
return area.height();
|
||||
}
|
||||
|
||||
/* Check to see if a point intersects the bounds of the widget.
|
||||
*/
|
||||
virtual int HitRect(int x, int y);
|
||||
virtual int HitRect(int x, int y, const Common::Rect &rect);
|
||||
|
||||
/* Set the display surface for this widget */
|
||||
virtual void SetDisplay(Screen *s);
|
||||
|
||||
/* Show the widget.
|
||||
If the surface needs to be locked, it will be locked
|
||||
before this call, and unlocked after it returns.
|
||||
*/
|
||||
virtual void Display(bool full_redraw = false);
|
||||
void DisplayChildren(bool full_redraw = false);
|
||||
|
||||
/* Redraw the widget and only the widget */
|
||||
virtual void Redraw(void);
|
||||
|
||||
/* should this widget be redrawn */
|
||||
inline bool needs_redraw() const {
|
||||
return update_display;
|
||||
}
|
||||
/* widget has focus or no widget is focused */
|
||||
bool widget_has_focus(); // SB-X
|
||||
|
||||
/* GUI idle function -- run when no events pending */
|
||||
virtual GUI_status Idle(void);
|
||||
|
||||
/* Widget event handlers.
|
||||
These functions should return a status telling the GUI whether
|
||||
or not the event should be passed on to other widgets.
|
||||
These are called by the default HandleEvent function.
|
||||
*/
|
||||
virtual GUI_status KeyDown(const Common::KeyState &key);
|
||||
virtual GUI_status KeyUp(Common::KeyState key);
|
||||
virtual GUI_status MouseDown(int x, int y, Events::MouseButton button);
|
||||
virtual GUI_status MouseUp(int x, int y, Events::MouseButton button);
|
||||
virtual GUI_status MouseMotion(int x, int y, uint8 state);
|
||||
virtual GUI_status MouseWheel(sint32 x, sint32 y);
|
||||
// <SB-X>
|
||||
virtual GUI_status MouseEnter(uint8 state);
|
||||
virtual GUI_status MouseLeave(uint8 state);
|
||||
virtual GUI_status MouseClick(int x, int y, Events::MouseButton button);
|
||||
virtual GUI_status MouseDouble(int x, int y, Events::MouseButton button);
|
||||
virtual GUI_status MouseDelayed(int x, int y, Events::MouseButton button);
|
||||
virtual GUI_status MouseHeld(int x, int y, Events::MouseButton button);
|
||||
// </SB-X>
|
||||
|
||||
bool drag_accept_drop(int x, int y, int message, void *data) override;
|
||||
void drag_perform_drop(int x, int y, int message, void *data) override;
|
||||
|
||||
/* Main event handler function.
|
||||
This function gets raw SDL events from the GUI.
|
||||
*/
|
||||
virtual GUI_status HandleEvent(const Common::Event *event);
|
||||
|
||||
/* Returns nullptr if everything is okay, or an error message if not */
|
||||
char *Error(void) {
|
||||
return errorptr;
|
||||
}
|
||||
|
||||
/* yields click state: none, pressed, intermediate */
|
||||
inline virtual int ClickState(int button) {
|
||||
return pressed[button - 1];
|
||||
}
|
||||
|
||||
/* set click state from remote */
|
||||
inline virtual void SetClickState(int button, int value) {
|
||||
if ((button > 0) && (button <= 3)) pressed[button - 1] = value;
|
||||
}
|
||||
|
||||
protected:
|
||||
/* The constructor, separated out for both access constructors */
|
||||
void Init(void *data, int x, int y, int w, int h);
|
||||
|
||||
void setParent(GUI_Widget *widget);
|
||||
|
||||
/* Useful for getting error feedback */
|
||||
void SetError(char *fmt, ...) {
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
Common::vsprintf_s(errbuf, fmt, ap);
|
||||
va_end(ap);
|
||||
errorptr = errbuf;
|
||||
}
|
||||
|
||||
// SB-X
|
||||
void set_accept_mouseclick(bool set, int button = 0);
|
||||
void set_mouseup(int set, int button = 0);
|
||||
void set_mousedown(int set, int button = 0);
|
||||
int get_mouseup(int button) const {
|
||||
if (button > 0 && button < 4) return (mouseup[button - 1]);
|
||||
else return 0;
|
||||
}
|
||||
int get_mousedown(int button) const {
|
||||
if (button > 0 && button < 4) return (mousedown[button - 1]);
|
||||
else return 0;
|
||||
}
|
||||
void wait_for_mouseclick(int button) {
|
||||
if (button >= Events::BUTTON_NONE && button < Events::BUTTON_MIDDLE)
|
||||
delayed_button = (Events::MouseButton)button;
|
||||
}
|
||||
void wait_for_mousedown(int button) {
|
||||
if (button >= Events::BUTTON_NONE && button <= Events::BUTTON_MIDDLE)
|
||||
held_button = (Events::MouseButton)button;
|
||||
}
|
||||
virtual GUI_status try_mouse_delayed();
|
||||
};
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
2577
engines/ultima/nuvie/gui/widgets/map_window.cpp
Normal file
2577
engines/ultima/nuvie/gui/widgets/map_window.cpp
Normal file
File diff suppressed because it is too large
Load Diff
383
engines/ultima/nuvie/gui/widgets/map_window.h
Normal file
383
engines/ultima/nuvie/gui/widgets/map_window.h
Normal file
@@ -0,0 +1,383 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NUVIE_CORE_MAP_WINDOW_H
|
||||
#define NUVIE_CORE_MAP_WINDOW_H
|
||||
|
||||
#include "ultima/shared/std/containers.h"
|
||||
|
||||
|
||||
#include "ultima/nuvie/core/nuvie_defs.h"
|
||||
#include "ultima/nuvie/core/obj_manager.h"
|
||||
#include "ultima/nuvie/gui/widgets/gui_widget.h"
|
||||
#include "ultima/nuvie/core/map.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
class Configuration;
|
||||
class TileManager;
|
||||
class ActorManager;
|
||||
class Actor;
|
||||
class AnimManager;
|
||||
class Map;
|
||||
class MapCoord;
|
||||
class Screen;
|
||||
class CallBack;
|
||||
class Game;
|
||||
|
||||
#define MAPWINDOW_THUMBNAIL_SIZE 52
|
||||
#define MAPWINDOW_THUMBNAIL_SCALE 3
|
||||
|
||||
#define MAP_OVERLAY_DEFAULT 0 /* just below border */
|
||||
#define MAP_OVERLAY_ONTOP 1 /* cover border */
|
||||
|
||||
#define MAPWINDOW_ROOFTILES_IMG_W 5
|
||||
#define MAPWINDOW_ROOFTILES_IMG_H 204
|
||||
|
||||
typedef struct {
|
||||
Tile *t;
|
||||
uint16 x, y;
|
||||
} TileInfo;
|
||||
|
||||
typedef struct {
|
||||
Tile *eye_tile;
|
||||
uint16 prev_x, prev_y;
|
||||
uint16 moves_left;
|
||||
CallBack *caller;
|
||||
} WizardEye;
|
||||
|
||||
enum RoofDisplayType {ROOF_DISPLAY_OFF, ROOF_DISPLAY_NORMAL, ROOF_DISPLAY_FORCE_ON };
|
||||
enum InterfaceType { INTERFACE_NORMAL, INTERFACE_FULLSCREEN, INTERFACE_IGNORE_BLOCK };
|
||||
enum X_RayType { X_RAY_CHEAT_OFF = -1, X_RAY_OFF = 0, X_RAY_ON = 1, X_RAY_CHEAT_ON = 2};
|
||||
enum CanDropOrMoveMsg { MSG_NOT_POSSIBLE, MSG_SUCCESS, MSG_BLOCKED, MSG_OUT_OF_RANGE, MSG_NO_TILE};
|
||||
|
||||
class MapWindow: public GUI_Widget {
|
||||
friend class AnimManager;
|
||||
friend class ConverseGumpWOU;
|
||||
Game *game;
|
||||
const Configuration *config;
|
||||
int game_type;
|
||||
bool enable_doubleclick;
|
||||
bool walk_with_left_button;
|
||||
uint8 walk_button_mask;
|
||||
X_RayType x_ray_view;
|
||||
InterfaceType interface;
|
||||
|
||||
bool custom_actor_tiles;
|
||||
|
||||
Map *map;
|
||||
|
||||
uint16 *tmp_map_buf; // tempory buffer for flood fill, hide rooms.
|
||||
uint16 tmp_map_width, tmp_map_height;
|
||||
Graphics::ManagedSurface *overlay; // used for visual effects
|
||||
uint8 overlay_level; // where the overlay surface is placed
|
||||
int min_brightness;
|
||||
|
||||
TileManager *tile_manager;
|
||||
ObjManager *obj_manager;
|
||||
ActorManager *actor_manager;
|
||||
AnimManager *anim_manager;
|
||||
|
||||
sint16 cur_x, cur_y;
|
||||
uint16 cursor_x, cursor_y, map_center_xoff;
|
||||
sint16 mousecenter_x, mousecenter_y; // location mousecursor rotates around, relative to cur_x&cur_y
|
||||
uint16 last_boundary_fill_x, last_boundary_fill_y; // start of boundary-fill in previous blacking update
|
||||
Tile *cursor_tile;
|
||||
Tile *use_tile;
|
||||
|
||||
bool show_cursor;
|
||||
bool show_use_cursor;
|
||||
bool show_grid;
|
||||
|
||||
unsigned char *thumbnail;
|
||||
bool new_thumbnail;
|
||||
|
||||
uint16 win_width, win_height, border_width;
|
||||
uint8 cur_level;
|
||||
uint16 map_width;
|
||||
|
||||
uint8 cur_x_add, cur_y_add; // pixel offset from cur_x,cur_y (set by shiftMapRelative)
|
||||
sint32 vel_x, vel_y; // velocity of automatic map movement (pixels per second)
|
||||
|
||||
Common::Rect clip_rect;
|
||||
Graphics::ManagedSurface _mapWinSubSurf; // sub surface of the screen clipped to MapWindow's clip_rect
|
||||
|
||||
Obj *selected_obj;
|
||||
Actor *look_actor;
|
||||
Obj *look_obj;
|
||||
bool hackmove;
|
||||
bool walking;
|
||||
bool look_on_left_click;
|
||||
bool looking; // used to stop look_on_left_click from triggering during mouseup from left button walking, failed drag, or input mode
|
||||
|
||||
bool window_updated;
|
||||
bool freeze_blacking_location;
|
||||
bool enable_blacking;
|
||||
|
||||
bool roof_mode;
|
||||
RoofDisplayType roof_display;
|
||||
|
||||
Graphics::ManagedSurface *roof_tiles;
|
||||
|
||||
WizardEye wizard_eye_info;
|
||||
|
||||
bool draw_brit_lens_anim;
|
||||
bool draw_garg_lens_anim;
|
||||
// Std::vector<TileInfo> m_ViewableObjTiles; // shouldn't need this for in_town checks
|
||||
Std::vector<TileInfo> m_ViewableMapTiles;
|
||||
|
||||
bool lighting_update_required;
|
||||
|
||||
bool game_started;
|
||||
|
||||
public:
|
||||
|
||||
MapWindow(const Configuration *cfg, Map *m);
|
||||
~MapWindow() override;
|
||||
|
||||
bool init(TileManager *tm, ObjManager *om, ActorManager *am);
|
||||
|
||||
sint16 get_cur_x() const {
|
||||
return cur_x;
|
||||
}
|
||||
sint16 get_cur_y() const {
|
||||
return cur_y;
|
||||
}
|
||||
bool set_windowSize(uint16 width, uint16 height);
|
||||
void set_show_cursor(bool state);
|
||||
void set_show_use_cursor(bool state);
|
||||
void set_show_grid(bool state);
|
||||
bool is_grid_showing() {
|
||||
return show_grid;
|
||||
}
|
||||
void set_velocity(sint16 vx, sint16 vy) {
|
||||
vel_x = vx;
|
||||
vel_y = vy;
|
||||
}
|
||||
void set_overlay(Graphics::ManagedSurface *surfpt);
|
||||
void set_overlay_level(int level = MAP_OVERLAY_DEFAULT) {
|
||||
overlay_level = level;
|
||||
}
|
||||
void set_x_ray_view(X_RayType state, bool cheat_off = false);
|
||||
X_RayType get_x_ray_view() {
|
||||
return x_ray_view;
|
||||
}
|
||||
void set_freeze_blacking_location(bool state);
|
||||
void set_enable_blacking(bool state);
|
||||
void set_roof_mode(bool roofs);
|
||||
void set_roof_display_mode(enum RoofDisplayType mode) {
|
||||
roof_display = mode;
|
||||
}
|
||||
void set_walking(bool state);
|
||||
void set_walk_button_mask();
|
||||
bool will_walk_with_left_button() {
|
||||
return walk_with_left_button;
|
||||
}
|
||||
void set_walk_with_left_button(bool val) {
|
||||
walk_with_left_button = val;
|
||||
set_walk_button_mask();
|
||||
}
|
||||
void set_looking(bool state) {
|
||||
looking = state;
|
||||
}
|
||||
int get_min_brightness() {
|
||||
return min_brightness;
|
||||
}
|
||||
void set_min_brightness(int brightness) {
|
||||
min_brightness = brightness;
|
||||
}
|
||||
|
||||
void moveLevel(uint8 new_level);
|
||||
void moveMap(sint16 new_x, sint16 new_y, sint8 new_level, uint8 new_x_add = 0, uint8 new_y_add = 0);
|
||||
void moveMapRelative(sint16 rel_x, sint16 rel_y);
|
||||
void shiftMapRelative(sint16 rel_x, sint16 rel_y);
|
||||
void set_mousecenter(sint16 new_x, sint16 new_y) {
|
||||
mousecenter_x = new_x;
|
||||
mousecenter_y = new_y;
|
||||
}
|
||||
void reset_mousecenter() {
|
||||
mousecenter_x = win_width / 2;
|
||||
mousecenter_y = win_height / 2;
|
||||
}
|
||||
uint16 get_win_area() {
|
||||
return win_width * win_height;
|
||||
}
|
||||
void centerMapOnActor(Actor *actor);
|
||||
void centerMap(uint16 x, uint16 y, uint8 z);
|
||||
void centerCursor();
|
||||
|
||||
void moveCursor(sint16 new_x, sint16 new_y);
|
||||
void moveCursorRelative(sint16 rel_x, sint16 rel_y);
|
||||
|
||||
bool is_doubleclick_enabled() {
|
||||
return enable_doubleclick;
|
||||
}
|
||||
void set_enable_doubleclick(bool val) {
|
||||
enable_doubleclick = val;
|
||||
}
|
||||
void set_look_on_left_click(bool val) {
|
||||
look_on_left_click = val;
|
||||
}
|
||||
void set_use_left_clicks();
|
||||
bool will_look_on_left_click() {
|
||||
return look_on_left_click;
|
||||
}
|
||||
bool is_on_screen(uint16 x, uint16 y, uint8 z);
|
||||
bool tile_is_black(uint16 x, uint16 y, const Obj *obj = nullptr) const; // subtracts cur_x and cur_y
|
||||
const char *look(uint16 x, uint16 y, bool show_prefix = true);
|
||||
const char *lookAtCursor(bool show_prefix = true) {
|
||||
return (look(cursor_x, cursor_y, show_prefix));
|
||||
}
|
||||
Obj *get_objAtCursor(bool for_use = false);
|
||||
Obj *get_objAtCoord(MapCoord coord, bool top_obj, bool include_ignored_objects, bool for_use = false);
|
||||
Actor *get_actorAtCursor();
|
||||
MapCoord get_cursorCoord();
|
||||
Obj *get_objAtMousePos(int x, int y);
|
||||
Actor *get_actorAtMousePos(int x, int y);
|
||||
void teleport_to_cursor();
|
||||
void select_target(int x, int y);
|
||||
void mouseToWorldCoords(int mx, int my, int &wx, int &wy);
|
||||
void get_movement_direction(uint16 mx, uint16 my, sint16 &rel_x, sint16 &rel_y, uint8 *mptr = nullptr);
|
||||
|
||||
TileManager *get_tile_manager() {
|
||||
return tile_manager;
|
||||
}
|
||||
AnimManager *get_anim_manager() {
|
||||
return anim_manager;
|
||||
}
|
||||
const Common::Rect *get_clip_rect() const {
|
||||
return &clip_rect;
|
||||
}
|
||||
Graphics::ManagedSurface *get_overlay();
|
||||
|
||||
void get_level(uint8 *level) const;
|
||||
void get_pos(uint16 *x, uint16 *y, uint8 *px = nullptr, uint8 *py = nullptr) const;
|
||||
void get_velocity(sint16 *vx, sint16 *vy) const {
|
||||
*vx = vel_x;
|
||||
*vy = vel_y;
|
||||
}
|
||||
void get_windowSize(uint16 *width, uint16 *height) const;
|
||||
|
||||
bool in_window(uint16 x, uint16 y, uint8 z) const;
|
||||
bool in_dungeon_level() const;
|
||||
bool in_town() const;
|
||||
// can put object at world location x,y?
|
||||
CanDropOrMoveMsg can_drop_or_move_obj(uint16 x, uint16 y, Actor *actor, Obj *obj);
|
||||
void display_can_drop_or_move_msg(CanDropOrMoveMsg msg, Std::string msg_text = "");
|
||||
bool can_get_obj(const Actor *actor, Obj *obj);
|
||||
bool blocked_by_wall(const Actor *actor, const Obj *obj);
|
||||
MapCoord original_obj_loc;
|
||||
|
||||
void updateBlacking();
|
||||
void updateAmbience();
|
||||
void update();
|
||||
void Display(bool full_redraw) override;
|
||||
|
||||
GUI_status MouseDown(int x, int y, Events::MouseButton button) override;
|
||||
GUI_status MouseUp(int x, int y, Events::MouseButton button) override;
|
||||
GUI_status MouseMotion(int x, int y, uint8 state) override;
|
||||
GUI_status MouseDouble(int x, int y, Events::MouseButton button) override;
|
||||
GUI_status MouseClick(int x, int y, Events::MouseButton button) override;
|
||||
GUI_status Idle(void) override;
|
||||
GUI_status MouseLeave(uint8 state) override;
|
||||
GUI_status MouseDelayed(int x, int y, Events::MouseButton button) override;
|
||||
GUI_status MouseHeld(int x, int y, Events::MouseButton button) override;
|
||||
GUI_status KeyDown(const Common::KeyState &key) override;
|
||||
GUI_status MouseWheel(sint32 x, sint32 y) override;
|
||||
|
||||
void drag_drop_success(int x, int y, int message, void *data) override;
|
||||
void drag_drop_failed(int x, int y, int message, void *data) override;
|
||||
|
||||
bool drag_accept_drop(int x, int y, int message, void *data) override;
|
||||
void drag_perform_drop(int x, int y, int message, void *data) override;
|
||||
bool move_on_drop(Obj *obj);
|
||||
void set_interface();
|
||||
InterfaceType get_interface();
|
||||
bool is_interface_fullscreen_in_combat();
|
||||
|
||||
void drag_draw(int x, int y, int message, void *data) override;
|
||||
|
||||
void update_mouse_cursor(uint32 mx, uint32 my);
|
||||
|
||||
unsigned char *make_thumbnail();
|
||||
void free_thumbnail();
|
||||
Graphics::ManagedSurface *get_sdl_surface();
|
||||
Graphics::ManagedSurface *get_sdl_surface(uint16 x, uint16 y, uint16 w, uint16 h);
|
||||
Graphics::ManagedSurface *get_roof_tiles() {
|
||||
return roof_tiles;
|
||||
}
|
||||
|
||||
Std::vector<const Obj *> m_ViewableObjects; //^^ dodgy public buffer
|
||||
|
||||
void wizard_eye_start(const MapCoord &location, uint16 duration, CallBack *caller);
|
||||
|
||||
bool using_map_tile_lighting;
|
||||
|
||||
protected:
|
||||
void create_thumbnail();
|
||||
|
||||
void drawActors();
|
||||
void drawAnims(bool top_anims);
|
||||
void drawObjs();
|
||||
void drawObjSuperBlock(bool draw_lowertiles, bool toptile);
|
||||
inline void drawObj(const Obj *obj, bool draw_lowertiles, bool toptile);
|
||||
inline void drawTile(const Tile *tile, uint16 x, uint16 y, bool toptile, bool use_tile_data = false);
|
||||
inline void drawNewTile(const Tile *tile, uint16 x, uint16 y, bool toptile);
|
||||
void drawBorder();
|
||||
inline void drawTopTile(const Tile *tile, uint16 x, uint16 y, bool toptile);
|
||||
inline void drawActor(const Actor *actor);
|
||||
void drawRoofs();
|
||||
void drawGrid();
|
||||
void drawRain();
|
||||
inline void drawLensAnim();
|
||||
|
||||
void updateLighting();
|
||||
void generateTmpMap();
|
||||
void boundaryFill(const byte *map_ptr, uint16 pitch, uint16 x, uint16 y);
|
||||
bool floorTilesVisible();
|
||||
bool boundaryLookThroughWindow(uint16 tile_num, uint16 x, uint16 y);
|
||||
|
||||
void reshapeBoundary();
|
||||
inline bool tmpBufTileIsBlack(uint16 x, uint16 y) const;
|
||||
bool tmpBufTileIsBoundary(uint16 x, uint16 y);
|
||||
bool tmpBufTileIsWall(uint16 x, uint16 y, NuvieDir direction);
|
||||
|
||||
void wizard_eye_stop();
|
||||
void wizard_eye_update();
|
||||
bool is_wizard_eye_mode() {
|
||||
if (wizard_eye_info.moves_left != 0) return true;
|
||||
else return false;
|
||||
}
|
||||
|
||||
void loadRoofTiles();
|
||||
|
||||
private:
|
||||
void createLightOverlay();
|
||||
|
||||
void AddMapTileToVisibleList(uint16 tile_num, uint16 x, uint16 y);
|
||||
bool can_display_obj(uint16 x, uint16 y, Obj *obj);
|
||||
};
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
1131
engines/ultima/nuvie/gui/widgets/msg_scroll.cpp
Normal file
1131
engines/ultima/nuvie/gui/widgets/msg_scroll.cpp
Normal file
File diff suppressed because it is too large
Load Diff
304
engines/ultima/nuvie/gui/widgets/msg_scroll.h
Normal file
304
engines/ultima/nuvie/gui/widgets/msg_scroll.h
Normal file
@@ -0,0 +1,304 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NUVIE_CORE_MSG_SCROLL_H
|
||||
#define NUVIE_CORE_MSG_SCROLL_H
|
||||
|
||||
#include "ultima/nuvie/misc/call_back.h"
|
||||
#include "ultima/nuvie/gui/widgets/gui_widget.h"
|
||||
#include "ultima/shared/std/containers.h"
|
||||
|
||||
#define MSGSCROLL_U6_WIDTH 17
|
||||
#define MSGSCROLL_U6_HEIGHT 10
|
||||
|
||||
#define MSGSCROLL_MD_WIDTH 16
|
||||
#define MSGSCROLL_MD_HEIGHT 8
|
||||
|
||||
#define MSGSCROLL_SE_WIDTH 16
|
||||
#define MSGSCROLL_SE_HEIGHT 8
|
||||
|
||||
#define MSGSCROLL_CURSOR_DELAY 6 // used to slow down the animated cursor
|
||||
|
||||
#define MSGSCROLL_SCROLLBACK_HEIGHT 100
|
||||
|
||||
#define MSGSCROLL_NO_MAP_DISPLAY false
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
using Std::list;
|
||||
|
||||
|
||||
class Configuration;
|
||||
class Font;
|
||||
class Actor;
|
||||
|
||||
class MsgText {
|
||||
public:
|
||||
|
||||
Font *font;
|
||||
Std::string s;
|
||||
uint8 color;
|
||||
|
||||
MsgText();
|
||||
MsgText(const Std::string &new_string, Font *f);
|
||||
~MsgText();
|
||||
|
||||
void append(const Std::string &new_string);
|
||||
void copy(MsgText *msg_text);
|
||||
uint32 length();
|
||||
|
||||
uint16 getDisplayWidth();
|
||||
bool operator<(const MsgText &rhs) const {
|
||||
return (s < rhs.s);
|
||||
}
|
||||
};
|
||||
|
||||
class MsgLine {
|
||||
public:
|
||||
|
||||
Std::list<MsgText *> text;
|
||||
uint32 total_length;
|
||||
|
||||
MsgLine() {
|
||||
total_length = 0;
|
||||
};
|
||||
~MsgLine();
|
||||
|
||||
void append(MsgText *new_text);
|
||||
void remove_char();
|
||||
uint32 length();
|
||||
MsgText *get_text_at_pos(uint16 pos);
|
||||
uint16 get_display_width();
|
||||
};
|
||||
|
||||
class MsgScroll: public GUI_Widget, public CallBack {
|
||||
protected:
|
||||
const Configuration *config;
|
||||
int game_type;
|
||||
Font *font;
|
||||
uint8 font_color;
|
||||
uint8 font_highlight_color;
|
||||
uint16 scroll_height;
|
||||
uint16 scroll_width;
|
||||
uint8 left_margin; // margin width in pixels
|
||||
|
||||
// set by request_input()
|
||||
CallBack *callback_target;
|
||||
char *callback_user_data;
|
||||
uint8 input_char;
|
||||
bool input_mode;
|
||||
const char *permit_input; // character list, or 0 = any string
|
||||
bool yes_no_only, aye_nay_only, numbers_only; // limited input selection
|
||||
|
||||
bool page_break;
|
||||
bool just_finished_page_break;
|
||||
bool just_displayed_prompt;
|
||||
virtual void process_page_break();
|
||||
Std::list<MsgLine *> msg_buf;
|
||||
|
||||
Std::string input_buf;
|
||||
bool permit_inputescape; // can RETURN or ESCAPE be used to escape input entry
|
||||
|
||||
uint16 cursor_wait;
|
||||
|
||||
uint16 scrollback_height;
|
||||
bool discard_whitespace;
|
||||
bool using_target_cursor;
|
||||
|
||||
uint8 bg_color;
|
||||
bool talking;
|
||||
|
||||
private:
|
||||
uint16 screen_x; //x offset to top left corner of MsgScroll
|
||||
uint16 screen_y; //y offset to top left corner of MsgScroll
|
||||
|
||||
bool keyword_highlight;
|
||||
|
||||
MsgText prompt;
|
||||
Std::list<MsgText *> holding_buffer;
|
||||
|
||||
bool show_cursor;
|
||||
bool autobreak; // if true, a page break will be added when the scroll is full
|
||||
|
||||
bool scroll_updated;
|
||||
uint8 cursor_char;
|
||||
uint16 cursor_x, cursor_y;
|
||||
|
||||
uint16 line_count; // count the number of lines since last page break.
|
||||
|
||||
uint16 display_pos;
|
||||
|
||||
bool capitalise_next_letter;
|
||||
|
||||
public:
|
||||
|
||||
MsgScroll(const Configuration *cfg, Font *f);
|
||||
MsgScroll() : GUI_Widget(nullptr, 0, 0, 0, 0),
|
||||
config(nullptr), game_type(0), font(nullptr), scroll_height(0),
|
||||
scroll_width(0), callback_target(nullptr), callback_user_data(nullptr),
|
||||
input_mode(false), permit_input(nullptr), page_break(false),
|
||||
just_finished_page_break(false), permit_inputescape(false),
|
||||
cursor_wait(0), screen_x(0), screen_y(0), bg_color(0),
|
||||
keyword_highlight(true), talking(false), show_cursor(false),
|
||||
autobreak(false), scroll_updated(false), cursor_char(0),
|
||||
cursor_x(0), cursor_y(0), line_count(0), display_pos(0),
|
||||
capitalise_next_letter(false), just_displayed_prompt(false),
|
||||
scrollback_height(MSGSCROLL_SCROLLBACK_HEIGHT), discard_whitespace(false),
|
||||
left_margin(0), font_color(0), font_highlight_color(0), input_char(0),
|
||||
yes_no_only(false), aye_nay_only(false), numbers_only(false),
|
||||
using_target_cursor(false) {
|
||||
}
|
||||
~MsgScroll() override;
|
||||
|
||||
void init(const Configuration *cfg, Font *f);
|
||||
|
||||
bool init(const char *player_name);
|
||||
void page_up();
|
||||
void page_down();
|
||||
virtual void move_scroll_down();
|
||||
virtual void move_scroll_up();
|
||||
void set_using_target_cursor(bool val) {
|
||||
using_target_cursor = val;
|
||||
}
|
||||
|
||||
void process_holding_buffer();
|
||||
|
||||
MsgText *holding_buffer_get_token();
|
||||
bool is_holding_buffer_empty() const {
|
||||
return holding_buffer.empty();
|
||||
}
|
||||
virtual bool can_display_prompt() const {
|
||||
return !just_displayed_prompt;
|
||||
}
|
||||
|
||||
virtual bool parse_token(MsgText *token);
|
||||
void add_token(MsgText *token);
|
||||
bool remove_char();
|
||||
|
||||
virtual void set_font(uint8 font_type);
|
||||
virtual bool is_garg_font();
|
||||
|
||||
template<class... TParam>
|
||||
int print(const Std::string &format, TParam... param);
|
||||
|
||||
virtual void display_string(const Std::string &s, Font *f, bool include_on_map_window);
|
||||
void display_string(const Std::string &s, Font *f, uint8 color, bool include_on_map_window);
|
||||
void display_string(const Std::string &s, uint16 length, uint8 lang_num);
|
||||
void display_string(const Std::string &s, bool include_on_map_window = true);
|
||||
void display_string(const Std::string &s, uint8 color, bool include_on_map_window);
|
||||
void display_fmt_string(const char *format, ...);
|
||||
void message(const char *string) {
|
||||
display_string(string);
|
||||
display_prompt();
|
||||
}
|
||||
|
||||
bool set_prompt(const char *new_prompt, Font *f = nullptr);
|
||||
virtual void display_prompt();
|
||||
virtual void display_converse_prompt();
|
||||
|
||||
void set_keyword_highlight(bool state);
|
||||
|
||||
void set_input_mode(bool state, const char *allowed = nullptr,
|
||||
bool can_escape = true, bool use_target_cursor = false,
|
||||
bool set_numbers_only_to_true = false);
|
||||
virtual void set_talking(bool state, Actor *actor = nullptr) {
|
||||
talking = state;
|
||||
input_char = 0;
|
||||
}
|
||||
bool is_talking() const {
|
||||
return talking;
|
||||
}
|
||||
void set_show_cursor(bool state) {
|
||||
show_cursor = state;
|
||||
}
|
||||
|
||||
void set_autobreak(bool state) {
|
||||
autobreak = state;
|
||||
}
|
||||
void set_discard_whitespace(bool discard) {
|
||||
discard_whitespace = discard;
|
||||
}
|
||||
|
||||
bool get_page_break() const {
|
||||
return page_break;
|
||||
}
|
||||
|
||||
GUI_status KeyDown(const Common::KeyState &key) override;
|
||||
GUI_status MouseUp(int x, int y, Events::MouseButton button) override;
|
||||
GUI_status MouseWheel(sint32 x, sint32 y) override;
|
||||
virtual Std::string get_token_string_at_pos(uint16 x, uint16 y);
|
||||
//void updateScroll();
|
||||
void Display(bool full_redraw) override;
|
||||
|
||||
void clearCursor(uint16 x, uint16 y);
|
||||
virtual void drawCursor(uint16 x, uint16 y);
|
||||
|
||||
void set_page_break();
|
||||
|
||||
virtual bool input_buf_add_char(char c);
|
||||
virtual bool input_buf_remove_char();
|
||||
|
||||
/* Converse uses this to tell if the scroll has finished displaying the converse dialog */
|
||||
virtual bool is_converse_finished() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool has_input();
|
||||
Std::string get_input();
|
||||
const char *peek_at_input();
|
||||
void request_input(CallBack *caller, void *user_data);
|
||||
void cancel_input_request() {
|
||||
request_input(nullptr, nullptr);
|
||||
}
|
||||
void clear_scroll();
|
||||
|
||||
protected:
|
||||
|
||||
void set_scroll_dimensions(uint16 w, uint16 h);
|
||||
void delete_front_line();
|
||||
virtual MsgLine *add_new_line();
|
||||
void drawLine(Screen *screen, MsgLine *msg_line, uint16 line_y);
|
||||
inline void clear_page_break();
|
||||
|
||||
virtual void set_permitted_input(const char *allowed);
|
||||
virtual void clear_permitted_input();
|
||||
virtual bool can_fit_token_on_msgline(MsgLine *msg_line, MsgText *token);
|
||||
void increase_input_char();
|
||||
void decrease_input_char();
|
||||
uint8 get_char_from_input_char();
|
||||
virtual uint8 get_input_font_color() const {
|
||||
return font_color;
|
||||
}
|
||||
|
||||
private:
|
||||
int print_internal(const Std::string *format, ...);
|
||||
};
|
||||
|
||||
template<class... TParam>
|
||||
inline int MsgScroll::print(const Std::string &format, TParam... param) {
|
||||
return print_internal(&format, Common::forward<TParam>(param)...);
|
||||
}
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
297
engines/ultima/nuvie/gui/widgets/msg_scroll_new_ui.cpp
Normal file
297
engines/ultima/nuvie/gui/widgets/msg_scroll_new_ui.cpp
Normal file
@@ -0,0 +1,297 @@
|
||||
/* 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/conf/configuration.h"
|
||||
#include "ultima/nuvie/misc/u6_misc.h"
|
||||
#include "ultima/nuvie/fonts/font_manager.h"
|
||||
#include "ultima/nuvie/fonts/font.h"
|
||||
#include "ultima/nuvie/screen/game_palette.h"
|
||||
#include "ultima/nuvie/gui/gui.h"
|
||||
#include "ultima/nuvie/gui/widgets/msg_scroll.h"
|
||||
#include "ultima/nuvie/portraits/portrait.h"
|
||||
#include "ultima/nuvie/core/player.h"
|
||||
#include "ultima/nuvie/fonts/conv_font.h"
|
||||
#include "ultima/nuvie/gui/widgets/msg_scroll_new_ui.h"
|
||||
#include "ultima/nuvie/actors/actor_manager.h"
|
||||
#include "ultima/nuvie/core/timed_event.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
// MsgScrollNewUI Class
|
||||
|
||||
MsgScrollNewUI::MsgScrollNewUI(const Configuration *cfg, Screen *s) {
|
||||
drop_target = false; //we don't participate in drag and drop.
|
||||
|
||||
font_normal = Game::get_game()->get_font_manager()->get_conv_font();
|
||||
font_garg = Game::get_game()->get_font_manager()->get_conv_garg_font();
|
||||
|
||||
init(cfg, font_normal);
|
||||
|
||||
Std::string new_scroll_cfg = config_get_game_key(config) + "/newscroll";
|
||||
|
||||
cfg->value(new_scroll_cfg + "/solid_bg", solid_bg, false);
|
||||
|
||||
int c;
|
||||
if (Game::get_game()->get_game_type() == NUVIE_GAME_U6) {
|
||||
bg_color = 218;
|
||||
border_color = 220;
|
||||
} else if (Game::get_game()->get_game_type() == NUVIE_GAME_SE) {
|
||||
bg_color = 216;
|
||||
border_color = 219;
|
||||
} else { // MD
|
||||
bg_color = 136;
|
||||
border_color = 133;
|
||||
}
|
||||
cfg->value(new_scroll_cfg + "/bg_color", c, bg_color);
|
||||
bg_color = clamp_max(c, 255);
|
||||
cfg->value(new_scroll_cfg + "/border_color", c, border_color);
|
||||
border_color = clamp_max(c, 255);
|
||||
|
||||
cfg->value(new_scroll_cfg + "/width", c, 18);
|
||||
scroll_width = c;
|
||||
cfg->value(new_scroll_cfg + "/height", c, 19);
|
||||
scroll_height = clamp_max(c, scrollback_height);
|
||||
|
||||
|
||||
|
||||
uint16 x_off = Game::get_game()->get_game_x_offset();
|
||||
uint16 y_off = Game::get_game()->get_game_y_offset();
|
||||
// need to accept clicks on whole game area
|
||||
GUI_Widget::Init(nullptr, x_off, y_off, Game::get_game()->get_game_width(), Game::get_game()->get_game_height());
|
||||
|
||||
cursor_wait = 0;
|
||||
|
||||
timer = nullptr;
|
||||
|
||||
position = 0;
|
||||
}
|
||||
|
||||
MsgScrollNewUI::~MsgScrollNewUI() {
|
||||
|
||||
}
|
||||
|
||||
bool MsgScrollNewUI::can_fit_token_on_msgline(MsgLine *msg_line, MsgText *token) {
|
||||
if (msg_line->get_display_width() + token->getDisplayWidth() > scroll_width * 7 - 8) {
|
||||
return false; //token doesn't fit on the current line.
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void MsgScrollNewUI::display_string(const Std::string &str, Font *f, bool include_on_map_window) {
|
||||
if (str.empty())
|
||||
return;
|
||||
bool has_trailing_whitespace = (!trailing_whitespace.empty());
|
||||
string s = trailing_whitespace + str;
|
||||
trailing_whitespace.clear();
|
||||
|
||||
uint16 i, pos;
|
||||
for (i = 0, pos = s.size(); pos >= 0; pos--, i++) {
|
||||
char c = s[pos];
|
||||
if (c != '\t' && c != '\n')
|
||||
break;
|
||||
}
|
||||
|
||||
if (i > 0) {
|
||||
trailing_whitespace = s.substr(s.size() - i, i);
|
||||
s = s.substr(0, s.size() - i);
|
||||
}
|
||||
|
||||
if (!s.empty()) {
|
||||
if (position > 0 && position == msg_buf.size()) {
|
||||
if (!has_trailing_whitespace)
|
||||
position--;
|
||||
else {
|
||||
position += count_empty_lines(s) - 1;
|
||||
}
|
||||
}
|
||||
timer = new TimedCallback(this, nullptr, 2000);
|
||||
|
||||
MsgScroll::display_string(s, f, include_on_map_window);
|
||||
}
|
||||
}
|
||||
|
||||
uint16 MsgScrollNewUI::count_empty_lines(const Std::string &s) {
|
||||
uint16 count = 0;
|
||||
for (char c : s) {
|
||||
if (c != ' ' && c != '\t' && c != '\n')
|
||||
break;
|
||||
|
||||
if (c == '\n')
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
void MsgScrollNewUI::set_font(uint8 font_type) {
|
||||
if (font_type == NUVIE_FONT_NORMAL) {
|
||||
font = font_normal;
|
||||
} else {
|
||||
if (font_garg) {
|
||||
font = font_garg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool MsgScrollNewUI::is_garg_font() {
|
||||
return (font == font_garg);
|
||||
}
|
||||
|
||||
uint16 MsgScrollNewUI::callback(uint16 msg, CallBack *caller, void *data) {
|
||||
if (msg == CB_TIMED && (timer == nullptr || timer == caller)) {
|
||||
timer = nullptr;
|
||||
if (input_mode) {
|
||||
new TimedCallback(this, nullptr, 100);
|
||||
} else {
|
||||
//roll up the message scroll so it's out of the way.
|
||||
if (position < msg_buf.size()) {
|
||||
if ((uint16)(position + 1) < msg_buf.size()
|
||||
|| msg_buf.back()->total_length > 0) { //don't advance if on second last line and the last line is empty.
|
||||
position++;
|
||||
new TimedCallback(this, nullptr, 50);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void MsgScrollNewUI::Display(bool full_redraw) {
|
||||
MsgText *token;
|
||||
|
||||
uint16 y = area.top + 4;
|
||||
uint16 total_length = 0;
|
||||
Std::list<MsgLine *>::iterator iter;
|
||||
|
||||
iter = msg_buf.begin();
|
||||
for (uint16 i = 0; i < position && iter != msg_buf.end(); i++)
|
||||
iter++;
|
||||
|
||||
for (uint16 i = 0; i < scroll_height && iter != msg_buf.end(); i++, iter++) {
|
||||
MsgLine *msg_line = *iter;
|
||||
Std::list<MsgText *>::iterator iter1;
|
||||
|
||||
iter1 = msg_line->text.begin();
|
||||
|
||||
//if not last record or if last record is not an empty line.
|
||||
if (i + position < ((int)msg_buf.size() - 1) || (iter1 != msg_line->text.end() && ((*iter)->total_length != 0))) {
|
||||
if (bg_color != 255) {
|
||||
if (solid_bg)
|
||||
screen->fill(bg_color, area.left, y + (i == 0 ? -4 : 4), scroll_width * 7 + 8, (i == 0 ? 18 : 10));
|
||||
else
|
||||
screen->stipple_8bit(bg_color, area.left, y + (i == 0 ? -4 : 4), scroll_width * 7 + 8, (i == 0 ? 18 : 10));
|
||||
}
|
||||
|
||||
if (border_color != 255) {
|
||||
screen->fill(border_color, area.left, y + (i == 0 ? -4 : 4), 1, (i == 0 ? 18 : 10));
|
||||
screen->fill(border_color, area.left + scroll_width * 7 + 7, y + (i == 0 ? -4 : 4), 1, (i == 0 ? 18 : 10));
|
||||
}
|
||||
|
||||
for (total_length = 0; iter1 != msg_line->text.end() ; iter1++) {
|
||||
token = *iter1;
|
||||
|
||||
total_length += token->font->drawString(screen, token->s.c_str(), area.left + 4 + 4 + total_length, y + 4, 0, 0); //FIX for hardcoded font height
|
||||
}
|
||||
y += 10;
|
||||
}
|
||||
|
||||
}
|
||||
if (input_char != 0)
|
||||
font->drawChar(screen, get_char_from_input_char(), total_length + 8, y - 6);
|
||||
if (border_color != 255 && y != area.top + 4) {
|
||||
screen->fill(border_color, area.left, y + 4, scroll_width * 7 + 8, 1); //draw bottom border
|
||||
}
|
||||
/* Debug
|
||||
char buf[10];
|
||||
snprintf(buf, 10, "%d", position);
|
||||
font_normal->drawString(screen, buf, 160, 10);
|
||||
snprintf(buf, 10, "%d", (int)msg_buf.size());
|
||||
font_normal->drawString(screen, buf, 160, 20);
|
||||
*/
|
||||
screen->update(area.left, area.top, scroll_width * 7 + 8, scroll_height * 10 + 8);
|
||||
}
|
||||
|
||||
GUI_status MsgScrollNewUI::KeyDown(const Common::KeyState &key) {
|
||||
MsgScrollEventType event = SCROLL_ESCAPE;
|
||||
/*
|
||||
switch(key.keycode)
|
||||
{
|
||||
case Common::KEYCODE_PAGEDOWN: if(input_mode) event = SCROLL_DOWN; break;
|
||||
case Common::KEYCODE_PAGEUP: if(input_mode) event = SCROLL_UP; break;
|
||||
default : break;
|
||||
}
|
||||
*/
|
||||
if (scroll_movement_event(event) == GUI_YUM)
|
||||
return GUI_YUM;
|
||||
|
||||
return MsgScroll::KeyDown(key);
|
||||
}
|
||||
|
||||
GUI_status MsgScrollNewUI::MouseDown(int x, int y, Events::MouseButton button) {
|
||||
MsgScrollEventType event = SCROLL_ESCAPE;
|
||||
|
||||
return scroll_movement_event(event);
|
||||
}
|
||||
|
||||
GUI_status MsgScrollNewUI::scroll_movement_event(MsgScrollEventType event) {
|
||||
switch (event) {
|
||||
case SCROLL_UP :
|
||||
if (position > 0) {
|
||||
timer = new TimedCallback(this, nullptr, 2000);
|
||||
position--;
|
||||
grab_focus();
|
||||
}
|
||||
return GUI_YUM;
|
||||
|
||||
case SCROLL_DOWN :
|
||||
timer = new TimedCallback(this, nullptr, 2000);
|
||||
if (position < msg_buf.size())
|
||||
position++;
|
||||
return GUI_YUM;
|
||||
|
||||
default :
|
||||
release_focus();
|
||||
new TimedCallback(this, nullptr, 50);
|
||||
break;
|
||||
}
|
||||
|
||||
return GUI_PASS;
|
||||
}
|
||||
|
||||
MsgLine *MsgScrollNewUI::add_new_line() {
|
||||
MsgLine *line = MsgScroll::add_new_line();
|
||||
|
||||
if (position + scroll_height < (uint16)msg_buf.size()) {
|
||||
position++;
|
||||
} else if (position + scroll_height > scrollback_height) {
|
||||
position--;
|
||||
}
|
||||
return line;
|
||||
}
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
109
engines/ultima/nuvie/gui/widgets/msg_scroll_new_ui.h
Normal file
109
engines/ultima/nuvie/gui/widgets/msg_scroll_new_ui.h
Normal file
@@ -0,0 +1,109 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NUVIE_CORE_MSG_SCROLL_NEW_UI_H
|
||||
#define NUVIE_CORE_MSG_SCROLL_NEW_UI_H
|
||||
|
||||
#include "ultima/nuvie/misc/call_back.h"
|
||||
#include "ultima/nuvie/gui/widgets/gui_widget.h"
|
||||
#include "ultima/shared/std/containers.h"
|
||||
#include "ultima/shared/std/string.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Nuvie {
|
||||
|
||||
using Std::list;
|
||||
|
||||
class Configuration;
|
||||
class Font;
|
||||
class MsgScroll;
|
||||
class Actor;
|
||||
class CallBack;
|
||||
|
||||
typedef enum {
|
||||
SCROLL_UP,
|
||||
SCROLL_DOWN,
|
||||
SCROLL_ESCAPE
|
||||
} MsgScrollEventType;
|
||||
|
||||
class MsgScrollNewUI: public MsgScroll {
|
||||
|
||||
CallBack *timer;
|
||||
|
||||
Font *font_normal;
|
||||
Font *font_garg;
|
||||
|
||||
bool solid_bg;
|
||||
uint8 bg_color;
|
||||
uint8 border_color;
|
||||
uint16 position;
|
||||
|
||||
Std::string trailing_whitespace;
|
||||
|
||||
public:
|
||||
|
||||
MsgScrollNewUI(const Configuration *cfg, Screen *s);
|
||||
~MsgScrollNewUI() override;
|
||||
|
||||
GUI_status callback(uint16 msg, GUI_CallBack *caller, void *data) override {
|
||||
return GUI_PASS;
|
||||
}
|
||||
uint16 callback(uint16 msg, CallBack *caller, void *data) override;
|
||||
bool can_display_prompt() const override {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool can_fit_token_on_msgline(MsgLine *msg_line, MsgText *token) override;
|
||||
|
||||
void Display(bool full_redraw) override;
|
||||
|
||||
void display_prompt() override {}
|
||||
|
||||
void display_string(const Std::string &s, Font *f, bool include_on_map_window) override;
|
||||
|
||||
void set_font(uint8 font_type) override;
|
||||
bool is_garg_font() override;
|
||||
|
||||
GUI_status KeyDown(const Common::KeyState &key) override;
|
||||
GUI_status MouseDown(int x, int y, Events::MouseButton button) override;
|
||||
|
||||
void move_scroll_down() override {
|
||||
scroll_movement_event(SCROLL_DOWN);
|
||||
}
|
||||
void move_scroll_up() override {
|
||||
scroll_movement_event(SCROLL_UP);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
MsgLine *add_new_line() override;
|
||||
|
||||
private:
|
||||
GUI_status scroll_movement_event(MsgScrollEventType event);
|
||||
uint16 count_empty_lines(const Std::string &s);
|
||||
|
||||
};
|
||||
|
||||
} // End of namespace Nuvie
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user