Skip to content

Instantly share code, notes, and snippets.

@huandu
Last active December 11, 2015 15:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save huandu/4624133 to your computer and use it in GitHub Desktop.
Save huandu/4624133 to your computer and use it in GitHub Desktop.
Sample concept source files for project "shana".

"shana" is a project to introduce html-like rendering experience to opengl-based cross platform mobile apps. It will be built on top of cocos2d-x 2.x.

"shana" will define a new mark-up UI language looks like html. It will use stylesheet and CSS selectors to ease styling work. To make styling work even more flexible, "shana" will support expressions in all node attributes and style rules. Writing "center" in attribute "x", or "parent.width/2+10" in attribute "width" will work exactly as expected.

"shana" will include a compiler to generate binary shana file from xml sources and a C++ lib to render shana file and manipulate nodes. It may include an http server to compile source files on the fly. And it may also include several apps to load and preview shana file on mobile devices.

"shana" project scope is quite big. Currently, I'm doing very early design work. If you are interested in this project, please feel free to let me know. Your suggestion and/or participant is highly appreciated.

<!--scene is the top level node in shana. its width/height is always screen width/height.-->
<scene>
<!--include an external stylesheet.-->
<!--inline stylesheet is NOT allowed.-->
<style src="sample_style.css" />
<!--include an external script.-->
<!--inline scripting is NOT allowed.-->
<script src="sample_script.js" />
<!--static image. width/height is image width/height by default. anchor point default value is (0.5, 0.5).-->
<node class="logo" x="center" y="scene.height-20" />
<!--static text. text width/height is decided by real font size on screen. it may vary on different platforms.-->
<text x="center" y="scene.height-80">Hello, world!</text>
<!--include an external widget in this scene. widget contains a set of nodes. its width/height must be set when included.-->
<widget src="sample_widget.xml" x="center" y="scene.height-120" width="scene.width" height="200" />
</scene>
// shana provides a global var '$' or 'Shana'.
// $ selector query works like jQuery. the root document node is always 'scene'.
// $ also provides some useful methods for manipulate node attributes and animations.
//
// what needs to keep in mind is that this javascript will NOT run in browser.
// there won't be 'window' object. shana's nodes are not compatible with DOM API.
// use script to implement animation and simple UI logic only.
// call this function when scene is created.
// it's a short hand of
// $('scene').on('load', function() { ... })
$(function() {
// say_hello and credit button are fade in in a sequence.
var ani = $.play(
$.animate('button').attr('enabled', 'no'), // create an animation to change attribute on selector result.
$('#say_hello').fadeIn(0.5),
$('#credit').fadeIn(0.5),
[
// following two animations happen start at same time.
$.animate('button').attr('enabled', 'yes'),
$.animate('#say_hello').text('Say Hey')
]
);
// handle 'tap' event.
// following events are supported.
// - load: node is created.
// - unload: node will be destroyed.
// - enter: node will be placed on screen.
// - exit: node leaves screen.
// - tap: touch starts and ends on the sample node.
// - touchstart: touch starts.
// - touchend: touch ends.
// - touchmove: touch moves.
// - touchenter: touch enters a node content boundary.
// - touchleave: touch leaves a node content boundary.
// - touchcancel: touch cancels.
$('scene').on('tap', function(e) {
// animation can be stopped or ended at any time.
ani.end(); // run all animations in ani to the end instantly
});
$('#say_hello').on('tap', function(e) {
// it's possible to call outer method implemented by C++.
// if outer method is not defined, throw exception.
$.call('showSayHello'); // call showSayHello() without any param.
})
});
// define a class
.logo { image: logo.png; }
// define default style for all <text> nodes.
text { font-family: Helvetica; font-size: 32; }
// define style for node with id "credit"
#credit { width: scene.width/2; height: auto; }
<widget>
<button id="say_hello" x="center" y="10"
image="say_hello_normal.png" image-tapped="say_hello_tapped.png" image-disabled="say_hello_disabled.png">Say Hello</button>
<button id="credit" x="center" y="#say_hello.y+25">Credit</button>
</widget>
#include "shana.h"
using namespace shana;
// omit function declaration...
// sample_page.xml, sample_widget.xml, sample_script.js, sample_style.css,
// and referenced png files are compiled to sample.shana.
Shana* shana = Shana::load("sample.shana");
// create scene based on sample_page.xml.
SScene* sample = shana->scene("sample_page");
// change scene node content with jQuery style selector.
// attr() will change attribute on all selected nodes.
sample->query("text")->attr("font-size", 24);
// or read attribute of first selected node.
// if font-size is not a valid attribute or not a float attribute,
// throw an exception.
SVFloat fontSize = sample->query("text")->attr("font-size");
// create a new node and set attributes.
SNode* node = shana->node();
node->attr("id", "new_node");
node->attr("x", "center");
node->attr("y", "scene.height-300"); // expression is allowed in dynamic created node.
node->attr("background-color", "blue");
node->attr("width", 100);
node->attr("height", 100);
sample->append(node);
// handle tapped events.
sample->query("#credit")->on([=this] (const SEvent::Tapped& event) {
// do something...
});
// export a C++ method to javascript.
sample->export("showSayHello", [=this] () {
// do something...
});
// add sample scene to global director with a customized and unique name.
// use SDirector::instance()->get("sample") to get the scene if necessary.
SDirector::instance()->add("sample", sample);
// finally, show the sample scene on screen.
sample->show();

Design principles

  1. Intuitive
  2. Strict

Intuitive - Every node, attribute and api function must be intuitive. Samples should be enough to start using it.

Strict - There is no warning in shana, only correct and error. It's a compile error to write any tag or attribute shana doesn't know in any xml files. Setting invalid value to any attribute will trigger C++ or javascript exception.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment