diff --git a/build/tizen/examples/Makefile.am b/build/tizen/examples/Makefile.am index 80d14de..40e33dc 100644 --- a/build/tizen/examples/Makefile.am +++ b/build/tizen/examples/Makefile.am @@ -26,6 +26,7 @@ bin_PROGRAMS = \ magnifier.example \ motion-blur.example \ motion-stretch.example \ + new-window.example \ page-turn-view.example \ radial-menu.example \ scroll-view.example \ @@ -112,6 +113,11 @@ motion_stretch_example_CXXFLAGS = $(EXAMPLE_CXXFLAGS) motion_stretch_example_DEPENDENCIES = $(EXAMPLE_DEPS) motion_stretch_example_LDADD = $(EXAMPLE_LDADD) +new_window_example_SOURCES = $(examples_src_dir)/new-window/new-window-example.cpp +new_window_example_CXXFLAGS = $(EXAMPLE_CXXFLAGS) +new_window_example_DEPENDENCIES = $(EXAMPLE_DEPS) +new_window_example_LDADD = $(EXAMPLE_LDADD) + page_turn_view_example_SOURCES = $(examples_src_dir)/page-turn-view/page-turn-view-example.cpp page_turn_view_example_CXXFLAGS = $(EXAMPLE_CXXFLAGS) page_turn_view_example_DEPENDENCIES = $(EXAMPLE_DEPS) diff --git a/com.samsung.dali-demo.xml b/com.samsung.dali-demo.xml index ea7888d..5ef3d06 100644 --- a/com.samsung.dali-demo.xml +++ b/com.samsung.dali-demo.xml @@ -13,6 +13,9 @@ + + + diff --git a/examples/new-window/new-window-example.cpp b/examples/new-window/new-window-example.cpp new file mode 100644 index 0000000..14445ac --- /dev/null +++ b/examples/new-window/new-window-example.cpp @@ -0,0 +1,521 @@ +/* + * Copyright (c) 2014 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. + */ + +#include +#include "../shared/view.h" + +using namespace Dali; +using namespace Dali::Toolkit; + +class NewWindowController; + +namespace +{ +const char * gModelFile = DALI_MODEL_DIR "AlbumCute.dae"; +const char * const BACKGROUND_IMAGE( DALI_IMAGE_DIR "background-2.jpg" ); +const char * const TOOLBAR_IMAGE( DALI_IMAGE_DIR "top-bar.png" ); +const char * const LOSE_CONTEXT_IMAGE( DALI_IMAGE_DIR "icon-cluster-wobble.png" ); +const char * const BASE_IMAGE( DALI_IMAGE_DIR "gallery-large-14.jpg" ); +const char * const EFFECT_IMAGE( DALI_IMAGE_DIR "gallery-large-18.jpg" ); + +const float EXPLOSION_DURATION(1.2f); +const unsigned int EMIT_INTERVAL_IN_MS(80); +const float TRACK_DURATION_IN_MS(970); + +Application gApplication; +NewWindowController* gNewWindowController(NULL); + +const char*const FRAG_SHADER= + "uniform float alpha;\n" + "\n" + "void main()\n" + "{\n" + " vec4 fragColor = texture2D(sTexture, vTexCoord);\n" + " vec4 fxColor = texture2D(sEffect, vTexCoord);\n" + " gl_FragColor = mix(fragColor,fxColor, alpha);\n" + "}\n"; + +}; // anonymous namespace + + +class NewWindowController : public ConnectionTracker +{ +public: + NewWindowController( Application& app ); + void Create( Application& app ); + void Destroy( Application& app ); + void OnKeyEvent(const KeyEvent& event); + bool OnLoseContextButtonClicked( Toolkit::Button button ); + static void NewWindow(void); + + void OnContextLost(); + void OnContextRegained(); + void CreateMeshActor(); + Mesh CreateMesh(bool, Material); + void CreateBubbles(Vector2 stageSize); + void CreateBlending(); + void CreateText(); + void CreateModel(); + void OnModelLoaded(Model model); + bool OnTrackTimerTick(); + bool OnExplodeTimerTick(); + void SetUpAnimation( Vector2 emitPosition, Vector2 direction ); + FrameBufferImage CreateMirrorImage(const char* imageName); + ImageActor CreateBlurredMirrorImage(const char* imageName); + FrameBufferImage CreateFrameBufferForImage(const char* imageName, Image image, ShaderEffect shaderEffect); + + +private: + Application mApplication; + Animation mModelAnimation; + Actor mModelActor; + Actor mCastingLight; + TextActor mTextActor; + ImageActor mImageActor; + ImageActor mBlendActor; + Image mEffectImage; + Image mBaseImage; + LightActor mKeyLightActor; + MeshActor mMeshActor; + MeshActor mAnimatedMeshActor; + Model mModel; + + Toolkit::View mView; ///< The View instance. + Toolkit::ToolBar mToolBar; ///< The View's Toolbar. + TextView mTitleActor; ///< The Toolbar's Title. + Layer mContentLayer; ///< Content layer (scrolling cluster content) + Toolkit::PushButton mLoseContextButton; + Vector3 mHSVDelta; + Toolkit::BubbleEmitter mEmitter; + + Timer mEmitTrackTimer; + Timer mExplodeTimer; + bool mNeedNewAnimation; + + unsigned int mAnimateComponentCount; + Animation mEmitAnimation; +}; + + +NewWindowController::NewWindowController( Application& application ) +: mApplication(application), + mHSVDelta(0.5f, 0.0f, 0.5f), + mNeedNewAnimation(true) +{ + mApplication.InitSignal().Connect(this, &NewWindowController::Create); + mApplication.TerminateSignal().Connect(this, &NewWindowController::Destroy); +} + +void NewWindowController::Create( Application& app ) +{ + Stage stage = Stage::GetCurrent(); + stage.SetBackgroundColor(Color::YELLOW); + + stage.KeyEventSignal().Connect(this, &NewWindowController::OnKeyEvent); + + // The Init signal is received once (only) during the Application lifetime + + // Hide the indicator bar + mApplication.GetWindow().ShowIndicator( Dali::Window::INVISIBLE ); + + mContentLayer = DemoHelper::CreateView( app, + mView, + mToolBar, + BACKGROUND_IMAGE, + TOOLBAR_IMAGE, + "Context recovery" ); + + // Point the default render task at the view + RenderTaskList taskList = stage.GetRenderTaskList(); + RenderTask defaultTask = taskList.GetTask( 0u ); + if ( defaultTask ) + { + defaultTask.SetSourceActor( mView ); + } + + mLoseContextButton = Toolkit::PushButton::New(); + mLoseContextButton.SetBackgroundImage( Image::New( LOSE_CONTEXT_IMAGE ) ); + mLoseContextButton.ClickedSignal().Connect( this, &NewWindowController::OnLoseContextButtonClicked ); + mToolBar.AddControl( mLoseContextButton, DemoHelper::DEFAULT_VIEW_STYLE.mToolBarButtonPercentage, Toolkit::Alignment::HorizontalRight, DemoHelper::DEFAULT_MODE_SWITCH_PADDING ); + + + Actor logoLayoutActor = Actor::New(); + logoLayoutActor.SetParentOrigin(ParentOrigin::CENTER); + logoLayoutActor.SetPosition(0.0f, -200.0f, 0.0f); + logoLayoutActor.SetScale(0.5f); + mContentLayer.Add(logoLayoutActor); + + Image image = Image::New(DALI_IMAGE_DIR "dali-logo.png"); + mImageActor = ImageActor::New(image); + mImageActor.SetName("dali-logo"); + mImageActor.SetParentOrigin(ParentOrigin::CENTER); + mImageActor.SetAnchorPoint(AnchorPoint::BOTTOM_CENTER); + logoLayoutActor.Add(mImageActor); + + ImageActor mirrorImageActor = CreateBlurredMirrorImage(DALI_IMAGE_DIR "dali-logo.png"); + mirrorImageActor.SetParentOrigin(ParentOrigin::CENTER); + mirrorImageActor.SetAnchorPoint(AnchorPoint::TOP_CENTER); + logoLayoutActor.Add(mirrorImageActor); + + CreateBubbles(stage.GetSize()); + CreateMeshActor(); + CreateBlending(); + CreateText(); + CreateModel(); + + stage.ContextLostSignal().Connect(this, &NewWindowController::OnContextLost); + stage.ContextRegainedSignal().Connect(this, &NewWindowController::OnContextRegained); +} + +void NewWindowController::Destroy( Application& app ) +{ + UnparentAndReset(mTextActor); +} + +bool NewWindowController::OnLoseContextButtonClicked( Toolkit::Button button ) +{ + // Add as an idle callback to avoid ProcessEvents being recursively called. + mApplication.AddIdle(NewWindowController::NewWindow); + return true; +} + +void NewWindowController::CreateMeshActor() +{ + mEffectImage = Image::New(EFFECT_IMAGE); + + Material baseMaterial = Material::New( "Material1" ); + Dali::MeshActor meshActor = MeshActor::New( CreateMesh(true, baseMaterial) ); + meshActor.SetScale( 100.0f ); + meshActor.SetParentOrigin( ParentOrigin::CENTER ); + meshActor.SetPosition(Vector3( -150.0f, 200.0f, 0.0f )); + meshActor.SetAffectedByLighting( false ); + meshActor.SetName("MeshActor"); + mContentLayer.Add( meshActor ); + + Material orchidMaterial = Material::New( "Material2" ); + orchidMaterial.SetDiffuseTexture(mEffectImage); + + Dali::MeshActor meshActor2 = MeshActor::New( CreateMesh(false, orchidMaterial) ); + meshActor2.SetScale( 100.0f ); + meshActor2.SetParentOrigin( ParentOrigin::CENTER ); + meshActor2.SetPosition(Vector3( -150.0f, 310.0f, 0.0f )); + meshActor2.SetAffectedByLighting( false ); + meshActor2.SetName("MeshActor"); + mContentLayer.Add( meshActor2 ); +} + +FrameBufferImage NewWindowController::CreateMirrorImage(const char* imageName) +{ + FrameBufferImage fbo; + Image image = Image::New(imageName); + fbo = CreateFrameBufferForImage(imageName, image, ShaderEffect()); + return fbo; +} + +ImageActor NewWindowController::CreateBlurredMirrorImage(const char* imageName) +{ + FrameBufferImage fbo; + Image image = Image::New( imageName ); + Vector2 FBOSize = Image::GetImageSize(imageName); + fbo = FrameBufferImage::New( FBOSize.width, FBOSize.height, Pixel::RGBA8888); + GaussianBlurView gbv = GaussianBlurView::New(5, 2.0f, Pixel::RGBA8888, 0.5f, 0.5f, true); + gbv.SetBackgroundColor(Color::TRANSPARENT); + gbv.SetUserImageAndOutputRenderTarget( image, fbo ); + gbv.SetSize(FBOSize); + Stage::GetCurrent().Add(gbv); + gbv.ActivateOnce(); + + ImageActor blurredActor = ImageActor::New(fbo); + blurredActor.SetSize(FBOSize); + blurredActor.SetScale(1.0f, -1.0f, 1.0f); + return blurredActor; +} + +FrameBufferImage NewWindowController::CreateFrameBufferForImage(const char* imageName, Image image, ShaderEffect shaderEffect) +{ + Stage stage = Stage::GetCurrent(); + Vector2 FBOSize = Image::GetImageSize(imageName); + + FrameBufferImage framebuffer = FrameBufferImage::New(FBOSize.x, FBOSize.y ); + + RenderTask renderTask = stage.GetRenderTaskList().CreateTask(); + + ImageActor imageActor = ImageActor::New(image); + imageActor.SetName("Source image actor"); + if(shaderEffect) + { + imageActor.SetShaderEffect(shaderEffect); + } + imageActor.SetParentOrigin(ParentOrigin::CENTER); + imageActor.SetAnchorPoint(AnchorPoint::CENTER); + imageActor.SetScale(1.0f, -1.0f, 1.0f); + stage.Add(imageActor); // Not in default image view + + CameraActor cameraActor = CameraActor::New(FBOSize); + cameraActor.SetParentOrigin(ParentOrigin::CENTER); + cameraActor.SetFieldOfView(Math::PI*0.25f); + cameraActor.SetNearClippingPlane(1.0f); + cameraActor.SetAspectRatio(FBOSize.width / FBOSize.height); + cameraActor.SetType(Dali::Camera::FREE_LOOK); // camera orientation based solely on actor + cameraActor.SetRotation(Quaternion(M_PI, Vector3::YAXIS)); + cameraActor.SetPosition(0.0f, 0.0f, ((FBOSize.height * 0.5f) / tanf(Math::PI * 0.125f))); + stage.Add(cameraActor); + + renderTask.SetSourceActor(imageActor); + renderTask.SetInputEnabled(false); + renderTask.SetTargetFrameBuffer(framebuffer); + renderTask.SetCameraActor( cameraActor ); + renderTask.SetClearColor( Color::TRANSPARENT ); + renderTask.SetClearEnabled( true ); + renderTask.SetRefreshRate(RenderTask::REFRESH_ONCE); + + return framebuffer; +} + +void NewWindowController::CreateBubbles(Vector2 stageSize) +{ + mEmitter = Toolkit::BubbleEmitter::New( stageSize, + Image::New( DALI_IMAGE_DIR "bubble-ball.png" ), + 1000, Vector2( 5.0f, 5.0f ) ); + + Image background = Image::New(BACKGROUND_IMAGE); + mEmitter.SetBackground( background, mHSVDelta ); + Actor bubbleRoot = mEmitter.GetRootActor(); + mContentLayer.Add( bubbleRoot ); + bubbleRoot.SetParentOrigin(ParentOrigin::CENTER); + bubbleRoot.SetZ(0.1f); + + mEmitTrackTimer = Timer::New( EMIT_INTERVAL_IN_MS ); + mEmitTrackTimer.TickSignal().Connect(this, &NewWindowController::OnTrackTimerTick); + mEmitTrackTimer.Start(); + + //mExplodeTimer = Timer::New( Random::Range(4000.f, 8000.f) ); + //mExplodeTimer.TickSignal().Connect(this, &NewWindowController::OnExplodeTimerTick); + //mExplodeTimer.Start(); +} + +bool NewWindowController::OnExplodeTimerTick() +{ + mEmitter.StartExplosion( EXPLOSION_DURATION, 5.0f ); + + mExplodeTimer = Timer::New( Random::Range(4.f, 8.f) ); + mExplodeTimer.TickSignal().Connect(this, &NewWindowController::OnExplodeTimerTick); + return false; +} + +void NewWindowController::SetUpAnimation( Vector2 emitPosition, Vector2 direction ) +{ + if( mNeedNewAnimation ) + { + float duration = Random::Range(1.f, 1.5f); + mEmitAnimation = Animation::New( duration ); + mNeedNewAnimation = false; + mAnimateComponentCount = 0; + } + + mEmitter.EmitBubble( mEmitAnimation, emitPosition, direction, Vector2(1, 1) ); + + mAnimateComponentCount++; + + if( mAnimateComponentCount % 20 ==0 ) + { + mEmitAnimation.Play(); + mNeedNewAnimation = true; + } +} + +bool NewWindowController::OnTrackTimerTick() +{ + static int time=0; + const float radius(250.0f); + + time += EMIT_INTERVAL_IN_MS; + float modTime = time / TRACK_DURATION_IN_MS; + float angle = 2.0f*Math::PI*modTime; + + Vector2 position(radius*cosf(angle), radius*-sinf(angle)); + Vector2 aimPos(radius*2*sinf(angle), radius*2*-cosf(angle)); + Vector2 direction = aimPos-position; + Vector2 stageSize = Stage::GetCurrent().GetSize(); + + for(int i=0; i<20; i++) + { + SetUpAnimation( stageSize*0.5f+position, direction ); + } + + return true; +} + + +void NewWindowController::CreateBlending() +{ + Toolkit::ColorAdjuster colorAdjuster = ColorAdjuster::New(mHSVDelta); + FrameBufferImage fb2 = CreateFrameBufferForImage( EFFECT_IMAGE, mEffectImage, colorAdjuster ); + + ImageActor tmpActor = ImageActor::New(fb2); + mContentLayer.Add(tmpActor); + tmpActor.SetParentOrigin(ParentOrigin::BOTTOM_RIGHT); + tmpActor.SetAnchorPoint(AnchorPoint::BOTTOM_RIGHT); + tmpActor.SetScale(0.25f); + + // create blending shader effect + ShaderEffect blendShader = ShaderEffect::New( "", FRAG_SHADER ); + blendShader.SetEffectImage( fb2 ); + blendShader.SetUniform("alpha", 0.5f); + + mBaseImage = Image::New(BASE_IMAGE); + mBlendActor = ImageActor::New( mBaseImage ); + mBlendActor.SetParentOrigin(ParentOrigin::CENTER); + mBlendActor.SetPosition(Vector3(150.0f, 200.0f, 0.0f)); + mBlendActor.SetSize(140, 140); + mBlendActor.SetShaderEffect( blendShader ); + mContentLayer.Add(mBlendActor); +} + +void NewWindowController::CreateText() +{ + mTextActor = TextActor::New("Some text"); + mTextActor.SetParentOrigin(ParentOrigin::CENTER); + mTextActor.SetColor(Color::RED); + mTextActor.SetName("PushMe text"); + mContentLayer.Add( mTextActor ); +} + +Mesh NewWindowController::CreateMesh(bool hasColor, Material material) +{ + // Create vertices and specify their color + MeshData::VertexContainer vertices(4); + vertices[ 0 ] = MeshData::Vertex( Vector3( -0.5f, -0.5f, 0.0f ), Vector2(0.0f, 0.0f), Vector3(1.0f, 0.0f, 0.0f) ); + vertices[ 1 ] = MeshData::Vertex( Vector3( 0.5f, -0.5f, 0.0f ), Vector2(1.0f, 0.0f), Vector3(1.0f, 1.0f, 0.0f) ); + vertices[ 2 ] = MeshData::Vertex( Vector3( -0.5f, 0.5f, 0.0f ), Vector2(0.0f, 1.0f), Vector3(0.0f,1.0f,0.0f) ); + vertices[ 3 ] = MeshData::Vertex( Vector3( 0.5f, 0.5f, 0.0f ), Vector2(1.0f, 1.0f), Vector3(0.0f,0.0f,1.0f) ); + + // Specify all the faces + MeshData::FaceIndices faces; + faces.reserve( 6 ); // 2 triangles in Quad + faces.push_back( 0 ); faces.push_back( 3 ); faces.push_back( 1 ); + faces.push_back( 0 ); faces.push_back( 2 ); faces.push_back( 3 ); + + // Create the mesh data from the vertices and faces + MeshData meshData; + meshData.SetHasColor( hasColor ); + meshData.SetMaterial( material ); + meshData.SetVertices( vertices ); + meshData.SetFaceIndices( faces ); + + // Create a mesh from the data + Dali::Mesh mesh = Mesh::New( meshData ); + return mesh; +} + +void NewWindowController::CreateModel() +{ + mModel = Model::New(gModelFile); + mModel.LoadingFinishedSignal().Connect(this, &NewWindowController::OnModelLoaded); + + //Create a Key light + Light keylight = Light::New("KeyLight"); + keylight.SetFallOff(Vector2(10000.0f, 10000.0f)); + + mCastingLight = Actor::New(); + mCastingLight.SetParentOrigin(ParentOrigin::CENTER); + mCastingLight.SetAnchorPoint(AnchorPoint::CENTER); + mCastingLight.SetPosition( Vector3( 0.0f, 0.0f, 800.0f ) ); + mContentLayer.Add( mCastingLight ); + + mKeyLightActor = LightActor::New(); + mKeyLightActor.SetParentOrigin(ParentOrigin::CENTER); + mKeyLightActor.SetName(keylight.GetName()); + + //Add all the actors to the stage + mCastingLight.Add(mKeyLightActor); + mKeyLightActor.SetLight(keylight); +} + +void NewWindowController::OnModelLoaded( Model model ) +{ + if( model.GetLoadingState() == ResourceLoadingSucceeded ) + { + std::cout << "Succeeded loading collada model" << std::endl; + mModelActor = ModelActorFactory::BuildActorTree(mModel, ""); // Gets root actor + mModelActor.SetSize(250.0f, 250.0f); + mModelActor.SetPosition(0.0f, 200.0f, 70.0f); + mModelActor.SetScale(0.5f); + mModelActor.SetRotation(Radian(Math::PI*0.25f), Vector3(1.0, 0.7, 0.0)); + + mContentLayer.Add( mModelActor ); + + if (mModel.NumberOfAnimations()) + { + mModelAnimation = ModelActorFactory::BuildAnimation(mModel, mModelActor, 0); + mModelAnimation.SetDuration(4.0f); + mModelAnimation.SetLooping(true); + mModelAnimation.Play(); + } + } + else + { + std::cout << "Failed loading collada model" << std::endl; + mApplication.Quit(); + } +} + +void NewWindowController::NewWindow(void) +{ + PositionSize posSize(0, 0, 720, 1280); + gApplication.ReplaceWindow(posSize, "NewWindow"); // Generates a new window +} + +void NewWindowController::OnKeyEvent(const KeyEvent& event) +{ + if(event.state == KeyEvent::Down) + { + if( IsKey( event, Dali::DALI_KEY_ESCAPE) || IsKey( event, Dali::DALI_KEY_BACK) ) + { + mApplication.Quit(); + } + } +} + +void NewWindowController::OnContextLost() +{ + printf("Stage reporting context loss\n"); +} + +void NewWindowController::OnContextRegained() +{ + printf("Stage reporting context regain\n"); +} + + + + +void RunTest(Application& app) +{ + gNewWindowController = new NewWindowController(app); + app.MainLoop(Configuration::APPLICATION_DOES_NOT_HANDLE_CONTEXT_LOSS); +} + +// Entry point for Linux & SLP applications +// + +int main(int argc, char **argv) +{ + gApplication = Application::New(&argc, &argv); + RunTest(gApplication); + + return 0; +}