Removed a bunch of unused GUI1 stuff (#9375)

Don't need these now that the GUI2 help browser is merged.
This commit is contained in:
Charles Dang 2024-09-23 23:54:47 -04:00 committed by GitHub
parent 53cb294b4e
commit 1261d88b15
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 4 additions and 1694 deletions

View File

@ -585,19 +585,13 @@
46F92EDD2174FD9900602C1C /* scrollbar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46F92ED32174FD9700602C1C /* scrollbar.cpp */; };
46F92EDE2174FD9900602C1C /* textbox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46F92ED52174FD9800602C1C /* textbox.cpp */; };
46F92EDF2174FD9900602C1C /* button.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46F92ED72174FD9800602C1C /* button.cpp */; };
46F92EE02174FD9900602C1C /* menu_style.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46F92ED82174FD9800602C1C /* menu_style.cpp */; };
46F92EE12174FD9900602C1C /* menu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46F92EDA2174FD9900602C1C /* menu.cpp */; };
46F92EE22174FDA100602C1C /* button.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46F92ED72174FD9800602C1C /* button.cpp */; };
46F92EE32174FDA600602C1C /* menu_style.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46F92ED82174FD9800602C1C /* menu_style.cpp */; };
46F92EE42174FDA600602C1C /* menu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46F92EDA2174FD9900602C1C /* menu.cpp */; };
46F92EE82174FDAB00602C1C /* scrollarea.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46F92ED12174FD9700602C1C /* scrollarea.cpp */; };
46F92EE92174FDAB00602C1C /* scrollbar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46F92ED32174FD9700602C1C /* scrollbar.cpp */; };
46F92EEA2174FDAB00602C1C /* textbox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46F92ED52174FD9800602C1C /* textbox.cpp */; };
46F92EEB2174FDAB00602C1C /* widget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B55999600EC62181008DD061 /* widget.cpp */; };
46F92EEE2174FE0E00602C1C /* floating_textbox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46F92EED2174FE0E00602C1C /* floating_textbox.cpp */; };
46F92EEF2174FE0E00602C1C /* floating_textbox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46F92EED2174FE0E00602C1C /* floating_textbox.cpp */; };
46F92EF22174FE5600602C1C /* show_dialog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46F92EF12174FE5500602C1C /* show_dialog.cpp */; };
46F92EF32174FE5600602C1C /* show_dialog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46F92EF12174FE5500602C1C /* show_dialog.cpp */; };
46F92F0F2174FEC000602C1C /* standard_colors.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46F92EF52174FEBD00602C1C /* standard_colors.cpp */; };
46F92F102174FEC000602C1C /* standard_colors.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46F92EF52174FEBD00602C1C /* standard_colors.cpp */; };
46F92F172174FEC000602C1C /* font_config.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46F92EFC2174FEBE00602C1C /* font_config.cpp */; };
@ -2112,18 +2106,13 @@
46F92ED12174FD9700602C1C /* scrollarea.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = scrollarea.cpp; sourceTree = "<group>"; };
46F92ED22174FD9700602C1C /* scrollarea.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = scrollarea.hpp; sourceTree = "<group>"; };
46F92ED32174FD9700602C1C /* scrollbar.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = scrollbar.cpp; sourceTree = "<group>"; };
46F92ED42174FD9700602C1C /* menu.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = menu.hpp; sourceTree = "<group>"; };
46F92ED52174FD9800602C1C /* textbox.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = textbox.cpp; sourceTree = "<group>"; };
46F92ED62174FD9800602C1C /* button.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = button.hpp; sourceTree = "<group>"; };
46F92ED72174FD9800602C1C /* button.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = button.cpp; sourceTree = "<group>"; };
46F92ED82174FD9800602C1C /* menu_style.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = menu_style.cpp; sourceTree = "<group>"; };
46F92ED92174FD9900602C1C /* textbox.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = textbox.hpp; sourceTree = "<group>"; };
46F92EDA2174FD9900602C1C /* menu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = menu.cpp; sourceTree = "<group>"; };
46F92EDB2174FD9900602C1C /* scrollbar.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = scrollbar.hpp; sourceTree = "<group>"; };
46F92EEC2174FE0D00602C1C /* floating_textbox.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = floating_textbox.hpp; sourceTree = "<group>"; };
46F92EED2174FE0E00602C1C /* floating_textbox.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = floating_textbox.cpp; sourceTree = "<group>"; };
46F92EF02174FE5500602C1C /* show_dialog.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = show_dialog.hpp; sourceTree = "<group>"; };
46F92EF12174FE5500602C1C /* show_dialog.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = show_dialog.cpp; sourceTree = "<group>"; };
46F92EF42174FEBD00602C1C /* standard_colors.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = standard_colors.hpp; path = font/standard_colors.hpp; sourceTree = "<group>"; };
46F92EF52174FEBD00602C1C /* standard_colors.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = standard_colors.cpp; path = font/standard_colors.cpp; sourceTree = "<group>"; };
46F92EF92174FEBE00602C1C /* error.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = error.hpp; path = font/error.hpp; sourceTree = "<group>"; };
@ -3482,8 +3471,6 @@
EC64D75F1A085CE60092EF75 /* seed_rng.cpp */,
91B621971B7672B400B00E0F /* seed_rng.hpp */,
B55999A60EC62181008DD061 /* serialization */,
46F92EF12174FE5500602C1C /* show_dialog.cpp */,
46F92EF02174FE5500602C1C /* show_dialog.hpp */,
9577DD2E2C1E1BEB0031135F /* side_controller.hpp */,
B5CE46F712A0417D00D665EE /* side_filter.cpp */,
B5CE46F812A0417D00D665EE /* side_filter.hpp */,
@ -4818,9 +4805,6 @@
children = (
46F92ED72174FD9800602C1C /* button.cpp */,
46F92ED62174FD9800602C1C /* button.hpp */,
46F92ED82174FD9800602C1C /* menu_style.cpp */,
46F92EDA2174FD9900602C1C /* menu.cpp */,
46F92ED42174FD9700602C1C /* menu.hpp */,
46F92ED12174FD9700602C1C /* scrollarea.cpp */,
46F92ED22174FD9700602C1C /* scrollarea.hpp */,
46F92ED32174FD9700602C1C /* scrollbar.cpp */,
@ -5549,7 +5533,6 @@
46F92DAB2174F6A300602C1C /* unit_recall.cpp in Sources */,
B5599B7B0EC62181008DD061 /* config_cache.cpp in Sources */,
9154743D2C8FBAC800EB1C94 /* lua_attributes.cpp in Sources */,
46F92EF22174FE5600602C1C /* show_dialog.cpp in Sources */,
B5599B7D0EC62181008DD061 /* config.cpp in Sources */,
EC0680291EA920A300EEE03B /* random_deterministic.cpp in Sources */,
B54AC69D0FEA9E8F006F6FBD /* configuration.cpp in Sources */,
@ -5603,7 +5586,6 @@
ECC84C1D1B973C5900A5F451 /* quit_confirmation.cpp in Sources */,
B559A0160EC8FE2E008DD061 /* editor_main.cpp in Sources */,
6295C3C2150FC9750077D8C5 /* editor_map.cpp in Sources */,
46F92EE02174FD9900602C1C /* menu_style.cpp in Sources */,
ECF44F6A1FC8A82B00B404D6 /* make.cpp in Sources */,
6295C3D6150FC9EB0077D8C5 /* editor_palettes.cpp in Sources */,
46F92E7D2174F6A400602C1C /* label.cpp in Sources */,
@ -5764,7 +5746,6 @@
46F92DC52174F6A300602C1C /* modeless_dialog.cpp in Sources */,
46F92D9B2174F6A300602C1C /* depcheck_confirm_change.cpp in Sources */,
469BDB55205C357500DBF748 /* base64.cpp in Sources */,
46F92EE12174FD9900602C1C /* menu.cpp in Sources */,
B5599B250EC62181008DD061 /* minimap.cpp in Sources */,
4685124A24AE1535005B6EB1 /* game_config_view.cpp in Sources */,
46EEFB762087434300E1E75A /* chat_log.cpp in Sources */,
@ -6190,7 +6171,6 @@
46F92E522174F6A400602C1C /* widget.cpp in Sources */,
46F92DC82174F6A300602C1C /* end_credits.cpp in Sources */,
46F92DCC2174F6A300602C1C /* drop_down_menu.cpp in Sources */,
46F92EE42174FDA600602C1C /* menu.cpp in Sources */,
91E356691CACC6E000774252 /* mouse_events.cpp in Sources */,
91E3566A1CACC6E000774252 /* mouse_handler_base.cpp in Sources */,
91AF565C284D9251007A7652 /* walker_scrollbar_container.cpp in Sources */,
@ -6439,7 +6419,6 @@
91E357001CACC9B200774252 /* flg_manager.cpp in Sources */,
91E357011CACC9B200774252 /* mp_game_utils.cpp in Sources */,
91E357031CACC9B200774252 /* multiplayer.cpp in Sources */,
46F92EF32174FE5600602C1C /* show_dialog.cpp in Sources */,
46F92E142174F6A400602C1C /* player_list_helper.cpp in Sources */,
91E3570A1CACC9B200774252 /* playcampaign.cpp in Sources */,
46F92DBC2174F6A300602C1C /* file_dialog.cpp in Sources */,
@ -6670,7 +6649,6 @@
46F92DFE2174F6A400602C1C /* wml_error.cpp in Sources */,
9164077F1D3C381B0057C4DE /* chat_command_handler.cpp in Sources */,
9193FC7B1D5AE5B2004F6C07 /* name_generator_factory.cpp in Sources */,
46F92EE32174FDA600602C1C /* menu_style.cpp in Sources */,
9193FC7F1D5BB64F004F6C07 /* advancement.cpp in Sources */,
9193FC831D5C2D00004F6C07 /* lua_unit.cpp in Sources */,
9193FC871D5D7461004F6C07 /* lua_unit_attacks.cpp in Sources */,

View File

@ -41,7 +41,6 @@ pathfind/astarsearch.cpp
pathutils.cpp
quit_confirmation.cpp
reports.cpp
show_dialog.cpp
sound.cpp
sound_music_track.cpp
soundsource.cpp
@ -54,8 +53,6 @@ time_of_day.cpp
tooltips.cpp
video.cpp
widgets/button.cpp
widgets/menu.cpp
widgets/menu_style.cpp
widgets/scrollarea.cpp
widgets/scrollbar.cpp
widgets/textbox.cpp

View File

@ -24,7 +24,6 @@
#include "mouse_handler_base.hpp"
#include "preferences/preferences.hpp"
#include "scripting/plugins/context.hpp"
#include "show_dialog.hpp" //gui::in_dialog
#include "gui/core/event/handler.hpp" // gui2::is_in_dialog
#include "soundsource.hpp"
#include "gui/core/timer.hpp"
@ -97,7 +96,7 @@ void controller_base::long_touch_callback(int x, int y)
void controller_base::handle_event(const SDL_Event& event)
{
if(gui::in_dialog()) {
if(gui2::is_in_dialog()) {
return;
}

View File

@ -26,9 +26,11 @@
#include "draw_manager.hpp"
#include "fake_unit_manager.hpp"
#include "filesystem.hpp"
#include "floating_label.hpp"
#include "font/sdl_ttf_compat.hpp"
#include "font/text.hpp"
#include "global.hpp"
#include "gui/core/event/handler.hpp" // is_in_dialog
#include "preferences/preferences.hpp"
#include "halo.hpp"
#include "hotkey/command_executor.hpp"
@ -40,7 +42,6 @@
#include "play_controller.hpp" //note: this can probably be refactored out
#include "reports.hpp"
#include "resources.hpp"
#include "show_dialog.hpp"
#include "synced_context.hpp"
#include "team.hpp"
#include "terrain/builder.hpp"
@ -2345,7 +2346,7 @@ void display::queue_rerender()
}
}
if (!gui::in_dialog()) {
if(!gui2::is_in_dialog()) {
labels().recalculate_labels();
}

View File

@ -33,7 +33,6 @@
#include "help/help_impl.hpp" // for hidden_symbol, toplevel, etc
#include "key.hpp" // for CKey
#include "log.hpp" // for LOG_STREAM, log_domain
#include "show_dialog.hpp" // for dialog_frame, etc
#include "terrain/terrain.hpp" // for terrain_type
#include "units/unit.hpp" // for unit
#include "units/types.hpp" // for unit_type, unit_type_data, etc

View File

@ -1,375 +0,0 @@
/*
Copyright (C) 2003 - 2024
by David White <dave@whitevine.net>
Part of the Battle for Wesnoth Project https://www.wesnoth.org/
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 2 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.
See the COPYING file for more details.
*/
#define GETTEXT_DOMAIN "wesnoth-lib"
#include "show_dialog.hpp"
#include "draw.hpp"
#include "draw_manager.hpp"
#include "picture.hpp"
#include "gettext.hpp"
#include "gui/core/event/handler.hpp" // is_in_dialog
#include "log.hpp"
#include "font/sdl_ttf_compat.hpp"
#include "font/standard_colors.hpp"
#include "sdl/rect.hpp"
#include "sdl/input.hpp" // get_mouse_state
#include "video.hpp"
static lg::log_domain log_display("display");
#define ERR_DP LOG_STREAM(err, log_display)
#define WRN_DP LOG_STREAM(warn, log_display)
#define DBG_DP LOG_STREAM(debug, log_display)
#define ERR_G LOG_STREAM(err, lg::general)
namespace {
bool is_in_dialog = false;
}
namespace gui {
//static initialization
const int ButtonHPadding = 10;
const int ButtonVPadding = 10;
//note: style names are directly related to the panel image file names
const dialog_frame::style dialog_frame::default_style("opaque", 0);
const int dialog_frame::title_border_w = 10;
const int dialog_frame::title_border_h = 5;
bool in_dialog()
{
return is_in_dialog || gui2::is_in_dialog();
}
dialog_manager::dialog_manager() : cursor::setter(cursor::NORMAL), reset_to(is_in_dialog)
{
is_in_dialog = true;
}
dialog_manager::~dialog_manager()
{
is_in_dialog = reset_to;
int mousex, mousey;
sdl::get_mouse_state(&mousex, &mousey);
SDL_Event pb_event;
pb_event.type = SDL_MOUSEMOTION;
pb_event.motion.state = 0;
pb_event.motion.x = mousex;
pb_event.motion.y = mousey;
pb_event.motion.xrel = 0;
pb_event.motion.yrel = 0;
SDL_PushEvent(&pb_event);
}
dialog_frame::dialog_frame(const std::string& title,
const style& style,
std::vector<button*>* buttons, button* help_button) :
title_(title),
dialog_style_(style),
buttons_(buttons),
help_button_(help_button),
dim_(),
top_(image::get_texture("dialogs/" + dialog_style_.panel + "-border-top.png")),
bot_(image::get_texture("dialogs/" + dialog_style_.panel + "-border-bottom.png")),
left_(image::get_texture("dialogs/" + dialog_style_.panel + "-border-left.png")),
right_(image::get_texture("dialogs/" + dialog_style_.panel + "-border-right.png")),
top_left_(image::get_texture("dialogs/" + dialog_style_.panel + "-border-topleft.png")),
bot_left_(image::get_texture("dialogs/" + dialog_style_.panel + "-border-botleft.png")),
top_right_(image::get_texture("dialogs/" + dialog_style_.panel + "-border-topright.png")),
bot_right_(image::get_texture("dialogs/" + dialog_style_.panel + "-border-botright.png")),
bg_(image::get_texture("dialogs/" + dialog_style_.panel + "-background.png")),
have_border_(top_ && bot_ && left_ && right_),
dirty_(true)
{
// Raise buttons so they are drawn on top.
// and BTW buttons_ being a pointer to a vector is fucking insane
for (button* b : *buttons_) {
draw_manager::raise_drawable(b);
}
if (help_button) {
draw_manager::raise_drawable(help_button_);
}
}
dialog_frame::~dialog_frame()
{
draw_manager::invalidate_region(screen_location());
}
dialog_frame::dimension_measurements::dimension_measurements() :
interior(sdl::empty_rect), exterior(sdl::empty_rect), title(sdl::empty_rect), button_row(sdl::empty_rect)
{}
dialog_frame::dimension_measurements dialog_frame::layout(const SDL_Rect& rect)
{
return layout(rect.x, rect.y, rect.w, rect.h);
}
int dialog_frame::top_padding() const
{
int padding = 0;
if(have_border_) {
padding += top_.h();
}
if(!title_.empty()) {
padding += font::get_max_height(font::SIZE_TITLE) + 2*dialog_frame::title_border_h;
}
return padding;
}
void dialog_frame::set_dirty(bool dirty)
{
dirty_ = dirty;
}
int dialog_frame::bottom_padding() const {
int padding = 0;
if(buttons_ != nullptr) {
for(std::vector<button*>::const_iterator b = buttons_->begin(); b != buttons_->end(); ++b) {
padding = std::max<int>((**b).height() + ButtonVPadding, padding);
}
}
if(have_border_) {
padding += bot_.h();
}
return padding;
}
dialog_frame::dimension_measurements dialog_frame::layout(int x, int y, int w, int h) {
dim_ = dimension_measurements();
if(!title_.empty()) {
dim_.title = draw_title(false);
dim_.title.w += title_border_w;
}
if(buttons_ != nullptr) {
for(std::vector<button*>::const_iterator b = buttons_->begin(); b != buttons_->end(); ++b) {
dim_.button_row.w += (**b).width() + ButtonHPadding;
dim_.button_row.h = std::max<int>((**b).height() + ButtonVPadding,dim_.button_row.h);
}
dim_.button_row.x = -dim_.button_row.w;
dim_.button_row.y = y + h;
dim_.button_row.w += ButtonHPadding;
}
std::size_t buttons_width = dim_.button_row.w;
if(help_button_ != nullptr) {
buttons_width += help_button_->width() + ButtonHPadding*2;
dim_.button_row.y = y + h;
}
y -= dim_.title.h;
w = std::max(w, std::max(dim_.title.w, static_cast<int>(buttons_width)));
h += dim_.title.h + dim_.button_row.h;
dim_.button_row.x += x + w;
rect bounds = video::game_canvas();
if(have_border_) {
bounds.x += left_.w();
bounds.y += top_.h();
bounds.w -= left_.w();
bounds.h -= top_.h();
}
if(x < bounds.x) {
w += x;
x = bounds.x;
}
if(y < bounds.y) {
h += y;
y = bounds.y;
}
if(x > bounds.w) {
w = 0;
} else if(x + w > bounds.w) {
w = bounds.w - x;
}
if(y > bounds.h) {
h = 0;
} else if(y + h > bounds.h) {
h = bounds.h - y;
}
dim_.interior.x = x;
dim_.interior.y = y;
dim_.interior.w = w;
dim_.interior.h = h;
if(have_border_) {
dim_.exterior.x = dim_.interior.x - left_.w();
dim_.exterior.y = dim_.interior.y - top_.h();
dim_.exterior.w = dim_.interior.w + left_.w() + right_.w();
dim_.exterior.h = dim_.interior.h + top_.h() + bot_.h();
} else {
dim_.exterior = dim_.interior;
}
dim_.title.x = dim_.interior.x + title_border_w;
dim_.title.y = dim_.interior.y + title_border_h;
draw_manager::invalidate_region(dim_.exterior);
return dim_;
}
void dialog_frame::draw_border()
{
if(have_border_ == false) {
return;
}
// Too much typing is bad for you.
const SDL_Rect& i = dim_.interior;
const SDL_Rect& e = dim_.exterior;
if(top_) {
draw::blit(top_, {i.x, e.y, i.w, top_.h()});
}
if(bot_) {
draw::blit(bot_, {i.x, i.y + i.h, i.w, bot_.h()});
}
if(left_) {
draw::blit(left_, {e.x, i.y, left_.w(), i.h});
}
if(right_) {
draw::blit(right_, {i.x + i.w, i.y, right_.w(), i.h});
}
if(!top_left_ || !bot_left_ || !top_right_ || !bot_right_) {
return;
}
draw::blit(top_left_,
{i.x - left_.w(), i.y - top_.h(), top_left_.w(), top_left_.h()});
draw::blit(bot_left_, {
i.x - left_.w(),
i.y + i.h + bot_.h() - bot_left_.h(),
bot_left_.w(),
bot_left_.h()
});
draw::blit(top_right_, {
i.x + i.w + right_.w() - top_right_.w(),
i.y - top_.h(),
top_right_.w(),
top_right_.h(),
});
draw::blit(bot_right_, {
i.x + i.w + right_.w() - bot_right_.w(),
i.y + i.h + bot_.h() - bot_right_.h(),
bot_right_.w(),
bot_right_.h()
});
}
void dialog_frame::draw_background()
{
if (dialog_style_.blur_radius) {
// This is no longer used by anything.
// The only thing that uses dialog_frame is help/help.cpp,
// and it uses the default style with no blur.
ERR_DP << "GUI1 dialog_frame blur has been removed";
}
if (!bg_) {
ERR_DP << "could not find dialog background '" << dialog_style_.panel << "'";
return;
}
auto clipper = draw::reduce_clip(dim_.interior);
for(int i = 0; i < dim_.interior.w; i += bg_.w()) {
for(int j = 0; j < dim_.interior.h; j += bg_.h()) {
SDL_Rect src {0,0,0,0};
src.w = std::min(dim_.interior.w - i, bg_.w());
src.h = std::min(dim_.interior.h - j, bg_.h());
SDL_Rect dst = src;
dst.x = dim_.interior.x + i;
dst.y = dim_.interior.y + j;
draw::blit(bg_, dst);
}
}
}
rect dialog_frame::draw_title(bool actually_draw)
{
rect r = video::game_canvas();
return font::pango_draw_text(
actually_draw, r, font::SIZE_TITLE, font::TITLE_COLOR, title_,
dim_.title.x, dim_.title.y, false, font::pango_text::STYLE_NORMAL
);
}
void dialog_frame::draw()
{
//draw background
draw_background();
//draw frame border
draw_border();
//draw title
if (!title_.empty()) {
draw_title(true);
}
}
void dialog_frame::layout()
{
if (!dirty_) {
return;
}
// Layout buttons
SDL_Rect buttons_area = dim_.button_row;
if(buttons_ != nullptr) {
#ifdef OK_BUTTON_ON_RIGHT
std::reverse(buttons_->begin(),buttons_->end());
#endif
for(std::vector<button*>::const_iterator b = buttons_->begin(); b != buttons_->end(); ++b) {
(**b).set_location(buttons_area.x, buttons_area.y);
buttons_area.x += (**b).width() + ButtonHPadding;
}
}
// Layout help button, if any
if(help_button_ != nullptr) {
help_button_->set_location(dim_.interior.x+ButtonHPadding, buttons_area.y);
}
dirty_ = false;
}
bool dialog_frame::expose(const rect& region)
{
DBG_DP << "dialog_frame::expose " << region;
// Just draw everthing.
draw();
return true;
}
rect dialog_frame::screen_location()
{
return dim_.exterior;
}
}

View File

@ -1,115 +0,0 @@
/*
Copyright (C) 2003 - 2024
by David White <dave@whitevine.net>
Part of the Battle for Wesnoth Project https://www.wesnoth.org/
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 2 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.
See the COPYING file for more details.
*/
#pragma once
#include "cursor.hpp"
#include "floating_label.hpp"
#include "gui/core/top_level_drawable.hpp"
#include "widgets/button.hpp"
namespace gui
{
extern const int ButtonHPadding;
extern const int ButtonVPadding;
enum DIALOG_RESULT {
DIALOG_BACK=-7,
DIALOG_FORWARD=-6,
CREATE_ITEM =-5,
DELETE_ITEM=-4,
ESCAPE_DIALOG=-3, //special return used by WML event dialogs
CONTINUE_DIALOG=-2,
CLOSE_DIALOG=-1
/* results (0..N) reserved for standard button indices */
};
bool in_dialog();
struct dialog_manager : private cursor::setter, private font::floating_label_context {
dialog_manager();
~dialog_manager();
private:
bool reset_to;
};
class dialog_frame : public gui2::top_level_drawable {
public:
struct dimension_measurements {
dimension_measurements();
SDL_Rect interior, exterior, title, button_row;
};
class style {
public:
style(const std::string& p, int br) : panel(p), blur_radius(br) {}
std::string panel;
int blur_radius;
};
//Static members
static const int title_border_w, title_border_h;
static const style default_style;
dialog_frame(const std::string& title="",
const style& dialog_style=default_style,
std::vector<button*>* buttons=nullptr,
button* help_button=nullptr);
~dialog_frame();
dimension_measurements layout(int x, int y, int w, int h);
dimension_measurements layout(const SDL_Rect& frame_area);
void set_layout(dimension_measurements &new_dim) { dim_ = new_dim; }
dimension_measurements get_layout() const { return dim_; }
int top_padding() const;
int bottom_padding() const;
void draw();
/** Called by draw_manager to validate layout. */
virtual void layout() override;
/** Called by draw_manager when it believes a redraw is necessary. */
virtual bool expose(const rect& region) override;
/** The current draw location of the window, on the screen. */
virtual rect screen_location() override;
//called by draw
void draw_border();
void draw_background();
//also called by layout with null param
rect draw_title(bool actually_draw);
void set_dirty(bool dirty = true);
private:
void clear_background();
std::string title_;
const style& dialog_style_;
std::vector<button*>* buttons_;
button* help_button_;
bool auto_restore_;
dimension_measurements dim_;
texture top_, bot_, left_, right_, top_left_, bot_left_, top_right_, bot_right_, bg_;
bool have_border_;
bool dirty_;
};
}

View File

@ -24,7 +24,6 @@
#include "sdl/texture.hpp"
#include "sdl/utils.hpp"
#include "sdl/window.hpp"
#include "widgets/menu.hpp" // for bluebg_style.unload_images
#ifdef TARGET_OS_OSX
#include "desktop/apple_video.hpp"
@ -122,7 +121,6 @@ void deinit()
font::flush_texture_cache();
render_texture_.reset();
current_render_target_.reset();
gui::menu::bluebg_style.unload_images();
// Destroy the window, and thus also the renderer.
window.reset();

View File

@ -1,688 +0,0 @@
/*
Copyright (C) 2003 - 2024
by David White <dave@whitevine.net>
Part of the Battle for Wesnoth Project https://www.wesnoth.org/
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 2 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.
See the COPYING file for more details.
*/
#define GETTEXT_DOMAIN "wesnoth-lib"
#include "widgets/menu.hpp"
#include "draw.hpp"
#include "font/sdl_ttf_compat.hpp"
#include "font/standard_colors.hpp"
#include "game_config.hpp"
#include "language.hpp"
#include "picture.hpp"
#include "sdl/rect.hpp"
#include "sdl/texture.hpp"
#include "sound.hpp"
#include "video.hpp"
namespace {
/**
* For converting indented_menu_item.indent_level into a width in pixels.
* The text size might change, so instead of caching a value pango_line_size
* is called repeatedly with this as an argument.
*/
const std::string indent_string{" "};
};
namespace gui {
menu::menu(bool click_selects, int max_height, int max_width, style *menu_style, const bool auto_join)
: scrollarea(auto_join), silent_(false),
max_height_(max_height), max_width_(max_width),
max_items_(-1), item_height_(-1),
selected_(0), click_selects_(click_selects), out_(false),
previous_button_(true), show_result_(false),
double_clicked_(false),
num_selects_(true),
ignore_next_doubleclick_(false),
last_was_doubleclick_(false), use_ellipsis_(false)
{
style_ = (menu_style) ? menu_style : &default_style;
style_->init();
fill_items({});
}
menu::~menu()
{
}
void menu::fill_items(const std::vector<indented_menu_item>& items)
{
for(const auto& itor : items) {
const std::size_t id = items_.size();
item_pos_.push_back(id);
items_.emplace_back(itor, id);
}
update_size();
}
void menu::update_scrollbar_grip_height()
{
set_full_size(items_.size());
set_shown_size(max_items_onscreen());
}
void menu::update_size()
{
int h = 0;
for(std::size_t i = get_position(),
i_end = std::min(items_.size(), i + max_items_onscreen());
i < i_end; ++i)
h += get_item_rect(i).h;
h = std::max(h, height());
if (max_height_ > 0 && h > (max_height_)) {
h = max_height_;
}
use_ellipsis_ = false;
int w = widest_row_width();
if (items_.size() > max_items_onscreen())
w += scrollbar_width();
w = std::max(w, width());
if (max_width_ > 0 && w > (max_width_)) {
use_ellipsis_ = true;
w = max_width_;
}
update_scrollbar_grip_height();
set_measurements(w, h);
}
int menu::selection() const
{
if (selected_ >= items_.size()) {
return -1;
}
return items_[selected_].id;
}
void menu::set_inner_location(const SDL_Rect& /*rect*/)
{
itemRects_.clear();
update_scrollbar_grip_height();
}
void menu::set_items(const std::vector<indented_menu_item>& items, utils::optional<std::size_t> selected)
{
const bool scrolled_to_max = (has_scrollbar() && get_position() == get_max_position());
items_.clear();
item_pos_.clear();
itemRects_.clear();
widest_row_width_.reset();
//undrawn_items_.clear();
max_items_ = -1; // Force recalculation of the max items.
item_height_ = -1; // Force recalculation of the item height.
if(selected) {
selected_ = *selected;
} else {
selected_ = 0;
}
fill_items(items);
if(scrolled_to_max) {
set_position(get_max_position());
}
update_scrollbar_grip_height();
adjust_viewport_to_selection();
queue_redraw();
}
void menu::set_max_height(const int new_max_height)
{
max_height_ = new_max_height;
itemRects_.clear();
max_items_ = -1;
update_size();
}
void menu::set_max_width(const int new_max_width)
{
max_width_ = new_max_width;
itemRects_.clear();
widest_row_width_.reset();
update_size();
}
std::size_t menu::max_items_onscreen() const
{
if(max_items_ != -1) {
return std::size_t(max_items_);
}
const std::size_t max_height = (
max_height_ == -1
? (video::game_canvas_size().y * 66) / 100
: max_height_
);
std::vector<int> heights;
std::size_t n;
for(n = 0; n != items_.size(); ++n) {
// The for loop, sort and sum around this are unnecessary, because
// get_item_height has ignored its argument since Wesnoth 0.6.99.1.
// It caches and returns the height of the tallest item.
heights.push_back(get_item_height(n));
}
std::sort(heights.begin(),heights.end(),std::greater<int>());
std::size_t sum = 0;
for(n = 0; n != items_.size() && sum < max_height; ++n) {
sum += heights[n];
}
if(sum > max_height && n > 1)
--n;
return max_items_ = n;
}
void menu::adjust_viewport_to_selection()
{
if(click_selects_)
return;
adjust_position(selected_);
}
void menu::set_selection_pos(std::size_t new_selected, bool silent, SELECTION_MOVE_VIEWPORT move_viewport)
{
if (new_selected >= items_.size())
return;
bool changed = false;
if (new_selected != selected_) {
invalidate_row_pos(selected_);
invalidate_row_pos(new_selected);
selected_ = new_selected;
changed = true;
}
if(move_viewport == MOVE_VIEWPORT) {
adjust_viewport_to_selection();
if(!silent_ && !silent && changed) {
sound::play_UI_sound(game_config::sounds::menu_select);
}
}
}
void menu::move_selection_up(std::size_t dep)
{
set_selection_pos(selected_ > dep ? selected_ - dep : 0);
}
void menu::move_selection_down(std::size_t dep)
{
std::size_t nb_items = items_.size();
set_selection_pos(selected_ + dep >= nb_items ? nb_items - 1 : selected_ + dep);
}
// private function with control over sound and viewport
void menu::move_selection_to(std::size_t id, bool silent, SELECTION_MOVE_VIEWPORT move_viewport)
{
if(id < item_pos_.size()) {
set_selection_pos(item_pos_[id], silent, move_viewport);
}
}
// public function
void menu::move_selection(std::size_t id)
{
if(id < item_pos_.size()) {
set_selection_pos(item_pos_[id], true, MOVE_VIEWPORT);
}
}
// public function
void menu::move_selection_keeping_viewport(std::size_t id)
{
if(id < item_pos_.size()) {
set_selection_pos(item_pos_[id], true, NO_MOVE_VIEWPORT);
}
}
void menu::reset_selection()
{
set_selection_pos(0, true);
}
void menu::key_press(SDL_Keycode key)
{
if (!click_selects_) {
switch(key) {
case SDLK_UP:
move_selection_up(1);
break;
case SDLK_DOWN:
move_selection_down(1);
break;
case SDLK_PAGEUP:
move_selection_up(max_items_onscreen());
break;
case SDLK_PAGEDOWN:
move_selection_down(max_items_onscreen());
break;
case SDLK_HOME:
set_selection_pos(0);
break;
case SDLK_END:
set_selection_pos(items_.size() - 1);
break;
//case SDLK_RETURN:
// double_clicked_ = true;
// break;
default:
break;
}
}
if (num_selects_ && key >= SDLK_1 && key <= SDLK_9)
set_selection_pos(key - SDLK_1);
}
bool menu::requires_event_focus(const SDL_Event* event) const
{
if(!focus_ || height() == 0 || hidden()) {
return false;
}
if(event == nullptr) {
//when event is not specified, signal that focus may be desired later
return true;
}
if(event->type == SDL_KEYDOWN) {
SDL_Keycode key = event->key.keysym.sym;
if (!click_selects_) {
switch(key) {
case SDLK_UP:
case SDLK_DOWN:
case SDLK_PAGEUP:
case SDLK_PAGEDOWN:
case SDLK_HOME:
case SDLK_END:
return true;
default:
break;
}
}
if (num_selects_ && key >= SDLK_1 && key <= SDLK_9) {
return true;
}
}
//mouse events are processed regardless of focus
return false;
}
void menu::handle_event(const SDL_Event& event)
{
scrollarea::handle_event(event);
if (height()==0 || hidden())
return;
if(event.type == SDL_KEYDOWN) {
// Only pass key events if we have the focus
if (focus(&event))
key_press(event.key.keysym.sym);
} else if(!mouse_locked() && ((event.type == SDL_MOUSEBUTTONDOWN &&
(event.button.button == SDL_BUTTON_LEFT || event.button.button == SDL_BUTTON_RIGHT)) ||
event.type == DOUBLE_CLICK_EVENT)) {
int x = 0;
int y = 0;
if(event.type == SDL_MOUSEBUTTONDOWN) {
x = event.button.x;
y = event.button.y;
} else {
x = reinterpret_cast<std::size_t>(event.user.data1);
y = reinterpret_cast<std::size_t>(event.user.data2);
}
const int item = hit(x,y);
if(item != -1) {
set_focus(true);
move_selection_to(item);
if(click_selects_) {
show_result_ = true;
}
if(event.type == DOUBLE_CLICK_EVENT) {
if (ignore_next_doubleclick_) {
ignore_next_doubleclick_ = false;
} else {
double_clicked_ = true;
last_was_doubleclick_ = true;
if(!silent_) {
sound::play_UI_sound(game_config::sounds::button_press);
}
}
} else if (last_was_doubleclick_) {
// If we have a double click as the next event, it means
// this double click was generated from a click that
// already has helped in generating a double click.
SDL_Event ev;
SDL_PeepEvents(&ev, 1, SDL_PEEKEVENT, DOUBLE_CLICK_EVENT, DOUBLE_CLICK_EVENT);
if (ev.type == DOUBLE_CLICK_EVENT) {
ignore_next_doubleclick_ = true;
}
last_was_doubleclick_ = false;
}
}
} else if(!mouse_locked() && event.type == SDL_MOUSEMOTION) {
if(click_selects_) {
const int item = hit(event.motion.x,event.motion.y);
const bool out = (item == -1);
if (out_ != out) {
out_ = out;
invalidate_row_pos(selected_);
}
if (item != -1) {
move_selection_to(item);
}
}
}
}
int menu::process()
{
if(show_result_) {
show_result_ = false;
return selected_;
} else {
return -1;
}
}
bool menu::double_clicked()
{
bool old = double_clicked_;
double_clicked_ = false;
return old;
}
void menu::set_click_selects(bool value)
{
click_selects_ = value;
}
void menu::set_numeric_keypress_selection(bool value)
{
num_selects_ = value;
}
void menu::scroll(unsigned int)
{
itemRects_.clear();
queue_redraw();
}
SDL_Rect menu::style::item_size(const indented_menu_item& imi) const {
SDL_Rect res {0,0,0,0};
res.w = imi.indent_level * font::pango_line_size(indent_string, get_font_size()).first;
if (!imi.icon.empty()) {
// Not the first item, add the spacing.
res.w += 5;
const texture img = image::get_texture(imi.icon);
res.w += img.w();
res.h = std::max<int>(img.h(), res.h);
}
if (!imi.text.empty()) {
// Not the first item, add the spacing.
res.w += 5;
const SDL_Rect area {0,0,10000,10000};
const SDL_Rect font_size =
font::pango_draw_text(false, area, get_font_size(),
font::NORMAL_COLOR, imi.text, 0, 0);
res.w += font_size.w;
res.h = std::max<int>(font_size.h, res.h);
}
return res;
}
void menu::style::draw_row_bg(menu& /*menu_ref*/, const std::size_t /*row_index*/, const SDL_Rect& rect, ROW_TYPE type)
{
int rgb = 0;
double alpha = 0.0;
switch(type) {
case NORMAL_ROW:
rgb = normal_rgb_;
alpha = normal_alpha_;
break;
case SELECTED_ROW:
rgb = selected_rgb_;
alpha = selected_alpha_;
break;
}
// FIXME: make this clearer
color_t c((rgb & 0xff0000) >> 16, (rgb & 0xff00) >> 8, rgb & 0xff);
c.a = 255 * alpha;
draw::fill(rect, c);
}
void menu::style::draw_row(menu& menu_ref, const std::size_t row_index, const SDL_Rect& rect, ROW_TYPE type)
{
if(rect.w == 0 || rect.h == 0) {
return;
}
draw_row_bg(menu_ref, row_index, rect, type);
SDL_Rect minirect = rect;
minirect.x += thickness_;
minirect.y += thickness_;
minirect.w -= 2*thickness_;
minirect.h -= 2*thickness_;
menu_ref.draw_row(row_index, minirect, type);
}
int menu::widest_row_width() const
{
if(!widest_row_width_) {
int widest = 0;
for(const auto& row : items_) {
const SDL_Rect size = style_->item_size(row.fields);
widest = std::max(widest, size.w);
}
// Assume there's text at the end of the item, and add padding accordingly.
widest_row_width_ = static_cast<int>(widest + style_->get_cell_padding());
}
return *widest_row_width_;
}
bool menu::hit_on_indent_or_icon(std::size_t row_index, int x) const
{
if(row_index >= items_.size()) {
return false;
}
// The virtual method item_size() is overloaded by imgsel_style::item_size(),
// which adds borders on both sides. Call it twice and remove one side's padding.
const auto& imi = items_[row_index].fields;
int width_used_so_far = style_->item_size({imi.indent_level, imi.icon, ""}).w;
width_used_so_far -= style_->item_size({0, "", ""}).w / 2;
const SDL_Rect& loc = inner_location();
if (current_language_rtl()) {
// inner_location() already takes account of the scrollbar width
return x > loc.x + loc.w - width_used_so_far;
}
return x < loc.x + width_used_so_far;
}
void menu::draw_row(const std::size_t row_index, const SDL_Rect& loc, ROW_TYPE)
{
//called from style, draws one row's contents in a generic and adaptable way
const auto& imi = items_[row_index].fields;
rect area = video::game_canvas();
bool lang_rtl = current_language_rtl();
// There's nothing to draw for the indent, just mark the space as used
int width_used_so_far = imi.indent_level * font::pango_line_size(indent_string, style_->get_font_size()).first;
if (!imi.icon.empty()) {
const texture img = image::get_texture(imi.icon);
int img_w = img.w();
int img_h = img.h();
const int remaining_width = max_width_ < 0 ? area.w : std::min<int>(max_width_, loc.w - width_used_so_far);
if(img && img_w <= remaining_width && loc.y + img_h < area.h) {
const std::size_t y = loc.y + (loc.h - img_h)/2;
const std::size_t x = loc.x + (lang_rtl ? loc.w - width_used_so_far - img_w : width_used_so_far);
draw::blit(img, {int(x), int(y), img_w, img_h});
// If there wasn't space for the icon, it doesn't get drawn, nor does the width get used.
// If it is drawn, add 5 pixels of padding.
width_used_so_far += img_w + 5;
}
}
// Expected to be non-empty, but I guess a unit type could have a blank name
if (!imi.text.empty()) {
const auto text_size = font::pango_line_size(imi.text, style_->get_font_size());
const std::size_t x = loc.x + (lang_rtl ? std::max(0, loc.w - width_used_so_far - text_size.first) : width_used_so_far);
const std::size_t y = loc.y + (loc.h - text_size.second)/2;
rect text_loc = loc;
text_loc.w = loc.w - (width_used_so_far) - 2 * style_->get_thickness();
text_loc.h = text_size.second;
font::pango_draw_text(true, text_loc, style_->get_font_size(), font::NORMAL_COLOR, imi.text,
x, y);
}
}
void menu::draw_contents()
{
for(std::size_t i = 0; i != item_pos_.size(); ++i) {
style_->draw_row(*this,item_pos_[i],get_item_rect(i),
(!out_ && item_pos_[i] == selected_) ? SELECTED_ROW : NORMAL_ROW);
}
}
int menu::hit(int x, int y) const
{
const SDL_Rect& loc = inner_location();
if (x >= loc.x && x < loc.x + loc.w && y >= loc.y && y < loc.y + loc.h) {
for(std::size_t i = 0; i != items_.size(); ++i) {
const SDL_Rect& rect = get_item_rect(i);
if (y >= rect.y && y < rect.y + rect.h)
return i;
}
}
return -1;
}
SDL_Rect menu::get_item_rect(int item) const
{
return get_item_rect_internal(item_pos_[item]);
}
SDL_Rect menu::get_item_rect_internal(std::size_t item) const
{
unsigned int first_item_on_screen = get_position();
if (item < first_item_on_screen ||
item >= first_item_on_screen + max_items_onscreen()) {
return sdl::empty_rect;
}
const std::map<int,SDL_Rect>::const_iterator i = itemRects_.find(item);
if(i != itemRects_.end())
return i->second;
const SDL_Rect& loc = inner_location();
int y = loc.y;
if (item != first_item_on_screen) {
const SDL_Rect& prev = get_item_rect_internal(item-1);
y = prev.y + prev.h;
}
rect res(loc.x, y, loc.w, get_item_height(item));
const point canvas_size = video::game_canvas_size();
if(res.x > canvas_size.x) {
return sdl::empty_rect;
} else if(res.x + res.w > canvas_size.x) {
res.w = canvas_size.x - res.x;
}
if(res.y > canvas_size.y) {
return sdl::empty_rect;
} else if(res.y + res.h > canvas_size.y) {
res.h = canvas_size.y - res.y;
}
//only insert into the cache if the menu's co-ordinates have
//been initialized
if (loc.x > 0 && loc.y > 0)
itemRects_.emplace(item, res);
return res;
}
std::size_t menu::get_item_height_internal(const indented_menu_item& imi) const
{
return style_->item_size(imi).h;
}
std::size_t menu::get_item_height(int) const
{
// This could probably return the height of a single line of Pango text, plus
// padding. However, keeping compatibility with the current numbers means
// less unknowns about what the numbers should actually be.
if(item_height_ != -1)
return std::size_t(item_height_);
std::size_t max_height = 0;
for(const auto& item : items_) {
max_height = std::max<int>(max_height,get_item_height_internal(item.fields));
}
return item_height_ = max_height;
}
void menu::invalidate_row(std::size_t id)
{
if(id >= items_.size()) {
return;
}
queue_redraw(get_item_rect(id));
}
void menu::invalidate_row_pos(std::size_t pos)
{
if(pos >= items_.size()) {
return;
}
invalidate_row(items_[pos].id);
}
}

View File

@ -1,260 +0,0 @@
/*
Copyright (C) 2003 - 2024
by David White <dave@whitevine.net>
Part of the Battle for Wesnoth Project https://www.wesnoth.org/
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 2 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.
See the COPYING file for more details.
*/
#pragma once
#include "utils/optional_fwd.hpp"
#include <map>
#include <set>
#include "scrollarea.hpp"
namespace gui {
/**
* The only kind of row still supported by the menu class.
*
* If comparing to 1.17.24 or before, these three items were held as a single string, thus a single member
* of the "fields" and a single "column" of the multi-column support.
*/
struct indented_menu_item
{
/** An amount of blank space at the start of the row, measured in tab-stops (so 1 is around 4 en-widths) */
int indent_level;
/** If non-empty, a picture to display before the text */
std::string icon;
std::string text;
};
/**
* Superclass of the help_menu, which displays the left-hand pane of the GUI1 help browser.
* Historically a more generic class, but now only used for that singular purpose.
*/
class menu : public scrollarea
{
public:
enum ROW_TYPE { NORMAL_ROW, SELECTED_ROW };
//basic menu style
class style
{
public:
style();
virtual ~style();
virtual void init() {}
virtual SDL_Rect item_size(const indented_menu_item& imi) const;
virtual void draw_row_bg(menu& menu_ref, const std::size_t row_index, const SDL_Rect& rect, ROW_TYPE type);
virtual void draw_row(menu& menu_ref, const std::size_t row_index, const SDL_Rect& rect, ROW_TYPE type);
std::size_t get_font_size() const;
std::size_t get_cell_padding() const;
std::size_t get_thickness() const;
protected:
std::size_t font_size_;
std::size_t cell_padding_;
std::size_t thickness_; //additional cell padding for style use only
int normal_rgb_, selected_rgb_;
double normal_alpha_, selected_alpha_;
};
//image-border selection style
class imgsel_style : public style
{
public:
imgsel_style(const std::string &img_base, bool has_bg,
int normal_rgb, int selected_rgb,
double normal_alpha, double selected_alpha);
virtual ~imgsel_style();
virtual SDL_Rect item_size(const indented_menu_item& imi) const;
virtual void draw_row_bg(menu& menu_ref, const std::size_t row_index, const SDL_Rect& rect, ROW_TYPE type);
virtual void draw_row(menu& menu_ref, const std::size_t row_index, const SDL_Rect& rect, ROW_TYPE type);
virtual void init() { load_images(); }
bool load_images();
void unload_images();
protected:
const std::string img_base_;
std::map<std::string,texture> img_map_;
private:
bool load_image(const std::string &img_sub);
bool has_background_;
bool initialized_;
bool load_failed_;
int normal_rgb2_, selected_rgb2_;
double normal_alpha2_, selected_alpha2_;
};
friend class style;
friend class imgsel_style;
static style &default_style;
static imgsel_style bluebg_style;
struct item
{
item(const indented_menu_item& fields, std::size_t id)
: fields(fields), id(id)
{}
indented_menu_item fields;
std::size_t id;
};
menu(
bool click_selects=false, int max_height=-1, int max_width=-1,
style *menu_style=nullptr, const bool auto_join=true);
/** Default implementation, but defined out-of-line for efficiency reasons. */
~menu();
int selection() const;
void move_selection(std::size_t id);
void move_selection_keeping_viewport(std::size_t id);
void reset_selection();
/**
* Set new items to show and redraw/recalculate everything. The menu tries
* to keep the selection at the same position as it were before the items
* were set.
*/
virtual void set_items(const std::vector<indented_menu_item>& items, utils::optional<std::size_t> selected);
/**
* Set a new max height for this menu. Note that this does not take
* effect immediately, only after certain operations that clear
* everything, such as set_items().
*/
void set_max_height(const int new_max_height);
void set_max_width(const int new_max_width);
int get_max_height() const { return max_height_; }
int get_max_width() const { return max_width_; }
std::size_t number_of_items() const { return items_.size(); }
int process();
bool double_clicked();
void set_click_selects(bool value);
void set_numeric_keypress_selection(bool value);
// scrollarea override
void scroll(unsigned int pos) override;
protected:
virtual void handle_event(const SDL_Event& event) override;
void set_inner_location(const SDL_Rect& rect) override;
bool requires_event_focus(const SDL_Event *event=nullptr) const override;
int widest_row_width() const;
virtual void draw_row(const std::size_t row_index, const SDL_Rect& rect, ROW_TYPE type);
style *style_;
bool silent_;
int hit(int x, int y) const;
/**
* Returns true if a mouse-click with the given x-coordinate, and an
* appropriate y-coordinate would lie within the indent or icon part of
* the given row.
*
* The unusual combination of arguments fit with this being called when
* handling a mouse event, where we already know which row was selected,
* and are just inquiring a bit more about the details of that row.
*/
bool hit_on_indent_or_icon(std::size_t row_index, int x) const;
void invalidate_row(std::size_t id);
void invalidate_row_pos(std::size_t pos);
private:
std::size_t max_items_onscreen() const;
int max_height_, max_width_;
mutable int max_items_, item_height_;
void adjust_viewport_to_selection();
void key_press(SDL_Keycode key);
std::vector<item> items_;
std::vector<std::size_t> item_pos_;
/**
* Cached return value of widest_row_width(), calculated on demand when calling that function.
*/
mutable utils::optional<int> widest_row_width_;
std::size_t selected_;
bool click_selects_;
bool out_;
bool previous_button_;
//std::set<std::size_t> undrawn_items_;
bool show_result_;
bool double_clicked_;
void draw_contents() override;
mutable std::map<int,SDL_Rect> itemRects_;
SDL_Rect get_item_rect(int item) const;
SDL_Rect get_item_rect_internal(std::size_t pos) const;
std::size_t get_item_height_internal(const indented_menu_item& imi) const;
std::size_t get_item_height(int item) const;
int items_start() const;
int items_end() const;
int items_height() const;
void update_scrollbar_grip_height();
/**
* variable which determines whether a numeric keypress should
* select an item on the dialog
*/
bool num_selects_;
// These two variables are used to get the correct double click
// behavior so that a click that causes one double click won't be
// counted as a first click in the "next" double click.
bool ignore_next_doubleclick_;
bool last_was_doubleclick_;
//ellipsis calculation is slightly off, so default to false
bool use_ellipsis_;
/**
* Set new items to show.
*/
void fill_items(const std::vector<indented_menu_item>& imi);
void update_size();
enum SELECTION_MOVE_VIEWPORT { MOVE_VIEWPORT, NO_MOVE_VIEWPORT };
void set_selection_pos(std::size_t pos, bool silent=false, SELECTION_MOVE_VIEWPORT move_viewport=MOVE_VIEWPORT);
void move_selection_to(std::size_t id, bool silent=false, SELECTION_MOVE_VIEWPORT move_viewport=MOVE_VIEWPORT);
void move_selection_up(std::size_t dep);
void move_selection_down(std::size_t dep);
std::set<int> invalid_;
};
}

View File

@ -1,224 +0,0 @@
/*
Copyright (C) 2006 - 2024
by Patrick Parker <patrick_x99@hotmail.com>
Copyright (C) 2003 - 2005 by David White <dave@whitevine.net>
Part of the Battle for Wesnoth Project https://www.wesnoth.org/
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 2 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.
See the COPYING file for more details.
*/
#define GETTEXT_DOMAIN "wesnoth-lib"
#include "widgets/menu.hpp"
#include "draw.hpp"
#include "font/constants.hpp"
#include "picture.hpp"
namespace gui {
//static initializations
menu::imgsel_style menu::bluebg_style("dialogs/selection", true,
0x000000, 0x000000,
0.35, 0.0);
menu::style &menu::default_style = menu::bluebg_style;
//constructors
menu::style::style() : font_size_(font::SIZE_NORMAL),
cell_padding_(font::SIZE_NORMAL * 3/5), thickness_(0),
normal_rgb_(0x000000), selected_rgb_(0x000099),
normal_alpha_(0.2), selected_alpha_(0.6)
{}
menu::style::~style()
{}
menu::imgsel_style::imgsel_style(const std::string &img_base, bool has_bg,
int normal_rgb, int selected_rgb,
double normal_alpha, double selected_alpha)
: img_base_(img_base), has_background_(has_bg), initialized_(false), load_failed_(false),
normal_rgb2_(normal_rgb), selected_rgb2_(selected_rgb),
normal_alpha2_(normal_alpha), selected_alpha2_(selected_alpha)
{}
menu::imgsel_style::~imgsel_style()
{}
std::size_t menu::style::get_font_size() const { return font_size_; }
std::size_t menu::style::get_cell_padding() const { return cell_padding_; }
std::size_t menu::style::get_thickness() const { return thickness_; }
bool menu::imgsel_style::load_image(const std::string &img_sub)
{
std::string path = img_base_ + "-" + img_sub + ".png";
const texture image = image::get_texture(path);
img_map_[img_sub] = image;
return bool(image);
}
bool menu::imgsel_style::load_images()
{
if(!initialized_)
{
if( load_image("border-botleft")
&& load_image("border-botright")
&& load_image("border-topleft")
&& load_image("border-topright")
&& load_image("border-left")
&& load_image("border-right")
&& load_image("border-top")
&& load_image("border-bottom") )
{
thickness_ = std::min(
img_map_["border-top"].h(),
img_map_["border-left"].w());
if(has_background_ && !load_image("background"))
{
load_failed_ = true;
}
else
{
normal_rgb_ = normal_rgb2_;
normal_alpha_ = normal_alpha2_;
selected_rgb_ = selected_rgb2_;
selected_alpha_ = selected_alpha2_;
load_failed_ = false;
}
initialized_ = true;
}
else
{
thickness_ = 0;
initialized_ = true;
load_failed_ = true;
}
}
return (!load_failed_);
}
void menu::imgsel_style::unload_images()
{
img_map_.clear();
}
void menu::imgsel_style::draw_row_bg(menu& menu_ref, const std::size_t row_index, const SDL_Rect& rect, ROW_TYPE type)
{
if(type == SELECTED_ROW && has_background_ && !load_failed_) {
draw::blit(img_map_["background"], rect);
}
else {
style::draw_row_bg(menu_ref, row_index, rect, type);
}
}
void menu::imgsel_style::draw_row(menu& menu_ref, const std::size_t row_index, const SDL_Rect& rect, ROW_TYPE type)
{
if(!load_failed_) {
//draw item inside
style::draw_row(menu_ref, row_index, rect, type);
if(type == SELECTED_ROW) {
// draw border
texture image;
SDL_Rect area;
auto clipper = draw::reduce_clip(rect);
area.x = rect.x;
area.y = rect.y;
image = img_map_["border-top"];
area.x = rect.x;
area.y = rect.y;
area.w = image.w();
area.h = image.h();
do {
draw::blit(image, area);
area.x += area.w;
} while( area.x < rect.x + rect.w );
image = img_map_["border-left"];
area.x = rect.x;
area.y = rect.y;
area.w = image.w();
area.h = image.h();
do {
draw::blit(image, area);
area.y += area.h;
} while( area.y < rect.y + rect.h );
image = img_map_["border-right"];
area.x = rect.x + rect.w - thickness_;
area.y = rect.y;
area.w = image.w();
area.h = image.h();
do {
draw::blit(image, area);
area.y += area.h;
} while( area.y < rect.y + rect.h );
image = img_map_["border-bottom"];
area.x = rect.x;
area.y = rect.y + rect.h - thickness_;
area.w = image.w();
area.h = image.h();
do {
draw::blit(image, area);
area.x += area.w;
} while( area.x < rect.x + rect.w );
image = img_map_["border-topleft"];
area.x = rect.x;
area.y = rect.y;
area.w = image.w();
area.h = image.h();
draw::blit(image, area);
image = img_map_["border-topright"];
area.x = rect.x + rect.w - image.w();
area.y = rect.y;
area.w = image.w();
area.h = image.h();
draw::blit(image, area);
image = img_map_["border-botleft"];
area.x = rect.x;
area.y = rect.y + rect.h - image.h();
area.w = image.w();
area.h = image.h();
draw::blit(image, area);
image = img_map_["border-botright"];
area.x = rect.x + rect.w - image.w();
area.y = rect.y + rect.h - image.h();
area.w = image.w();
area.h = image.h();
draw::blit(image, area);
}
}
else {
//default drawing
style::draw_row(menu_ref, row_index, rect, type);
}
}
SDL_Rect menu::imgsel_style::item_size(const indented_menu_item& imi) const
{
SDL_Rect bounds = style::item_size(imi);
bounds.w += 2 * thickness_;
bounds.h += 2 * thickness_ + 4;
return bounds;
}
} //namesapce gui