IntroWML code cleanup and fix/rename of [image]resize_with_background=
Prior to this commit, the scaled= attribute was undocumented and had what I assume was a bug - when enabled the image was scaled up to the width and height of the background - not to the same ratio as the background, but to the full size. So if you had a 1000 pixel wide background in an 800 pixel wide window, then scaled=yes meant each journey-marker was an 800 pixel-wide blob. However, if anyone was using it with background-size images as overlays then this commit will break that usage - that use case is still supported by having multiple [background_layer]s. Closes #5223, which was a question about whether to fix or simply remove the scaled attribute. Given that [background_layer]scale= and [image]scaled= have different meanings (the background_layer one should and does cause it to be full-window), I've kept the 'd' on the end of 'scaled' too. Use a loop instead of recursion. This cleanup is prompted by #5041 (drawing map labels in IntroWML), which will add more items to be drawn in this loop. The old implementation would not have triggered tail-recursion optimisations, as the recursion site wasn't the final code in the function. Correct documentation in the .hpp file about when the delay takes effect (this isn't a behavior change, just a documentation correction). Review the schema, and remove attributes that aren't supported by the code. Many of these attributes are supported for `background_layer` but not `image`.
This commit is contained in:
parent
f39bd33899
commit
1cdc4ef530
5 changed files with 72 additions and 106 deletions
|
@ -20,6 +20,9 @@
|
|||
### WML Engine
|
||||
### Miscellaneous and Bug Fixes
|
||||
* Fixed a rare issue on Windows that could result in wesnoth.exe sticking around waiting for console input after encountering an error despite not being launched with the `--wconsole` option.
|
||||
* Fixed a potential crash when drawing many images on the story screens.
|
||||
* Fixed the schema's list of attributes supported by IntroWML.
|
||||
* Fixed and renamed IntroWML's `[image]resize_with_background=yes` to keep images proportional to the background.
|
||||
* Fixed precise log timestamps missing a space between the timestamp and the log severity label.
|
||||
* Improve the in-game help's topic about orbs, add crowns and ellipses.
|
||||
* Removed documentation for network proxy-related command line options previously removed in version 1.13.1 along with libana.
|
||||
|
|
|
@ -329,24 +329,6 @@
|
|||
max=infinite
|
||||
{SIMPLE_KEY title string}
|
||||
{INSERT_TAG}
|
||||
# TODO: Is this really recognized at story toplevel? Wiki claims it is.
|
||||
[tag]
|
||||
name="image"
|
||||
max=infinite
|
||||
{INSERT_TAG}
|
||||
{SIMPLE_KEY x int}
|
||||
{SIMPLE_KEY y int}
|
||||
{SIMPLE_KEY centered bool}
|
||||
{SIMPLE_KEY file string}
|
||||
{SIMPLE_KEY delay int}
|
||||
# These keys possibly not documented?
|
||||
{SIMPLE_KEY scale_vertically bool}
|
||||
{SIMPLE_KEY scale_horizontally bool}
|
||||
{SIMPLE_KEY scale bool}
|
||||
{SIMPLE_KEY tile_vertically bool}
|
||||
{SIMPLE_KEY tile_horizontally bool}
|
||||
{SIMPLE_KEY tile bool}
|
||||
[/tag]
|
||||
[tag]
|
||||
name="part"
|
||||
max=infinite
|
||||
|
@ -360,7 +342,6 @@
|
|||
{SIMPLE_KEY sound string_list}
|
||||
{DEFAULT_KEY text_layout string bottom}
|
||||
{DEFAULT_KEY title_alignment text_alignment left}
|
||||
{SIMPLE_KEY delay int} # Not documented?
|
||||
[tag]
|
||||
name="background_layer"
|
||||
max=infinite
|
||||
|
@ -375,6 +356,17 @@
|
|||
{SIMPLE_KEY tile bool}
|
||||
{SIMPLE_KEY base_layer bool}
|
||||
[/tag]
|
||||
[tag]
|
||||
name="image"
|
||||
max=infinite
|
||||
{INSERT_TAG}
|
||||
{SIMPLE_KEY x int}
|
||||
{SIMPLE_KEY y int}
|
||||
{SIMPLE_KEY centered bool}
|
||||
{SIMPLE_KEY file string}
|
||||
{SIMPLE_KEY delay int}
|
||||
{SIMPLE_KEY resize_with_background bool}
|
||||
[/tag]
|
||||
[tag]
|
||||
name="if"
|
||||
max=infinite
|
||||
|
@ -404,7 +396,6 @@
|
|||
super="scenario/story/part"
|
||||
[/tag]
|
||||
[/tag]
|
||||
{LINK_TAG "scenario/story/image"}
|
||||
{LINK_TAG "$action_wml/deprecated_message"}
|
||||
{LINK_TAG "$action_wml/wml_message"}
|
||||
[/tag]
|
||||
|
|
|
@ -319,63 +319,58 @@ void story_viewer::display_part(window& window)
|
|||
void story_viewer::draw_floating_image(window& window, floating_image_list::const_iterator image_iter, int this_part_index)
|
||||
{
|
||||
const auto& images = current_part_->get_floating_images();
|
||||
|
||||
// If the current part has changed or we're out of images to draw, exit the draw loop.
|
||||
if((this_part_index != part_index_) || (image_iter == images.end())) {
|
||||
timer_id_ = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& floating_image = *image_iter;
|
||||
|
||||
std::ostringstream x_ss;
|
||||
std::ostringstream y_ss;
|
||||
|
||||
// Floating images are scaled by the same factor as the background.
|
||||
x_ss << "(trunc(fi_ref_x * base_scale_x) + base_origin.x";
|
||||
y_ss << "(trunc(fi_ref_y * base_scale_y) + base_origin.y";
|
||||
|
||||
if(floating_image.centered()) {
|
||||
x_ss << " - (image_original_width / 2)";
|
||||
y_ss << " - (image_original_height / 2)";
|
||||
}
|
||||
|
||||
x_ss << " where fi_ref_x = " << floating_image.ref_x() << ")";
|
||||
y_ss << " where fi_ref_y = " << floating_image.ref_y() << ")";
|
||||
|
||||
config cfg, image;
|
||||
|
||||
image["x"] = x_ss.str();
|
||||
image["y"] = y_ss.str();
|
||||
image["w"] = floating_image.autoscale() ? "(width)" : "(image_width)";
|
||||
image["h"] = floating_image.autoscale() ? "(height)" : "(image_height)";
|
||||
image["name"] = floating_image.file();
|
||||
|
||||
// TODO: implement handling of the tiling options.
|
||||
//image["resize_mode"] = "tile_centered"
|
||||
|
||||
cfg.add_child("image", std::move(image));
|
||||
|
||||
canvas& window_canvas = window.get_canvas(0);
|
||||
|
||||
// Needed to make the background redraw correctly.
|
||||
window_canvas.append_cfg(cfg);
|
||||
window_canvas.set_is_dirty(true);
|
||||
// If the current part has changed or we're out of images to draw, exit the draw loop.
|
||||
while((this_part_index == part_index_) && (image_iter != images.end())) {
|
||||
const auto& floating_image = *image_iter;
|
||||
++image_iter;
|
||||
|
||||
window.set_is_dirty(true);
|
||||
std::ostringstream x_ss;
|
||||
std::ostringstream y_ss;
|
||||
|
||||
++image_iter;
|
||||
// Floating images' locations are scaled by the same factor as the background.
|
||||
x_ss << "(trunc(" << floating_image.ref_x() << " * base_scale_x) + base_origin.x";
|
||||
y_ss << "(trunc(" << floating_image.ref_y() << " * base_scale_y) + base_origin.y";
|
||||
|
||||
// If a delay is specified, schedule the next image draw. This *must* be a non-repeating timer!
|
||||
// Else draw the next image immediately.
|
||||
const unsigned int draw_delay = floating_image.display_delay();
|
||||
if(floating_image.centered()) {
|
||||
x_ss << " - (image_width / 2)";
|
||||
y_ss << " - (image_height / 2)";
|
||||
}
|
||||
|
||||
if(draw_delay != 0) {
|
||||
timer_id_ = add_timer(draw_delay,
|
||||
std::bind(&story_viewer::draw_floating_image, this, std::ref(window), image_iter, this_part_index), false);
|
||||
} else {
|
||||
draw_floating_image(window, image_iter, this_part_index);
|
||||
x_ss << ")";
|
||||
y_ss << ")";
|
||||
|
||||
config image;
|
||||
image["x"] = x_ss.str();
|
||||
image["y"] = y_ss.str();
|
||||
|
||||
// Width and height don't need to be set unless the image needs to be scaled.
|
||||
if(floating_image.resize_with_background()) {
|
||||
image["w"] = "(image_original_width * base_scale_x)";
|
||||
image["h"] = "(image_original_height * base_scale_y)";
|
||||
}
|
||||
|
||||
image["name"] = floating_image.file();
|
||||
config cfg{"image", std::move(image)};
|
||||
|
||||
cfg.add_child("image", std::move(image));
|
||||
window_canvas.append_cfg(std::move(cfg));
|
||||
|
||||
// Needed to make the background redraw correctly.
|
||||
window_canvas.set_is_dirty(true);
|
||||
window.set_is_dirty(true);
|
||||
|
||||
// If a delay is specified, schedule the next image draw and break out of the loop.
|
||||
const unsigned int draw_delay = floating_image.display_delay();
|
||||
if(draw_delay != 0) {
|
||||
// This must be a non-repeating timer
|
||||
timer_id_ = add_timer(draw_delay, std::bind(&story_viewer::draw_floating_image, this, std::ref(window), image_iter, this_part_index), false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
timer_id_ = 0;
|
||||
}
|
||||
|
||||
void story_viewer::nav_button_callback(window& window, NAV_DIRECTION direction)
|
||||
|
|
|
@ -24,41 +24,16 @@
|
|||
|
||||
namespace storyscreen
|
||||
{
|
||||
floating_image::floating_image(const floating_image& fi)
|
||||
: file_()
|
||||
, x_(0)
|
||||
, y_(0)
|
||||
, delay_(0)
|
||||
, autoscaled_(false)
|
||||
, centered_(false)
|
||||
{
|
||||
this->assign(fi);
|
||||
}
|
||||
|
||||
floating_image::floating_image(const config& cfg)
|
||||
: file_(cfg["file"])
|
||||
, x_(cfg["x"])
|
||||
, y_(cfg["y"])
|
||||
, delay_(cfg["delay"])
|
||||
, autoscaled_(cfg["scaled"].to_bool())
|
||||
, resize_with_background_(cfg["resize_with_background"].to_bool())
|
||||
, centered_(cfg["centered"].to_bool())
|
||||
{
|
||||
}
|
||||
|
||||
void floating_image::assign(const floating_image& fi)
|
||||
{
|
||||
if(&fi == this) {
|
||||
return;
|
||||
}
|
||||
|
||||
file_ = fi.file_;
|
||||
x_ = fi.x_;
|
||||
y_ = fi.y_;
|
||||
delay_ = fi.delay_;
|
||||
autoscaled_ = fi.autoscaled_;
|
||||
centered_ = fi.centered_;
|
||||
}
|
||||
|
||||
background_layer::background_layer()
|
||||
: scale_horizontally_(true)
|
||||
, scale_vertically_(true)
|
||||
|
|
|
@ -44,10 +44,8 @@ public:
|
|||
*/
|
||||
floating_image(const config& cfg);
|
||||
|
||||
/**
|
||||
* Copy constructor.
|
||||
*/
|
||||
floating_image(const floating_image& fi);
|
||||
floating_image(const floating_image& fi) = default;
|
||||
floating_image(floating_image&& fi) = default;
|
||||
|
||||
floating_image& operator=(const floating_image& fi)
|
||||
{
|
||||
|
@ -79,12 +77,13 @@ public:
|
|||
}
|
||||
|
||||
/**
|
||||
* Whether the image should be automatically scaled as much as
|
||||
* the storyscreen background is.
|
||||
* If true, the size of the image is changed in the same way that the ref_x
|
||||
* and ref_y are mapped to use the base layer's pixels as the coordinate
|
||||
* system.
|
||||
*/
|
||||
bool autoscale() const
|
||||
bool resize_with_background() const
|
||||
{
|
||||
return autoscaled_;
|
||||
return resize_with_background_;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -96,7 +95,10 @@ public:
|
|||
return centered_;
|
||||
}
|
||||
|
||||
/** Delay before displaying, in milliseconds. */
|
||||
/**
|
||||
* Delay after displaying this image and before displaying the next image,
|
||||
* in milliseconds.
|
||||
*/
|
||||
int display_delay() const
|
||||
{
|
||||
return delay_;
|
||||
|
@ -106,7 +108,7 @@ private:
|
|||
std::string file_;
|
||||
int x_, y_; // referential (non corrected) x,y
|
||||
int delay_;
|
||||
bool autoscaled_;
|
||||
bool resize_with_background_;
|
||||
bool centered_;
|
||||
|
||||
/** Copy constructor and operator=() implementation details. */
|
||||
|
|
Loading…
Add table
Reference in a new issue