Skip to content

Commit

Permalink
Merge branch 'data_binding'
Browse files Browse the repository at this point in the history
# Conflicts:
#	Source/Core/Context.cpp
#	Source/Core/Element.cpp
#	Source/Core/Factory.cpp
  • Loading branch information
mikke89 committed Jun 28, 2020
2 parents 97a288f + 08bc704 commit c09981b
Show file tree
Hide file tree
Showing 77 changed files with 5,944 additions and 422 deletions.
17 changes: 17 additions & 0 deletions CMake/FileList.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ set(Core_HDR_FILES
${PROJECT_SOURCE_DIR}/Source/Core/Clock.h
${PROJECT_SOURCE_DIR}/Source/Core/ComputeProperty.h
${PROJECT_SOURCE_DIR}/Source/Core/ContextInstancerDefault.h
${PROJECT_SOURCE_DIR}/Source/Core/DataControllerDefault.h
${PROJECT_SOURCE_DIR}/Source/Core/DataExpression.h
${PROJECT_SOURCE_DIR}/Source/Core/DataViewDefault.h
${PROJECT_SOURCE_DIR}/Source/Core/DecoratorGradient.h
${PROJECT_SOURCE_DIR}/Source/Core/DecoratorNinePatch.h
${PROJECT_SOURCE_DIR}/Source/Core/DecoratorTiled.h
Expand Down Expand Up @@ -107,6 +110,12 @@ set(Core_PUB_HDR_FILES
${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/ContextInstancer.h
${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/ConvolutionFilter.h
${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Core.h
${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/DataController.h
${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/DataModel.h
${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/DataTypeRegister.h
${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/DataTypes.h
${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/DataVariable.h
${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/DataView.h
${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Debug.h
${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Decorator.h
${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/DecoratorInstancer.h
Expand Down Expand Up @@ -191,6 +200,14 @@ set(Core_SRC_FILES
${PROJECT_SOURCE_DIR}/Source/Core/ContextInstancerDefault.cpp
${PROJECT_SOURCE_DIR}/Source/Core/ConvolutionFilter.cpp
${PROJECT_SOURCE_DIR}/Source/Core/Core.cpp
${PROJECT_SOURCE_DIR}/Source/Core/DataController.cpp
${PROJECT_SOURCE_DIR}/Source/Core/DataControllerDefault.cpp
${PROJECT_SOURCE_DIR}/Source/Core/DataExpression.cpp
${PROJECT_SOURCE_DIR}/Source/Core/DataModel.cpp
${PROJECT_SOURCE_DIR}/Source/Core/DataTypeRegister.cpp
${PROJECT_SOURCE_DIR}/Source/Core/DataVariable.cpp
${PROJECT_SOURCE_DIR}/Source/Core/DataView.cpp
${PROJECT_SOURCE_DIR}/Source/Core/DataViewDefault.cpp
${PROJECT_SOURCE_DIR}/Source/Core/Decorator.cpp
${PROJECT_SOURCE_DIR}/Source/Core/DecoratorGradient.cpp
${PROJECT_SOURCE_DIR}/Source/Core/DecoratorInstancer.cpp
Expand Down
7 changes: 7 additions & 0 deletions CMake/SampleFileList.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,13 @@ set(customlog_SRC_FILES
${PROJECT_SOURCE_DIR}/Samples/basic/customlog/src/SystemInterface.cpp
)

set(databinding_HDR_FILES
)

set(databinding_SRC_FILES
${PROJECT_SOURCE_DIR}/Samples/basic/databinding/src/main.cpp
)

set(demo_HDR_FILES
)

Expand Down
2 changes: 1 addition & 1 deletion CMake/gen_samplelists.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ hdr='set(sample_HDR_FILES'
srcdir='${PROJECT_SOURCE_DIR}'
srcpath=Samples
samples=( 'shell'
'basic/animation' 'basic/benchmark' 'basic/bitmapfont' 'basic/customlog' 'basic/demo' 'basic/drag' 'basic/loaddocument' 'basic/treeview' 'basic/transform'
'basic/animation' 'basic/benchmark' 'basic/bitmapfont' 'basic/customlog' 'basic/databinding' 'basic/demo' 'basic/drag' 'basic/loaddocument' 'basic/treeview' 'basic/transform'
'basic/sdl2' 'basic/sfml2'
'tutorial/template' 'tutorial/datagrid' 'tutorial/datagrid_tree' 'tutorial/drag'
'invaders' 'luainvaders'
Expand Down
5 changes: 4 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,7 @@ endmacro()
if(BUILD_SAMPLES)
include(SampleFileList)

set(samples treeview customlog drag loaddocument transform bitmapfont animation benchmark demo)
set(samples treeview customlog drag loaddocument transform bitmapfont animation benchmark demo databinding)
set(tutorials template datagrid datagrid_tree drag)

if(NOT BUILD_FRAMEWORK)
Expand Down Expand Up @@ -668,6 +668,9 @@ if(BUILD_SAMPLES)
install(DIRECTORY ${PROJECT_SOURCE_DIR}/Samples/basic/bitmapfont/data
DESTINATION ${SAMPLES_DIR}/basic/bitmapfont
)
install(DIRECTORY ${PROJECT_SOURCE_DIR}/Samples/basic/databinding/data
DESTINATION ${SAMPLES_DIR}/basic/databinding
)
install(DIRECTORY ${PROJECT_SOURCE_DIR}/Samples/basic/demo/data
DESTINATION ${SAMPLES_DIR}/basic/demo
)
Expand Down
6 changes: 6 additions & 0 deletions Include/RmlUi/Core.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@
#include "Core/ComputedValues.h"
#include "Core/Context.h"
#include "Core/ContextInstancer.h"
#include "Core/DataController.h"
#include "Core/DataModel.h"
#include "Core/DataTypeRegister.h"
#include "Core/DataTypes.h"
#include "Core/DataVariable.h"
#include "Core/DataView.h"
#include "Core/Decorator.h"
#include "Core/DecoratorInstancer.h"
#include "Core/Element.h"
Expand Down
58 changes: 40 additions & 18 deletions Include/RmlUi/Core/BaseXMLParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ namespace Rml {
namespace Core {

class Stream;
class URL;
using XMLAttributes = Dictionary;

enum class XMLDataType { Text, CData, InnerXML };

/**
@author Peter Curry
Expand All @@ -53,6 +57,14 @@ class RMLUICORE_API BaseXMLParser
/// @param[in] tag The tag to register as containing generic character data.
void RegisterCDATATag(const String& tag);

/// When an XML attribute with the given name is encountered during parsing, then all content below the current
/// node is treated as data.
/// @note While children nodes are treated as data (text), it is assumed that the content represents valid XML.
/// The parsing proceeds as normal except that the Handle...() functions are not called until the
/// starting node is closed. Then, all its contents are submitted as Data (raw text string).
/// @note In particular, this behavior is useful for some data-binding views.
void RegisterInnerXMLAttribute(const String& attribute_name);

/// Parses the given stream as an XML file, and calls the handlers when
/// interesting phenomena are encountered.
void Parse(Stream* stream);
Expand All @@ -68,50 +80,60 @@ class RMLUICORE_API BaseXMLParser
/// Called when the parser finds the end of an element tag.
virtual void HandleElementEnd(const String& name);
/// Called when the parser encounters data.
virtual void HandleData(const String& data);
virtual void HandleData(const String& data, XMLDataType type);

protected:
// The stream we're reading the XML from.
Stream* xml_source;
const URL* GetSourceURLPtr() const;

private:
const URL* source_url = nullptr;
String xml_source;
size_t xml_index = 0;

void Next();
bool AtEnd() const;
char Look() const;

void HandleElementStartInternal(const String& name, const XMLAttributes& attributes);
void HandleElementEndInternal(const String& name);
void HandleDataInternal(const String& data, XMLDataType type);

void ReadHeader();
void ReadBody();

bool ReadOpenTag();
bool ReadCloseTag();
bool ReadAttributes(XMLAttributes& attributes);
bool ReadCDATA(const char* terminator = nullptr);

bool ReadCloseTag(size_t xml_index_tag);
bool ReadAttributes(XMLAttributes& attributes, bool& parse_raw_xml_content);
bool ReadCDATA(const char* tag_terminator = nullptr);

// Reads from the stream until a complete word is found.
// @param[out] word Word thats been found
// @param[in] terminators List of characters that terminate the search
bool FindWord(String& word, const char* terminators = nullptr);
// Reads from the stream until the given character set is found. All
// intervening characters will be returned in data.
bool FindString(const unsigned char* string, String& data);
bool FindString(const char* string, String& data, bool escape_brackets = false);
// Returns true if the next sequence of characters in the stream
// matches the given string. If consume is set and this returns true,
// the characters will be consumed.
bool PeekString(const unsigned char* string, bool consume = true);
bool PeekString(const char* string, bool consume = true);

// Fill the buffer as much as possible, without removing any content that is still pending
bool FillBuffer();
int line_number = 0;
int line_number_open_tag = 0;
int open_tag_depth = 0;

unsigned char* read;
unsigned char* buffer;
int buffer_size;
int buffer_used;
int line_number;
int line_number_open_tag;
int open_tag_depth;
// Enabled when an attribute for inner xml data is encountered (see description in Register...() above).
bool inner_xml_data = false;
int inner_xml_data_terminate_depth = 0;
size_t inner_xml_data_index_begin = 0;

// The element attributes being read.
XMLAttributes attributes;
// The loose data being read.
String data;

SmallUnorderedSet< String > cdata_tags;
SmallUnorderedSet< String > attributes_for_inner_xml_data;
};

}
Expand Down
2 changes: 1 addition & 1 deletion Include/RmlUi/Core/Containers/chobo/flat_map.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ class flat_map
template <class... Args>
std::pair<iterator, bool> emplace(Args&&... args)
{
value_type val(args...);
value_type val(std::forward<Args>(args)...);
return insert(std::move(val));
}

Expand Down
2 changes: 1 addition & 1 deletion Include/RmlUi/Core/Containers/chobo/flat_set.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ class flat_set
template <class... Args>
std::pair<iterator, bool> emplace(Args&&... args)
{
value_type val(args...);
value_type val(std::forward<Args>(args)...);
return insert(std::move(val));
}

Expand Down
34 changes: 31 additions & 3 deletions Include/RmlUi/Core/Context.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ class ContextInstancer;
class ElementDocument;
class EventListener;
class RenderInterface;
class DataModel;
class DataModelConstructor;
class DataTypeRegister;
enum class EventId : uint16_t;

/**
Expand Down Expand Up @@ -218,6 +221,25 @@ class RMLUICORE_API Context : public ScriptInterface
/// @param[in] instancer The context's instancer.
void SetInstancer(ContextInstancer* instancer);

/// Creates a data model.
/// The returned constructor can be used to bind data variables. Elements can bind to the model using the attribute 'data-model="name"'.
/// @param[in] name The name of the data model.
/// @return A constructor for the data model, or empty if it could not be created.
DataModelConstructor CreateDataModel(const String& name);

/// Retrieves the constructor for an existing data model.
/// The returned constructor can be used to add additional bindings to an existing model.
/// @param[in] name The name of the data model.
/// @return A constructor for the data model, or empty if it could not be found.
DataModelConstructor GetDataModel(const String& name);

/// Removes the given data model.
/// This also removes all data views, controllers and bindings contained by the data model.
/// @warning Invalidates all handles and constructors pointing to the data model.
/// @param[in] name The name of the data model.
/// @return True if succesfully removed, false if no data model was found.
bool RemoveDataModel(const String& name);

protected:
void Release() override;

Expand Down Expand Up @@ -286,6 +308,11 @@ class RMLUICORE_API Context : public ScriptInterface
Vector2i clip_origin;
Vector2i clip_dimensions;

using DataModels = UnorderedMap<String, UniquePtr<DataModel>>;
DataModels data_models;

UniquePtr<DataTypeRegister> data_type_register;

// Internal callback for when an element is detached or removed from the hierarchy.
void OnElementDetach(Element* element);
// Internal callback for when a new element gains focus.
Expand All @@ -297,13 +324,14 @@ class RMLUICORE_API Context : public ScriptInterface
// Updates the current hover elements, sending required events.
void UpdateHoverChain(const Dictionary& parameters, const Dictionary& drag_parameters, const Vector2i& old_mouse_position);

// Creates the drag clone from the given element. The old drag clone will be released if
// necessary.
// @param[in] element The element to clone.
// Creates the drag clone from the given element. The old drag clone will be released if necessary.
void CreateDragClone(Element* element);
// Releases the drag clone, if one exists.
void ReleaseDragClone();

// Returns the data model with the provided name, or nullptr if it does not exist.
DataModel* GetDataModelPtr(const String& name) const;

// Builds the parameters for a generic key event.
void GenerateKeyEventParameters(Dictionary& parameters, Input::KeyIdentifier key_identifier);
// Builds the parameters for a generic mouse event.
Expand Down
Loading

0 comments on commit c09981b

Please sign in to comment.