Add 'ExclusiveArch: armv7l' limit build to arm architecture
[platform/core/uifw/dali-toolkit.git] / optional / dali-toolkit / internal / controls / image-view / image-view-impl.cpp
1 //
2 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
3 //
4 // Licensed under the Flora License, Version 1.0 (the License);
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //     http://floralicense.org/license/
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an AS IS BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16
17 #include <dali-toolkit/internal/controls/image-view/image-view-impl.h>
18 #include <dali-toolkit/public-api/shader-effects/distance-field-effect.h>
19
20 using namespace Dali;
21
22 namespace
23 {
24 //Type registration
25 BaseHandle Create()
26 {
27   return Toolkit::ImageView::New();
28 }
29 TypeRegistration mType( typeid(Toolkit::ImageView), typeid(Toolkit::Control), Create );
30
31   /**
32    * CameraDetailConstraint, generates detail value
33    * based on camera's position and ImageView's position.
34    */
35   struct CameraDetailConstraint
36   {
37     CameraDetailConstraint(float detailFactor)
38       : mDetailFactor(detailFactor)
39     {
40
41     }
42
43     float operator()(const float&    current,
44                      const PropertyInput& propertyTargetPosition,
45                      const PropertyInput& propertySourcePosition)
46     {
47       const Vector3& targetPosition = propertyTargetPosition.GetVector3();
48       const Vector3& sourcePosition = propertySourcePosition.GetVector3();
49       const float distance = (targetPosition - sourcePosition).Length();
50       const float detail = mDetailFactor / distance;
51
52       return detail;
53     }
54
55     const float mDetailFactor;
56   };
57
58 } // unnamed namespace
59
60 namespace Dali
61 {
62
63 namespace Toolkit
64 {
65
66 namespace Internal
67 {
68
69 ///////////////////////////////////////////////////////////////////////////////////////////////////
70 // ImageView
71 ///////////////////////////////////////////////////////////////////////////////////////////////////
72
73 Dali::Toolkit::ImageView ImageView::New()
74 {
75   // Create the implementation
76   ImageViewPtr imageView(new ImageView());
77
78   // Pass ownership to CustomActor via derived handle
79   Dali::Toolkit::ImageView handle(*imageView);
80
81   // Second-phase init of the implementation
82   // This can only be done after the CustomActor connection has been made...
83   imageView->Initialize();
84
85   return handle;
86 }
87
88 ImageView::ImageView()
89 : ControlImpl(true)
90 {
91 }
92
93 void ImageView::Initialize()
94 {
95   Actor self = Self();
96   // Register property that represents the level of detail.
97   mPropertyDetail = self.RegisterProperty(Toolkit::ImageView::DETAIL_PROPERTY_NAME, 0.0f);
98
99   // Create an empty image actor, filling the entire size of this ImageView.
100   Image emptyImage;
101   mImageActor = ImageActor::New( emptyImage );
102   self.Add( mImageActor );
103   mImageActor.ApplyConstraint( Constraint::New<Vector3>( Actor::SIZE, ParentSource( Actor::SIZE ), EqualToConstraint() ) );
104   mImageActor.SetParentOrigin( ParentOrigin::CENTER );
105 }
106
107 ImageView::~ImageView()
108 {
109
110 }
111
112 void ImageView::SetImage(const std::string& filename, ImageType type, float min, float max)
113 {
114   switch(type)
115   {
116     case Toolkit::ImageView::BitmapType:
117     {
118       SetImageBitmap(filename, min, max);
119       break;
120     }
121     case Toolkit::ImageView::DistanceFieldType:
122     {
123       SetImageDistanceField(filename);
124       break;
125     }
126   }
127 }
128
129 void ImageView::SetImageBitmap(const std::string& filename, float min, float max)
130 {
131   int minLevel = ceilf(logf(min) / logf(2.0f));
132   int maxLevel = ceilf(logf(max) / logf(2.0f));
133
134   ImageAttributes attributes;
135   const Vector3 size = Self().GetCurrentSize();
136
137   if(minLevel==maxLevel)
138   { // Single image detail level, no need for any notifications.
139     const float detail = powf(2.0f, maxLevel);
140     attributes.SetSize( size.x * detail, size.y * detail );
141     Image image = Image::New( filename, attributes);
142     mImageActor.SetImage( image );
143   }
144   else
145   { // Multi image detail level...
146     for( int level = minLevel; level <= maxLevel; level++)
147     {
148       const float minDetail = powf(2.0f, level - 1);
149       const float maxDetail = powf(2.0f, level);
150       ImageRequest req(filename, size.x * maxDetail, size.y * maxDetail );
151
152       if(level==minLevel)
153       {
154         AddImage(req, LessThanCondition(maxDetail) );
155       }
156       else if(level==maxLevel)
157       {
158         AddImage(req, GreaterThanCondition(minDetail) );
159       }
160       else
161       {
162         AddImage(req, InsideCondition(minDetail, maxDetail) );
163       }
164     }
165   }
166 }
167
168 void ImageView::SetImageDistanceField(const std::string& filename)
169 {
170   ImageAttributes attributes = Dali::ImageAttributes::NewDistanceField(1.0f, 1);
171   const Vector3 size = Self().GetCurrentSize();
172
173   attributes.SetSize( size.x, size.y );
174   Image image = Image::NewDistanceField(filename, attributes);
175   mImageActor.SetImage( image );
176
177   DistanceFieldEffect effect = DistanceFieldEffect::New();
178   Self().SetShaderEffect( effect );
179 }
180
181 void ImageView::SetImage(Image image)
182 {
183   mImageActor.SetImage( image );
184 }
185
186 void ImageView::AddImage(ImageRequest& req, PropertyCondition condition)
187 {
188   Actor self = Self();
189
190   PropertyNotification notification = self.AddPropertyNotification( mPropertyDetail, condition );
191
192   notification.NotifySignal().Connect( this, &ImageView::OnDetailChange );
193
194   mNotifications[notification] = req;
195 }
196
197 void ImageView::SetDetail(float detail)
198 {
199   Self().SetProperty( mPropertyDetail, detail );
200 }
201
202 void ImageView::SetCameraActor(CameraActor camera, float detailFactor)
203 {
204   Constraint constraint = Constraint::New<float>( mPropertyDetail,
205                                                   LocalSource( Actor::WORLD_POSITION ),
206                                                   Source( camera, Actor::WORLD_POSITION ),
207                                                   CameraDetailConstraint(detailFactor));
208   Self().RemoveConstraints();
209   Self().ApplyConstraint(constraint);
210 }
211
212 void ImageView::OnDetailChange( PropertyNotification& notification )
213 {
214   ImageRequest& req = mNotifications[notification];
215   Image image = Image::New( req.mFilename, req.mAttributes );
216   mImageActor.SetImage( image );
217 }
218
219 } // namespace Internal
220
221 } // namespace Toolkit
222
223 } // namespace Dali