mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-08-18 06:55:48 +03:00
Several improvements in the CSS Animations.
UITabWidget now acts as a draw invalidator, skipping the draw invalidation if the element invalidating is not visible in the current tab. premake5 file now supports different architectures. Updated README.md and docs. Minor fixes in UIColorPicker. Updated SOIL2 and efsw. Added LICENSE file.
This commit is contained in:
19
LICENSE
Normal file
19
LICENSE
Normal file
@@ -0,0 +1,19 @@
|
||||
Copyright (c) 2020 Martín Lucas Golini
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
@@ -233,7 +233,8 @@ UITextView::New()->setText( "Text on test 1" )
|
||||
|
||||
Element styling can be done with a custom implementation of Cascading Style
|
||||
Sheets, most common CSS2 rules are available, plus several CSS3 rules (some
|
||||
examples: [transitions](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Transitions),
|
||||
examples: [animations](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Animations/),
|
||||
[transitions](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Transitions),
|
||||
[custom properties](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties),
|
||||
[media queries](https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries/Using_media_queries),
|
||||
[@font-face at rule](https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face),
|
||||
@@ -522,8 +523,6 @@ Keep improving the UI system, adding new widgets and layouts and improving the C
|
||||
|
||||
Simplify and improve the UI widgets skinning/theming support.
|
||||
|
||||
Add [CSS animations](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Animations/Using_CSS_animations) support.
|
||||
|
||||
Improve/create documentation for the UI module.
|
||||
|
||||
Add more examples and some tools.
|
||||
@@ -532,7 +531,7 @@ Add Scripting support ( first I would like to stabilize the library, but I'm get
|
||||
|
||||
Add 2D skeletal animations support ( probably Spine2D, shouldn't be much work to implement ).
|
||||
|
||||
Probably deprecate the Maps module, since i will focus my efforts on the UI system.
|
||||
Probably deprecate the Maps module, since I will focus my efforts on the UI system.
|
||||
|
||||
## Acknowledgements
|
||||
|
||||
|
||||
@@ -184,7 +184,7 @@ CheckBox:checked {
|
||||
background-color: #221122;
|
||||
}
|
||||
to {
|
||||
background-color: #332233;
|
||||
background-color: #110011;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -456,6 +456,16 @@ TabWidget {
|
||||
animation: 0.5s infinite alternate pulse;
|
||||
}
|
||||
|
||||
#rttv {
|
||||
animation: 0.5s infinite alternate paused ease-in pulse;
|
||||
}
|
||||
|
||||
#rttv:hover {
|
||||
/** This rule should be ignored. */
|
||||
foreground-color: red;
|
||||
animation-play-state: running;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1024px) {
|
||||
|
||||
#lvbox {
|
||||
|
||||
@@ -1,30 +1,27 @@
|
||||
UI Introduction
|
||||
===============
|
||||
# UI Introduction
|
||||
|
||||
## Introduction
|
||||
|
||||
Introduction
|
||||
------------
|
||||
eepp UI is designed to be flexible and efficient. Inspired in
|
||||
[Android Layouts structure](https://developer.android.com/guide/topics/ui/declaring-layout)
|
||||
and [CSS standards](https://developer.mozilla.org/en-US/docs/Web/CSS).
|
||||
It's still a work in progress so several features are still not stable, but
|
||||
already provides a very solid foundation to create rich and interactive UIs.
|
||||
|
||||
## Layout
|
||||
|
||||
Layout
|
||||
------
|
||||
A layout defines the structure for a user interface in your app.
|
||||
For constructing layouts in eepp we have two options: instantiate layout
|
||||
elements at runtime or declare UI elements in XML.
|
||||
|
||||
* **Declare UI elements in XML.** eepp provides a straightforward XML
|
||||
vocabulary that corresponds to the UI Widget classes and subclasses.
|
||||
There are two kinds of widgets: normal widgets and layouts. The difference
|
||||
between this two is that layouts are the ones in charge of arranging their
|
||||
child in a particular way.
|
||||
* **Declare UI elements in XML.** eepp provides a straightforward XML
|
||||
vocabulary that corresponds to the UI Widget classes and subclasses.
|
||||
There are two kinds of widgets: normal widgets and layouts. The difference
|
||||
between this two is that layouts are the ones in charge of arranging their
|
||||
child in a particular way.
|
||||
|
||||
* **Instantiate layout elements at runtime.** Your app can create Widget and
|
||||
Layout objects (and manipulate their properties) programmatically.
|
||||
* **Instantiate layout elements at runtime.** Your app can create Widget and
|
||||
Layout objects (and manipulate their properties) programmatically.
|
||||
|
||||
Declaring your UI in XML allows you to separate the presentation of your app
|
||||
from the code that controls its behavior. Using XML files in conjunction with
|
||||
@@ -35,9 +32,8 @@ The framework gives you the flexibility to use either or both of these methods
|
||||
to build your app's UI. For example, you can declare your app's default
|
||||
layouts in XML, and then modify the layout at runtime.
|
||||
|
||||
## Write the XML
|
||||
|
||||
Write the XML
|
||||
-------------
|
||||
Using eepp XML vocabulary, you can quickly design UI layouts and the screen
|
||||
elements they contain, in the same way you create web pages in HTML — with a
|
||||
series of nested elements.
|
||||
@@ -67,9 +63,8 @@ and a EE::UI::UIPushButton:
|
||||
After you've declared your layout in XML, save the file with the `.xml`
|
||||
extension into a project accessible path and you're done.
|
||||
|
||||
## Initializing the UI
|
||||
|
||||
Initializing the UI
|
||||
-------------------
|
||||
The library does not assume that the user is going to use the UI at all, so you
|
||||
must initialize it manually. This usually comes right after the main
|
||||
EE::Window::Window initialization.
|
||||
@@ -79,6 +74,7 @@ EE::UI::UISceneNode. Setting the font as the default scene node. And finally,
|
||||
adding this scene node to the EE::Scene::SceneManager.
|
||||
|
||||
For example:
|
||||
|
||||
```cpp
|
||||
// ... after window creation
|
||||
// Load a font to use as the default font in our UI.
|
||||
@@ -98,13 +94,13 @@ SceneManager::instance()->add( uiSceneNode );
|
||||
|
||||
And that's all we need for a basic initialization.
|
||||
|
||||
## Updating the UI
|
||||
|
||||
Updating the UI
|
||||
---------------
|
||||
Updating the UI consist in two simple steps: updating and drawing the UI scene
|
||||
node contained by the EE::Scene::SceneManager.
|
||||
|
||||
So we just need to do in our main loop:
|
||||
|
||||
```cpp
|
||||
// Update the UI scene
|
||||
SceneManager::instance()->update();
|
||||
@@ -130,9 +126,8 @@ the scene on every update or only when is needed. There are several options
|
||||
regarding this topic, since each scene node can be drawn into a separated
|
||||
frame buffer, in order to be able to control when to redraw a scene.
|
||||
|
||||
## Load the XML Layout Resource
|
||||
|
||||
Load the XML Layout Resource
|
||||
----------------------------
|
||||
XML layout resources can be loaded from any file system path,
|
||||
EE::UI::Pack accessible path or a hard-coded string.
|
||||
|
||||
@@ -142,6 +137,7 @@ root scene node will be used.
|
||||
|
||||
Following the [Write the XML](#write-the-xml) layout and the
|
||||
[Initializing the UI](#initializing-the-ui) code:
|
||||
|
||||
```cpp
|
||||
uiSceneNode->loadLayoutFromString( R"xml(
|
||||
<LinearLayout layout_width="match_parent"
|
||||
@@ -162,37 +158,37 @@ uiSceneNode->loadLayoutFromString( R"xml(
|
||||
This will load and create the widgets into the root element of the UI scene
|
||||
node.
|
||||
|
||||
## Cascading Style Sheets
|
||||
|
||||
Cascading Style Sheets
|
||||
----------------------
|
||||
[CSS (Cascading Style Sheets)](https://developer.mozilla.org/en-US/docs/Web/CSS)
|
||||
is the code you use to style the UI. It's very heavily based on the
|
||||
[CSS 2.1](https://www.w3.org/TR/CSS21/) standards with a good amount of CSS 3
|
||||
features. Some of the main current differences are: eepp CSS properties don't
|
||||
support inheritance (except for
|
||||
[Custom properties](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties),
|
||||
support inheritance (except for the case
|
||||
[custom properties](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties),
|
||||
and `*` is supported), eepp also adds new properties oriented to decoration
|
||||
related and layout control stuffs, and CSS layout properties differ from the
|
||||
standard since we use a different layout model. But you can learn how style the
|
||||
standard since we use a different layout model. But you can learn how to style the
|
||||
UI following the CSS standards and then reading about the specific eepp UI
|
||||
features.
|
||||
Important CSS3 features that are currently supported:
|
||||
|
||||
* [Transitions](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Transitions)
|
||||
* [Animations](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Animations/)
|
||||
|
||||
* [Custom properties](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties)
|
||||
* [Transitions](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Transitions)
|
||||
|
||||
* [Media queries](https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries/Using_media_queries)
|
||||
* [Custom properties](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties)
|
||||
|
||||
* [@font-face at rule](https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face)
|
||||
* [Media queries](https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries/Using_media_queries)
|
||||
|
||||
* [:root element](https://developer.mozilla.org/en-US/docs/Web/CSS/:root)
|
||||
* [@font-face at rule](https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face)
|
||||
|
||||
* [Most of the background properties](https://developer.mozilla.org/en-US/docs/Web/CSS/background)
|
||||
* [:root element](https://developer.mozilla.org/en-US/docs/Web/CSS/:root)
|
||||
|
||||
* [Most of the background properties](https://developer.mozilla.org/en-US/docs/Web/CSS/background)
|
||||
|
||||
## Write the CSS
|
||||
|
||||
Write the CSS
|
||||
-------------
|
||||
Following [Load the XML Layout Resource](#load-the-xml-layout-resource) we are
|
||||
going to write a very simple style to our UI. In order to that we can create a
|
||||
new CSS file (with `.css` extension) in our file system and save it in an
|
||||
@@ -200,6 +196,7 @@ accesible path to our project, or we can simply write the CSS in a string in our
|
||||
code.
|
||||
|
||||
This is how our CSS could look like:
|
||||
|
||||
```css
|
||||
* {
|
||||
font-size: 22dp;
|
||||
@@ -223,8 +220,8 @@ pixel](https://en.wikipedia.org/wiki/Device-independent_pixel), that allow us to
|
||||
keep our layout consistent between different screen densities. This concept was
|
||||
taken from the [Android pixel density implementation](https://developer.android.com/guide/practices/screens_support.html#density).
|
||||
|
||||
Loading the CSS Resource
|
||||
------------------------
|
||||
## Loading the CSS Resource
|
||||
|
||||
Following [Load the XML Layout Resource](#load-the-xml-layout-resource) and
|
||||
[Write the CSS](#write-the-css) we are going to load our CSS from a string:
|
||||
|
||||
@@ -252,13 +249,14 @@ To load a CSS from a file we need to first parse it with the
|
||||
EE::UI::CSS::StyleSheetParser.
|
||||
|
||||
It will look like:
|
||||
|
||||
```cpp
|
||||
CSS::StyleSheetParser parser;
|
||||
parser.loadFromFile( "path/to/our/stylesheet.css" );
|
||||
uiSceneNode->setStyleSheet( parser.getStyleSheet() );
|
||||
```
|
||||
|
||||
Example
|
||||
-------
|
||||
## Example
|
||||
|
||||
For a complete example of this introduction you can look into:
|
||||
[src/examples/ui_hello_world/ui_hello_world.cpp](https://github.com/SpartanJ/eepp/blob/develop/src/examples/ui_hello_world/ui_hello_world.cpp).
|
||||
|
||||
@@ -49,7 +49,6 @@ class EE_API ActionManager {
|
||||
protected:
|
||||
std::list<Action*> mActions;
|
||||
std::list<Action*> mActionsRemoveList;
|
||||
Mutex mMutex;
|
||||
bool mUpdating;
|
||||
};
|
||||
|
||||
|
||||
@@ -329,7 +329,7 @@ class EE_API Node : public Transformable {
|
||||
|
||||
bool invalidated() const;
|
||||
|
||||
void invalidate();
|
||||
virtual void invalidate( Node* invalidator );
|
||||
|
||||
Uint32 getChildCount() const;
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include <eepp/math/ease.hpp>
|
||||
#include <eepp/system/time.hpp>
|
||||
#include <eepp/ui/css/stylesheetproperty.hpp>
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
using namespace EE::Math;
|
||||
@@ -14,7 +14,7 @@ namespace EE { namespace UI { namespace CSS {
|
||||
|
||||
class EE_API AnimationDefinition {
|
||||
public:
|
||||
static std::map<std::string, AnimationDefinition>
|
||||
static std::unordered_map<std::string, AnimationDefinition>
|
||||
parseAnimationProperties( const std::vector<StyleSheetProperty>& stylesheetProperties );
|
||||
|
||||
/* https://developer.mozilla.org/en-US/docs/Web/CSS/animation-direction */
|
||||
@@ -57,17 +57,50 @@ class EE_API AnimationDefinition {
|
||||
|
||||
const Ease::Interpolation& getTimingFunction() const;
|
||||
|
||||
std::string name;
|
||||
Time delay = Time::Zero;
|
||||
Time duration = Time::Zero;
|
||||
Int32 iterations = 1; /* -1 == "infinite" */
|
||||
Ease::Interpolation timingFunction = Ease::Interpolation::Linear;
|
||||
AnimationDirection direction = Normal;
|
||||
AnimationFillMode fillMode = None;
|
||||
bool paused = false;
|
||||
const AnimationFillMode& getFillMode() const;
|
||||
|
||||
void setName( const std::string& value );
|
||||
|
||||
void setDelay( const Time& value );
|
||||
|
||||
void setDuration( const Time& value );
|
||||
|
||||
void setIterations( const Int32& value );
|
||||
|
||||
void setTimingFunction( const Ease::Interpolation& value );
|
||||
|
||||
void setDirection( const AnimationDirection& value );
|
||||
|
||||
void setFillMode( const AnimationFillMode& value );
|
||||
|
||||
void setPaused( bool value );
|
||||
|
||||
const Uint32& getId() const;
|
||||
|
||||
protected:
|
||||
Uint32 mId;
|
||||
std::string mName;
|
||||
Time mDelay = Time::Zero;
|
||||
Time mDuration = Time::Zero;
|
||||
Int32 mIterations = 1; /* -1 == "infinite" */
|
||||
Ease::Interpolation mTimingFunction = Ease::Interpolation::Linear;
|
||||
AnimationDirection mDirection = Normal;
|
||||
AnimationFillMode mFillMode = None;
|
||||
bool mPaused = false;
|
||||
};
|
||||
|
||||
typedef std::map<std::string, AnimationDefinition> AnimationsMap;
|
||||
inline bool operator==( const AnimationDefinition& a, const AnimationDefinition& b ) {
|
||||
return a.getDuration() == b.getDuration() && a.getTimingFunction() == b.getTimingFunction() &&
|
||||
a.getDelay() == b.getDelay() && a.getDirection() == b.getDirection() &&
|
||||
a.isPaused() == b.isPaused() && a.getIterations() == b.getIterations() &&
|
||||
a.getName() == b.getName();
|
||||
}
|
||||
|
||||
inline bool operator!=( const AnimationDefinition& a, const AnimationDefinition& b ) {
|
||||
return !( a == b );
|
||||
}
|
||||
|
||||
typedef std::unordered_map<std::string, AnimationDefinition> AnimationsMap;
|
||||
|
||||
}}} // namespace EE::UI::CSS
|
||||
|
||||
|
||||
@@ -74,8 +74,14 @@ class EE_API StyleSheetPropertyAnimation : public Action {
|
||||
|
||||
const AnimationOrigin& getAnimationOrigin() const;
|
||||
|
||||
void setRunning( const bool& running );
|
||||
|
||||
void setPaused( const bool& paused );
|
||||
|
||||
void notifyClose();
|
||||
|
||||
const AnimationDefinition& getAnimation() const;
|
||||
|
||||
protected:
|
||||
AnimationDefinition mAnimation;
|
||||
const PropertyDefinition* mPropertyDef;
|
||||
@@ -87,6 +93,7 @@ class EE_API StyleSheetPropertyAnimation : public Action {
|
||||
Uint32 mPropertyIndex;
|
||||
std::string mFillModeValue;
|
||||
AnimationOrigin mAnimationOrigin;
|
||||
bool mPaused;
|
||||
|
||||
StyleSheetPropertyAnimation( const AnimationDefinition& animation,
|
||||
const PropertyDefinition* propertyDef,
|
||||
|
||||
@@ -15,6 +15,10 @@ namespace EE { namespace Graphics {
|
||||
class Font;
|
||||
}} // namespace EE::Graphics
|
||||
|
||||
namespace EE { namespace UI { namespace CSS {
|
||||
class StyleSheetPropertyAnimation;
|
||||
}}} // namespace EE::UI::CSS
|
||||
|
||||
namespace EE { namespace UI {
|
||||
|
||||
class UIWidget;
|
||||
@@ -41,6 +45,10 @@ class EE_API UIStyle : public UIState {
|
||||
|
||||
bool hasTransition( const std::string& propertyName );
|
||||
|
||||
CSS::StyleSheetPropertyAnimation* getAnimation( const CSS::PropertyDefinition* propertyDef );
|
||||
|
||||
bool hasAnimation( const CSS::PropertyDefinition* propertyDef );
|
||||
|
||||
CSS::TransitionDefinition getTransition( const std::string& propertyName );
|
||||
|
||||
const bool& isChangingState() const;
|
||||
@@ -54,8 +62,8 @@ class EE_API UIStyle : public UIState {
|
||||
CSS::StyleSheetStyle mElementStyle;
|
||||
CSS::StyleSheetProperties mProperties;
|
||||
CSS::StyleSheetVariables mVariables;
|
||||
std::vector<CSS::StyleSheetProperty> mTransitionAttributes;
|
||||
std::vector<CSS::StyleSheetProperty> mAnimationAttributes;
|
||||
std::vector<CSS::StyleSheetProperty> mTransitionProperties;
|
||||
std::vector<CSS::StyleSheetProperty> mAnimationProperties;
|
||||
CSS::TransitionsMap mTransitions;
|
||||
CSS::AnimationsMap mAnimations;
|
||||
std::set<UIWidget*> mRelatedWidgets;
|
||||
@@ -87,7 +95,11 @@ class EE_API UIStyle : public UIState {
|
||||
void applyStyleSheetProperty( const CSS::StyleSheetProperty& property,
|
||||
CSS::StyleSheetProperties& prevProperties );
|
||||
|
||||
void startAnimations();
|
||||
void updateAnimationsPlayState();
|
||||
|
||||
void updateAnimations();
|
||||
|
||||
void startAnimations( const CSS::AnimationsMap& animations );
|
||||
|
||||
void removeAllAnimations();
|
||||
|
||||
|
||||
@@ -116,6 +116,10 @@ class EE_API UITabWidget : public UIWidget {
|
||||
virtual std::string getPropertyString( const PropertyDefinition* propertyDef,
|
||||
const Uint32& propertyIndex = 0 );
|
||||
|
||||
virtual bool isDrawInvalidator() const;
|
||||
|
||||
void invalidate( Node* invalidator );
|
||||
|
||||
protected:
|
||||
friend class UITab;
|
||||
|
||||
|
||||
@@ -146,7 +146,7 @@ class EE_API UIWindow : public UIWidget {
|
||||
|
||||
virtual void internalDraw();
|
||||
|
||||
void invalidate();
|
||||
void invalidate( Node* invalidator );
|
||||
|
||||
bool invalidated();
|
||||
|
||||
|
||||
@@ -802,14 +802,7 @@ solution "eepp"
|
||||
|
||||
project "SOIL2-static"
|
||||
kind "StaticLib"
|
||||
|
||||
if is_vs() then
|
||||
language "C++"
|
||||
buildoptions { "/TP" }
|
||||
else
|
||||
language "C"
|
||||
end
|
||||
|
||||
language "C"
|
||||
set_targetdir("libs/" .. os.get_real() .. "/thirdparty/")
|
||||
files { "src/thirdparty/SOIL2/src/SOIL2/*.c" }
|
||||
includedirs { "src/thirdparty/SOIL2" }
|
||||
|
||||
18
premake5.lua
18
premake5.lua
@@ -216,9 +216,12 @@ function build_link_configuration( package_name, use_ee_icon )
|
||||
links { "SDL2", "SDL2main" }
|
||||
end
|
||||
|
||||
filter { "options:windows-vc-build", "system:windows" }
|
||||
filter { "options:windows-vc-build", "system:windows", "platforms:x86" }
|
||||
syslibdirs { "src/thirdparty/" .. remote_sdl2_version .."/lib/x86" }
|
||||
|
||||
filter { "options:windows-vc-build", "system:windows", "platforms:x86_64" }
|
||||
syslibdirs { "src/thirdparty/" .. remote_sdl2_version .."/lib/x64" }
|
||||
|
||||
filter "system:emscripten"
|
||||
linkoptions{ "-O2 -s TOTAL_MEMORY=67108864 -s ASM_JS=1 -s VERBOSE=1 -s DISABLE_EXCEPTION_CATCHING=0 -s USE_SDL=2 -s ERROR_ON_UNDEFINED_SYMBOLS=0 -s ERROR_ON_MISSING_LIBRARIES=0 -s FULL_ES3=1 -s \"BINARYEN_TRAP_MODE='clamp'\"" }
|
||||
buildoptions { "-fno-strict-aliasing -O2 -s USE_SDL=2 -s PRECISE_F32=1 -s ENVIRONMENT=web" }
|
||||
@@ -534,6 +537,7 @@ end
|
||||
workspace "eepp"
|
||||
targetdir("./bin/")
|
||||
configurations { "debug", "release" }
|
||||
platforms { "x86_64", "x86" }
|
||||
rtti "On"
|
||||
download_and_extract_dependencies()
|
||||
select_backend()
|
||||
@@ -542,6 +546,12 @@ workspace "eepp"
|
||||
location("./make/" .. os.target() .. "/")
|
||||
objdir("obj/" .. os.target() .. "/")
|
||||
|
||||
filter "platforms:x86"
|
||||
architecture "x86"
|
||||
|
||||
filter "platforms:x86_64"
|
||||
architecture "x86_64"
|
||||
|
||||
filter "system:macosx"
|
||||
defines { "GL_SILENCE_DEPRECATION" }
|
||||
|
||||
@@ -558,15 +568,11 @@ workspace "eepp"
|
||||
|
||||
project "SOIL2-static"
|
||||
kind "StaticLib"
|
||||
language "C"
|
||||
targetdir("libs/" .. os.target() .. "/thirdparty/")
|
||||
files { "src/thirdparty/SOIL2/src/SOIL2/*.c" }
|
||||
incdirs { "src/thirdparty/SOIL2" }
|
||||
build_base_configuration( "SOIL2" )
|
||||
filter "action:vs*"
|
||||
language "C++"
|
||||
buildoptions { "/TP" }
|
||||
filter "action:not vs*"
|
||||
language "C"
|
||||
|
||||
project "glew-static"
|
||||
kind "StaticLib"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE QtCreatorProject>
|
||||
<!-- Written by QtCreator 4.11.1, 2020-02-19T00:05:12. -->
|
||||
<!-- Written by QtCreator 4.11.1, 2020-02-25T01:13:48. -->
|
||||
<qtcreator>
|
||||
<data>
|
||||
<variable>EnvironmentId</variable>
|
||||
@@ -79,7 +79,7 @@
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{6d057187-158a-4883-8d5b-d470a6b6b025}</value>
|
||||
<value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">10</value>
|
||||
<value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
|
||||
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">15</value>
|
||||
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
|
||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">../../make/linux</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||
@@ -130,7 +130,7 @@
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<valuelist type="QVariantList" key="GenericProjectManager.GenericMakeStep.BuildTargets"/>
|
||||
<value type="bool" key="GenericProjectManager.GenericMakeStep.Clean">false</value>
|
||||
<value type="QString" key="GenericProjectManager.GenericMakeStep.MakeArguments">-e config=release eepp-test</value>
|
||||
<value type="QString" key="GenericProjectManager.GenericMakeStep.MakeArguments">-e config=release_x86_64 eepp-test</value>
|
||||
<value type="QString" key="GenericProjectManager.GenericMakeStep.MakeCommand"></value>
|
||||
<value type="bool" key="GenericProjectManager.GenericMakeStep.OverrideMakeflags">false</value>
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
@@ -144,7 +144,7 @@
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProcessStep.Arguments">-e config=release clean</value>
|
||||
<value type="QString" key="ProjectExplorer.ProcessStep.Arguments">-e config=release_x86_64 clean</value>
|
||||
<value type="QString" key="ProjectExplorer.ProcessStep.Command">/usr/bin/make</value>
|
||||
<value type="QString" key="ProjectExplorer.ProcessStep.WorkingDirectory">%{buildDir}</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">clean</value>
|
||||
@@ -217,8 +217,8 @@
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
|
||||
<valuelist type="QVariantList" key="GenericProjectManager.GenericMakeStep.BuildTargets"/>
|
||||
<value type="bool" key="GenericProjectManager.GenericMakeStep.Clean">false</value>
|
||||
<value type="QString" key="GenericProjectManager.GenericMakeStep.MakeArguments">-e config=release</value>
|
||||
<value type="QString" key="GenericProjectManager.GenericMakeStep.MakeCommand">make</value>
|
||||
<value type="QString" key="GenericProjectManager.GenericMakeStep.MakeArguments">-e config=release_x86_64</value>
|
||||
<value type="QString" key="GenericProjectManager.GenericMakeStep.MakeCommand"></value>
|
||||
<value type="bool" key="GenericProjectManager.GenericMakeStep.OverrideMakeflags">false</value>
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericMakeStep</value>
|
||||
@@ -231,7 +231,7 @@
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProcessStep.Arguments">-e config=release clean</value>
|
||||
<value type="QString" key="ProjectExplorer.ProcessStep.Arguments">-e config=release_x86_64 clean</value>
|
||||
<value type="QString" key="ProjectExplorer.ProcessStep.Command">make</value>
|
||||
<value type="QString" key="ProjectExplorer.ProcessStep.WorkingDirectory">%{buildDir}</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.ProcessStep</value>
|
||||
@@ -253,7 +253,7 @@
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<valuelist type="QVariantList" key="GenericProjectManager.GenericMakeStep.BuildTargets"/>
|
||||
<value type="bool" key="GenericProjectManager.GenericMakeStep.Clean">false</value>
|
||||
<value type="QString" key="GenericProjectManager.GenericMakeStep.MakeArguments"></value>
|
||||
<value type="QString" key="GenericProjectManager.GenericMakeStep.MakeArguments">-e config=debug_x86</value>
|
||||
<value type="QString" key="GenericProjectManager.GenericMakeStep.MakeCommand">make.sh</value>
|
||||
<value type="bool" key="GenericProjectManager.GenericMakeStep.OverrideMakeflags">false</value>
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
@@ -289,7 +289,7 @@
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<valuelist type="QVariantList" key="GenericProjectManager.GenericMakeStep.BuildTargets"/>
|
||||
<value type="bool" key="GenericProjectManager.GenericMakeStep.Clean">false</value>
|
||||
<value type="QString" key="GenericProjectManager.GenericMakeStep.MakeArguments">-e config=release</value>
|
||||
<value type="QString" key="GenericProjectManager.GenericMakeStep.MakeArguments">-e config=release_x86</value>
|
||||
<value type="QString" key="GenericProjectManager.GenericMakeStep.MakeCommand">make.sh</value>
|
||||
<value type="bool" key="GenericProjectManager.GenericMakeStep.OverrideMakeflags">false</value>
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
@@ -303,7 +303,7 @@
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProcessStep.Arguments">-e config=release clean</value>
|
||||
<value type="QString" key="ProjectExplorer.ProcessStep.Arguments">-e config=release_x86 clean</value>
|
||||
<value type="QString" key="ProjectExplorer.ProcessStep.Command">make.sh</value>
|
||||
<value type="QString" key="ProjectExplorer.ProcessStep.WorkingDirectory">%{buildDir}</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.ProcessStep</value>
|
||||
@@ -657,7 +657,7 @@
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<valuelist type="QVariantList" key="GenericProjectManager.GenericMakeStep.BuildTargets"/>
|
||||
<value type="bool" key="GenericProjectManager.GenericMakeStep.Clean">false</value>
|
||||
<value type="QString" key="GenericProjectManager.GenericMakeStep.MakeArguments">-e config=release eepp-static</value>
|
||||
<value type="QString" key="GenericProjectManager.GenericMakeStep.MakeArguments">-e config=release_x86_64 eepp-static</value>
|
||||
<value type="QString" key="GenericProjectManager.GenericMakeStep.MakeCommand"></value>
|
||||
<value type="bool" key="GenericProjectManager.GenericMakeStep.OverrideMakeflags">false</value>
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
@@ -671,7 +671,7 @@
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProcessStep.Arguments">-e config=release clean</value>
|
||||
<value type="QString" key="ProjectExplorer.ProcessStep.Arguments">-e config=release_x86_64 clean</value>
|
||||
<value type="QString" key="ProjectExplorer.ProcessStep.Command">make</value>
|
||||
<value type="QString" key="ProjectExplorer.ProcessStep.WorkingDirectory">%{buildDir}</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">clean</value>
|
||||
@@ -731,7 +731,7 @@
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<valuelist type="QVariantList" key="GenericProjectManager.GenericMakeStep.BuildTargets"/>
|
||||
<value type="bool" key="GenericProjectManager.GenericMakeStep.Clean">false</value>
|
||||
<value type="QString" key="GenericProjectManager.GenericMakeStep.MakeArguments">-e config=release eepp-shared</value>
|
||||
<value type="QString" key="GenericProjectManager.GenericMakeStep.MakeArguments">-e config=release_x86_64 eepp-shared</value>
|
||||
<value type="QString" key="GenericProjectManager.GenericMakeStep.MakeCommand"></value>
|
||||
<value type="bool" key="GenericProjectManager.GenericMakeStep.OverrideMakeflags">false</value>
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
@@ -745,7 +745,7 @@
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProcessStep.Arguments">-e config=release clean</value>
|
||||
<value type="QString" key="ProjectExplorer.ProcessStep.Arguments">-e config=release_x86_64 clean</value>
|
||||
<value type="QString" key="ProjectExplorer.ProcessStep.Command">make</value>
|
||||
<value type="QString" key="ProjectExplorer.ProcessStep.WorkingDirectory">%{buildDir}</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">clean</value>
|
||||
@@ -813,7 +813,7 @@
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<valuelist type="QVariantList" key="GenericProjectManager.GenericMakeStep.BuildTargets"/>
|
||||
<value type="bool" key="GenericProjectManager.GenericMakeStep.Clean">false</value>
|
||||
<value type="QString" key="GenericProjectManager.GenericMakeStep.MakeArguments">-e config=release eepp-ew</value>
|
||||
<value type="QString" key="GenericProjectManager.GenericMakeStep.MakeArguments">-e config=release_x86_64 eepp-ew</value>
|
||||
<value type="QString" key="GenericProjectManager.GenericMakeStep.MakeCommand"></value>
|
||||
<value type="bool" key="GenericProjectManager.GenericMakeStep.OverrideMakeflags">false</value>
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
@@ -828,7 +828,7 @@
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProcessStep.Arguments">-e config=release clean</value>
|
||||
<value type="QString" key="ProjectExplorer.ProcessStep.Arguments">-e config=release_x86_64 clean</value>
|
||||
<value type="QString" key="ProjectExplorer.ProcessStep.Command">/usr/bin/make</value>
|
||||
<value type="QString" key="ProjectExplorer.ProcessStep.WorkingDirectory">%{buildDir}</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clone of clean</value>
|
||||
@@ -889,7 +889,7 @@
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<valuelist type="QVariantList" key="GenericProjectManager.GenericMakeStep.BuildTargets"/>
|
||||
<value type="bool" key="GenericProjectManager.GenericMakeStep.Clean">false</value>
|
||||
<value type="QString" key="GenericProjectManager.GenericMakeStep.MakeArguments">-e config=release eepp-es</value>
|
||||
<value type="QString" key="GenericProjectManager.GenericMakeStep.MakeArguments">-e config=release_x86_64 eepp-es</value>
|
||||
<value type="QString" key="GenericProjectManager.GenericMakeStep.MakeCommand"></value>
|
||||
<value type="bool" key="GenericProjectManager.GenericMakeStep.OverrideMakeflags">false</value>
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
@@ -904,7 +904,7 @@
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProcessStep.Arguments">-e config=release clean</value>
|
||||
<value type="QString" key="ProjectExplorer.ProcessStep.Arguments">-e config=release_x86_64 clean</value>
|
||||
<value type="QString" key="ProjectExplorer.ProcessStep.Command">/usr/bin/make</value>
|
||||
<value type="QString" key="ProjectExplorer.ProcessStep.WorkingDirectory">%{buildDir}</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clone of clean</value>
|
||||
|
||||
@@ -104,7 +104,7 @@ void UIMap::scheduledUpdate( const Time& time ) {
|
||||
UIWindow::scheduledUpdate( time );
|
||||
|
||||
if ( NULL != mMap ) {
|
||||
invalidate();
|
||||
invalidate( this );
|
||||
invalidateDraw();
|
||||
|
||||
mMap->update();
|
||||
|
||||
@@ -17,8 +17,6 @@ ActionManager::~ActionManager() {
|
||||
}
|
||||
|
||||
void ActionManager::addAction( Action* action ) {
|
||||
Lock lock( mMutex );
|
||||
|
||||
bool found = ( std::find( mActions.begin(), mActions.end(), action ) != mActions.end() );
|
||||
|
||||
if ( !found ) {
|
||||
@@ -27,8 +25,6 @@ void ActionManager::addAction( Action* action ) {
|
||||
}
|
||||
|
||||
Action* ActionManager::getActionByTag( const Uint32& tag ) {
|
||||
Lock lock( mMutex );
|
||||
|
||||
for ( auto it = mActions.begin(); it != mActions.end(); ++it ) {
|
||||
Action* action = ( *it );
|
||||
|
||||
@@ -40,7 +36,6 @@ Action* ActionManager::getActionByTag( const Uint32& tag ) {
|
||||
}
|
||||
|
||||
std::vector<Action*> ActionManager::getActionsFromTarget( Node* target ) {
|
||||
Lock lock( mMutex );
|
||||
std::vector<Action*> actions;
|
||||
|
||||
for ( auto it = mActions.begin(); it != mActions.end(); ++it ) {
|
||||
@@ -54,7 +49,6 @@ std::vector<Action*> ActionManager::getActionsFromTarget( Node* target ) {
|
||||
}
|
||||
|
||||
std::vector<Action*> ActionManager::getActionsByTagFromTarget( Node* target, const Uint32& tag ) {
|
||||
Lock lock( mMutex );
|
||||
std::vector<Action*> actions;
|
||||
|
||||
for ( auto it = mActions.begin(); it != mActions.end(); ++it ) {
|
||||
@@ -74,15 +68,11 @@ void ActionManager::removeActionByTag( const Uint32& tag ) {
|
||||
void ActionManager::removeActionsByTagFromTarget( Node* target, const Uint32& tag ) {
|
||||
std::vector<Action*> removeList;
|
||||
|
||||
{
|
||||
Lock lock( mMutex );
|
||||
for ( auto it = mActions.begin(); it != mActions.end(); ++it ) {
|
||||
Action* action = ( *it );
|
||||
|
||||
for ( auto it = mActions.begin(); it != mActions.end(); ++it ) {
|
||||
Action* action = ( *it );
|
||||
|
||||
if ( action->getTarget() == target && action->getTag() == tag ) {
|
||||
removeList.push_back( *it );
|
||||
}
|
||||
if ( action->getTarget() == target && action->getTag() == tag ) {
|
||||
removeList.push_back( *it );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,25 +86,22 @@ void ActionManager::update( const Time& time ) {
|
||||
|
||||
std::vector<Action*> removeList;
|
||||
|
||||
{
|
||||
Lock lock( mMutex );
|
||||
mUpdating = true;
|
||||
mUpdating = true;
|
||||
|
||||
for ( auto it = mActions.begin(); it != mActions.end(); ++it ) {
|
||||
Action* action = ( *it );
|
||||
for ( auto it = mActions.begin(); it != mActions.end(); ++it ) {
|
||||
Action* action = ( *it );
|
||||
|
||||
action->update( time );
|
||||
action->update( time );
|
||||
|
||||
if ( action->isDone() ) {
|
||||
action->sendEvent( Action::ActionType::OnDone );
|
||||
if ( action->isDone() ) {
|
||||
action->sendEvent( Action::ActionType::OnDone );
|
||||
|
||||
removeList.push_back( action );
|
||||
}
|
||||
removeList.push_back( action );
|
||||
}
|
||||
|
||||
mUpdating = false;
|
||||
}
|
||||
|
||||
mUpdating = false;
|
||||
|
||||
for ( auto it = mActionsRemoveList.begin(); it != mActionsRemoveList.end(); ++it )
|
||||
removeAction( ( *it ) );
|
||||
|
||||
@@ -125,20 +112,14 @@ void ActionManager::update( const Time& time ) {
|
||||
}
|
||||
|
||||
std::size_t ActionManager::count() const {
|
||||
Lock lock( const_cast<Mutex&>( mMutex ) );
|
||||
|
||||
return mActions.size();
|
||||
}
|
||||
|
||||
bool ActionManager::isEmpty() const {
|
||||
Lock lock( const_cast<Mutex&>( mMutex ) );
|
||||
|
||||
return mActions.empty();
|
||||
}
|
||||
|
||||
void ActionManager::clear() {
|
||||
Lock lock( mMutex );
|
||||
|
||||
for ( auto it = mActions.begin(); it != mActions.end(); ++it ) {
|
||||
Action* action = ( *it );
|
||||
|
||||
@@ -149,8 +130,6 @@ void ActionManager::clear() {
|
||||
}
|
||||
|
||||
void ActionManager::removeAction( Action* action ) {
|
||||
Lock lock( mMutex );
|
||||
|
||||
if ( NULL != action ) {
|
||||
if ( !mUpdating ) {
|
||||
bool found = std::find( mActions.begin(), mActions.end(), action ) != mActions.end();
|
||||
@@ -175,15 +154,11 @@ void ActionManager::removeActions( const std::vector<Action*>& actions ) {
|
||||
void ActionManager::removeAllActionsFromTarget( Node* target ) {
|
||||
std::vector<Action*> removeList;
|
||||
|
||||
{
|
||||
Lock lock( mMutex );
|
||||
for ( auto it = mActions.begin(); it != mActions.end(); ++it ) {
|
||||
Action* action = ( *it );
|
||||
|
||||
for ( auto it = mActions.begin(); it != mActions.end(); ++it ) {
|
||||
Action* action = ( *it );
|
||||
|
||||
if ( action->getTarget() == target ) {
|
||||
removeList.push_back( *it );
|
||||
}
|
||||
if ( action->getTarget() == target ) {
|
||||
removeList.push_back( *it );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ void EventDispatcher::inputCallback( InputEvent* Event ) {
|
||||
case InputEvent::VideoResize:
|
||||
case InputEvent::VideoExpose: {
|
||||
if ( NULL != mSceneNode )
|
||||
mSceneNode->invalidate();
|
||||
mSceneNode->invalidate( NULL );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1101,7 +1101,7 @@ void Node::setReverseDraw( bool reverseDraw ) {
|
||||
|
||||
void Node::invalidateDraw() {
|
||||
if ( NULL != mNodeDrawInvalidator ) {
|
||||
mNodeDrawInvalidator->invalidate();
|
||||
mNodeDrawInvalidator->invalidate( this );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1572,7 +1572,7 @@ bool Node::isDrawInvalidator() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
void Node::invalidate() {
|
||||
void Node::invalidate( Node* invalidator ) {
|
||||
if ( mVisible && mAlpha != 0.f ) {
|
||||
writeNodeFlag( NODE_FLAG_VIEW_DIRTY, 1 );
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ bool isTimingFunction( const std::string& str ) {
|
||||
return Ease::Interpolation::None != Ease::fromName( str, Ease::Interpolation::None );
|
||||
}
|
||||
|
||||
std::map<std::string, AnimationDefinition> AnimationDefinition::parseAnimationProperties(
|
||||
std::unordered_map<std::string, AnimationDefinition> AnimationDefinition::parseAnimationProperties(
|
||||
const std::vector<StyleSheetProperty>& stylesheetProperties ) {
|
||||
AnimationsMap animations;
|
||||
std::vector<std::string> names;
|
||||
@@ -41,40 +41,39 @@ std::map<std::string, AnimationDefinition> AnimationDefinition::parseAnimationPr
|
||||
std::string val( String::trim( String::toLower( part ) ) );
|
||||
|
||||
if ( isDirectionString( val ) ) {
|
||||
animationDef.direction = directionFromString( val );
|
||||
animationDef.setDirection( directionFromString( val ) );
|
||||
} else if ( isAnimationFillModeString( val ) ) {
|
||||
animationDef.fillMode = fillModeFromString( val );
|
||||
animationDef.setFillMode( fillModeFromString( val ) );
|
||||
} else if ( "infinite" == val ) {
|
||||
animationDef.iterations = -1;
|
||||
animationDef.setIterations( -1 );
|
||||
} else if ( "paused" == val ) {
|
||||
animationDef.paused = true;
|
||||
animationDef.setPaused( true );
|
||||
} else if ( "running" == val ) {
|
||||
animationDef.paused = false;
|
||||
animationDef.setPaused( false );
|
||||
} else if ( isTimingFunction( val ) ) {
|
||||
animationDef.timingFunction = Ease::fromName( val );
|
||||
animationDef.setTimingFunction( Ease::fromName( val ) );
|
||||
} else if ( Time::isValid( val ) ) {
|
||||
if ( durationSet ) {
|
||||
animationDef.delay =
|
||||
StyleSheetProperty( "animation-delay", val ).asTime();
|
||||
animationDef.setDelay( Time::fromString( val ) );
|
||||
} else {
|
||||
animationDef.duration =
|
||||
StyleSheetProperty( "animation-duration", val ).asTime();
|
||||
animationDef.setDuration( Time::fromString( val ) );
|
||||
durationSet = true;
|
||||
}
|
||||
} else if ( String::isNumber( val, true ) ) {
|
||||
int iterations = 1;
|
||||
|
||||
if ( String::fromString( iterations, val ) ) {
|
||||
animationDef.iterations = iterations;
|
||||
animationDef.setIterations( iterations );
|
||||
}
|
||||
} else {
|
||||
animationDef.name = part;
|
||||
animationDef.setName( part );
|
||||
}
|
||||
}
|
||||
|
||||
animations[animationDef.name] = std::move( animationDef );
|
||||
animations[animationDef.getName()] = std::move( animationDef );
|
||||
}
|
||||
}
|
||||
return animations;
|
||||
break;
|
||||
}
|
||||
case PropertyId::AnimationName:
|
||||
@@ -133,27 +132,27 @@ std::map<std::string, AnimationDefinition> AnimationDefinition::parseAnimationPr
|
||||
|
||||
for ( size_t i = 0; i < names.size(); i++ ) {
|
||||
AnimationDefinition animationDef;
|
||||
animationDef.name = names[i];
|
||||
animationDef.setName( names[i] );
|
||||
|
||||
if ( !delays.empty() )
|
||||
animationDef.delay = delays[i % delays.size()];
|
||||
animationDef.setDelay( delays[i % delays.size()] );
|
||||
|
||||
if ( !durations.empty() )
|
||||
animationDef.duration = delays[i % durations.size()];
|
||||
animationDef.setDuration( delays[i % durations.size()] );
|
||||
|
||||
if ( !fillModes.empty() )
|
||||
animationDef.fillMode = fillModes[i % fillModes.size()];
|
||||
animationDef.setFillMode( fillModes[i % fillModes.size()] );
|
||||
|
||||
if ( !pausedStates.empty() )
|
||||
animationDef.paused = pausedStates[i % pausedStates.size()];
|
||||
animationDef.setPaused( pausedStates[i % pausedStates.size()] );
|
||||
|
||||
if ( !iterations.empty() )
|
||||
animationDef.iterations = iterations[i % iterations.size()];
|
||||
animationDef.setIterations( iterations[i % iterations.size()] );
|
||||
|
||||
if ( !timingFunctions.empty() )
|
||||
animationDef.timingFunction = timingFunctions[i % timingFunctions.size()];
|
||||
animationDef.setTimingFunction( timingFunctions[i % timingFunctions.size()] );
|
||||
|
||||
animations[animationDef.name] = std::move( animationDef );
|
||||
animations[animationDef.getName()] = std::move( animationDef );
|
||||
}
|
||||
|
||||
return animations;
|
||||
@@ -205,31 +204,72 @@ AnimationDefinition::AnimationFillMode AnimationDefinition::fillModeFromString(
|
||||
AnimationDefinition::AnimationDefinition() {}
|
||||
|
||||
const AnimationDefinition::AnimationDirection& AnimationDefinition::getDirection() const {
|
||||
return direction;
|
||||
return mDirection;
|
||||
}
|
||||
|
||||
const bool& AnimationDefinition::isPaused() const {
|
||||
return paused;
|
||||
return mPaused;
|
||||
}
|
||||
|
||||
const Int32& AnimationDefinition::getIterations() const {
|
||||
return iterations;
|
||||
return mIterations;
|
||||
}
|
||||
|
||||
const std::string& AnimationDefinition::getName() const {
|
||||
return name;
|
||||
return mName;
|
||||
}
|
||||
|
||||
const Time& AnimationDefinition::getDelay() const {
|
||||
return delay;
|
||||
return mDelay;
|
||||
}
|
||||
|
||||
const Time& AnimationDefinition::getDuration() const {
|
||||
return duration;
|
||||
return mDuration;
|
||||
}
|
||||
|
||||
const Ease::Interpolation& AnimationDefinition::getTimingFunction() const {
|
||||
return timingFunction;
|
||||
return mTimingFunction;
|
||||
}
|
||||
|
||||
void AnimationDefinition::setName( const std::string& value ) {
|
||||
mName = value;
|
||||
mId = String::hash( mName );
|
||||
}
|
||||
|
||||
void AnimationDefinition::setFillMode( const AnimationFillMode& value ) {
|
||||
mFillMode = value;
|
||||
}
|
||||
|
||||
void AnimationDefinition::setPaused( bool value ) {
|
||||
mPaused = value;
|
||||
}
|
||||
|
||||
const Uint32& AnimationDefinition::getId() const {
|
||||
return mId;
|
||||
}
|
||||
|
||||
const AnimationDefinition::AnimationFillMode& AnimationDefinition::getFillMode() const {
|
||||
return mFillMode;
|
||||
}
|
||||
|
||||
void AnimationDefinition::setDirection( const AnimationDirection& value ) {
|
||||
mDirection = value;
|
||||
}
|
||||
|
||||
void AnimationDefinition::setTimingFunction( const Ease::Interpolation& value ) {
|
||||
mTimingFunction = value;
|
||||
}
|
||||
|
||||
void AnimationDefinition::setIterations( const Int32& value ) {
|
||||
mIterations = value;
|
||||
}
|
||||
|
||||
void AnimationDefinition::setDuration( const Time& value ) {
|
||||
mDuration = value;
|
||||
}
|
||||
|
||||
void AnimationDefinition::setDelay( const Time& value ) {
|
||||
mDelay = value;
|
||||
}
|
||||
|
||||
}}} // namespace EE::UI::CSS
|
||||
|
||||
@@ -106,12 +106,14 @@ const KeyframesDefinition& StyleSheet::getKeyframesDefinition( const std::string
|
||||
}
|
||||
|
||||
void StyleSheet::addKeyframes( const KeyframesDefinition& keyframes ) {
|
||||
mKeyframesMap[keyframes.getName()] = keyframes;
|
||||
// "none" is a reserved keyword
|
||||
if ( keyframes.getName() != "none" )
|
||||
mKeyframesMap[keyframes.getName()] = keyframes;
|
||||
}
|
||||
|
||||
void StyleSheet::addKeyframes( const KeyframesDefinitionMap& keyframesMap ) {
|
||||
for ( auto& keyframe : keyframesMap ) {
|
||||
mKeyframesMap[keyframe.first] = keyframe.second;
|
||||
for ( auto& keyframes : keyframesMap ) {
|
||||
addKeyframes( keyframes.second );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -172,9 +172,9 @@ StyleSheetPropertyAnimation* StyleSheetPropertyAnimation::New(
|
||||
const Uint32& propertyIndex, const Time& duration, const Time& delay,
|
||||
const Ease::Interpolation& timingFunction, const AnimationOrigin& animationOrigin ) {
|
||||
AnimationDefinition animation;
|
||||
animation.delay = delay;
|
||||
animation.duration = duration;
|
||||
animation.timingFunction = timingFunction;
|
||||
animation.setDelay( delay );
|
||||
animation.setDuration( duration );
|
||||
animation.setTimingFunction( timingFunction );
|
||||
return New( animation, property, {startValue, endValue}, {0, 1}, propertyIndex,
|
||||
animationOrigin );
|
||||
}
|
||||
@@ -189,9 +189,10 @@ StyleSheetPropertyAnimation::StyleSheetPropertyAnimation( const AnimationDefinit
|
||||
mPropertyDef( propertyDef ),
|
||||
mStates( states ),
|
||||
mAnimationStepsTime( animationStepsTime ),
|
||||
mPendingIterations( animation.iterations ),
|
||||
mPendingIterations( animation.getIterations() ),
|
||||
mPropertyIndex( propertyIndex ),
|
||||
mAnimationOrigin( animationOrigin ) {
|
||||
mAnimationOrigin( animationOrigin ),
|
||||
mPaused( mAnimation.isPaused() ) {
|
||||
mId = ID;
|
||||
}
|
||||
|
||||
@@ -208,38 +209,41 @@ void StyleSheetPropertyAnimation::stop() {
|
||||
}
|
||||
|
||||
void StyleSheetPropertyAnimation::update( const Time& time ) {
|
||||
if ( mPaused )
|
||||
return;
|
||||
|
||||
mRealElapsed += time;
|
||||
|
||||
bool wasDone = false;
|
||||
|
||||
if ( mRealElapsed >= mAnimation.delay ) {
|
||||
if ( mRealElapsed >= mAnimation.getDelay() ) {
|
||||
mElapsed += time;
|
||||
|
||||
if ( mPendingIterations > 0 ) {
|
||||
while ( mElapsed > mAnimation.duration ) {
|
||||
while ( mElapsed > mAnimation.getDuration() ) {
|
||||
if ( mPendingIterations > 0 ) {
|
||||
mPendingIterations--;
|
||||
|
||||
if ( mPendingIterations > 0 ) {
|
||||
wasDone = true;
|
||||
mElapsed -= mAnimation.duration;
|
||||
mElapsed -= mAnimation.getDuration();
|
||||
} else {
|
||||
mElapsed = mAnimation.duration;
|
||||
mElapsed = mAnimation.getDuration();
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if ( mPendingIterations == -1 ) {
|
||||
while ( mElapsed > mAnimation.duration ) {
|
||||
mElapsed -= mAnimation.duration;
|
||||
while ( mElapsed > mAnimation.getDuration() ) {
|
||||
mElapsed -= mAnimation.getDuration();
|
||||
wasDone = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( wasDone && ( mPendingIterations > 0 || mPendingIterations == -1 ) ) {
|
||||
if ( mAnimation.direction == AnimationDefinition::AnimationDirection::Alternate ||
|
||||
mAnimation.direction ==
|
||||
if ( mAnimation.getDirection() == AnimationDefinition::AnimationDirection::Alternate ||
|
||||
mAnimation.getDirection() ==
|
||||
AnimationDefinition::AnimationDirection::AlternateReverse ) {
|
||||
reverseAnimation();
|
||||
}
|
||||
@@ -254,16 +258,16 @@ void StyleSheetPropertyAnimation::update( const Time& time ) {
|
||||
}
|
||||
|
||||
bool StyleSheetPropertyAnimation::isDone() {
|
||||
return mElapsed.asMicroseconds() >= mAnimation.duration.asMicroseconds() &&
|
||||
return mElapsed.asMicroseconds() >= mAnimation.getDuration().asMicroseconds() &&
|
||||
( mPendingIterations == 0 || mPendingIterations != -1 );
|
||||
}
|
||||
|
||||
Float StyleSheetPropertyAnimation::getCurrentProgress() {
|
||||
return eemin( mElapsed.asMilliseconds() / mAnimation.duration.asMilliseconds(), 1. );
|
||||
return eemin( mElapsed.asMilliseconds() / mAnimation.getDuration().asMilliseconds(), 1. );
|
||||
}
|
||||
|
||||
Time StyleSheetPropertyAnimation::getTotalTime() {
|
||||
return mAnimation.duration;
|
||||
return mAnimation.getDuration();
|
||||
}
|
||||
|
||||
Action* StyleSheetPropertyAnimation::clone() const {
|
||||
@@ -291,7 +295,7 @@ const std::string& StyleSheetPropertyAnimation::getEndValue() const {
|
||||
}
|
||||
|
||||
void StyleSheetPropertyAnimation::onStart() {
|
||||
if ( mRealElapsed >= mAnimation.delay ) {
|
||||
if ( mRealElapsed >= mAnimation.getDelay() ) {
|
||||
onUpdate( Time::Zero );
|
||||
}
|
||||
}
|
||||
@@ -313,15 +317,58 @@ void StyleSheetPropertyAnimation::onUpdate( const Time& time ) {
|
||||
|
||||
if ( curPos - 1 >= 0 && curPos < static_cast<Int32>( mStates.size() ) ) {
|
||||
tweenProperty( widget, normalizedProgress, mPropertyDef, mStates[curPos - 1],
|
||||
mStates[curPos], mAnimation.timingFunction, mPropertyIndex, isDone() );
|
||||
mStates[curPos], mAnimation.getTimingFunction(), mPropertyIndex,
|
||||
isDone() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void StyleSheetPropertyAnimation::onTargetChange() {
|
||||
if ( NULL != mNode && mNode->isWidget() && mAnimationOrigin == AnimationOrigin::Animation ) {
|
||||
UIWidget* widget = mNode->asType<UIWidget>();
|
||||
mFillModeValue = widget->getPropertyString( mPropertyDef, mPropertyIndex );
|
||||
if ( mAnimation.getFillMode() == AnimationDefinition::AnimationFillMode::None ) {
|
||||
UIWidget* widget = mNode->asType<UIWidget>();
|
||||
mFillModeValue = widget->getPropertyString( mPropertyDef, mPropertyIndex );
|
||||
} else if ( mAnimation.getFillMode() == AnimationDefinition::AnimationFillMode::Forwards ) {
|
||||
if ( mStates.empty() )
|
||||
return;
|
||||
switch ( mAnimation.getDirection() ) {
|
||||
case AnimationDefinition::AnimationDirection::Normal: {
|
||||
mFillModeValue = mStates[mStates.size() - 1];
|
||||
break;
|
||||
}
|
||||
case AnimationDefinition::AnimationDirection::Reverse: {
|
||||
mFillModeValue = mStates[0];
|
||||
break;
|
||||
}
|
||||
case AnimationDefinition::AnimationDirection::Alternate: {
|
||||
if ( mAnimation.getIterations() % 2 == 0 ) {
|
||||
mFillModeValue = mStates[0];
|
||||
} else {
|
||||
mFillModeValue = mStates[mStates.size() - 1];
|
||||
}
|
||||
break;
|
||||
}
|
||||
case AnimationDefinition::AnimationDirection::AlternateReverse: {
|
||||
if ( mAnimation.getIterations() % 2 == 0 ) {
|
||||
mFillModeValue = mStates[mStates.size() - 1];
|
||||
} else {
|
||||
|
||||
mFillModeValue = mStates[0];
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if ( mAnimation.getFillMode() ==
|
||||
AnimationDefinition::AnimationFillMode::Backwards ) {
|
||||
if ( mStates.empty() )
|
||||
return;
|
||||
if ( mAnimation.getDirection() == AnimationDefinition::AnimationDirection::Normal ||
|
||||
mAnimation.getDirection() == AnimationDefinition::AnimationDirection::Alternate ) {
|
||||
mFillModeValue = mStates[0];
|
||||
} else {
|
||||
mFillModeValue = mStates[mStates.size() - 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -329,10 +376,10 @@ void StyleSheetPropertyAnimation::setElapsed( const Time& elapsed ) {
|
||||
mElapsed = elapsed;
|
||||
|
||||
if ( mPendingIterations > 0 ) {
|
||||
while ( mElapsed > mAnimation.duration ) {
|
||||
while ( mElapsed > mAnimation.getDuration() ) {
|
||||
if ( mPendingIterations > 0 ) {
|
||||
mPendingIterations--;
|
||||
mElapsed = mAnimation.duration - mElapsed;
|
||||
mElapsed = mAnimation.getDuration() - mElapsed;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
@@ -344,9 +391,17 @@ const AnimationOrigin& StyleSheetPropertyAnimation::getAnimationOrigin() const {
|
||||
return mAnimationOrigin;
|
||||
}
|
||||
|
||||
void StyleSheetPropertyAnimation::setRunning( const bool& running ) {
|
||||
mPaused = !running;
|
||||
}
|
||||
|
||||
void StyleSheetPropertyAnimation::setPaused( const bool& paused ) {
|
||||
mPaused = paused;
|
||||
}
|
||||
|
||||
void StyleSheetPropertyAnimation::notifyClose() {
|
||||
if ( mAnimationOrigin == AnimationOrigin::Animation && NULL != mNode && mNode->isWidget() ) {
|
||||
if ( mAnimation.fillMode == AnimationDefinition::AnimationFillMode::None ) {
|
||||
if ( mAnimation.getFillMode() != AnimationDefinition::AnimationFillMode::Both ) {
|
||||
UIWidget* widget = mNode->asType<UIWidget>();
|
||||
widget->applyProperty(
|
||||
StyleSheetProperty( mPropertyDef, mFillModeValue, mPropertyIndex ) );
|
||||
@@ -354,13 +409,17 @@ void StyleSheetPropertyAnimation::notifyClose() {
|
||||
}
|
||||
}
|
||||
|
||||
const AnimationDefinition& StyleSheetPropertyAnimation::getAnimation() const {
|
||||
return mAnimation;
|
||||
}
|
||||
|
||||
const Time& StyleSheetPropertyAnimation::getElapsed() const {
|
||||
return mElapsed;
|
||||
}
|
||||
|
||||
void StyleSheetPropertyAnimation::prepareDirection() {
|
||||
if ( mAnimation.direction == AnimationDefinition::AnimationDirection::Reverse ||
|
||||
mAnimation.direction == AnimationDefinition::AnimationDirection::AlternateReverse ) {
|
||||
if ( mAnimation.getDirection() == AnimationDefinition::AnimationDirection::Reverse ||
|
||||
mAnimation.getDirection() == AnimationDefinition::AnimationDirection::AlternateReverse ) {
|
||||
reverseAnimation();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,11 +6,14 @@ namespace EE { namespace UI { namespace CSS {
|
||||
SINGLETON_DECLARE_IMPLEMENTATION( StyleSheetSpecification )
|
||||
|
||||
StyleSheetSpecification::StyleSheetSpecification() {
|
||||
// TODO: Add support to animations (@keyframes).
|
||||
// TODO: Add correct "background" and "foreground" shorthand.
|
||||
// TODO: Support border-color top right bottom left.
|
||||
// TODO: Support border-radius top right bottom left.
|
||||
// TODO: Support box-sizing or something similar.
|
||||
// TODO: Add correct "background" and "foreground" shorthand.
|
||||
// TODO: Create a rule to set the border position against its box.
|
||||
// Something like: "border-box", with the following options:
|
||||
// inside: The border is drawn inside the box.
|
||||
// outside: The border is drawn outside the box.
|
||||
// over: The border is drawn in the middle point of inside and outside.
|
||||
registerDefaultProperties();
|
||||
registerDefaultNodeSelectors();
|
||||
}
|
||||
|
||||
@@ -182,27 +182,27 @@ UIColorPicker::UIColorPicker( UIWindow* attachTo, const UIColorPicker::ColorPick
|
||||
</RelativeLayout>
|
||||
</LinearLayout>
|
||||
<Widget class="separator" layout_width="match_parent" layout_height="1dp" />
|
||||
<LinearLayout id="red_container" class="slider_container" orientation="horizontal" ayout_width="match_parent" layout_height="wrap_content">
|
||||
<LinearLayout id="red_container" class="slider_container" orientation="horizontal" layout_width="match_parent" layout_height="wrap_content">
|
||||
<TextView layout_width="16dp" layout_height="wrap_content" text="R" layout_gravity="center" />
|
||||
<Slider layout_width="0dp" layout_weight="1" layout_height="wrap_content" orientation="horizontal" layout_gravity="center" minValue="0" maxValue="255" />
|
||||
<SpinBox layout_width="48dp" layout_height="wrap_content" minValue="0" maxValue="255" />
|
||||
</LinearLayout>
|
||||
<LinearLayout id="green_container" class="slider_container" orientation="horizontal" ayout_width="match_parent" layout_height="wrap_content">
|
||||
<LinearLayout id="green_container" class="slider_container" orientation="horizontal" layout_width="match_parent" layout_height="wrap_content">
|
||||
<TextView layout_width="16dp" layout_height="wrap_content" text="G" layout_gravity="center" />
|
||||
<Slider layout_width="0dp" layout_weight="1" layout_height="wrap_content" orientation="horizontal" layout_gravity="center" minValue="0" maxValue="255" />
|
||||
<SpinBox layout_width="48dp" layout_height="wrap_content" minValue="0" maxValue="255" />
|
||||
</LinearLayout>
|
||||
<LinearLayout id="blue_container" class="slider_container" orientation="horizontal" ayout_width="match_parent" layout_height="wrap_content">
|
||||
<LinearLayout id="blue_container" class="slider_container" orientation="horizontal" layout_width="match_parent" layout_height="wrap_content">
|
||||
<TextView layout_width="16dp" layout_height="wrap_content" text="B" layout_gravity="center" />
|
||||
<Slider layout_width="0dp" layout_weight="1" layout_height="wrap_content" orientation="horizontal" layout_gravity="center" minValue="0" maxValue="255" />
|
||||
<SpinBox layout_width="48dp" layout_height="wrap_content" minValue="0" maxValue="255" />
|
||||
</LinearLayout>
|
||||
<LinearLayout id="alpha_container" class="slider_container" orientation="horizontal" ayout_width="match_parent" layout_height="wrap_content">
|
||||
<LinearLayout id="alpha_container" class="slider_container" orientation="horizontal" layout_width="match_parent" layout_height="wrap_content">
|
||||
<TextView layout_width="16dp" layout_height="wrap_content" text="A" layout_gravity="center" />
|
||||
<Slider layout_width="0dp" layout_weight="1" layout_height="wrap_content" orientation="horizontal" layout_gravity="center" minValue="0" maxValue="255" />
|
||||
<SpinBox layout_width="48dp" layout_height="wrap_content" minValue="0" maxValue="255" />
|
||||
</LinearLayout>
|
||||
<LinearLayout id="footer" class="footer" orientation="horizontal" ayout_width="match_parent" layout_height="wrap_content">
|
||||
<LinearLayout id="footer" class="footer" orientation="horizontal" layout_width="match_parent" layout_height="wrap_content">
|
||||
<Widget layout_width="0dp" layout_weight="1" layout_height="match_parent" />
|
||||
<TextView layout_width="wrap_content" layout_height="wrap_content" text="#" layout_gravity="center" />
|
||||
<TextInput layout_width="120dp" layout_height="wrap_content" />
|
||||
|
||||
@@ -97,6 +97,26 @@ bool UIStyle::hasTransition( const std::string& propertyName ) {
|
||||
mTransitions.find( "all" ) != mTransitions.end();
|
||||
}
|
||||
|
||||
StyleSheetPropertyAnimation* UIStyle::getAnimation( const PropertyDefinition* propertyDef ) {
|
||||
std::vector<Action*> actions = mWidget->getActionsByTag( propertyDef->getId() );
|
||||
if ( !actions.empty() ) {
|
||||
for ( auto& action : actions ) {
|
||||
if ( action->getId() == StyleSheetPropertyAnimation::ID ) {
|
||||
StyleSheetPropertyAnimation* animation =
|
||||
static_cast<StyleSheetPropertyAnimation*>( action );
|
||||
if ( animation->getAnimationOrigin() == AnimationOrigin::Animation ) {
|
||||
return animation;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool UIStyle::hasAnimation( const PropertyDefinition* propertyDef ) {
|
||||
return NULL != getAnimation( propertyDef );
|
||||
}
|
||||
|
||||
TransitionDefinition UIStyle::getTransition( const std::string& propertyName ) {
|
||||
auto propertyTransitionIt = mTransitions.find( propertyName );
|
||||
|
||||
@@ -152,9 +172,9 @@ void UIStyle::tryApplyStyle( const StyleSheetStyle& style ) {
|
||||
mProperties[property.getId()] = property;
|
||||
|
||||
if ( String::startsWith( property.getName(), "transition" ) )
|
||||
mTransitionAttributes.push_back( property );
|
||||
mTransitionProperties.push_back( property );
|
||||
else if ( String::startsWith( property.getName(), "animation" ) )
|
||||
mAnimationAttributes.push_back( property );
|
||||
mAnimationProperties.push_back( property );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -223,12 +243,10 @@ void UIStyle::onStateChange() {
|
||||
if ( NULL != mWidget ) {
|
||||
mChangingState = true;
|
||||
|
||||
bool wasAnAnimation = !mAnimations.empty();
|
||||
CSS::StyleSheetProperties prevProperties( mProperties );
|
||||
mProperties.clear();
|
||||
mTransitionAttributes.clear();
|
||||
mAnimationAttributes.clear();
|
||||
mAnimations.clear();
|
||||
mTransitionProperties.clear();
|
||||
mAnimationProperties.clear();
|
||||
|
||||
tryApplyStyle( mElementStyle );
|
||||
|
||||
@@ -241,21 +259,14 @@ void UIStyle::onStateChange() {
|
||||
}
|
||||
|
||||
if ( !mapEquals( mProperties, prevProperties ) ) {
|
||||
if ( wasAnAnimation )
|
||||
removeAllAnimations();
|
||||
|
||||
if ( !mAnimationAttributes.empty() ) {
|
||||
mAnimations = AnimationDefinition::parseAnimationProperties( mAnimationAttributes );
|
||||
}
|
||||
|
||||
if ( !mTransitionAttributes.empty() ) {
|
||||
mTransitions =
|
||||
TransitionDefinition::parseTransitionProperties( mTransitionAttributes );
|
||||
}
|
||||
|
||||
mWidget->beginAttributesTransaction();
|
||||
|
||||
startAnimations();
|
||||
updateAnimations();
|
||||
|
||||
if ( !mTransitionProperties.empty() ) {
|
||||
mTransitions =
|
||||
TransitionDefinition::parseTransitionProperties( mTransitionProperties );
|
||||
}
|
||||
|
||||
for ( auto& prop : mProperties ) {
|
||||
StyleSheetProperty& property = prop.second;
|
||||
@@ -382,7 +393,8 @@ void UIStyle::applyStyleSheetProperty( const StyleSheetProperty& property,
|
||||
|
||||
if ( !mWidget->isSceneNodeLoading() && NULL != propertyDefinition &&
|
||||
StyleSheetPropertyAnimation::animationSupported( propertyDefinition->getType() ) &&
|
||||
hasTransition( property.getName() ) ) {
|
||||
hasTransition( property.getName() ) &&
|
||||
!hasAnimation( property.getPropertyDefinition() ) ) {
|
||||
std::string currentValue =
|
||||
mWidget->getPropertyString( propertyDefinition, property.getIndex() );
|
||||
std::string startValue( currentValue );
|
||||
@@ -467,14 +479,95 @@ void UIStyle::applyStyleSheetProperty( const StyleSheetProperty& property,
|
||||
}
|
||||
}
|
||||
|
||||
void UIStyle::startAnimations() {
|
||||
void UIStyle::updateAnimations() {
|
||||
bool isDifferent = false;
|
||||
CSS::AnimationsMap animations;
|
||||
|
||||
if ( !mAnimationProperties.empty() ) {
|
||||
animations = AnimationDefinition::parseAnimationProperties( mAnimationProperties );
|
||||
if ( animations.size() == mAnimations.size() ) {
|
||||
for ( auto& animation : animations ) {
|
||||
auto animIt = mAnimations.find( animation.second.getName() );
|
||||
if ( animIt == mAnimations.end() || animIt->second != animation.second ) {
|
||||
isDifferent = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
isDifferent = true;
|
||||
}
|
||||
} else if ( !mAnimations.empty() && mAnimationProperties.empty() ) {
|
||||
isDifferent = true;
|
||||
}
|
||||
|
||||
if ( isDifferent ) {
|
||||
mAnimations.clear();
|
||||
|
||||
removeAllAnimations();
|
||||
|
||||
startAnimations( animations );
|
||||
} else if ( !mAnimationProperties.empty() ) {
|
||||
updateAnimationsPlayState();
|
||||
}
|
||||
}
|
||||
|
||||
void UIStyle::updateAnimationsPlayState() {
|
||||
if ( mAnimations.empty() )
|
||||
return;
|
||||
std::vector<Action*> actions = mWidget->getActions();
|
||||
for ( auto& action : actions ) {
|
||||
if ( action->getId() == StyleSheetPropertyAnimation::ID ) {
|
||||
StyleSheetPropertyAnimation* animation =
|
||||
static_cast<StyleSheetPropertyAnimation*>( action );
|
||||
if ( animation->getAnimationOrigin() == AnimationOrigin::Animation ) {
|
||||
// Check all the active animations.
|
||||
size_t animPos = 0;
|
||||
for ( auto anim = mAnimations.begin(); anim != mAnimations.end(); anim++ ) {
|
||||
// Find the animation index by iterating over them...
|
||||
if ( anim->first == animation->getAnimation().getName() ) {
|
||||
// Once found the iteration index of the corresponding keyframe animation
|
||||
// First check if in the current animation properties is there any
|
||||
// "animation-play-state" definition.
|
||||
bool isSet = false;
|
||||
for ( auto& animProp : mAnimationProperties ) {
|
||||
if ( NULL != animProp.getPropertyDefinition() &&
|
||||
animProp.getPropertyDefinition()->getPropertyId() ==
|
||||
PropertyId::AnimationPlayState ) {
|
||||
// If found, get the pause/running state of the property, using the
|
||||
// index of the current animation, and set the animation.play-state.
|
||||
size_t animPropCount = animProp.getPropertyIndexCount();
|
||||
bool paused = animProp.getPropertyIndex( animPos % animPropCount )
|
||||
.getValue() == "paused"
|
||||
? true
|
||||
: false;
|
||||
animation->setPaused( paused );
|
||||
isSet = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// If animation-play-state if set, continue with the next action.
|
||||
if ( isSet )
|
||||
break;
|
||||
// Otherwise set the animation-play-state defined on the animation.
|
||||
animation->setPaused( animation->getAnimation().isPaused() );
|
||||
}
|
||||
animPos++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UIStyle::startAnimations( const CSS::AnimationsMap& animations ) {
|
||||
UISceneNode* uiSceneNode = mWidget->getUISceneNode();
|
||||
|
||||
if ( NULL == uiSceneNode )
|
||||
return;
|
||||
|
||||
mAnimations = animations;
|
||||
|
||||
CSS::StyleSheet& styleSheet = uiSceneNode->getStyleSheet();
|
||||
for ( auto& anim : mAnimations ) {
|
||||
for ( auto& anim : animations ) {
|
||||
if ( styleSheet.isKeyframesDefined( anim.first ) ) {
|
||||
const AnimationDefinition& animation = anim.second;
|
||||
const KeyframesDefinition& keyframes = styleSheet.getKeyframesDefinition( anim.first );
|
||||
@@ -493,6 +586,7 @@ void UIStyle::startAnimations() {
|
||||
StyleSheetPropertyAnimation* newAnimation =
|
||||
StyleSheetPropertyAnimation::fromAnimationKeyframes(
|
||||
animation, keyframes, propDef, mWidget, i );
|
||||
newAnimation->setFlags( animation.getId() );
|
||||
newAnimation->setTag( propDef->getId() );
|
||||
mWidget->runAction( newAnimation );
|
||||
}
|
||||
@@ -501,6 +595,7 @@ void UIStyle::startAnimations() {
|
||||
StyleSheetPropertyAnimation* newAnimation =
|
||||
StyleSheetPropertyAnimation::fromAnimationKeyframes(
|
||||
animation, keyframes, propDef, mWidget, 0 );
|
||||
newAnimation->setFlags( animation.getId() );
|
||||
newAnimation->setTag( propDef->getId() );
|
||||
mWidget->runAction( newAnimation );
|
||||
}
|
||||
@@ -509,6 +604,7 @@ void UIStyle::startAnimations() {
|
||||
StyleSheetPropertyAnimation* newAnimation =
|
||||
StyleSheetPropertyAnimation::fromAnimationKeyframes(
|
||||
animation, keyframes, propDef, mWidget, 0 );
|
||||
newAnimation->setFlags( animation.getId() );
|
||||
newAnimation->setTag( propDef->getId() );
|
||||
mWidget->runAction( newAnimation );
|
||||
}
|
||||
|
||||
@@ -160,6 +160,33 @@ std::string UITabWidget::getPropertyString( const PropertyDefinition* propertyDe
|
||||
}
|
||||
}
|
||||
|
||||
bool UITabWidget::isDrawInvalidator() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
void UITabWidget::invalidate( Node* invalidator ) {
|
||||
// Only invalidate if the invalidator is actually visible in the current active tab.
|
||||
if ( NULL != invalidator ) {
|
||||
if ( invalidator == mCtrlContainer ) {
|
||||
mSceneNode->invalidate( mCtrlContainer );
|
||||
} else if ( invalidator->getParent() == mCtrlContainer ) {
|
||||
if ( invalidator->isVisible() ) {
|
||||
mSceneNode->invalidate( mCtrlContainer );
|
||||
}
|
||||
} else {
|
||||
Node* container = invalidator->getParent();
|
||||
while ( container->getParent() != NULL && container->getParent() != mCtrlContainer ) {
|
||||
container = container->getParent();
|
||||
}
|
||||
if ( container->getParent() == mCtrlContainer && container->isVisible() ) {
|
||||
mSceneNode->invalidate( mCtrlContainer );
|
||||
}
|
||||
}
|
||||
} else if ( NULL != mSceneNode ) {
|
||||
mSceneNode->invalidate( this );
|
||||
}
|
||||
}
|
||||
|
||||
bool UITabWidget::applyProperty( const StyleSheetProperty& attribute ) {
|
||||
if ( !checkPropertyDefinition( attribute ) )
|
||||
return false;
|
||||
|
||||
@@ -1112,7 +1112,7 @@ void UIWindow::onPositionChange() {
|
||||
// Invalidate the buffer since a position change can get childs into a drawable position
|
||||
// (on screen), when the drawable could have been outside the viewport and not drawn in the
|
||||
// previous position.
|
||||
invalidate();
|
||||
invalidate( this );
|
||||
|
||||
UIWidget::onPositionChange();
|
||||
}
|
||||
@@ -1241,12 +1241,12 @@ void UIWindow::internalDraw() {
|
||||
}
|
||||
}
|
||||
|
||||
void UIWindow::invalidate() {
|
||||
void UIWindow::invalidate( Node* invalidator ) {
|
||||
if ( mVisible && mAlpha != 0.f ) {
|
||||
writeNodeFlag( NODE_FLAG_VIEW_DIRTY, 1 );
|
||||
|
||||
if ( NULL != mSceneNode )
|
||||
mSceneNode->invalidate();
|
||||
mSceneNode->invalidate( invalidator );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
2
src/thirdparty/SOIL2
vendored
2
src/thirdparty/SOIL2
vendored
Submodule src/thirdparty/SOIL2 updated: d6886e006e...5adc6cd56b
2
src/thirdparty/efsw
vendored
2
src/thirdparty/efsw
vendored
Submodule src/thirdparty/efsw updated: e9990449f4...36f27d7ccf
Reference in New Issue
Block a user