Merge branch 'master' into tizen
[platform/core/uifw/dali-toolkit.git] / base / dali-toolkit / internal / controls / text-input / text-input-handles-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 // INTERNAL INCLUDES
18 #include <dali-toolkit/internal/controls/text-input/text-input-handles-impl.h>
19 #include <dali-toolkit/internal/controls/text-input/textview-character-positions-impl.h>
20
21 #include <dali/dali.h>
22
23 #include <dali-toolkit/internal/controls/text-input/text-input-impl.h>
24 #include <dali-toolkit/internal/controls/text-view/text-processor.h>
25 #include <dali-toolkit/internal/controls/text-view/text-view-impl.h>
26 #include <dali-toolkit/public-api/controls/buttons/push-button.h>
27 #include <dali-toolkit/public-api/controls/alignment/alignment.h>
28
29 #include <dali/integration-api/debug.h>
30
31 #include <math.h>
32 #include <sstream>
33 #include <algorithm>
34
35 using namespace Dali;
36 using namespace std;
37
38 namespace
39 {
40 const char* const DEFAULT_SELECTION_HANDLE_ONE( DALI_IMAGE_DIR "text-input-selection-handle-left.png" );
41 const char* const DEFAULT_SELECTION_HANDLE_TWO( DALI_IMAGE_DIR "text-input-selection-handle-right.png" );
42 const char* const DEFAULT_SELECTION_HANDLE_ONE_PRESSED( DALI_IMAGE_DIR "text-input-selection-handle-left-press.png" );
43 const char* const DEFAULT_SELECTION_HANDLE_TWO_PRESSED( DALI_IMAGE_DIR "text-input-selection-handle-right-press.png" );
44
45 const char* const DEFAULT_GRAB_HANDLE( DALI_IMAGE_DIR "insertpoint-icon.png" );
46
47 const Vector3 DEFAULT_SELECTION_HANDLE_RELATIVE_SCALE( 1.5f, 1.5f, 1.0f );
48 const Vector3 DEFAULT_GRAB_HANDLE_RELATIVE_SCALE( 1.5f, 2.0f, 1.0f );
49
50 const char* const SELECTION_GRAB_AREA_ONE( "SelectionHandleOneGrabArea");
51 const char* const SELECTION_GRAB_AREA_TWO( "SelectionHandleTwoGrabArea");
52 const char* const GRABHANDLE_GRAB_AREA( "GrabHandleGrabArea");
53
54 #if defined(DEBUG_ENABLED)
55 Debug::Filter* gLogFilter = Debug::Filter::New( Debug::NoLogging, false, "TEXT_INPUT_HANDLES" );
56 #endif
57
58 Actor CreateGrabArea( const std::string& name, const Vector3& relativeScale )
59 {
60   DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextInputHandles: CreateGrabArea\n" );
61
62   Actor handleGrabArea = Actor::New(); // Area that Grab handle responds to, larger than actual handle so easier to move
63   handleGrabArea.SetName( name );
64   handleGrabArea.ApplyConstraint( Constraint::New<Vector3>( Actor::SIZE, ParentSource( Actor::SIZE ), RelativeToConstraint( relativeScale ) ) );  // grab area to be larger than text actor
65   handleGrabArea.SetPositionInheritanceMode( Dali::USE_PARENT_POSITION );
66
67   return handleGrabArea;
68 }
69
70 Actor CreateHandle( const Vector3& anchorPoint, const Image& handleImage, const std::string& name )
71 {
72   DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextInputHandles: CreateSelectionHandle\n" );
73
74   ImageActor selectionHandle = ImageActor::New( handleImage );
75   selectionHandle.SetName( name );
76   selectionHandle.SetAnchorPoint( anchorPoint );
77   selectionHandle.SetDrawMode( DrawMode::OVERLAY ); // ensure handle above text
78
79   return selectionHandle;
80 }
81 }
82
83 namespace Dali
84 {
85
86 namespace Toolkit
87 {
88
89 namespace Internal
90 {
91
92 // Default constructor
93 TextInputHandles::TextInputHandles():
94   mSelectionHandleOne(),
95   mSelectionHandleTwo(),
96   mSelectionHandleOneOffset( Vector3::ZERO ),
97   mSelectionHandleTwoOffset( Vector3::ZERO ),
98   mSelectionHandleOneCoordinatePosition( Vector3::ZERO ),
99   mSelectionHandleTwoCoordinatePosition( Vector3::ZERO ),
100   mSelectionHandleOneStringPosition( 0 ),
101   mSelectionHandleTwoStringPosition( 0 ),
102   mIsSelectionHandleOneFlipped( false ),
103   mIsSelectionHandleTwoFlipped( false )
104 {
105 }
106
107 TextInputHandles::~TextInputHandles()
108 {
109 }
110
111 void TextInputHandles::CreateSelectionHandles()
112 {
113   DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextInputHandles: CreateSelectionHandles\n" );
114
115   mSelectionHandleOneImage = Image::New( DEFAULT_SELECTION_HANDLE_ONE );
116   mSelectionHandleOneImagePressed = Image::New( DEFAULT_SELECTION_HANDLE_ONE_PRESSED );
117   mSelectionHandleOne = CreateHandle( AnchorPoint::TOP_RIGHT, mSelectionHandleOneImage, "SelectionHandleOne" );
118   mIsSelectionHandleOneFlipped = false;
119
120   mHandleOneGrabArea = CreateGrabArea( SELECTION_GRAB_AREA_ONE, DEFAULT_SELECTION_HANDLE_RELATIVE_SCALE );
121   mSelectionHandleOne.Add( mHandleOneGrabArea );
122   mHandleOneGrabArea.TouchedSignal().Connect(this, &TextInputHandles::OnSelectionHandleTouched);
123
124 //  mTapDetector.Attach( mHandleOneGrabArea );
125
126   mSelectionHandleTwoImage = Image::New( DEFAULT_SELECTION_HANDLE_TWO );
127   mSelectionHandleTwoImagePressed = Image::New( DEFAULT_SELECTION_HANDLE_TWO_PRESSED );
128   mSelectionHandleTwo = CreateHandle( AnchorPoint::TOP_LEFT, mSelectionHandleTwoImage, "SelectionHandleTwo" );
129   mIsSelectionHandleTwoFlipped = false;
130
131   mHandleTwoGrabArea = CreateGrabArea( SELECTION_GRAB_AREA_TWO, DEFAULT_SELECTION_HANDLE_RELATIVE_SCALE );
132   mSelectionHandleTwo.Add( mHandleTwoGrabArea );
133   mHandleTwoGrabArea.TouchedSignal().Connect(this, &TextInputHandles::OnSelectionHandleTouched);
134
135   //  mTapDetector.Attach( mHandleTwoGrabArea );
136 }
137
138 void TextInputHandles::DestorySelectionHandles()
139 {
140   if ( mSelectionHandleOne && mSelectionHandleTwo)
141   {
142     mSelectionHandleOne.Unparent();
143     mSelectionHandleTwo.Unparent();
144     mSelectionHandleOneImagePressed.Reset();
145     mSelectionHandleOneImage.Reset();
146     mSelectionHandleTwoImagePressed.Reset();
147     mSelectionHandleTwoImage.Reset();
148     mSelectionHandleOne.Reset();
149     mSelectionHandleTwo.Reset();
150   }
151 }
152
153 void TextInputHandles::SetSelectionHandleOneVisibility( bool visibility )
154 {
155   if ( mSelectionHandleOne )
156   {
157     mSelectionHandleOne.SetVisible( visibility );
158   }
159 }
160
161 void TextInputHandles::SetSelectionHandleTwoVisibility( bool visibility )
162 {
163   if ( mSelectionHandleTwo )
164   {
165     mSelectionHandleTwo.SetVisible( visibility );
166   }
167 }
168
169 void TextInputHandles::AttachSelectionHandlesToGivenPanGesture( PanGestureDetector& panGestureDetector )
170 {
171   DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextInputHandles: AttachSelectionHandlesToGivenPanGesture\n" );
172
173   panGestureDetector.Attach( mHandleOneGrabArea );
174   panGestureDetector.Attach( mHandleTwoGrabArea );
175 }
176
177 void TextInputHandles::AttachSelectionHandlesToGivenTapDetector(TapGestureDetector& tapGestureDetector )
178 {
179   tapGestureDetector.Attach( mHandleOneGrabArea );
180   tapGestureDetector.Attach( mHandleTwoGrabArea );
181 }
182
183 void TextInputHandles::AttachGrabHandleToGivenPanGesture( PanGestureDetector& panGestureDetector )
184 {
185   DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextInputHandles: AttachGrabHandleToGivenPanGesture\n" );
186
187   panGestureDetector.Attach( mGrabHandleGrabArea );
188 }
189
190 Actor TextInputHandles::GetSelectionHandleOne()
191 {
192   return mSelectionHandleOne;
193 }
194
195 Actor TextInputHandles::GetSelectionHandleTwo()
196 {
197   return mSelectionHandleTwo;
198 }
199
200 bool TextInputHandles::OnSelectionHandleTouched(Dali::Actor actor, const TouchEvent& touch)
201 {
202   DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextInputHandles: OnSelectionHandleTouched\n" );
203
204   Image pressedImage;
205   Image normalImage;
206
207   ImageActor handleTouched = ImageActor::DownCast( actor.GetParent() ); // Hit actor would be the GrabArea hence get parent.
208
209   if ( handleTouched == mSelectionHandleOne )
210   {
211     pressedImage = mSelectionHandleOneImagePressed;
212     normalImage = mSelectionHandleOneImage;
213   }
214   else
215   {
216     pressedImage = mSelectionHandleTwoImagePressed;
217     normalImage = mSelectionHandleTwoImage;
218   }
219
220   if (touch.GetPoint(0).state == TouchPoint::Down)
221   {
222     handleTouched.SetImage( pressedImage );
223   }
224   else if (touch.GetPoint(0).state == TouchPoint::Up )
225   {
226     handleTouched.SetImage( normalImage );
227   }
228   return false;
229 }
230
231 // Grab handle
232
233 Actor TextInputHandles::GetGrabHandle()
234 {
235   DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextInputHandles: GetGrabHandle\n" );
236
237   return mGrabHandle;
238 }
239
240 void TextInputHandles::CreateGrabHandle()
241 {
242   DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextInputHandles: CreateGrabHandle\n" );
243
244   if ( !mGrabHandle )
245   {
246     if ( !mGrabHandleImage )
247     {
248       mGrabHandleImage = Image::New( DEFAULT_GRAB_HANDLE );
249     }
250
251     mGrabHandle = CreateHandle( AnchorPoint::TOP_CENTER, mGrabHandleImage, "GrabHandle" );
252     mGrabHandleGrabArea = CreateGrabArea( GRABHANDLE_GRAB_AREA, DEFAULT_GRAB_HANDLE_RELATIVE_SCALE );
253     mGrabHandle.Add( mGrabHandleGrabArea );
254   }
255 }
256
257 void TextInputHandles::DestoryGrabHandle()
258 {
259   if ( mGrabHandle )
260   {
261     mGrabHandle.Unparent();
262     mGrabHandleImage.Reset();
263     mGrabHandle.Reset();
264   }
265 }
266
267 void TextInputHandles::SetGrabHandleImage( Dali::Image image )
268 {
269   if ( mGrabHandle )
270   {
271     mGrabHandleImage = image;
272     mGrabHandle.SetImage( mGrabHandleImage );
273   }
274 }
275
276 void TextInputHandles::SetGrabHandleVisibility( bool visibility )
277 {
278   DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextInputHandles: SetGrabHandleVisibility (%s) \n", ( visibility )?"true":"false" );
279
280   if ( mGrabHandle )
281   {
282     mGrabHandle.SetVisible( visibility );
283   }
284 }
285
286 } // Internal
287
288 } // namespace Toolkit
289
290 } // namespace Dali
291