Explorar el Código

Create data binding sample

Michael Ragazzon hace 6 años
padre
commit
0250e9debe

+ 7 - 0
CMake/SampleFileList.cmake

@@ -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
 )
 

+ 1 - 1
CMake/gen_samplelists.sh

@@ -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'

+ 4 - 1
CMakeLists.txt

@@ -446,7 +446,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)
@@ -663,6 +663,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
 	)

+ 233 - 0
Samples/basic/databinding/data/databinding.rml

@@ -0,0 +1,233 @@
+<rml>
+<head>
+<link type="text/template" href="../../../assets/window.rml"/>
+<title>Data Binding Sample</title>
+<style>
+body.window
+{
+	width: 1300px;
+	height: 750px;
+	min-width: 1090px;
+	min-height: 300px;
+	max-width: -1px;
+	max-height: -1px;
+}
+div#title_bar div#icon
+{
+	display: none;
+}
+div#content
+{ 
+	position: relative; 
+}
+tabset
+{
+	display: block;
+}
+tabs
+{
+    display: block;
+	position: fixed;
+	clip: none;
+	text-align: right;
+	padding-left: 200px;
+	padding-right: 10px;
+	top: -47px;
+}
+tab
+{
+    width: 100px;
+	padding: 0px 20px;
+	line-height: 40px;
+	
+	font-size: 16px;
+	color: #ddd;
+	text-align: center;
+	
+	decorator: tiled-horizontal( datagridheader-l, datagridheader-c, datagridheader-r );
+	image-color: #cffc;
+}
+tab:hover
+{
+	image-color: #fffe;
+	color: #fff;
+}
+tab:active, tab:selected
+{
+	image-color: #fff;
+	color: #fff;
+}
+panels
+{
+    display: block;
+}
+panel
+{
+    display: block;
+	padding: 30px;
+	margin-left: auto;
+	margin-right: auto;
+	max-width: 500px;
+}
+h1
+{
+	margin: 1.4em 0 0.7em;
+	font-size: 18px;
+}
+p.title
+{
+	font-size: 35px;
+	color: #b33;
+	font-effect: glow(2px #ed5);
+}
+.center {
+	text-align: center;
+}
+.clickable
+{ 
+	cursor: pointer;
+}
+
+
+/***  Decorators  ***/
+#decorators {
+	text-align: left;
+}
+#decorators p
+{
+	margin: 0.5em 0;
+}
+#decorators button.gradient
+{
+	decorator: gradient( vertical #415857 #5990A3 );
+	border: 2px #415857;
+	margin-right: 12px;
+}
+#decorators button.gradient.horizontal
+{
+	decorator: gradient( horizontal #DB6565 #F1B58A );
+	border: 2px #DB6565;
+}
+#decorators button.gradient:hover
+{
+	border-color: #F9EFA3;
+}
+
+/***  Font effects  ***/
+
+#font_effects div 
+{
+	display: inline-block;
+	width: 150px;
+	margin: 0px 30px 30px;
+	text-align: center;
+	font-size: 35px;
+	color: #b33;
+}
+
+
+/***  Forms  ***/
+
+form
+{
+	display: block;
+	text-align: left;
+}
+form input, form select { margin-left: 0; }
+form h2 
+{
+	display: block;
+	font-size: 16px;
+	font-weight: bold;
+	margin-top: 8px;
+}
+#rating {
+	display: inline-block;
+	width: 40px;
+	padding-left: 1em;
+}
+#rating_emoji { 
+	color: #ffd40f;
+	font-size: 1.7em;
+}
+#controls textarea 
+{
+	font-size: 18px;
+	font-effect: outline(2px #006600);
+	color: #ddd;
+}
+</style>
+</head>
+
+<body template="window">
+<tabset id="menu">
+<tab>Welcome</tab>
+<panel id="welcome">
+	<p class="title" style="margin-top: 1.8em;">{{hello_world}}</p>
+	<p>Data binding demo.</p>
+</panel>
+<tab>Decorators</tab>
+<panel id="decorators">
+	<h1>Gradient decorator</h1>
+	<p>The 'gradient' decorator renders a color gradient in the vertical or horizontal direction.</p>
+	<div class="center">
+		<button class="gradient">Gradient</button>
+		<button class="gradient horizontal">Gradient</button>
+	</div>
+</panel>
+<tab>Font effects</tab>
+<panel id="font_effects">
+	<h1>None</h1>
+	<div class="original">RmlUi 😍</div>
+</panel>
+<tab>Forms</tab>
+<panel id="controls">
+	<form onsubmit="submit_form">
+		<h2>Full name</h2>
+		<div>
+			<input type="text" size="20" name="name"/>
+		</div>
+		<h2>Email and password</h2>
+		<div>
+			<input type="text" size="10" name="email"/>
+			<input type="password" size="10" name="password"/>
+		</div>
+		<h2>Favorite animal</h2>
+		<div>
+			<input type="radio" name="animal" value="dog" checked/> Dog
+			<input type="radio" name="animal" value="cat"/> Cat
+			<input type="radio" name="animal" value="narwhal"/> Narwhal
+			<input type="radio" name="animal" value="no"/> I don't like animals
+		</div>
+		<h2>Favorite meals</h2>
+		<div>
+			<input type="checkbox" name="meals" value="pizza" checked/> Pizza
+			<input type="checkbox" name="meals" value="pasta" checked/> Pasta
+			<input type="checkbox" name="meals" value="lasagne" checked/> Lasagne
+		</div>
+		<h2>Rating</h2>
+		<div>
+			<input type="range" name="rating" min="0" max="100" step="1" value="50" onchange="rating"/> <span id="rating"/><span id="rating_emoji">&nbsp;</span>
+		</div>
+		<h2>Subject</h2>
+		<div>
+			<select name="subject">
+				<option value="none" selected>Choose your subject</option>
+				<option value="feature">Feature request</option>
+				<option value="bug">Bug report</option>
+				<option value="praise">Praise</option>
+				<option value="criticism">Criticism</option>
+			</select>
+		</div>
+		<h2>Message</h2>
+		<div>
+			<textarea cols="30" rows="5" wrap="nowrap" name="message">😍 Hello 🌐 World! 😎</textarea>
+		</div>
+		<div style="margin-bottom: 15px;">
+			<input type="submit">Submit</input>
+		</div>
+	</form>
+</panel>
+</tabset>
+</body>
+</rml>

+ 232 - 0
Samples/basic/databinding/src/main.cpp

@@ -0,0 +1,232 @@
+/*
+ * This source file is part of RmlUi, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://github.com/mikke89/RmlUi
+ *
+ * Copyright (c) 2018 Michael R. P. Ragazzon
+ * Copyright (c) 2019 The RmlUi Team, and contributors
+ *
+ * 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.
+ *
+ */
+
+#include <RmlUi/Core.h>
+#include <RmlUi/Controls.h>
+#include <RmlUi/Debugger.h>
+#include <Input.h>
+#include <Shell.h>
+#include <ShellRenderInterfaceOpenGL.h>
+
+
+class DemoWindow : public Rml::Core::EventListener
+{
+public:
+	DemoWindow(const Rml::Core::String &title, const Rml::Core::Vector2f &position, Rml::Core::Context *context)
+	{
+		using namespace Rml::Core;
+		document = context->LoadDocument("basic/databinding/data/databinding.rml");
+		if (document)
+		{
+			document->GetElementById("title")->SetInnerRML(title);
+			document->SetProperty(PropertyId::Left, Property(position.x, Property::PX));
+			document->SetProperty(PropertyId::Top, Property(position.y, Property::PX));
+
+			document->Show();
+		}
+	}
+
+	void Update() 
+	{
+
+	}
+
+	void Shutdown() 
+	{
+		if (document)
+		{
+			document->Close();
+			document = nullptr;
+		}
+	}
+
+	void ProcessEvent(Rml::Core::Event& event) override
+	{
+		using namespace Rml::Core;
+
+		switch (event.GetId())
+		{
+		case EventId::Keydown:
+		{
+			Rml::Core::Input::KeyIdentifier key_identifier = (Rml::Core::Input::KeyIdentifier) event.GetParameter< int >("key_identifier", 0);
+			bool ctrl_key = event.GetParameter< bool >("ctrl_key", false);
+
+			if (key_identifier == Rml::Core::Input::KI_ESCAPE)
+			{
+				Shell::RequestExit();
+			}
+			else if (key_identifier == Rml::Core::Input::KI_F8)
+			{
+				Rml::Debugger::SetVisible(!Rml::Debugger::IsVisible());
+			}
+		}
+		break;
+
+		default:
+			break;
+		}
+	}
+
+	Rml::Core::ElementDocument * GetDocument() {
+		return document;
+	}
+
+
+private:
+	Rml::Core::ElementDocument *document = nullptr;
+};
+
+
+Rml::Core::Context* context = nullptr;
+ShellRenderInterfaceExtensions *shell_renderer;
+std::unique_ptr<DemoWindow> demo_window;
+
+void GameLoop()
+{
+	demo_window->Update();
+	context->Update();
+
+	shell_renderer->PrepareRenderBuffer();
+	context->Render();
+	shell_renderer->PresentRenderBuffer();
+}
+
+
+
+
+class DemoEventListener : public Rml::Core::EventListener
+{
+public:
+	DemoEventListener(const Rml::Core::String& value, Rml::Core::Element* element) : value(value), element(element) {}
+
+	void ProcessEvent(Rml::Core::Event& event) override
+	{
+		using namespace Rml::Core;
+
+		if (value == "exit")
+		{
+			Shell::RequestExit();
+		}
+	}
+
+	void OnDetach(Rml::Core::Element* element) override { delete this; }
+
+private:
+	Rml::Core::String value;
+	Rml::Core::Element* element;
+};
+
+
+
+class DemoEventListenerInstancer : public Rml::Core::EventListenerInstancer
+{
+public:
+	Rml::Core::EventListener* InstanceEventListener(const Rml::Core::String& value, Rml::Core::Element* element) override
+	{
+		return new DemoEventListener(value, element);
+	}
+};
+
+
+#if defined RMLUI_PLATFORM_WIN32
+#include <windows.h>
+int APIENTRY WinMain(HINSTANCE RMLUI_UNUSED_PARAMETER(instance_handle), HINSTANCE RMLUI_UNUSED_PARAMETER(previous_instance_handle), char* RMLUI_UNUSED_PARAMETER(command_line), int RMLUI_UNUSED_PARAMETER(command_show))
+#else
+int main(int RMLUI_UNUSED_PARAMETER(argc), char** RMLUI_UNUSED_PARAMETER(argv))
+#endif
+{
+#ifdef RMLUI_PLATFORM_WIN32
+	RMLUI_UNUSED(instance_handle);
+	RMLUI_UNUSED(previous_instance_handle);
+	RMLUI_UNUSED(command_line);
+	RMLUI_UNUSED(command_show);
+#else
+	RMLUI_UNUSED(argc);
+	RMLUI_UNUSED(argv);
+#endif
+
+	const int width = 1600;
+	const int height = 900;
+
+	ShellRenderInterfaceOpenGL opengl_renderer;
+	shell_renderer = &opengl_renderer;
+
+	// Generic OS initialisation, creates a window and attaches OpenGL.
+	if (!Shell::Initialise() ||
+		!Shell::OpenWindow("Data Binding Sample", shell_renderer, width, height, true))
+	{
+		Shell::Shutdown();
+		return -1;
+	}
+
+	// RmlUi initialisation.
+	Rml::Core::SetRenderInterface(&opengl_renderer);
+	opengl_renderer.SetViewport(width, height);
+
+	ShellSystemInterface system_interface;
+	Rml::Core::SetSystemInterface(&system_interface);
+
+	Rml::Core::Initialise();
+
+	// Create the main RmlUi context and set it on the shell's input layer.
+	context = Rml::Core::CreateContext("main", Rml::Core::Vector2i(width, height));
+	if (context == nullptr)
+	{
+		Rml::Core::Shutdown();
+		Shell::Shutdown();
+		return -1;
+	}
+
+	Rml::Controls::Initialise();
+	Rml::Debugger::Initialise(context);
+	Input::SetContext(context);
+	shell_renderer->SetContext(context);
+	
+	DemoEventListenerInstancer event_listener_instancer;
+	Rml::Core::Factory::RegisterEventListenerInstancer(&event_listener_instancer);
+
+	Shell::LoadFonts("assets/");
+
+	demo_window = std::make_unique<DemoWindow>("Data binding", Rml::Core::Vector2f(150, 50), context);
+	demo_window->GetDocument()->AddEventListener(Rml::Core::EventId::Keydown, demo_window.get());
+	demo_window->GetDocument()->AddEventListener(Rml::Core::EventId::Keyup, demo_window.get());
+
+	Shell::EventLoop(GameLoop);
+
+	demo_window->Shutdown();
+
+	// Shutdown RmlUi.
+	Rml::Core::Shutdown();
+
+	Shell::CloseWindow();
+	Shell::Shutdown();
+
+	demo_window.reset();
+
+	return 0;
+}