|
1 /* |
|
2 * Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of the License "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: WebFormFillPopup.cpp |
|
15 * |
|
16 */ |
|
17 |
|
18 // INCLUDE FILES |
|
19 #include <../bidi.h> |
|
20 #include "WebFormFillPopup.h" |
|
21 #include "WebView.h" |
|
22 #include "WebFrame.h" |
|
23 #include "WebFrameView.h" |
|
24 #include "BrCtlDefs.h" |
|
25 #include "PopupSelectListBox.h" |
|
26 #include "BrCtlDialogsProvider.h" |
|
27 #include "WebFepTextEditor.h" |
|
28 #include "FormFillCallback.h" |
|
29 |
|
30 #include <aknenv.h> |
|
31 #include <coemain.h> |
|
32 #include <eikpanic.h> |
|
33 #include <aknedsts.h> |
|
34 #include <AknUtils.h> |
|
35 |
|
36 #include "eikon.hrh" |
|
37 |
|
38 |
|
39 static const TInt KMaxNumToShow = 6; // max number of list items to show |
|
40 static const TInt KInitArraySize = 10; // initial array size |
|
41 static const TInt KBorderSize = 1; // List Box Border size |
|
42 static const TInt KListBoxPadding = 12; |
|
43 static const TInt KListBoxMinWidth = 100; |
|
44 static const TInt KListBoxMargin = 6; |
|
45 |
|
46 WebFormFillPopup* WebFormFillPopup::NewL(WebView* parent, CFont* font, MFormFillCallback* callback) |
|
47 { |
|
48 WebFormFillPopup* self = new (ELeave) WebFormFillPopup(parent, font, callback); |
|
49 CleanupStack::PushL(self); |
|
50 self->ConstructL(font); |
|
51 CleanupStack::Pop(); |
|
52 return self; |
|
53 } |
|
54 |
|
55 WebFormFillPopup::WebFormFillPopup(WebView* parent, CFont* font, MFormFillCallback* callback) : |
|
56 m_parent(parent), m_font(font), m_callback(callback) |
|
57 { |
|
58 } |
|
59 |
|
60 WebFormFillPopup::~WebFormFillPopup() |
|
61 { |
|
62 MakeVisible(EFalse); |
|
63 m_parent->setFormFillPopup(NULL); |
|
64 delete m_listBox; |
|
65 } |
|
66 |
|
67 void WebFormFillPopup::ConstructL(CFont* aFont) |
|
68 { |
|
69 m_parent->setFormFillPopup(this); |
|
70 ConstructListBoxL(aFont); |
|
71 ClearData(); |
|
72 } |
|
73 |
|
74 void WebFormFillPopup::ConstructListBoxL(CFont* aFont) |
|
75 { |
|
76 m_listBox = new (ELeave) PopupSelectListBox(); |
|
77 m_listBox->ConstructL(m_parent, EFalse, aFont); |
|
78 |
|
79 m_listBox->CreateScrollBarFrameL(ETrue); |
|
80 m_listBox->ScrollBarFrame()->SetScrollBarVisibilityL(CEikScrollBarFrame::EOff, CEikScrollBarFrame::EOff); |
|
81 |
|
82 m_listBox->SetListBoxObserver(this); |
|
83 m_listBox->SetBorder(TGulBorder::ESingleGray); |
|
84 m_listBox->SetBackground( TRgb(212, 212, 212) ); |
|
85 |
|
86 m_listBox->SetFocus(ETrue); |
|
87 |
|
88 //iEikonEnv->EikAppUi()->AddToStackL(this); |
|
89 m_listBox->ActivateL(); |
|
90 m_listBox->SetRect(TRect(TPoint(0,0), TSize(10,10))); |
|
91 MakeVisible(EFalse); |
|
92 } |
|
93 |
|
94 void WebFormFillPopup::addRow(const TPtrC& row) |
|
95 { |
|
96 TBrCtlSelectOptionData* data = new TBrCtlSelectOptionData(row, EFalse, EFalse, EFalse); |
|
97 m_data.Append(data); |
|
98 } |
|
99 |
|
100 void WebFormFillPopup::invalidate() |
|
101 { |
|
102 MakeVisible(ETrue); |
|
103 positionListBox(); |
|
104 |
|
105 // now update the listbox |
|
106 m_listBox->UpdateContentL(m_data); |
|
107 } |
|
108 |
|
109 void WebFormFillPopup::ClearData() |
|
110 { |
|
111 m_data.ResetAndDestroy(); |
|
112 MakeVisible(EFalse); |
|
113 } |
|
114 |
|
115 void WebFormFillPopup::positionListBox() |
|
116 { |
|
117 TRect r = m_parent->Rect(); |
|
118 r.Shrink(KListBoxMargin, KListBoxMargin); |
|
119 |
|
120 // size |
|
121 TInt width = 0; |
|
122 for (TInt i=0; i<m_data.Count(); ++i) |
|
123 { |
|
124 TInt w = m_font->MeasureText(m_data[i]->Text()); |
|
125 width = width > w ? width : w; |
|
126 } |
|
127 width += KListBoxPadding; |
|
128 |
|
129 // clamp width to [100, screen_width] |
|
130 width = width > KListBoxMinWidth ? width : KListBoxMinWidth; |
|
131 width = width < r.Width() ? width : r.Width(); |
|
132 |
|
133 // only change the rect when it gets wider or position changed, to avoid |
|
134 // unnecessary flicking. |
|
135 TInt x = m_pos.iX; |
|
136 TInt y = m_pos.iY; |
|
137 if (width > m_listBox->Rect().Width() || m_posChanged) |
|
138 { |
|
139 // x position |
|
140 if (x + width > r.Width() ) |
|
141 x = r.Width() - width; |
|
142 x = x > 0 ? x : 0; |
|
143 |
|
144 // y position |
|
145 TInt height = m_font->HeightInPixels()*KMaxNumToShow; |
|
146 if (y + height > r.Height()) |
|
147 y -= height; |
|
148 else |
|
149 y += m_inputHeight; |
|
150 |
|
151 //m_listBox->SetRect(TRect(TPoint(x, y), TSize(width, height))); |
|
152 SetRect(TRect(TPoint(x, y), TSize(width, height))); |
|
153 } |
|
154 } |
|
155 |
|
156 TKeyResponse WebFormFillPopup::OfferKeyEventL(const TKeyEvent& aKeyEvent, TEventCode aType) |
|
157 { |
|
158 TKeyResponse response = EKeyWasNotConsumed; |
|
159 |
|
160 // We only pass ArrowUp, ArrowDown and Activate to listbox, to prevent Listbox |
|
161 // eating up all the keyevents. |
|
162 switch (aKeyEvent.iCode) |
|
163 { |
|
164 |
|
165 case EKeyUpArrow: // North |
|
166 case EKeyDownArrow: // South |
|
167 response = m_listBox->OfferKeyEventL(aKeyEvent, aType); |
|
168 break; |
|
169 |
|
170 case EKeyDevice3: |
|
171 case EKeyEnter: |
|
172 response = m_listBox->OfferKeyEventL(aKeyEvent, aType); |
|
173 m_callback->cancelPopup(); |
|
174 break; |
|
175 |
|
176 case EKeyLeftArrow: // West |
|
177 case EKeyRightArrow: // East |
|
178 MakeVisible(EFalse); |
|
179 response = m_parent->OfferKeyEventL(aKeyEvent, aType); |
|
180 m_callback->cancelPopup(); |
|
181 break; |
|
182 |
|
183 // All of the diagonal KeyEvents are allowed to flow through the "default" case... |
|
184 // |
|
185 // case EKeyRightUpArrow: // Northeast |
|
186 // case EStdKeyDevice11: // : Extra KeyEvent supports diagonal event simulator wedge |
|
187 // case EKeyRightDownArrow: // Southeast |
|
188 // case EStdKeyDevice12: // : Extra KeyEvent supports diagonal event simulator wedge |
|
189 // case EKeyLeftDownArrow: // Southwest |
|
190 // case EStdKeyDevice13: // : Extra KeyEvent supports diagonal event simulator wedge |
|
191 // case EKeyLeftUpArrow: // Northwest |
|
192 // case EStdKeyDevice10: // : Extra KeyEvent supports diagonal event simulator wedge |
|
193 default: |
|
194 response = m_parent->OfferKeyEventL(aKeyEvent, aType); |
|
195 break; |
|
196 |
|
197 } |
|
198 |
|
199 return response; |
|
200 } |
|
201 |
|
202 // Handle the key event from touch device |
|
203 TKeyResponse WebFormFillPopup::HandleKeyEventL(const TKeyEvent& aKeyEvent, TEventCode aType) |
|
204 { |
|
205 TKeyResponse response = EKeyWasNotConsumed; |
|
206 |
|
207 // We only pass ArrowUp, ArrowDown and Activate to listbox, to prevent Listbox |
|
208 // eating up all the keyevents. |
|
209 switch (aKeyEvent.iCode) |
|
210 { |
|
211 |
|
212 case EKeyUpArrow: // North |
|
213 case EKeyDownArrow: // South |
|
214 response = m_listBox->OfferKeyEventL(aKeyEvent, aType); |
|
215 break; |
|
216 |
|
217 case EKeyDevice3: |
|
218 case EKeyEnter: |
|
219 response = m_listBox->OfferKeyEventL(aKeyEvent, aType); |
|
220 m_callback->cancelPopup(); |
|
221 break; |
|
222 |
|
223 case EKeyLeftArrow: // West |
|
224 case EKeyRightArrow: // East |
|
225 MakeVisible(EFalse); |
|
226 m_callback->cancelPopup(); |
|
227 response = EKeyWasConsumed; |
|
228 break; |
|
229 |
|
230 // All of the diagonal KeyEvents are to be ignored and consumed |
|
231 case EKeyRightUpArrow: // Northeast |
|
232 case EStdKeyDevice11: // : Extra KeyEvent supports diagonal event simulator wedge |
|
233 case EKeyRightDownArrow: // Southeast |
|
234 case EStdKeyDevice12: // : Extra KeyEvent supports diagonal event simulator wedge |
|
235 case EKeyLeftDownArrow: // Southwest |
|
236 case EStdKeyDevice13: // : Extra KeyEvent supports diagonal event simulator wedge |
|
237 case EKeyLeftUpArrow: // Northwest |
|
238 case EStdKeyDevice10: // : Extra KeyEvent supports diagonal event simulator wedge |
|
239 response = EKeyWasConsumed; |
|
240 break; |
|
241 |
|
242 // Allow vkb keyevents to be handled later. |
|
243 default: |
|
244 response = EKeyWasNotConsumed; |
|
245 break; |
|
246 |
|
247 } |
|
248 |
|
249 return response; |
|
250 } |
|
251 |
|
252 CCoeControl* WebFormFillPopup::ComponentControl( TInt /*aIndex*/ ) const |
|
253 { |
|
254 return m_listBox; |
|
255 } |
|
256 |
|
257 TInt WebFormFillPopup::CountComponentControls() const |
|
258 { |
|
259 return 1; |
|
260 } |
|
261 |
|
262 |
|
263 void WebFormFillPopup::SizeChanged() |
|
264 { |
|
265 m_listBox->SetRect( Rect() ); |
|
266 } |
|
267 |
|
268 void WebFormFillPopup::HandleListBoxEventL(CEikListBox* aListBox, TListBoxEvent aEventType) |
|
269 { |
|
270 if (aListBox != m_listBox) |
|
271 return; |
|
272 |
|
273 if (aEventType == EEventItemDoubleClicked || aEventType == EEventEnterKeyPressed) |
|
274 { |
|
275 // get the selected item from listbox |
|
276 m_listBox->View()->UpdateSelectionL(CListBoxView::ESingleSelection); |
|
277 const CListBoxView::CSelectionIndexArray* selected = m_listBox->SelectionIndexes(); |
|
278 if (m_listBox->IsFocused()) |
|
279 { |
|
280 MakeVisible(EFalse); |
|
281 m_callback->autoComplete(m_data[selected->At(0)]->Text()); |
|
282 } |
|
283 } |
|
284 else if (aEventType == EEventPenDownOnItem) { |
|
285 if (!m_listBox->IsFocused()) { |
|
286 m_listBox->SetFocus(ETrue); // highlight first item |
|
287 m_listBox->DrawNow(); |
|
288 } |
|
289 } |
|
290 } |
|
291 |
|
292 TCoeInputCapabilities WebFormFillPopup::InputCapabilities() const |
|
293 { |
|
294 // tricky!!! we need to retain T9 capabilities of WebKitView. |
|
295 return m_parent->fepTextEditor()->InputCapabilities(); |
|
296 } |
|
297 |
|
298 void WebFormFillPopup::clear() |
|
299 { |
|
300 ClearData(); |
|
301 } |
|
302 |
|
303 void WebFormFillPopup::setLocationHintInDoc(const TRect& r, WebCore::Frame* frame) |
|
304 { |
|
305 WebFrame* webFrame = kit(frame); |
|
306 |
|
307 // now lets reverse back to the root frame to figure out the screen position |
|
308 TPoint pt = webFrame->frameView()->frameCoordsInViewCoords(r.iTl); |
|
309 m_posChanged = !(pt == m_pos); |
|
310 |
|
311 m_pos = pt; |
|
312 m_inputHeight = r.Height(); |
|
313 } |
|
314 |
|
315 void WebFormFillPopup::MakeVisible(TBool aVisible) |
|
316 { |
|
317 if (aVisible == IsVisible()) |
|
318 return; |
|
319 |
|
320 CCoeControl::MakeVisible(aVisible); |
|
321 |
|
322 if ( aVisible ) |
|
323 { |
|
324 m_listBox->ScrollBarFrame()->SetScrollBarVisibilityL(CEikScrollBarFrame::EOff, CEikScrollBarFrame::EAuto); |
|
325 m_listBox->MakeVisible(ETrue); |
|
326 // for touch we want to prevent list from focusing and closing the VKB |
|
327 if (!AknLayoutUtils::PenEnabled()){ |
|
328 iEikonEnv->EikAppUi()->AddToStackL(this); |
|
329 } |
|
330 } |
|
331 else |
|
332 { |
|
333 m_listBox->ScrollBarFrame()->SetScrollBarVisibilityL(CEikScrollBarFrame::EOff, CEikScrollBarFrame::EOff); |
|
334 m_listBox->MakeVisible(EFalse); |
|
335 iEikonEnv->EikAppUi()->RemoveFromStack(this); |
|
336 } |
|
337 } |
|
338 |
|
339 void WebFormFillPopup::reDraw() |
|
340 { |
|
341 m_listBox->DrawNow(); |
|
342 } |
|
343 |
|
344 void WebFormFillPopup::handleCommandL(int command) |
|
345 { |
|
346 switch (command) |
|
347 { |
|
348 case TBrCtlDefs::ECommandCancel: |
|
349 MakeVisible(EFalse); |
|
350 m_callback->cancelPopup(); |
|
351 break; |
|
352 } |
|
353 } |
|
354 |
|
355 void WebFormFillPopup::HandlePointerEventL(const TPointerEvent& aPointerEvent) |
|
356 { |
|
357 if (Rect().Contains(aPointerEvent.iPosition)) { |
|
358 m_listBox->HandlePointerEventL( aPointerEvent ); |
|
359 } |
|
360 else { |
|
361 m_callback->cancelPopup(); |
|
362 } |
|
363 } |
|
364 |
|
365 // End of File |