mirror of
https://github.com/wesnoth/wesnoth
synced 2025-04-17 10:46:20 +00:00
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:
parent
53cb294b4e
commit
1261d88b15
|
@ -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 */,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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_;
|
||||
};
|
||||
|
||||
}
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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_;
|
||||
};
|
||||
|
||||
}
|
|
@ -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
|
Loading…
Reference in New Issue
Block a user