From e53655f697e178dfa0bfe3c1bf350e1afa94c349 Mon Sep 17 00:00:00 2001 From: Andrew Mickelson Date: Wed, 11 Jul 2018 20:24:48 -0700 Subject: [PATCH] Issue #401 - Implement proposed changes to zorder behaviour (#408) - This changes the behaviour of the zorder attribute of image, text, and listbox objects. *** Layouts that use the zorder attribute may have to be updated as a result *** - zorder attribute can be set to any integer value. The value stays at whatever it is set to (previous behaviour was that all objects had a unique zorder value, forced in to the range of 0 to number of objects-1) - objects with a lower zorder are drawn first. Order remains stable when objects are assigned the same zorder. - Default zorder value is 0, with objects drawn in their order of creation - updates to loader/hyperspin.nut to address zorder changes --- Layouts.md | 15 ++++++++----- config/loader/hyperspin.nut | 44 ++++++++++++++++++++----------------- src/fe_presentable.cpp | 36 +++++++++++++----------------- src/fe_presentable.hpp | 1 + 4 files changed, 49 insertions(+), 47 deletions(-) diff --git a/Layouts.md b/Layouts.md index db3c7f187..bd8737a50 100644 --- a/Layouts.md +++ b/Layouts.md @@ -1466,6 +1466,9 @@ Properties: `Transition.EndNavigation`. Default value is `Transition.ToNewSelection`. * `smooth` - Get/set whether the image is to be smoothed. Default value can be configured in attract.cfg + * `zorder` - Get/set the Image's order in the applicable draw list. Objects + with a lower zorder are drawn first, so that when objects overlap, the one + with the higher zorder is drawn on top. Default value is 0. * `blend_mode` - Get/set the blend mode for this image. Can have one of the following values: - `BlendMode.Alpha` @@ -1480,8 +1483,6 @@ Properties: The default value is `false`. It's advised to force anisotropic filtering in the display driver settings if the Image with auto generated mipmap is scaled by the ratio that is not isotropic. - * `zorder` - Get/set the Image's order in the applicable draw list. When - objects overlap, the one with the higher zorder will be drawn on top. Member Functions: @@ -1657,8 +1658,9 @@ Properties: Default value is `-1` which calcualtes the margin based on the .char_size. * `shader` - Get/set the GLSL shader for this text. This can only be set to an instance of the class `fe.Shader` (see: `fe.add_shader()`). - * `zorder` - Get/set the Text's order in the applicable draw list. When - objects overlap, the one with the higher zorder will be drawn on top. + * `zorder` - Get/set the Text's order in the applicable draw list. Objects + with a lower zorder are drawn first, so that when objects overlap, the one + with the higher zorder is drawn on top. Default value is 0. Member Functions: @@ -1762,8 +1764,9 @@ Properties: behaviour as if set to "[Title]"). Default is an empty value. * `shader` - Get/set the GLSL shader for this listbox. This can only be set to an instance of the class `fe.Shader` (see: `fe.add_shader()`). - * `zorder` - Get/set the Listbox's order in the applicable draw list. When - objects overlap, the one with the higher zorder will be drawn on top. + * `zorder` - Get/set the Listbox's order in the applicable draw list. Objects + with a lower zorder are drawn first, so that when objects overlap, the one + with the higher zorder is drawn on top. Default value is 0. Member Functions: diff --git a/config/loader/hyperspin.nut b/config/loader/hyperspin.nut index 9dc66b911..6663ececc 100644 --- a/config/loader/hyperspin.nut +++ b/config/loader/hyperspin.nut @@ -118,54 +118,65 @@ for ( local i=0; i< fe.displays.len(); i++ ) // // - background // - art1 +// - (video_overlay if overlaybelow=true) // - video // - video_overlay +// - (art1 if below=true) // - art2 // - art3 // - art4 +// - (wheel) +// - (prompts) +// - override transitions // ::hs_ent.background <- { dir = "Images/Backgrounds/" obj = fe.add_image( "" ) - zorder = 0 + zorder = -10 }; ::hs_ent.artwork1 <- { dir = "Images/Artwork1/" obj = fe.add_image( "" ) - zorder = 1 + zorder = -9 }; +// zorder -8 - hs_ent.video_overlay zorder goes here if overlaybelow=true + ::hs_ent.video <- { dir = "Video/" obj = fe.add_image( "" ) - zorder = 2 + zorder = -7 }; ::hs_ent.video_overlay <- { dir = "" obj = fe.add_image( "" ) - zorder = 3 + zorder = -6 }; +// zorder -5 - hs_ent.artwork1 zorder goes here if below=true + ::hs_ent.artwork2 <- { dir = "Images/Artwork2/" obj = fe.add_image( "" ) - zorder = 4 + zorder = -4 }; ::hs_ent.artwork3 <- { dir = "Images/Artwork3/" obj = fe.add_image( "" ) - zorder = 5 + zorder = -3 }; ::hs_ent.artwork4 <- { dir = "Images/Artwork4/" obj = fe.add_image( "" ) - zorder = 6 + zorder = -2 }; +// wheel and prompts zorder is at 0 + ::hs_ent.override_transition <- { dir = "Video/Override Transitions/" obj = fe.add_image( "", 0, 0, fe.layout.width, fe.layout.height ) @@ -519,7 +530,7 @@ function load( ttype, match_map, hs_sys_dir ) local d=0.0; local type = ""; local start = ""; - local vid_below=false; + local overlay_below=false; local overlayoffsetx = 0; local overlayoffsety = 0; @@ -544,7 +555,7 @@ function load( ttype, match_map, hs_sys_dir ) break; case "overlaybelow": if ( v == "true" ) - vid_below = true; + overlay_below = true; break; case "forceaspect": if (( c.tag == "video" ) && ( v == "both" )) @@ -601,8 +612,8 @@ function load( ttype, match_map, hs_sys_dir ) obj2.height = obj2.texture_height; obj2.rotation = obj.rotation; - if ( vid_below ) - obj2.zorder = obj.zorder-1; + if ( overlay_below ) + obj2.zorder = ::hs_ent["video"].zorder-1; } if ( r != 0 ) @@ -776,15 +787,8 @@ function load( ttype, match_map, hs_sys_dir ) //below seems to swap zorder of video + overlay with artwork 1 // - if ( below ) - { - if ( found_tags["artwork1"] ) - // we only need to update artwork1 zorder to "3" zorder of - // the artworks with lower zorder seem to change - // automatically, verified with print statements - // - ::hs_ent["artwork1"].obj.zorder = 3; - } + if ( below && found_tags["artwork1"] ) + ::hs_ent["artwork1"].obj.zorder = ::hs_ent["video_overlay"].zorder + 1; return call_into_transition; } diff --git a/src/fe_presentable.cpp b/src/fe_presentable.cpp index 5fea4c19f..d82de7ebf 100644 --- a/src/fe_presentable.cpp +++ b/src/fe_presentable.cpp @@ -26,7 +26,8 @@ FeBasePresentable::FeBasePresentable( FePresentableParent &p ) : m_parent( p ), m_shader( NULL ), - m_visible( true ) + m_visible( true ), + m_zorder( 0 ) { } @@ -192,33 +193,26 @@ void FeBasePresentable::script_set_shader( FeShader *sh ) int FeBasePresentable::get_zorder() { - for ( size_t i=0; i< m_parent.elements.size(); i++ ) + return m_zorder; +} + +namespace +{ + bool zcompare( FeBasePresentable *one, FeBasePresentable *two ) { - if ( this == m_parent.elements[i] ) - return i; + return ( one->get_zorder() < two->get_zorder() ); } - - return -1; -} +}; void FeBasePresentable::set_zorder( int pos ) { - if ( pos >= (int)m_parent.elements.size() ) - pos = m_parent.elements.size()-1; - if ( pos < 0 ) - pos = 0; + if ( pos == m_zorder ) + return; - int old = get_zorder(); - if (( old >= 0 ) && ( old != pos )) - { - FeBasePresentable *temp = m_parent.elements[old]; - m_parent.elements.erase( m_parent.elements.begin() + old ); - - m_parent.elements.insert( m_parent.elements.begin() + pos, - temp ); + m_zorder = pos; - FePresent::script_flag_redraw(); - } + std::stable_sort( m_parent.elements.begin(), m_parent.elements.end(), zcompare ); + FePresent::script_flag_redraw(); } FeImage *FePresentableParent::add_image(const char *n, int x, int y, int w, int h) diff --git a/src/fe_presentable.hpp b/src/fe_presentable.hpp index 79ef2d9a5..571f0cccd 100644 --- a/src/fe_presentable.hpp +++ b/src/fe_presentable.hpp @@ -42,6 +42,7 @@ class FeBasePresentable FePresentableParent &m_parent; FeShader *m_shader; bool m_visible; + int m_zorder; public: FeBasePresentable( FePresentableParent &p );