308 lines
8.2 KiB
C++
308 lines
8.2 KiB
C++
/* ScummVM - Graphic Adventure Engine
|
|
*
|
|
* ScummVM is the legal property of its developers, whose names
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
* file distributed with this source distribution.
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
#include "ultima/shared/std/string.h"
|
|
#include "ultima/nuvie/core/nuvie_defs.h"
|
|
#include "ultima/nuvie/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/views/scroll_widget_gump.h"
|
|
#include "ultima/nuvie/actors/actor_manager.h"
|
|
#include "ultima/nuvie/core/timed_event.h"
|
|
#include "ultima/nuvie/keybinding/keys.h"
|
|
|
|
namespace Ultima {
|
|
namespace Nuvie {
|
|
|
|
// ScrollWidgetGump Class
|
|
|
|
ScrollWidgetGump::ScrollWidgetGump(const Configuration *cfg, Screen *s) :
|
|
arrow_up_rect(SCROLLWIDGETGUMP_W - 8 - 1, 4 + 1,
|
|
SCROLLWIDGETGUMP_W - 8 - 1 + 7, 4 + 1 + 5),
|
|
arrow_down_rect(SCROLLWIDGETGUMP_W - 8 - 1, SCROLLWIDGETGUMP_H - 8 + 3,
|
|
SCROLLWIDGETGUMP_W - 8 - 1 + 7, SCROLLWIDGETGUMP_H - 8 + 3 + 5) {
|
|
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);
|
|
|
|
font_color = 0; // black
|
|
font_highlight = FONT_COLOR_U6_HIGHLIGHT;
|
|
|
|
scroll_width = 40;
|
|
scroll_height = 10;
|
|
|
|
show_up_arrow = false;
|
|
show_down_arrow = false;
|
|
|
|
GUI_Widget::Init(nullptr, 0, 0, SCROLLWIDGETGUMP_W, SCROLLWIDGETGUMP_H);
|
|
|
|
add_new_line(); //MsgScroll requires a line to start.
|
|
|
|
position = 0;
|
|
// ignore_page_breaks = true;
|
|
}
|
|
|
|
ScrollWidgetGump::~ScrollWidgetGump() {
|
|
// ignore_page_breaks = false;
|
|
}
|
|
|
|
void ScrollWidgetGump::set_font(uint8 font_type) {
|
|
if (font_type == NUVIE_FONT_NORMAL) {
|
|
font = font_normal;
|
|
} else {
|
|
font = font_garg;
|
|
}
|
|
}
|
|
|
|
bool ScrollWidgetGump::is_garg_font() {
|
|
return (font == font_garg);
|
|
}
|
|
|
|
bool ScrollWidgetGump::can_fit_token_on_msgline(MsgLine *msg_line, MsgText *token) {
|
|
if (msg_line->get_display_width() + token->getDisplayWidth() > SCROLLWIDGETGUMP_W - 8 - 8) {
|
|
return false; //token doesn't fit on the current line.
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ScrollWidgetGump::parse_token(MsgText *token) {
|
|
if (token->s[0] == '*') // We don't want page breaks in the scroll widget.
|
|
return true;
|
|
|
|
return MsgScroll::parse_token(token);
|
|
}
|
|
|
|
void ScrollWidgetGump::display_string(const Std::string &s) {
|
|
MsgScroll::display_string(s);
|
|
update_arrows();
|
|
}
|
|
|
|
void ScrollWidgetGump::Display(bool full_redraw) {
|
|
MsgText *token;
|
|
|
|
uint16 y = area.top + 4;
|
|
Std::list<MsgLine *>::iterator iter;
|
|
|
|
if (show_up_arrow) {
|
|
font_normal->drawChar(screen, FONT_UP_ARROW_CHAR, area.left + SCROLLWIDGETGUMP_W - 8, area.top + 4);
|
|
}
|
|
|
|
if (show_down_arrow) {
|
|
font_normal->drawChar(screen, FONT_DOWN_ARROW_CHAR, area.left + SCROLLWIDGETGUMP_W - 8, area.top + SCROLLWIDGETGUMP_H - 8);
|
|
}
|
|
|
|
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))) {
|
|
//screen->fill(26, area.left, y + (i==0?-4:4), scroll_width * 7 + 8, (i==0?18:10));
|
|
|
|
|
|
for (uint16 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, font_color, font_highlight); //FIX for hardcoded font height
|
|
}
|
|
y += 10;
|
|
}
|
|
|
|
}
|
|
|
|
screen->update(area.left, area.top, area.width(), area.height());
|
|
}
|
|
|
|
GUI_status ScrollWidgetGump::KeyDown(const Common::KeyState &key) {
|
|
ScrollEventType event = SCROLL_ESCAPE;
|
|
|
|
KeyBinder *keybinder = Game::get_game()->get_keybinder();
|
|
ActionType a = keybinder->get_ActionType(key);
|
|
|
|
switch (keybinder->GetActionKeyType(a)) {
|
|
case MSGSCROLL_DOWN_KEY:
|
|
event = SCROLL_PAGE_DOWN;
|
|
break;
|
|
case SOUTH_KEY:
|
|
event = SCROLL_DOWN;
|
|
break;
|
|
case MSGSCROLL_UP_KEY:
|
|
event = SCROLL_PAGE_UP;
|
|
break;
|
|
case NORTH_KEY:
|
|
event = SCROLL_UP;
|
|
break;
|
|
case HOME_KEY:
|
|
event = SCROLL_TO_BEGINNING;
|
|
break;
|
|
case END_KEY:
|
|
event = SCROLL_TO_END;
|
|
break;
|
|
default :
|
|
break;
|
|
}
|
|
|
|
if (scroll_movement_event(event) == GUI_YUM)
|
|
return GUI_YUM;
|
|
|
|
return MsgScroll::KeyDown(key);
|
|
}
|
|
|
|
GUI_status ScrollWidgetGump::MouseWheel(sint32 x, sint32 y) {
|
|
ScrollEventType event = SCROLL_ESCAPE;
|
|
|
|
if (y > 0)
|
|
event = SCROLL_UP;
|
|
if (y < 0)
|
|
event = SCROLL_DOWN;
|
|
|
|
return scroll_movement_event(event);
|
|
}
|
|
|
|
GUI_status ScrollWidgetGump::MouseDown(int x, int y, Events::MouseButton button) {
|
|
ScrollEventType event = SCROLL_ESCAPE;
|
|
|
|
switch (button) {
|
|
case Events::BUTTON_LEFT : {
|
|
x -= area.left;
|
|
y -= area.top;
|
|
if (HitRect(x, y, arrow_up_rect))
|
|
event = SCROLL_UP;
|
|
else if (HitRect(x, y, arrow_down_rect))
|
|
event = SCROLL_DOWN;
|
|
// FIXME - uncomment when we get a checkmark
|
|
// else if(show_down_arrow || show_up_arrow) // don't close if scrollable
|
|
// return GUI_YUM;
|
|
break;
|
|
}
|
|
default :
|
|
break;
|
|
}
|
|
|
|
return scroll_movement_event(event);
|
|
}
|
|
|
|
GUI_status ScrollWidgetGump::scroll_movement_event(ScrollEventType event) {
|
|
switch (event) {
|
|
case SCROLL_UP :
|
|
if (position > 0) {
|
|
//timer = new TimedCallback(this, nullptr, 2000);
|
|
position--;
|
|
update_arrows();
|
|
//grab_focus();
|
|
}
|
|
return GUI_YUM;
|
|
|
|
case SCROLL_DOWN :
|
|
//timer = new TimedCallback(this, nullptr, 2000);
|
|
if (page_break && position + scroll_height >= (int)msg_buf.size()) {
|
|
if (position + scroll_height == (int)msg_buf.size()) // break was just off the page so advance text
|
|
position++;
|
|
process_page_break();
|
|
update_arrows();
|
|
} else if (position + scroll_height < (int)msg_buf.size()) {
|
|
position++;
|
|
update_arrows();
|
|
}
|
|
return GUI_YUM;
|
|
case SCROLL_PAGE_UP:
|
|
if (position > 0) {
|
|
position = position > scroll_height ? position - scroll_height : 0;
|
|
update_arrows();
|
|
}
|
|
return GUI_YUM;
|
|
case SCROLL_PAGE_DOWN:
|
|
if (position + scroll_height < (int)msg_buf.size() || page_break) {
|
|
if (position + scroll_height >= (int)msg_buf.size())
|
|
position = (int)msg_buf.size();
|
|
else {
|
|
position += scroll_height;
|
|
update_arrows();
|
|
return GUI_YUM;
|
|
}
|
|
if (page_break) { // we didn't have enough text showing to fill out the current page.
|
|
position = msg_buf.size();
|
|
process_page_break();
|
|
}
|
|
update_arrows();
|
|
}
|
|
return GUI_YUM;
|
|
case SCROLL_TO_BEGINNING :
|
|
if (position > 0) {
|
|
position = 0;
|
|
update_arrows();
|
|
}
|
|
return GUI_YUM;
|
|
case SCROLL_TO_END :
|
|
if (position + scroll_height < (int)msg_buf.size() || page_break) {
|
|
while (position + scroll_height < (int)msg_buf.size() || page_break) {
|
|
if (page_break)
|
|
process_page_break();
|
|
else // added else just in case noting is added to the buffer
|
|
position++;
|
|
}
|
|
update_arrows();
|
|
}
|
|
return GUI_YUM;
|
|
default :
|
|
//release_focus();
|
|
//new TimedCallback(this, nullptr, 50);
|
|
break;
|
|
}
|
|
|
|
return GUI_PASS;
|
|
}
|
|
|
|
void ScrollWidgetGump::update_arrows() {
|
|
if (position == 0) {
|
|
show_up_arrow = false;
|
|
} else {
|
|
show_up_arrow = true;
|
|
}
|
|
|
|
if (position + scroll_height < (int)msg_buf.size() || page_break) {
|
|
show_down_arrow = true;
|
|
} else {
|
|
show_down_arrow = false;
|
|
}
|
|
}
|
|
|
|
} // End of namespace Nuvie
|
|
} // End of namespace Ultima
|