From a9ead80a3f5389bbea75800d855057cae8103255 Mon Sep 17 00:00:00 2001 From: Nick Holland Date: Thu, 26 Mar 2015 17:38:49 +0000 Subject: [PATCH] JavaScript and JSON command line launcher Usage: Will load both JSON and JavaScript file from command line scripting.example my-scene.json my-script.js Change-Id: I36330b8bae84a532f57989b4087843d178d03e0b --- com.samsung.dali-demo.xml | 3 + examples/scripting/launcher.cpp | 103 +++++++++++++++++++++++++++++ examples/scripting/launcher.h | 66 +++++++++++++++++++ examples/scripting/scripting-example.cpp | 96 +++++++++++++++++++++++++++ resources/scripts/simple-image-wall.js | 108 +++++++++++++++++++++++++++++++ 5 files changed, 376 insertions(+) create mode 100644 examples/scripting/launcher.cpp create mode 100644 examples/scripting/launcher.h create mode 100644 examples/scripting/scripting-example.cpp create mode 100644 resources/scripts/simple-image-wall.js diff --git a/com.samsung.dali-demo.xml b/com.samsung.dali-demo.xml index 028ee55..79d2187 100644 --- a/com.samsung.dali-demo.xml +++ b/com.samsung.dali-demo.xml @@ -52,6 +52,9 @@ + + + diff --git a/examples/scripting/launcher.cpp b/examples/scripting/launcher.cpp new file mode 100644 index 0000000..6c11537 --- /dev/null +++ b/examples/scripting/launcher.cpp @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// CLASS HEADER +#include "launcher.h" + +// EXTERNAL INCLUDES +#include +#include +#include + + + +using namespace Dali; + +#define TOKEN_STRING(x) #x + +namespace +{ +std::string GetFileContents(const std::string& filename) +{ + std::ifstream t(filename.c_str()); + return std::string((std::istreambuf_iterator(t)), + std::istreambuf_iterator()); +}; + +} // unnamed namespace + +Launcher::Launcher( Dali::Application application, std::string layoutFileName, std::string scriptFileName ) +: mApplication( application ), + mJSONFileName(layoutFileName ), + mJavaScriptFileName( scriptFileName ) +{ + + mApplication.InitSignal().Connect( this, &Launcher::Create ); +} + +Launcher::~Launcher() +{ +} + +void Launcher::Create( Dali::Application& application ) +{ + TextActor textActor = TextActor::New( "JSON & JavaScript Launcher..." ); + + // Reposition the actor + textActor.SetParentOrigin( ParentOrigin::TOP_LEFT ); + textActor.SetAnchorPoint( AnchorPoint::TOP_LEFT ); + textActor.SetPosition( 20, 0 ); + + // Get a handle to the stage + Stage stage = Stage::GetCurrent(); + + // Display the actor on the stage + stage.Add( textActor ); + + // change the background color to purple + Stage::GetCurrent().SetBackgroundColor( Vector4(0.2,0.2,0.4,1.0) ); + + // Try loading a JSON file + if( !mJSONFileName.empty() ) + { + mBuilder = Toolkit::Builder::New(); + + Property::Map defaultDirs; + defaultDirs[ TOKEN_STRING(DALI_IMAGE_DIR) ] = DALI_IMAGE_DIR; + defaultDirs[ TOKEN_STRING(DALI_MODEL_DIR) ] = DALI_MODEL_DIR; + defaultDirs[ TOKEN_STRING(DALI_SCRIPT_DIR) ] = DALI_SCRIPT_DIR; + mBuilder.AddConstants( defaultDirs ); + + std::string json_data(GetFileContents( mJSONFileName )); + mBuilder.LoadFromString(json_data); + mBuilder.AddActors( stage.GetRootLayer() ); + } + + // Try load a JavaScript file + if( !mJavaScriptFileName.empty() ) + { + // execute the script + mScript = Toolkit::Script::New(); + + mScript.ExecuteFile( mJavaScriptFileName); + } +} + +void Launcher::MainLoop() +{ + mApplication.MainLoop(); +} diff --git a/examples/scripting/launcher.h b/examples/scripting/launcher.h new file mode 100644 index 0000000..dc56b42 --- /dev/null +++ b/examples/scripting/launcher.h @@ -0,0 +1,66 @@ +#ifndef DALI_APP_H +#define DALI_APP_H + +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// EXTERNAL INCLUDES +#include +#include + +/** + * Example app that can load both JSON and JavaScript files from command line + * E.g. scripting.example my-first.js my-first.json + * See dali-demo/resources/scripts for example JSON and JavaScript files + */ +class Launcher: public Dali::ConnectionTracker +{ +public: + + /** + * @brief Construcctor + * @param application application + * @param layoutFileName JSON file to run + * @param scriptFileName JavaScript file to run + */ + Launcher( Dali::Application application, std::string layoutFileName, std::string scriptFileName ); + + /** + * @brief destructor + */ + ~Launcher(); + + /** + * @brief create app + */ + void Create( Dali::Application& application ); + + /** + * @brief run application MainLoop + */ + void MainLoop(); + +private: + + Dali::Toolkit::Script mScript; ///< Used to load and execute JavaScript + Dali::Toolkit::Builder mBuilder; ///< Used to parse JSON + Dali::Application mApplication; ///< application + std::string mJSONFileName; ///< JSON filename + std::string mJavaScriptFileName; ///< JavaScript filename +}; + +#endif // header diff --git a/examples/scripting/scripting-example.cpp b/examples/scripting/scripting-example.cpp new file mode 100644 index 0000000..6a9c4b9 --- /dev/null +++ b/examples/scripting/scripting-example.cpp @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// EXTERNAL INCLUDES +#include +#include +#include +#include + +// INTERNAL INCLUDES +#include "launcher.h" + +namespace +{ +bool CheckIfFileExists( const std::string& filename ) +{ + struct stat buf; + // fstat returns -1 on error + if (stat( filename.c_str(), &buf) != -1) + { + return true; + } + return false; +} + +} +int main( int argc, char* argv[] ) +{ + // pull out the JSON file and JavaScript file from the command line arguments + std::string javaScriptFileName; + std::string jSONFileName; + + for( int i = 1 ; i < argc ; ++i ) + { + std::string arg( argv[i] ); + + size_t idx = std::string::npos; + + idx = arg.find( ".json" ); + if( idx != std::string::npos ) + { + jSONFileName = arg; + } + else + { + idx = arg.find( ".js" ); + if( idx != std::string::npos ) + { + javaScriptFileName = arg; + } + } + } + + if( !jSONFileName.empty() ) + { + bool exists = CheckIfFileExists( jSONFileName ); + if( !exists ) + { + DALI_ASSERT_ALWAYS( 0 && "JSON file not found ") + } + } + if( !javaScriptFileName.empty() ) + { + bool exists = CheckIfFileExists( javaScriptFileName ); + if( !exists ) + { + DALI_ASSERT_ALWAYS( 0 && "JavaScript file not found ") + } + } + if( jSONFileName.empty() && javaScriptFileName.empty() ) + { + printf("Please specify a JSON and/or JavaScript file to load, e.g. scripting.example mylayout.json my-test.js\n"); + return -1; + } + + + Launcher daliApplication( Dali::Application::New( &argc, &argv ), jSONFileName, javaScriptFileName ); + + daliApplication.MainLoop(); + + return 0; +} diff --git a/resources/scripts/simple-image-wall.js b/resources/scripts/simple-image-wall.js new file mode 100644 index 0000000..2620865 --- /dev/null +++ b/resources/scripts/simple-image-wall.js @@ -0,0 +1,108 @@ +// Image Wall example +// +// Example usage of Dali API +// +// +// +// get the dali-demo image directory path +// hard code for the device to /usr/apps/com.samsung.dali-demo/images/ +var imageDir = dali.DALI_DATA_DIRECTORY; + +if (imageDir != "/usr/share/dali//") { + imageDir = imageDir.substring(0, imageDir.lastIndexOf("dali/")); + imageDir += "com.samsung.dali-demo/images/"; +} else // on device +{ + imageDir = "/usr/apps/com.samsung.dali-demo/images/"; +} + + +var NUMBER_OF_IMAGES = 40; // for now use 16 ( demo files go up to 30) +var DEMO_IMAGES = []; // array to store Dali Images +var VIDEO_WALL_ACTORS = []; // array to store Image actors +var VIDEO_WALL_ROWS = 7; // use 3 rows for the video wall +var VIDEO_WALL_COLUMNS = 12; // use 12 columns for the video wall +var VIDEO_WALL_TOTAL_ITEMS = VIDEO_WALL_COLUMNS * VIDEO_WALL_ROWS; // total items +var VIDEO_WALL_ITEM_SIZE = 128; // width / height of a item in the video wall +var BORDER_SIZE = 5; +var VIDEO_WALL_ITEM_SIZE_NO_BORDER = VIDEO_WALL_ITEM_SIZE - BORDER_SIZE; +var VIDEO_WALL_WIDTH = VIDEO_WALL_COLUMNS * VIDEO_WALL_ITEM_SIZE; +var VIDEO_WALL_HEIGHT = VIDEO_WALL_ROWS * VIDEO_WALL_ITEM_SIZE; + +var daliApp = {}; + +var wallRootActor; // the root actor of the video wall + +// we want demo images of format gallery-small-1.jpg +daliApp.getFileName = function(index) { + fileName = "gallery-small-" + (index+1) + ".jpg"; + return fileName; +} + +// load the images +daliApp.loadImages = function() { + for (index = 0; index < NUMBER_OF_IMAGES; ++index) { + fileName = imageDir + daliApp.getFileName(index); + DEMO_IMAGES[index] = new dali.ResourceImage( { url:fileName } ); + } +} + +daliApp.createRootActor = function() { + wallRootActor = new dali.Actor(); + wallRootActor.parentOrigin = dali.CENTER; + wallRootActor.anchorPoint = dali.CENTER; + dali.stage.add(wallRootActor); +} + + + +daliApp.getWallActorIndex = function(x, y) { + return x + y * VIDEO_WALL_COLUMNS; +} + +daliApp.createActors = function() { + daliApp.createRootActor(); + + for (y = 0; y < VIDEO_WALL_ROWS; ++y) { + for (x = 0; x < VIDEO_WALL_COLUMNS; ++x) { + + var actorIndex = daliApp.getWallActorIndex(x, y); + var imageActor = new dali.ImageActor(); + + // wrap image index between 0 and NUMBER_OF_IMAGES + var imageIndex = actorIndex % NUMBER_OF_IMAGES; + + imageActor.setImage(DEMO_IMAGES[imageIndex]); + + imageActor.parentOrigin = dali.CENTER; + imageActor.anchorPoint = dali.CENTER; + imageActor.size = [VIDEO_WALL_ITEM_SIZE_NO_BORDER, VIDEO_WALL_ITEM_SIZE_NO_BORDER, 1.0]; // start with zero size so it zooms up + + var xPosition = x * VIDEO_WALL_ITEM_SIZE; + // as the middle the wall is at zero (relative to wallRootActor), we need to subtract half the wall width. + // + add half item size because the item anchor point is the center of the wallRootActor. + xPosition = xPosition - (VIDEO_WALL_WIDTH / 2) + (VIDEO_WALL_ITEM_SIZE / 2); + + var yPosition = y * VIDEO_WALL_ITEM_SIZE; + yPosition = yPosition - (VIDEO_WALL_HEIGHT / 2) + (VIDEO_WALL_ITEM_SIZE / 2); + + imageActor.position = [xPosition, yPosition, 0.0]; + // store the actor + VIDEO_WALL_ACTORS[actorIndex] = imageActor; + + // Add to the video wall root actor. + wallRootActor.add(imageActor); + } + } +} + +function Initialise() { + + daliApp.loadImages(); + + daliApp.createActors(); + + +} + +Initialise(); -- 2.7.4