Story screen redesign (#8510)

This commit is contained in:
Subhraman Sarkar 2024-05-24 19:29:46 +05:30 committed by GitHub
parent 2591899723
commit 9b38089db0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
17 changed files with 476 additions and 90 deletions

View file

@ -0,0 +1,2 @@
### User interface
* Redesigned story screen layout with new graphics

View file

@ -18269,6 +18269,7 @@ Date,File,License,Author - Real Name(other name);Real Name(other name);etc,Notes
2019/01/01,images/misc/bar-energy.png,GNU GPL v2+,Emilien Rotival(LordBob),,,d0534f89f08daaa95b42b25bde4fcbde
2011/03/27,images/misc/blank.png,GNU GPL v2+,Cédric Duval,,,7bf2e878f822ab30304cf309e1a97ea1
2011/06/15,images/misc/capture.png,GNU GPL v2+,Richard Kettering(Jetrel),,,619d047b726856ce4a1b74d3212d259d
2024/04/17,images/misc/dots.png,GNU GPL v2+,Subhraman Sarkar(babaissarkar),,,d025787cb7e81d6572ec4f877b3aeee8
2011/03/11,images/misc/ellipse-1.png,GNU GPL v2+,Jordà Polo(ettin);Lari Nieminen(zookeeper),,,0e69fc97ba9cf9ea6809f0ee445500f2
2011/03/11,images/misc/ellipse-bottom.png,GNU GPL v2+,Jordà Polo(ettin);Lari Nieminen(zookeeper),,,bdd155ee1f163ce620c4a9a26ba51390
2012/11/04,images/misc/ellipse-hero-bottom.png,GNU GPL v2+,J.W. Bjerk(Eleazar);(Elvish_Hunter),,,89716afccc95826038d426dbba09e514
@ -18371,6 +18372,8 @@ Date,File,License,Author - Real Name(other name);Real Name(other name);etc,Notes
2021/01/12,images/misc/orb-two-color.png,GNU GPL v2+,Emilien Rotival(LordBob);Steve Cotton(octalot),,,379fad15afff70ca547ead3ea8726f33
2014/03/02,images/misc/orb.png,GNU GPL v2+,Emilien Rotival(LordBob),,,3dab3f94bd36bda49ea7750e2efdaeba
2014/03/02,images/misc/orb@2x.png,GNU GPL v2+,Emilien Rotival(LordBob),,,85903aa2cdf599b19647f23a67d59b59
2024/04/17,images/misc/ornate_big_arrow_decor_left.png,GNU GPL v2+,Subhraman Sarkar(babaissarkar),,,bdf3b58ef68f6e06a418302235493bbe
2024/04/17,images/misc/ornate_big_arrow_decor_right.png,GNU GPL v2+,Subhraman Sarkar(babaissarkar),,,1bb499958610315f5d449978050fc42e
2024/02/02,images/misc/petrified.png,GNU GPL v2+,Hogne Håskjold(frame/freim),,,127ac3340eeb1a91bc997aa21ddf632d
2024/02/02,images/misc/poisoned.png,GNU GPL v2+,(Maester Pixel),,,c73e8d2ccc0da40c9a87dc5c8bf6f5d2
2011/06/15,images/misc/shuffle-sides.png,GNU GPL v2+,Lukasz Dobrogowski,,,89a681be2bcaf93d4643b2cdd159867f

Can't render this file because it is too large.

View file

@ -458,7 +458,7 @@
{_GUI_DEFINITION
"preview"
"Preview button."
"Preview button"
"buttons/button_square/button_square_25"
"icons/action/zoomdefault_25"
()

View file

@ -0,0 +1,333 @@
#textdomain wesnoth-lib
## Specialized buttons definitions used in the story screen
# Modified version of _GUI_RESOLUTION_MINIMAL that uses
# the original size of the image
#define _GUI_RESOLUTION_ORIGINAL_SIZE RESOLUTION IMAGE
[resolution]
{RESOLUTION}
min_width = 0
min_height = 0
default_width = 128
default_height = 128
max_width = 0
max_height = 0
[state_enabled]
[draw]
[image]
name = {IMAGE} + ".png"
[/image]
[/draw]
[/state_enabled]
[state_disabled]
[draw]
[image]
name = {IMAGE} + ".png~GS()"
[/image]
[/draw]
[/state_disabled]
[state_pressed]
[draw]
[image]
name = {IMAGE} + ".png~BLEND(255,63,0,0.7)"
[/image]
[/draw]
[/state_pressed]
[state_focused]
[draw]
[image]
name = {IMAGE} + ".png~BLEND(255,255,0,0.2)"
[/image]
[/draw]
[/state_focused]
[/resolution]
#enddef
# Modified version of _GUI_DEFINITION_MINIMAL that uses
# the original size of the image
#define _GUI_DEFINITION_ORIGINAL_SIZE ID DESCRIPTION IMAGE
[button_definition]
id = {ID}
description = {DESCRIPTION}
{_GUI_RESOLUTION_ORIGINAL_SIZE () ({IMAGE})}
[/button_definition]
#enddef
### Text helper macro, from button_default.cfg
#define _GUI_BUTTON_TEXT DX DY FONT_SIZE FONT_STYLE FONT_COLOR FONT_FAMILY
[text]
# relative positioning of text so that it doesn't overlap with the preceding image
x = {DX}
y = {DY}
w = "(text_width)"
h = "(text_height)"
font_size = {FONT_SIZE}
font_style = {FONT_STYLE}
font_family = {FONT_FAMILY}
color = "{FONT_COLOR},200"
text = "(text)"
text_markup = "(text_markup)"
outline = true
actions = "( set_var('tw', text_width) )"
[/text]
#enddef
#define _GUI_BUTTON_TEXT_ONLY FONT_SIZE FONT_STYLE FONT_COLOR
[text]
# relative positioning of text so that it doesn't overlap with the preceding image
x = "(width-text_width)"
y = {GUI__TEXT_VERTICALLY_CENTRED}
w = "(text_width)"
h = "(text_height)"
font_size = {FONT_SIZE}
font_style = {FONT_STYLE}
font_family = script
color = {FONT_COLOR}
text = "(text)"
text_markup = true
outline = true
actions = "([set_var('tw', text_width), set_var('th', text_height)])"
[/text]
#enddef
# Modified version of _GUI_DEFINITION_MINIMAL that
# shows header text with decorations
# to the left and right side. Used in story_viewer.
# Uses BLEND to generate active/clicked versions
# of the images used on-the-fly.
#define _GUI_RESOLUTION_HEADER RESOLUTION ACTIVE_TINT PRESS_TINT
[resolution]
{RESOLUTION}
min_width = 128
min_height = 32
default_width = 250
default_height = 32
max_width = 0
max_height = 0
[state_enabled]
[draw]
[image]
x = 0
y = "(max((height - image_height - 2) / 2, 0))"
name = "misc/dots.png"
actions = "( [set_var('iw', image_width), set_var('iy', clip_y)] )"
[/image]
{_GUI_BUTTON_TEXT "(iw+5)" "(iy)" 20 () ("215, 215, 215") ()}
[image]
x = "(iw + tw + 10)"
y = "(max((height - image_height - 2) / 2, 0))"
name = "misc/dots.png~FL()"
[/image]
[/draw]
[/state_enabled]
[state_disabled]
[draw]
[image]
x = 0
y = "(max((height - image_height - 2) / 2, 0))"
name = "misc/dots.png"
actions = "( [set_var('iw', image_width), set_var('iy', clip_y)] )"
[/image]
{_GUI_BUTTON_TEXT "(iw+5)" "(iy)" 20 () ("128, 128, 128") ()}
[image]
x = "(iw + tw + 10)"
y = "(max((height - image_height - 2) / 2, 0))"
name = "misc/dots.png~FL()"
[/image]
[/draw]
[/state_disabled]
[state_pressed]
[draw]
[image]
x = 0
y = "(max((height - image_height - 2) / 2, 0))"
name = "misc/dots.png~BLEND({PRESS_TINT},0.7)"
actions = "( [set_var('iw', image_width), set_var('iy', clip_y)] )"
[/image]
{_GUI_BUTTON_TEXT "(iw+5)" "(iy)" 20 () ({PRESS_TINT}) ()}
[image]
x = "(iw + tw + 10)"
y = "(max((height - image_height - 2) / 2, 0))"
name = "misc/dots.png~FL()~BLEND({PRESS_TINT},0.7)"
[/image]
[/draw]
[/state_pressed]
[state_focused]
[draw]
[image]
x = 0
y = "(max((height - image_height - 2) / 2, 0))"
name = "misc/dots.png~BLEND({ACTIVE_TINT},0.4)"
actions = "( [set_var('iw', image_width), set_var('iy', clip_y)] )"
[/image]
{_GUI_BUTTON_TEXT "(iw+5)" "(iy)" 20 () ({ACTIVE_TINT}) ()}
[image]
x = "(iw + tw + 10)"
y = "(max((height - image_height - 2) / 2, 0))"
name = "misc/dots.png~FL()~BLEND({ACTIVE_TINT},0.4)"
[/image]
[/draw]
[/state_focused]
[/resolution]
#enddef
#define _GUI_RESOLUTION_TEXT_ONLY RESOLUTION ACTIVE_TINT PRESS_TINT
[resolution]
{RESOLUTION}
min_width = 128
min_height = 32
default_width = 250
default_height = 32
max_width = 0
max_height = 0
[state_enabled]
[draw]
{_GUI_BUTTON_TEXT_ONLY 22 ("italic") ("255, 255, 255, 255")}
[/draw]
[/state_enabled]
[state_disabled]
[draw]
{_GUI_BUTTON_TEXT_ONLY 22 ("italic") ("128, 128, 128, 255")}
[/draw]
[/state_disabled]
[state_pressed]
[draw]
{_GUI_BUTTON_TEXT_ONLY 22 ("italic") ("{PRESS_TINT},200")}
[/draw]
[/state_pressed]
[state_focused]
[draw]
{_GUI_BUTTON_TEXT_ONLY 22 ("italic") ("{ACTIVE_TINT},200")}
[/draw]
[/state_focused]
[/resolution]
#enddef
#define _GUI_DEFINITION_HEADER ID DESCRIPTION ACTIVE_TINT PRESS_TINT
[button_definition]
id = {ID}
description = {DESCRIPTION}
{_GUI_RESOLUTION_HEADER () ({ACTIVE_TINT}) ({PRESS_TINT})}
[/button_definition]
#enddef
#define _GUI_DEFINITION_TEXT_ONLY ID DESCRIPTION ACTIVE_TINT PRESS_TINT
[button_definition]
id = {ID}
description = {DESCRIPTION}
{_GUI_RESOLUTION_TEXT_ONLY () ({ACTIVE_TINT}) ({PRESS_TINT})}
[/button_definition]
#enddef
# Big decorated buttons for story screen
{_GUI_DEFINITION_ORIGINAL_SIZE
"right_arrow_story"
"Big right ornate arrow for story"
"misc/ornate_big_arrow_decor_right"
}
{_GUI_DEFINITION_ORIGINAL_SIZE
"left_arrow_story"
"Big right ornate arrow for story"
"misc/ornate_big_arrow_decor_left"
}
{_GUI_DEFINITION_HEADER
"header_story_skip"
"Header with decorations for story, skip button"
"150,0,0"
"200,0,0"
}
{_GUI_DEFINITION_TEXT_ONLY
"story_text"
"text only skip button"
"255,100,100"
"200,0,0"
}
#undef _GUI_DEFINITION_ORIGINAL_SIZE
#undef _GUI_DEFINITION_HEADER
#undef _GUI_RESOLUTION_ORIGINAL_SIZE
#under _GUI_RESOLUTION_HEADER
#undef _GUI_BUTTON_TEXT

View file

@ -105,10 +105,10 @@
[/label_definition]
#enddef
{_GUI_DEFINITION "default" "default label" () DEFAULT () DEFAULT }
{_GUI_DEFINITION "default_bold" "default label, bold font" () DEFAULT "bold" DEFAULT }
{_GUI_DEFINITION "default_italic" "default label, italic font" () DEFAULT "italic" DEFAULT }
{_GUI_DEFINITION "title" "label used for titles" () TITLE () TITLE }
{_GUI_DEFINITION "default" "default label" () DEFAULT () DEFAULT }
{_GUI_DEFINITION "default_bold" "default label, bold font" () DEFAULT "bold" DEFAULT }
{_GUI_DEFINITION "default_italic" "default label, italic font" () DEFAULT "italic" DEFAULT }
{_GUI_DEFINITION "title" "label used for titles" () TITLE () TITLE }
{_GUI_DEFINITION "default_large" "default, large font size" () LARGE () DEFAULT }
{_GUI_DEFINITION "default_huge" "default, huge font size" () HUGE () DEFAULT }
{_GUI_DEFINITION "default_small" "default, small font size" () SMALL () DEFAULT }

View file

@ -1,5 +1,7 @@
#textdomain wesnoth-lib
#define _GUI_MAIN_STACK
[stacked_widget]
id = "text_and_control_stack"
@ -18,7 +20,7 @@
[spacer]
definition = "default"
height = "(max(200, screen_height / 4))"
height = "(max(150, screen_height / 4))"
[/spacer]
[/column]
@ -56,89 +58,82 @@
[layer]
[row]
grow_factor = 0
[column]
grow_factor = 1
border = "all"
border_size = 20
horizontal_grow = true
vertical_grow = true
[scroll_label]
definition = "default"
id = "part_text"
use_markup = true
[/scroll_label]
[/column]
[column]
grow_factor = 0
horizontal_grow = true
border_size = "10"
horizontal_alignment = "left"
vertical_alignment = "bottom"
[grid]
[row]
grow_factor = 0
[column]
[grid]
[row]
[column]
border = "left,top,bottom"
border_size = 10
[button]
id = "back"
definition = "left_arrow_ornate"
[/button]
[/column]
[column]
border = "right,top,bottom"
border_size = 10
[button]
id = "next"
definition = "right_arrow_ornate"
[/button]
[/column]
[/row]
[/grid]
[/column]
[/row]
[row]
[column]
border = "left,right,bottom"
border_size = 20
[button]
id = "cancel"
definition = "default"
label = _ "Skip"
[/button]
[/column]
[/row]
[/grid]
[button]
id = "prev"
definition = "left_arrow_story"
[/button]
[/column]
[column]
horizontal_alignment = "right"
vertical_alignment = "center"
[grid]
[row]
[column]
grow_factor = 1
border = "all"
border_size = 20
horizontal_grow = true
vertical_grow = true
[scroll_label]
definition = "default"
id = "part_text"
horizontal_scrollbar_mode = "never"
use_markup = true
[/scroll_label]
[/column]
[/row]
[row]
[column]
horizontal_alignment = "center"
vertical_alignment = "bottom"
[grid]
[row]
grow_factor = 0
[column]
border = "top"
border_size = "10"
horizontal_alignment = "center"
[button]
id = "cancel"
label = _ "Skip"
definition = "header_story_skip"
[/button]
[/column]
[/row]
[row]
[column]
[spacer]
height=30
[/spacer]
[/column]
[/row]
[/grid]
[/column]
[/row]
[/grid]
[/column]
[column]
border = "all"
border_size = "10"
horizontal_alignment = "right"
vertical_alignment = "bottom"
[button]
id = "next"
definition = "right_arrow_story"
[/button]
[/column]
[/row]
[/layer]
@ -206,7 +201,6 @@
[/helptip]
[grid]
[row]
grow_factor = 0

View file

@ -152,6 +152,7 @@
{DEFAULT_KEY "w" f_unsigned 0}
{DEFAULT_KEY "x" f_unsigned 0}
{DEFAULT_KEY "y" f_unsigned 0}
{DEFAULT_KEY "actions" string ""}
[/tag]
[/tag]
[/tag]

BIN
images/misc/dots.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

View file

@ -395,7 +395,7 @@ image_shape::resize_mode image_shape::get_resize_mode(const std::string& resize_
/***** ***** ***** ***** ***** TEXT ***** ***** ***** ***** *****/
text_shape::text_shape(const config& cfg)
text_shape::text_shape(const config& cfg, wfl::action_function_symbol_table& functions)
: rect_bounded_shape(cfg)
, font_family_(font::str_to_family_class(cfg["font_family"]))
, font_size_(cfg["font_size"])
@ -413,6 +413,7 @@ text_shape::text_shape(const config& cfg)
, highlight_end_(cfg["highlight_end"], 0)
, highlight_color_(cfg["highlight_color"], color_t::from_hex_string("215380"))
, outline_(cfg["outline"], false)
, actions_formula_(cfg["actions"], &functions)
{
if(!font_size_.has_formula()) {
VALIDATE(font_size_(), _("Text has a font size of 0."));
@ -473,6 +474,9 @@ void text_shape::draw(wfl::map_formula_callable& variables)
const int h = h_(local_variables);
rect dst_rect{x, y, w, h};
// Execute the provided actions for this context.
wfl::variant(variables.fake_ptr()).execute_variant(actions_formula_.evaluate(local_variables));
texture tex = text_renderer.render_and_get_texture();
if(!tex) {
DBG_GUI_D << "Text: Rendering '" << text << "' resulted in an empty canvas, leave.";
@ -623,7 +627,7 @@ void canvas::parse_cfg(const config& cfg)
} else if(type == "image") {
shapes_.emplace_back(std::make_unique<image_shape>(data, functions_));
} else if(type == "text") {
shapes_.emplace_back(std::make_unique<text_shape>(data));
shapes_.emplace_back(std::make_unique<text_shape>(data, functions_));
} else if(type == "pre_commit") {
/* note this should get split if more preprocessing is used. */

View file

@ -239,8 +239,9 @@ public:
* Constructor.
*
* @param cfg The config object to define the text.
* @param functions WFL functions to execute.
*/
explicit text_shape(const config& cfg);
explicit text_shape(const config& cfg, wfl::action_function_symbol_table& functions);
void draw(wfl::map_formula_callable& variables) override;
@ -290,6 +291,9 @@ private:
/** Whether to apply a text outline. */
typed_formula<bool> outline_;
/** Any extra WFL actions to execute. */
wfl::formula actions_formula_;
};
}

View file

@ -20,10 +20,14 @@
#include "display.hpp"
#include "formula/variant.hpp"
#include "gui/auxiliary/find_widget.hpp"
#include "sdl/point.hpp"
#include "gui/core/timer.hpp"
#include "gui/widgets/button.hpp"
#include "gui/widgets/grid.hpp"
#include "gui/widgets/image.hpp"
#include "gui/widgets/label.hpp"
#include "gui/widgets/scroll_label.hpp"
#include "gui/widgets/settings.hpp"
#include "gui/widgets/stacked_widget.hpp"
#include "gui/widgets/window.hpp"
#include "sound.hpp"
@ -87,10 +91,12 @@ void story_viewer::pre_show(window& window)
connect_signal_mouse_left_click(find_widget<button>(&window, "next", false),
std::bind(&story_viewer::nav_button_callback, this, DIR_FORWARD));
connect_signal_mouse_left_click(find_widget<button>(&window, "back", false),
connect_signal_mouse_left_click(find_widget<button>(&window, "prev", false),
std::bind(&story_viewer::nav_button_callback, this, DIR_BACKWARDS));
scroll_label& text_label = find_widget<scroll_label>(get_window(), "part_text", false);
text_label.connect_signal_left_click(std::bind(&story_viewer::nav_button_callback, this, DIR_FORWARD));
// Tell the game display not to draw
game_was_already_hidden_ = display::get_singleton()->get_prevent_draw();
display::get_singleton()->set_prevent_draw(true);
@ -113,7 +119,7 @@ void story_viewer::display_part()
{
static const int VOICE_SOUND_SOURCE_ID = 255;
// Update Back button state. Doing this here so it gets called in pre_show too.
find_widget<button>(get_window(), "back", false).set_active(part_index_ != 0);
find_widget<button>(get_window(), "prev", false).set_active(part_index_ != 0);
//
// Music and sound
@ -263,6 +269,7 @@ void story_viewer::display_part()
std::string new_panel_mode;
switch(current_part_->story_text_location()) {
case storyscreen::part::BLOCK_TOP:
new_panel_mode = "top";
break;
@ -301,6 +308,11 @@ void story_viewer::display_part()
scroll_label& text_label = find_widget<scroll_label>(get_window(), "part_text", false);
// TODO Hardcoded max width, should be made customizable
// preferably as an key to [part]
unsigned win_width = get_window()->get_size().x;
unsigned best_text_width = (win_width < 1500) ? win_width/1.5 : 800;
text_label.set_text_max_width(best_text_width);
text_label.set_text_alignment(story_text_alignment);
text_label.set_text_alpha(0);
text_label.set_label(part_text);

View file

@ -17,6 +17,7 @@
#include "gui/dialogs/modal_dialog.hpp"
#include "config.hpp"
#include "storyscreen/controller.hpp"
#include "storyscreen/part.hpp"

View file

@ -49,6 +49,11 @@ scroll_label::scroll_label(const implementation::builder_scroll_label& builder)
event::dispatcher::back_pre_child);
}
void scroll_label::connect_signal_left_click(std::function<void()> click_handler)
{
click_handler_ = click_handler;
}
label* scroll_label::get_internal_label()
{
if(content_grid()) {
@ -157,6 +162,8 @@ void scroll_label::signal_handler_left_button_down(const event::ui_event event)
DBG_GUI_E << LOG_HEADER << ' ' << event << ".";
get_window()->keyboard_capture(this);
click_handler_();
}
// }---------- DEFINITION ---------{

View file

@ -16,6 +16,7 @@
#pragma once
#include "gui/widgets/scrollbar_container.hpp"
#include "gui/widgets/label.hpp"
#include "gui/core/widget_definition.hpp"
#include "gui/core/window_builder.hpp"
@ -26,6 +27,7 @@ namespace gui2
// ------------ WIDGET -----------{
class label;
class spacer;
namespace implementation
{
@ -66,6 +68,15 @@ public:
void set_link_aware(bool l);
void set_text_max_width(int max_width) {
label* text_label = get_internal_label();
if (text_label) {
text_label->set_text_maximum_width(max_width);
}
}
void connect_signal_left_click(std::function<void()> click_handler);
private:
/**
* Possible states of the widget.
@ -94,6 +105,8 @@ private:
bool link_aware_;
std::function<void()> click_handler_;
void finalize_subclass() override;
label* get_internal_label();

View file

@ -347,6 +347,17 @@ protected:
*/
int get_text_maximum_height() const;
public:
/**
* Set how wide the text can become. If the text is bigger
* than this limit, it gets wrapped
*/
void set_text_maximum_width(int max_width) {
if (max_width > 0) {
text_maximum_width_ = max_width;
}
}
private:
/**
* The definition is the id of that widget class.
@ -514,6 +525,7 @@ private:
// }---------- BUILDER -----------{
class styled_widget;
namespace implementation
{