From f0460f9dfeb9a6719f6e90ed016c1a75ba6205c2 Mon Sep 17 00:00:00 2001 From: David Steele Date: Thu, 19 Apr 2018 12:18:25 +0100 Subject: [PATCH] Simple example to show off layouts and transitions Change-Id: I62365ce561fc9f699aea1b8f2d5b56b43f380b78 --- examples/layouting/layouting-example.cpp | 222 +++++++++++++++++++++ resources/images/icon-reverse-selected.png | Bin 0 -> 1830 bytes resources/images/icon-reverse.png | Bin 0 -> 1716 bytes .../images/icon-rotate-anticlockwise-selected.png | Bin 0 -> 2083 bytes resources/images/icon-rotate-anticlockwise.png | Bin 0 -> 2112 bytes 5 files changed, 222 insertions(+) create mode 100644 examples/layouting/layouting-example.cpp create mode 100644 resources/images/icon-reverse-selected.png create mode 100644 resources/images/icon-reverse.png create mode 100644 resources/images/icon-rotate-anticlockwise-selected.png create mode 100644 resources/images/icon-rotate-anticlockwise.png diff --git a/examples/layouting/layouting-example.cpp b/examples/layouting/layouting-example.cpp new file mode 100644 index 0000000..6315235 --- /dev/null +++ b/examples/layouting/layouting-example.cpp @@ -0,0 +1,222 @@ +/* + * Copyright (c) 2018 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" +#include +#include +#include +#include +#include +#include +#include + +using namespace Dali; +using namespace Dali::Toolkit; + +namespace +{ + +const char* BACKGROUND_IMAGE( DEMO_IMAGE_DIR "lake_front.jpg" ); +const char* TOOLBAR_IMAGE( DEMO_IMAGE_DIR "top-bar.png" ); + +const char* LTR_IMAGE( DEMO_IMAGE_DIR "icon-play.png" ); +const char* LTR_SELECTED_IMAGE( DEMO_IMAGE_DIR "icon-play-selected.png" ); + +const char* RTL_IMAGE( DEMO_IMAGE_DIR "icon-reverse.png" ); +const char* RTL_SELECTED_IMAGE( DEMO_IMAGE_DIR "icon-reverse-selected.png" ); + +const char* ROTATE_CLOCKWISE_IMAGE( DEMO_IMAGE_DIR "icon-reset.png" ); +const char* ROTATE_CLOCKWISE_SELECTED_IMAGE( DEMO_IMAGE_DIR "icon-reset-selected.png" ); + +//const char* ROTATE_ANTICLOCKWISE_IMAGE( DEMO_IMAGE_DIR "icon-rotate-anticlockwise.png" ); +//const char* ROTATE_ANTICLOCKWISE_SELECTED_IMAGE( DEMO_IMAGE_DIR "icon-rotate-anticlockwise-selected.png" ); + + +const char* APPLICATION_TITLE( "Layout tester" ); + +const char* IMAGE_PATH[] = { + DEMO_IMAGE_DIR "application-icon-101.png", + DEMO_IMAGE_DIR "application-icon-102.png", + DEMO_IMAGE_DIR "application-icon-103.png", + DEMO_IMAGE_DIR "application-icon-104.png" +}; +const unsigned int NUMBER_OF_RESOURCES = sizeof(IMAGE_PATH) / sizeof(char*); + +} // namespace + +class LayoutingExample: public ConnectionTracker +{ + public: + + LayoutingExample( Application& application ) + : mApplication( application ), + mDirection( false ) + { + // Connect to the Application's Init signal + mApplication.InitSignal().Connect( this, &LayoutingExample::Create ); + } + + ~LayoutingExample() + { + // Nothing to do here + } + + void Create( Application& application ) + { + // The Init signal is received once (only) during the Application lifetime + auto stage = Stage::GetCurrent(); + + auto bg = ImageView::New( BACKGROUND_IMAGE ); + bg.SetParentOrigin( ParentOrigin::CENTER ); + stage.Add( bg ); + auto toolbar = ImageView::New( TOOLBAR_IMAGE ); + toolbar.SetParentOrigin( ParentOrigin::TOP_CENTER ); + toolbar.SetAnchorPoint( AnchorPoint::TOP_CENTER ); + toolbar.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH ); + toolbar.SetProperty( Actor::Property::SIZE_HEIGHT, 50.0f); + + stage.Add( toolbar ); + + auto title = TextLabel::New( APPLICATION_TITLE ); + title.SetParentOrigin( ParentOrigin::CENTER ); + title.SetAnchorPoint( AnchorPoint::CENTER ); + title.SetProperty( TextLabel::Property::TEXT_COLOR, Color::BLUE ); + title.SetProperty( TextLabel::Property::HORIZONTAL_ALIGNMENT, HorizontalAlignment::CENTER ); + toolbar.Add( title ); + + mDirectionButton = PushButton::New(); + mDirectionButton.SetProperty( PushButton::Property::UNSELECTED_ICON, RTL_IMAGE ); + mDirectionButton.SetProperty( PushButton::Property::SELECTED_ICON, RTL_SELECTED_IMAGE ); + mDirectionButton.ClickedSignal().Connect( this, &LayoutingExample::OnDirectionClicked ); + mDirectionButton.SetParentOrigin( Vector3(0.33f, 1.0f, 0.5f ) ); + mDirectionButton.SetAnchorPoint( AnchorPoint::BOTTOM_CENTER ); + mDirectionButton.SetSize(75, 75); + stage.Add( mDirectionButton ); + + mRotateButton = PushButton::New(); + mRotateButton.SetProperty( PushButton::Property::UNSELECTED_ICON, ROTATE_CLOCKWISE_IMAGE ); + mRotateButton.SetProperty( PushButton::Property::SELECTED_ICON, ROTATE_CLOCKWISE_SELECTED_IMAGE ); + mRotateButton.ClickedSignal().Connect( this, &LayoutingExample::OnRotateClicked ); + mRotateButton.SetParentOrigin( Vector3(0.66f, 1.0f, 0.5f )); + mRotateButton.SetAnchorPoint( Vector3(0.5f, 1.0f, 0.5f)); + mRotateButton.SetSize(75, 75); + stage.Add( mRotateButton ); + + // Create a hbox layout + mLinearContainer = Control::New(); + mIsHorizontal = false; + + auto layout = VboxLayout::New(); + layout.SetAnimateLayout(true); + DevelControl::SetLayout( mLinearContainer, layout ); + + mLinearContainer.SetParentOrigin( ParentOrigin::CENTER ); + mLinearContainer.SetAnchorPoint( AnchorPoint::CENTER ); + mLinearContainer.SetName( "linearContainer" ); + stage.Add( mLinearContainer ); + mLinearContainer.SetProperty( Toolkit::LayoutBase::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::MATCH_PARENT ); + mLinearContainer.SetProperty( Toolkit::LayoutBase::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::MATCH_PARENT ); + mLinearContainer.SetProperty( Actor::Property::LAYOUT_DIRECTION, LayoutDirection::LEFT_TO_RIGHT ); + + for( unsigned int x = 0; x < NUMBER_OF_RESOURCES; ++x ) + { + mImageViews[x] = Toolkit::ImageView::New(); + Property::Map imagePropertyMap; + imagePropertyMap[ Toolkit::Visual::Property::TYPE ] = Toolkit::Visual::IMAGE; + imagePropertyMap[ Toolkit::ImageVisual::Property::URL ] = IMAGE_PATH[ x ]; + imagePropertyMap[ ImageVisual::Property::DESIRED_WIDTH ] = 100.0f; + imagePropertyMap[ ImageVisual::Property::DESIRED_HEIGHT ] = 100.0f; + + mImageViews[x].SetProperty(Toolkit::ImageView::Property::IMAGE , imagePropertyMap ); + mImageViews[x].SetName("ImageView"); + mImageViews[x].SetAnchorPoint( AnchorPoint::TOP_LEFT ); + mImageViews[x].SetResizePolicy( ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS ); + mLinearContainer.Add( mImageViews[x] ); + } + + Stage::GetCurrent().KeyEventSignal().Connect(this, &LayoutingExample::OnKeyEvent); + } + +private: + /** + * Main key event handler + */ + void OnKeyEvent(const KeyEvent& event) + { + if(event.state == KeyEvent::Down) + { + if( IsKey( event, DALI_KEY_ESCAPE) || IsKey( event, DALI_KEY_BACK ) ) + { + mApplication.Quit(); + } + } + } + + bool OnDirectionClicked( Button button ) + { + if( mDirection ) + { + mDirectionButton.SetProperty( PushButton::Property::UNSELECTED_ICON, LTR_IMAGE ); + mDirectionButton.SetProperty( PushButton::Property::SELECTED_ICON, LTR_SELECTED_IMAGE ); + mLinearContainer.SetProperty( Actor::Property::LAYOUT_DIRECTION, LayoutDirection::LEFT_TO_RIGHT ); + } + else + { + mDirectionButton.SetProperty( PushButton::Property::UNSELECTED_ICON, RTL_IMAGE ); + mDirectionButton.SetProperty( PushButton::Property::SELECTED_ICON, RTL_SELECTED_IMAGE ); + mLinearContainer.SetProperty( Actor::Property::LAYOUT_DIRECTION, LayoutDirection::RIGHT_TO_LEFT ); + } + mDirection = !mDirection; + return true; + } + + bool OnRotateClicked( Button button ) + { + mIsHorizontal = !mIsHorizontal; + if( mIsHorizontal ) + { + auto hboxLayout = HboxLayout::New(); + hboxLayout.SetAnimateLayout(true); + DevelControl::SetLayout( mLinearContainer, hboxLayout ); + } + else + { + auto vboxLayout = VboxLayout::New(); + vboxLayout.SetAnimateLayout(true); + DevelControl::SetLayout( mLinearContainer, vboxLayout ); + } + return true; + } + +private: + Application& mApplication; + Toolkit::ImageView mImageViews[ NUMBER_OF_RESOURCES ]; + PushButton mDirectionButton; + PushButton mRotateButton; + Control mLinearContainer; + bool mDirection; + bool mIsHorizontal = true; +}; + +int DALI_EXPORT_API main( int argc, char **argv ) +{ + Application application = Application::New( &argc, &argv, DEMO_THEME_PATH ); + LayoutingExample test( application ); + application.MainLoop(); + return 0; +} diff --git a/resources/images/icon-reverse-selected.png b/resources/images/icon-reverse-selected.png new file mode 100644 index 0000000000000000000000000000000000000000..d53dc21289ae384dc7b3ccea9e63585285308599 GIT binary patch literal 1830 zcmV+>2if?EP)- zK~!ko<(h45TUQy!|IhKY<2GB8W=)gU@moP1NPyI?D(ZocN=lQa zOE-l@irB}kRm;S>jcveSOq;gxWiSbZDw)!Sje&p`HkE2?leAgQDp)_jTIb$#&hzlW zPO_CGwXf~OrdPV(?$tTJ`~RQk%_b4S^>8`)K6uMrLrc2RKRfx7fqXzgf0xW@@kLdXKnMgwO(gbyF_~R*6<{eE45A_xRYidkRKRH> z*b$h_Zq{yCOxB{pvlcChXNtA1KSc?oR1=9EhRyVe@xtu6kP<5Rzbnd|U#tL7Rp5eX zg4kggw~swH%sGp4(P!{l3opVMB>)g^6tN?)dN*sgR!p{3E0=<$x2~cE1F~4tC~Swp zx=*xM%bp7^Nfa$S>duvxic*vau-cmiG+wRs+!+P21Y;VJBCY$Os7nMrb)^w(he*r- zds&Mz8;H+DU%De&il|Ej@5=j)V0#aV8D#C%T0I*@Q2~QCfy|kv@&@%X@7K>LsJ%L? z-Ng+u1r!XvtlQo*To3RNS)Bzea~>>7)GZ_!eSYVC^}_ZZh#6$pt()%XrNC}t2@Yv~ zXS99$P(8D~o5b8J6>QOkI5{_3nHO|(*Zw^u<^a2Hoft1`QEMTnrfL2)tlQSP?@2Lk zuV@!+boooQvVzVNbvJkJYiIXLFS{8qn<@p&y_ApKgkMG*Ml^ z1#~YWG74anh}tJ7#=D}4`+SG6^X?+Hnc?Jfl$q| zvV$rGF*G!-d0y#U#{Zaz1GAS}>YqxYd_f6dI@lN00n-~7YqOaD6e_G#-*Wy;^d zz`vs3{O+?ptwc~t;mQ456@c4_Xj>!}->{-3noz+|xEzYYn)Hd^{U+iIwD+Osiaa}6 z;3o#}oCfZW#Nz84np@+g1XfBxtVy4I^_V}<-QRn@M8P7vnaB5iLjmZ>DZIX+IZ_f} zqO77PU;C{;&~H8be2JrDR^jgteEoyK8ycD;v0{Lyt$XrSpP+k=yilfeKnN&>NB4eB z0r*lN5a?Xp8eQMe9Em9>81@x)tx5m&wd4Lk`;NR==KPlheq`@g9RMAHK%jedYxGm~ ztJV|dISh{^|9beSz+M^k<9Q zKxcs;?z_VQ(4mytu_hY(ME$BYakT(2DTT}LUHti()2F^t6`=C~->#JES_qi6_n)`l z_)Dkjx-a{zb(ij6>6Qf|VgUSth<^Fbxry7;ljpluwXFVFZCyiSP3?^h5Rs|N|GqRi zcIK$o`d3BtqZKnMnE`$`eW4BM3!4CJ0H6W<5x@^~&r~<)Rlvt`_q8h~TqoCm0btVF UCDF{E@c;k-07*qoM6N<$f+MAPXaE2J literal 0 HcmV?d00001 diff --git a/resources/images/icon-reverse.png b/resources/images/icon-reverse.png new file mode 100644 index 0000000000000000000000000000000000000000..9e5ed88d1f311dec6c8d209e52b4ae7140326ae5 GIT binary patch literal 1716 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 N002ovPDHLkV1j~$&}IMt literal 0 HcmV?d00001 diff --git a/resources/images/icon-rotate-anticlockwise.png b/resources/images/icon-rotate-anticlockwise.png new file mode 100644 index 0000000000000000000000000000000000000000..8c58af451ce3fcd72a9bfa5b8e3368c9d56a23e1 GIT binary patch literal 2112 zcmV-G2*3AFe5OM>C7!rs{C<%laVh~Ue7$J77JjVwGoPwh$FF~g= zSdb|Ktqji;QDDkQr#L|CSSl^$F{ReZAZk&IfLak+$Uvkdko!Dm@BX+qAvocZgg^dp zÏ&)IkH@2s`<`o49@7=!QHVE7IW(eg*-l;=CN2qiBe02e#r_xE34abr-7sBP|L ztb#H2C^0sai0&jJ5CO&j#+X{8^*^=NZ)>gJG{*e*mOMpiK@k{Z6kC3_N0+jBOkb{@6=a!|E>Q=U;d}7B`t8q z!H8AEuodxG?717&NNV|D=#xvD!|3<>YAoA++IDPk&LJ3i)2oMkJh;4Q(S37P{Lyt? zXsz+>g(-Dl80R=pv(OJ<_O`zqetho-#|r_#bzOuT!w5Hqhq;NwAp_vh#>Hto#TbYH zA>6Y<%Z}q5HN+oMRx$@Tk?z+sZ`b|vS02;afPuh>wb=*+&()BE*HjPa^A8w6 zZ~>(hZp+S^&$+l^PC09L?mPbesWSzP2wVsV!9hfDT^EsX1kq>=uInE6Ja3%V`eb`~ zoO6yntDYS=Z^O=mS7Qms^E||&F}J?HA#?Z3^CGPga%6D%9ouc&g5$HHlmzDtj1h$3 z@cA8N1~V{WL{;OSRnLVPOFnCl0S03itUcT-H~VxlZ#lT&qHC96#SK-$fYO3j^K-H; zbDpZyDHB4#vMlr~%D*^u^x&5te16SYVk}uA+F`^9+5omCKWy@x5CYw@J6ENXE?-yl z$~)Y23R_xMhOcp2^`On;U#Qt>j7hycYqup22tH5oXfg`6>XBAY4eM9D#<4_#GeVPD zg1bK%b=SV2-}$-rykrgP0H7pK5*j11FlR`u&)_J_P75m2?;Pk`nEO@J#sDyGaNlFS zaznEx{H!KI>=po}Lf#OL<+QvP3^)yGK|TE9Mt4AQkF5Y1BErDl1!sno6+QFNiyO}Z z1R{1zpg8AvsUeeE4%+E*~slm&h{ z60J%q4T2C%-`l_B?>Ch$Qrp45+gd$!+ty zcDb10*q^5j9}$Dr235TaSA;rcES$V_i)M^ZlUy!LF?@$jaAEl!-)c)raK-^c=vSDx zf9mpI>-3&t1Q0M~*_Ka;(NIgtHI@_=Fh)n?iT4t&dk`IH$%rxdl-k54?`}x}VuWtN zjQV@}7OmO*_Mw~TDaM=CLVmX{KfV%8R47Zr)0&BB?5)OdWTNYNe}-va*rXIo9G^YK zv26&!;c1PL6~%j}uiSR@IxXE=_!uWJPT-tj!K0&(=H+y{s+5FdEBJkO!0&hdq?EOU z3&xw~-q;v~;N5K7+L;mXE%NysNXbD23@YvMRe53VVr_Jag3^H^o>HF#$C6tn53k(q zS1QIihplX61_H?N`xiON{zwY>7-u5b^q-c-ndq*hwcPJGUt|UX69PUTl$2n^(6eio z3qQQG&!Q(*{q_V5U8i#lc?4Y|+|4#F6?o`-ncMJyhN z>w56CK52}pHO8DIqH-b%3C@ZvDPdU>mK4pWx1@XM+?au7o1b}Q*W!4>ZC0&Yo}JwG zZsy4~+v_&YedMvnM-5!O`^fPJKmEG)c1ub~&S5JF&(qLamuPKDj4?x-n1J(?rMe!* z$QxYRdc6iw?IDIJLDyX02##V8*&Pv=Ds5 z`llwob4PAy+PO>hgFZf88#;ffA^6SJaE9w?k$edtE8tx5SyrrfUg%xiLIe=mS{uWbD0jL9T5WtZ+ q8+KmtykyryXd6}0_ur@5IQ|dX^UpZ)5jW%j0000;8xU literal 0 HcmV?d00001 -- 2.7.4