2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0/
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an ”AS IS” BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
19 * @file FUiCtrl_OptionMenuListPresenter.cpp
20 * @brief This is the implementation file for the _OptionMenuPresenter class.
23 #include <FBaseErrorDefine.h>
24 #include <FBaseSysLog.h>
25 #include <FGrp_BitmapImpl.h>
26 #include <FGrp_CanvasImpl.h>
27 #include <FGrp_TextTextSimple.h>
28 #include "FUi_AccessibilityContainer.h"
29 #include "FUi_AccessibilityElement.h"
30 #include "FUi_CoordinateSystemUtils.h"
32 #include "FUi_ResourceManager.h"
33 #include "FUiAnim_MatrixUtil.h"
34 #include "FUiCtrl_ActionEvent.h"
35 #include "FUiCtrl_IActionEventListener.h"
37 #include "FUiCtrl_OptionMenuPresenter.h"
39 using namespace Tizen::Graphics;
40 using namespace Tizen::Ui;
41 using namespace Tizen::Base;
42 using namespace Tizen::Base::Runtime;
43 using namespace Tizen::Graphics::_Text;
44 using namespace Tizen::Ui::Animations;
47 static const float TOUCH_PRESS_THRESHOLD_INSENSITIVE = 0.16f;
48 static const int OPTION_MENU_LIST_ELEMENT_TEXT = 0;
49 static const int OPTION_MENU_LIST_ELEMENT_BITMAP = 1;
52 namespace Tizen { namespace Ui { namespace Controls
56 SineThirtyThreeTimingFunction::CalculateProgress(float timeProgress) const
58 const float segments[2][3] = {{0.0f, 0.050f, 0.495f}, {0.495f, 0.940f, 1.0f}};
60 float loc_5 = timeProgress;
61 int loc_6 = 2; //Length of the segments array
62 int loc_9 = (int)floor(loc_6 * loc_5);
69 float loc_7 = (loc_5 - loc_9 * (1.0f / loc_6)) * loc_6;
73 for (int i = 0; i < 3; i++)
75 loc_8[i] = segments[loc_9][i];
78 float ret = 0 + 1 * (loc_8[0] + loc_7 * (2 * (1 - loc_7) * (loc_8[1] - loc_8[0]) + loc_7 * (loc_8[2] - loc_8[0])));
83 SineSixtyTimingFunction::CalculateProgress(float timeProgress) const
85 const float segments[3][3] = {{0.0f, 0.01f, 0.37f}, {0.37f, 0.72f, 0.888f}, {0.888f, 0.9999f, 1.0f}};
86 float loc_5 = timeProgress;
87 int loc_6 = 3; //Length of the segments array
88 int loc_9 = (int)floor(loc_6 * loc_5);
94 float loc_7 = (loc_5 - loc_9 * (1.0 / loc_6)) * loc_6;
97 for (int i = 0; i < 3; i++)
99 loc_8[i] = segments[loc_9][i];
102 float ret = 0 + 1 * (loc_8[0] + loc_7 * (2 * (1 - loc_7) * (loc_8[1] - loc_8[0]) + loc_7 * (loc_8[2] - loc_8[0])));
107 _OptionMenuPresenter::_OptionMenuPresenter(_OptionMenu* pOptionMenu)
108 : __pOptionMenu(pOptionMenu)
111 , __layoutSize(FloatDimension(0.0f, 0.0f))
112 , __touchOutRect(false)
113 , __selectedIndex(-1)
114 , __scrollEnable(false)
118 , __bottomMargin(0.0f)
120 , __rightMargin(0.0f)
122 , __itemMinWidth(0.0f)
124 , __itemMaxWidth(0.0f)
126 , __itemBitmapWidth(0.0f)
127 , __itemBitmapHeight(0.0f)
128 , __itemFontSize(0.0f)
129 , __dividerHeight(0.0f)
135 _OptionMenuPresenter::~_OptionMenuPresenter(void)
137 __pOptionMenu = null;
147 _OptionMenuPresenter::Install(void)
149 result r = E_SUCCESS;
153 __pModel = new (std::nothrow) _OptionMenuModel;
154 SysTryReturnResult(NID_UI_CTRL, __pModel != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
156 r = __pModel->Construct();
157 SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
159 __pFont = __pOptionMenu->GetFallbackFont();
161 SysTryCatch(NID_UI_CTRL, (__pFont != null), , r, "[%s] Propagating.", GetErrorMessage(r));
175 _OptionMenuPresenter::LoadShape(void)
177 GET_SHAPE_CONFIG(OPTIONMENU::LIST_MIN_WIDTH, _CONTROL_ORIENTATION_PORTRAIT, __itemMinWidth);
178 GET_SHAPE_CONFIG(OPTIONMENU::LIST_MAX_WIDTH, _CONTROL_ORIENTATION_PORTRAIT, __itemMaxWidth);
179 GET_SHAPE_CONFIG(OPTIONMENU::LIST_ITEM_HEIGHT, _CONTROL_ORIENTATION_PORTRAIT, __itemHeight);
180 GET_SHAPE_CONFIG(OPTIONMENU::LIST_ITEM_GAP, _CONTROL_ORIENTATION_PORTRAIT, __itemGap);
182 GET_SHAPE_CONFIG(OPTIONMENU::LIST_TOP_MARGIN, _CONTROL_ORIENTATION_PORTRAIT, __topMargin);
183 GET_SHAPE_CONFIG(OPTIONMENU::LIST_BOTTOM_MARGIN, _CONTROL_ORIENTATION_PORTRAIT, __bottomMargin);
184 GET_SHAPE_CONFIG(OPTIONMENU::LIST_LEFT_MARGIN, _CONTROL_ORIENTATION_PORTRAIT, __leftMargin);
185 GET_SHAPE_CONFIG(OPTIONMENU::LIST_RIGHT_MARGIN, _CONTROL_ORIENTATION_PORTRAIT, __rightMargin);
187 GET_SHAPE_CONFIG(OPTIONMENU::LIST_ICON_WIDTH, _CONTROL_ORIENTATION_PORTRAIT, __itemBitmapWidth);
188 GET_SHAPE_CONFIG(OPTIONMENU::LIST_ICON_HEIGHT, _CONTROL_ORIENTATION_PORTRAIT, __itemBitmapHeight);
190 GET_SHAPE_CONFIG(OPTIONMENU::LIST_ITEM_FONT_SIZE, _CONTROL_ORIENTATION_PORTRAIT, __itemFontSize);
191 GET_SHAPE_CONFIG(OPTIONMENU::LIST_DIVIDER_HEIGHT, _CONTROL_ORIENTATION_PORTRAIT, __dividerHeight);
193 __itemWidth = __itemMinWidth;
197 _OptionMenuPresenter::CreateItemN(const String& text, int actionId, const Bitmap* pNormalBitmap, const Bitmap* pPressedBitmap, const Bitmap* pHighlightedBitmap, bool isSubItem)
199 _OptionMenuItem* pItem = _OptionMenuItem::CreateOptionMenuItemN();
200 SysTryReturn(NID_UI_CTRL, pItem != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
202 OptionMenuItemDrawingType itemType = OPTION_MENU_ITEM_DRAWING_TYPE_TEXT;
203 _Label* pLabel = null;
204 result r = E_SUCCESS;
207 pLabel = _Label::CreateLabelN();
208 if (GetLastResult() != E_SUCCESS)
214 pLabel->SetBackgroundBitmap(*pNormalBitmap);
215 pLabel->SetBackgroundColor(Color(0, 0, 0, 0));
217 int bitmapY = (__itemHeight - __itemBitmapHeight) / 2;
218 pLabel->SetBounds(FloatRectangle(__leftMargin, bitmapY, __itemBitmapWidth, __itemBitmapHeight));
219 pLabel->SetTouchPressThreshold(TOUCH_PRESS_THRESHOLD_INSENSITIVE);
220 pItem->AttachChild(*pLabel);
221 pItem->SetBitmapLabel(pLabel);
223 _AccessibilityContainer* pContainer = pLabel->GetAccessibilityContainer();
224 if (pContainer != null)
226 pContainer->Activate(false);
229 if (pNormalBitmap != null)
231 r = pItem->SetBitmap(OPTION_MENU_ITEM_DRAWING_STATUS_NORMAL, pNormalBitmap);
238 itemType = OPTION_MENU_ITEM_DRAWING_TYPE_BITMAP;
241 if (pPressedBitmap != null)
243 r = pItem->SetBitmap(OPTION_MENU_ITEM_DRAWING_STATUS_PRESSED, pPressedBitmap);
251 if (pHighlightedBitmap != null)
253 r = pItem->SetBitmap(OPTION_MENU_ITEM_DRAWING_STATUS_HIGHLIGHTED, pHighlightedBitmap);
261 pItem->SetType(itemType);
262 pItem->SetActionId(actionId);
264 pItem->SetTextSize(__itemFontSize);
265 r = pItem->SetText(text);
272 // calculate item size
273 float bitmapWidth = 0.0f;
275 if (itemType == OPTION_MENU_ITEM_DRAWING_TYPE_BITMAP)
277 bitmapWidth = __itemBitmapWidth;
280 FloatDimension textArea(0.0f, 0.0f);
281 FloatDimension itemSize(0.0f, 0.0f);
283 CalculateItemSize(text, itemType, textArea, itemSize);
285 float labelLeftMargin = 0.0f;
286 GET_SHAPE_CONFIG(LABEL::LEFT_MARGIN, _CONTROL_ORIENTATION_PORTRAIT, labelLeftMargin);
287 pItem->SetSize(itemSize);
290 float textLabelX = labelLeftMargin + bitmapWidth;
292 pLabel = _Label::CreateLabelN();
293 if (GetLastResult() != E_SUCCESS)
299 pLabel->SetText(text);
300 OptionMenuCoreItemStatus itemStatus = OPTION_MENU_CORE_ITEM_STATUS_NORMAL;
301 pLabel->SetTextColor(__pOptionMenu->GetTextColor(itemStatus));
302 pLabel->SetBackgroundColor(Color(0, 0, 0, 0));
304 itemSize = pItem->GetSize();
305 pLabel->SetBounds(FloatRectangle(textLabelX, (itemSize.height - textArea.height) / 2.0f, textArea.width, textArea.height));
306 pLabel->SetTextVerticalAlignment(ALIGNMENT_MIDDLE);
307 pLabel->SetTextHorizontalAlignment(ALIGNMENT_LEFT);
308 pLabel->SetTextConfig(__itemFontSize, LABEL_TEXT_STYLE_NORMAL);
310 pLabel->SetTouchPressThreshold(TOUCH_PRESS_THRESHOLD_INSENSITIVE);
311 pItem->AttachChild(*pLabel);
313 pContainer = pLabel->GetAccessibilityContainer();
315 if (pContainer != null)
317 pContainer->Activate(false);
319 pItem->SetTextLabel(pLabel);
323 __itemWidth = __itemWidth < itemSize.width ? itemSize.width : __itemWidth;
326 pItem->SetTouchPressThreshold(TOUCH_PRESS_THRESHOLD_INSENSITIVE);
331 _OptionMenuPresenter::CalculateItemSize(const String &text, OptionMenuItemDrawingType itemType, FloatDimension &textArea, FloatDimension &itemSize)
333 float labelLeftMargin = 0.0f;
334 float labelTopMargin = 0.0f;
335 __pFont->GetTextExtent(text, text.GetLength(), textArea);
337 GET_SHAPE_CONFIG(LABEL::LEFT_MARGIN, _CONTROL_ORIENTATION_PORTRAIT, labelLeftMargin);
338 GET_SHAPE_CONFIG(LABEL::TOP_MARGIN, _CONTROL_ORIENTATION_PORTRAIT, labelTopMargin);
340 textArea.width += 2.0f * labelLeftMargin;
341 textArea.height += 2.0f * labelTopMargin;
342 itemSize.height = __itemHeight + (__dividerHeight * 2.0f);
343 itemSize.width = __leftMargin + textArea.width + __rightMargin;
345 if (itemType == OPTION_MENU_ITEM_DRAWING_TYPE_BITMAP)
347 itemSize.width = itemSize.width + __itemBitmapWidth;
350 itemSize.width = itemSize.width < __itemMinWidth ? __itemMinWidth : itemSize.width;
352 if (itemSize.width > __itemMaxWidth)
354 textArea.width -= itemSize.width - __itemMaxWidth;
355 itemSize.width = __itemMaxWidth;
360 _OptionMenuPresenter::AddItem(const String& text, int actionId, const Bitmap* normalBitmap, const Bitmap* pPressedBitmap, const Bitmap* pHighlightedBitmap)
362 _OptionMenuItem* pItem = CreateItemN(text, actionId, normalBitmap, pPressedBitmap, pHighlightedBitmap);
363 SysTryReturnResult(NID_UI_CTRL, pItem != null, GetLastResult(), "Failed to create item.");
365 result r = __pModel->AddItem(pItem);
370 SysTryReturnResult(NID_UI_CTRL, false, r, "Failed to add item.");
377 _OptionMenuPresenter::AddSubItem(int mainIndex, const String& text, int actionId)
379 SysTryReturnResult(NID_UI_CTRL, mainIndex >=0 && mainIndex < __pModel->GetItemCount(), E_INVALID_ARG, "Invalid argument is used. mainIndex (%d) is invalid.", mainIndex);
381 _OptionMenuItem* pItem = CreateItemN(text, actionId, null, null, null, true);
382 SysTryReturnResult(NID_UI_CTRL, pItem != null, GetLastResult(), "Failed to create item.");
384 result r = __pModel->AddItem(pItem, mainIndex);
389 SysTryReturnResult(NID_UI_CTRL, false, r, "Failed to add item.");
396 _OptionMenuPresenter::GetItemIndexFromActionId(int actionId) const
398 return __pModel->GetItemIndexFromActionId(actionId);
402 _OptionMenuPresenter::GetItemActionIdAt(int mainIndex) const
404 _OptionMenuItem* pItem = __pModel->GetItem(mainIndex);
410 return pItem->GetActionId();
414 _OptionMenuPresenter::InsertItem(int mainIndex, const String& text, int actionId, const Bitmap* normalBitmap,
415 const Bitmap* pPressedBitmap, const Bitmap* pHighlightedBitmap)
417 _OptionMenuItem* pItem = CreateItemN(text, actionId, normalBitmap, pPressedBitmap, pHighlightedBitmap);
418 SysTryReturnResult(NID_UI_CTRL, pItem != null, GetLastResult(), "Failed to create item.");
420 result r = __pModel->InsertItemAt(pItem, mainIndex);
424 SysTryReturnResult(NID_UI_CTRL, false, r, "Failed to add item.");
431 _OptionMenuPresenter::InsertSubItemAt(int mainIndex, int subIndex, const String& text, int actionId)
433 SysTryReturnResult(NID_UI_CTRL, mainIndex >=0 && mainIndex < __pModel->GetItemCount(), E_INVALID_ARG, " Invalid argument is used. mainIndex (%d) is invalid.", mainIndex);
434 SysTryReturnResult(NID_UI_CTRL, subIndex >=0 && subIndex <= __pModel->GetSubItemCount(mainIndex), E_INVALID_ARG, " Invalid subIndex %d.", subIndex);
436 _OptionMenuItem* pItem = CreateItemN(text, actionId, null, null, null, true);
437 SysTryReturnResult(NID_UI_CTRL, pItem != null, GetLastResult(), "Failed to create item.");
439 result r = __pModel->InsertItemAt(pItem, mainIndex, subIndex);
440 SysTryReturnResult(NID_UI_CTRL, (r == E_SUCCESS), r, "Propagating.");
446 _OptionMenuPresenter::SetSubItemAt(int mainIndex, int subIndex, const String& text, int actionId)
448 SysTryReturnResult(NID_UI_CTRL, mainIndex >=0 && mainIndex < __pModel->GetItemCount(), E_INVALID_ARG, "Invalid argument is used. mainIndex (%d) is invalid.", mainIndex);
449 SysTryReturnResult(NID_UI_CTRL, subIndex >=0 && subIndex < __pModel->GetSubItemCount(mainIndex), E_INVALID_ARG, "Invalid argument is used. SubIndex (%d) is invalid.", subIndex);
451 result r = __pModel->SetItemAt(mainIndex, text, actionId, null, null, null, __itemFontSize, subIndex);
452 SysTryReturnResult(NID_UI_CTRL, (r == E_SUCCESS), r, "Propagating.");
458 _OptionMenuPresenter::RemoveSubItemAt(int mainIndex, int subIndex)
460 SysTryReturnResult(NID_UI_CTRL, mainIndex >=0 && mainIndex < __pModel->GetItemCount(), E_INVALID_ARG, "Invalid argument is used. mainIndex (%d) is invalid", mainIndex);
461 SysTryReturnResult(NID_UI_CTRL, subIndex >=0 && subIndex < __pModel->GetSubItemCount(mainIndex), E_INVALID_ARG, "Invalid argument is used. SubIndex (%d) is invalid.", subIndex);
463 result r = __pModel->RemoveItem(mainIndex, subIndex);
464 SysTryReturnResult(NID_UI_CTRL, (r == E_SUCCESS), r, "Propagating.");
470 _OptionMenuPresenter::GetSubItemCount(int mainIndex) const
472 SysTryReturn(NID_UI_CTRL, mainIndex >=0 && mainIndex < __pModel->GetItemCount(), -1, E_INVALID_ARG, "[%s] Invalid argument is used. mainIndex (%d) is invalid.", GetErrorMessage(E_INVALID_ARG), mainIndex);
473 return __pModel->GetSubItemCount(mainIndex);
477 _OptionMenuPresenter::GetSubItemIndexFromActionId(int actionId) const
480 return __pModel->GetSubItemIndexFromActionId(actionId, mainIndex);
484 _OptionMenuPresenter::GetSubItemActionIdAt(int mainIndex, int subIndex) const
486 _OptionMenuItem* pItem = __pModel->GetItem(mainIndex, subIndex);
492 return pItem->GetActionId();
496 _OptionMenuPresenter::CalculateItemMaximumWidth(void)
498 FloatDimension itemSize(0.0f, 0.0f);
499 FloatDimension textArea(0.0f, 0.0f);
500 float maxItemWidth = __itemMinWidth;
502 for (int i = 0; i < __pModel->GetItemCount(); i++)
504 _OptionMenuItem* pItem = null;
506 pItem = __pModel->GetItem(i);
507 SysTryReturnVoidResult(NID_UI_CTRL, pItem != null, E_SYSTEM, "[%s] A system has error occurred. Unable to get the item.", GetErrorMessage(E_SYSTEM));
509 CalculateItemSize(pItem->GetText(), pItem->GetType(), textArea, itemSize);
511 if (maxItemWidth < itemSize.width)
513 maxItemWidth = itemSize.width;
517 __itemWidth = maxItemWidth;
521 _OptionMenuPresenter::SetItem(int index, const String& text, int actionId, const Bitmap* normalBitmap, const Bitmap* pPressedBitmap, const Bitmap* pHighlightedBitmap)
523 SysTryReturnResult(NID_UI_CTRL, index >=0 && index < __pModel->GetItemCount(), E_INVALID_ARG, "Invalid argument is used. mainIndex (%d) is invalid.", index);
525 result r = __pModel->SetItemAt(index, text, actionId, normalBitmap, pPressedBitmap, pHighlightedBitmap, __itemFontSize);
526 SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Propagating.");
528 _OptionMenuItem* pItem = __pModel->GetItem(index);
530 SysTryReturnResult(NID_UI_CTRL, pItem != null, r, "Propagating.");
531 CalculateItemMaximumWidth();
537 _OptionMenuPresenter::DeleteItem(int index)
539 SysTryReturnResult(NID_UI_CTRL, (index < __pOptionMenu->GetItemCount()), E_INVALID_ARG,
540 "Invalid argument is used. The specified index (%d) is invalid.", index);
542 result r = E_SUCCESS;
543 _OptionMenuItem* pItem = null;
545 pItem = __pModel->GetItem(index);
547 if (pItem != null && pItem->HasParent())
549 r = __pOptionMenu->GetScrollPanel()->DetachChild(*__pModel->GetItem(index));
550 SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Failed to detach item.");
553 r = __pModel->RemoveItem(index);
554 SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Failed to delete item.");
556 CalculateItemMaximumWidth();
562 _OptionMenuPresenter::DeleteItemAll(void)
564 SysTryReturnResult(NID_UI_CTRL, (__pOptionMenu->GetItemCount() > 0), E_SYSTEM,
565 "A system error has occurred. No items exists.");
567 __pOptionMenu->GetScrollPanel()->DetachAllChildren();
569 result r = __pModel->RemoveAllItem();
570 SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Failed to delete all items.");
576 _OptionMenuPresenter::CalculateWindowRect(void)
578 result r = CalculateRect();
579 AdjustItemPosition();
585 _OptionMenuPresenter::ApplyColorProperty(void)
588 count = __pOptionMenu->GetItemCount();
590 for (int i = 0; i < count; i++)
592 _OptionMenuItem* pItem = null;
593 Color color = __pOptionMenu->GetItemColor(OPTION_MENU_CORE_ITEM_STATUS_PRESSED);
595 pItem = __pModel->GetItem(i);
596 pItem->SetPressedItemColor(color);
603 _OptionMenuPresenter::CalculateRect(void)
605 FloatRectangle windowRect = FloatRectangle(0.0f, 0.0f, 0.0f, 0.0f); // OptionMenu window itself
606 FloatRectangle bodyRect = FloatRectangle(0.0f, 0.0f, 0.0f, 0.0f); // bg surronding showing items, relative to window
607 FloatRectangle itemRect = FloatRectangle(0.0f, 0.0f, 0.0f, 0.0f); // relative to window
609 float bodyTopMargin = __topMargin;
610 float bodyBottomMargin = __bottomMargin;
611 float bodyLeftMargin = __leftMargin;
612 float bodyRightMargin = __rightMargin;
614 int scrollPanelMargin;
615 GET_SHAPE_CONFIG(OPTIONMENU::SCROLL_PANEL_MARGIN, _CONTROL_ORIENTATION_PORTRAIT, scrollPanelMargin);
617 FloatDimension screen = _ControlManager::GetInstance()->GetScreenSizeF();
618 _ControlRotation rotation = __pOptionMenu->GetRotation();
620 if (__pOptionMenu->GetLayout() == _CONTROL_ORIENTATION_LANDSCAPE)
622 screen.SetSize(screen.height, screen.width);
627 bodyRect.width = __layoutSize.width + bodyLeftMargin + bodyRightMargin;
628 bodyRect.height = __layoutSize.height + bodyTopMargin + bodyBottomMargin + 2 * scrollPanelMargin;
630 if (rotation == _CONTROL_ROTATION_270 && __pOptionMenu->GetLayout() == _CONTROL_ORIENTATION_LANDSCAPE)
632 bodyRect.x = screen.width - bodyRect.width;
635 bodyRect.y = screen.height - bodyRect.height;
637 bodyRect = CoordinateSystem::AlignToDevice(bodyRect);
639 windowRect = bodyRect;
644 itemRect.x = bodyRect.x + bodyLeftMargin;
645 itemRect.y = bodyRect.y + bodyTopMargin + scrollPanelMargin;
646 itemRect.width = __layoutSize.width;
647 itemRect.height = __layoutSize.height;
649 __pOptionMenu->SetWindowRect(windowRect);
650 __pOptionMenu->SetBodyRect(bodyRect);
651 __pOptionMenu->SetItemRect(itemRect);
653 // _ScrollPanel API call sequence: SetBounds() -> SetScrollAreaBounds()
654 // _Scroll visual interaction if Bounds < ScrollAreaBounds
655 if (__pOptionMenu->IsVisible())
657 __pOptionMenu->GetScrollPanel()->SetBounds(FloatRectangle(bodyRect.x + bodyLeftMargin, bodyRect.y + bodyTopMargin + scrollPanelMargin,
658 __layoutSize.width, __layoutSize.height));
659 int itemCount = __pModel->GetItemCount();
660 float itemHeight = __itemHeight + (__dividerHeight * 2.0f);
661 float layoutClientHeight = itemCount * itemHeight - (__dividerHeight * 2.0f);
662 __pOptionMenu->GetScrollPanel()->SetClientAreaHeight(layoutClientHeight);
665 __pOptionMenu->SetMovable(true);
666 __pOptionMenu->SetResizable(true);
668 __pOptionMenu->SetBounds(windowRect);
670 __pOptionMenu->SetMovable(false);
671 __pOptionMenu->SetResizable(false);
677 _OptionMenuPresenter::AdjustItemLayout(void)
679 FloatDimension layoutSize(0.0f, 0.0f);
681 int itemCount = __pModel->GetItemCount();
685 __layoutSize.width = __itemWidth;
686 __layoutSize.height = __itemHeight;
690 layoutSize = AdjustItemLayoutStyle();
692 FloatDimension screen = _ControlManager::GetInstance()->GetScreenSizeF();
693 if (__pOptionMenu->GetLayout() == _CONTROL_ORIENTATION_LANDSCAPE)
695 screen.SetSize(screen.height, screen.width);
698 int maxHeight = screen.height;
699 if (layoutSize.height > maxHeight)
701 layoutSize.height = maxHeight;
704 __layoutSize = layoutSize;
708 _OptionMenuPresenter::AdjustItemLayoutStyle(void)
710 int itemMaxCount = __pOptionMenu->GetMaximumVisibleItemsCount();
712 int itemCount = __pModel->GetItemCount();
713 float itemHeight = __itemHeight + (__dividerHeight * 2.0f);
715 FloatDimension layoutSize(__itemWidth, 0.0f);
717 float layoutClientHeight = itemCount * itemHeight - (__dividerHeight * 2.0f);
718 float layoutMaxHeight = itemMaxCount * itemHeight - (__dividerHeight * 2.0f);
719 if (layoutClientHeight > layoutMaxHeight)
721 __scrollEnable = true;
722 layoutSize.height = layoutMaxHeight + itemHeight / 2;
726 __scrollEnable = false;
727 layoutSize.height = layoutClientHeight;
734 _OptionMenuPresenter::AdjustItemPosition(void)
736 int itemCount = __pModel->GetItemCount();
742 float itemHeight = __itemHeight + (__dividerHeight * 2.0f);
743 float drawItemY = 0.0f;
745 float x = __pOptionMenu->GetBodyRect().x + __leftMargin;
746 float y = __pOptionMenu->GetBodyRect().y + __topMargin;
748 _OptionMenuItem* pItem = null;
750 for (int i = 0; i < itemCount; i++)
752 pItem = __pModel->GetItem(i);
759 FloatRectangle drawRect(x, drawItemY + y, __itemWidth, itemHeight);
761 pItem->SetDrawRect(drawRect);
762 pItem->SetUpperDivider(i > 0);
763 pItem->SetLowerDivider(i < itemCount - 1);
764 pItem->SetParentScrollEnable(__scrollEnable);
765 pItem->SetBounds(FloatRectangle(0.0f, drawItemY, drawRect.width, drawRect.height));
767 if (!pItem->HasParent())
769 __pOptionMenu->GetScrollPanel()->AttachChild(*pItem);
772 drawItemY += itemHeight;
777 _OptionMenuPresenter::GetItemIndexFromPosition(const FloatPoint& point) const
780 int itemCount = __pModel->GetItemCount();
787 _OptionMenuItem* pItem = null;
789 float scrollPosition = __pOptionMenu->GetScrollPanel()->GetScrollPosition();
790 FloatPoint position(point.x, point.y + scrollPosition);
792 for (int i = 0; i < itemCount; i++)
794 pItem = __pModel->GetItem(i);
801 FloatRectangle drawRect = pItem->GetDrawRect();
803 if (drawRect.Contains(position))
814 _OptionMenuPresenter::Draw(void)
816 result r = E_SUCCESS;
818 Canvas* pCanvas = __pOptionMenu->GetCanvasN();
819 SysTryReturnResult(NID_UI_CTRL, pCanvas != null, GetLastResult(), "Propagating");
821 // Clear canvas for drawing area of the OptionMenu.
822 pCanvas->SetBackgroundColor(Color(0, 0, 0, 0));
823 FloatRectangle bounds(__pOptionMenu->GetWindowRect());
824 pCanvas->Clear(FloatRectangle(0.0f, 0.0f, bounds.width, bounds.height));
826 r = DrawBackground(pCanvas);
829 SysLog(NID_UI_CTRL, "[%s] Failed to draw background.", GetErrorMessage(r));
837 _OptionMenuPresenter::DrawFocus(int index)
840 result r = E_SUCCESS;
843 _OptionMenuItem* pItem = __pModel->GetItem(index);
846 pItem->SetHighlighted(true);
847 pItem->Invalidate(true);
849 __focusedIndex = index;
856 _OptionMenuPresenter::ClearFocus(void)
858 _OptionMenuItem* pPreviousItem;
859 if (__focusedIndex != -1)
861 pPreviousItem = __pModel->GetItem(__focusedIndex);
862 if (pPreviousItem != null)
864 pPreviousItem->SetHighlighted(false);
865 pPreviousItem->RemoveFocusRing();
866 pPreviousItem->Invalidate(true);
872 _OptionMenuPresenter::OnEnterKeyReleased(int selectedIndex)
874 _OptionMenuItem* pItem = null;
875 pItem = __pModel->GetItem(selectedIndex);
876 __selectedIndex = -1;
881 if (pItem->HasSubItem())
884 __pOptionMenu->ShowSubMenu(selectedIndex, *pItem);
889 __pOptionMenu->CloseAnimation(pItem->GetActionId());
896 _OptionMenuPresenter::DrawBackground(Canvas* pCanvas)
898 SysTryReturnResult(NID_UI_CTRL, pCanvas != null, E_SYSTEM, "A system error has occurred. pCanvas is null");
900 result r = E_SUCCESS;
902 FloatRectangle bodyRect = __pOptionMenu->GetBodyRect();
904 const Bitmap* pBackgroundNormalBitmap = __pOptionMenu->GetBackgroundNormalBitmap();
905 const Bitmap* pBackgroundEffectBitmap = __pOptionMenu->GetBackgroundEffectBitmap();
907 if (pBackgroundNormalBitmap == null && pBackgroundEffectBitmap == null)
909 pCanvas->SetForegroundColor(__pOptionMenu->GetColor());
910 pCanvas->DrawRectangle(bodyRect);
914 if (pBackgroundNormalBitmap != null)
916 r = DrawBitmap(*pCanvas, bodyRect, *pBackgroundNormalBitmap);
919 if (pBackgroundEffectBitmap != null)
921 r = DrawBitmap(*pCanvas, bodyRect, *pBackgroundEffectBitmap);
928 _UiTouchEventDelivery
929 _OptionMenuPresenter::OnPreviewTouchPressed(const _Control& source, const _TouchInfo& touchinfo)
931 return _UI_TOUCH_EVENT_DELIVERY_FORCED_YES;
935 _OptionMenuPresenter::OnTouchPressed(const _Control& source, const _TouchInfo& touchinfo)
937 FloatPoint touchPosition = touchinfo.GetCurrentPosition();
938 FloatRectangle itemRect = __pOptionMenu->GetItemRect();
940 if (__pOptionMenu->IsSubMenuShown())
942 __pOptionMenu->DestroySubMenu();
943 __pOptionMenu->SetTouchCapture(false, false);
947 if (!itemRect.Contains(touchPosition))
949 __selectedIndex = -1;
950 __touchOutRect = true;
954 __selectedIndex = GetItemIndexFromPosition(touchPosition);
955 __touchOutRect = false;
959 _UiTouchEventDelivery
960 _OptionMenuPresenter::OnPreviewTouchReleased(const _Control& source, const _TouchInfo& touchinfo)
962 return _UI_TOUCH_EVENT_DELIVERY_FORCED_YES;
966 _OptionMenuPresenter::OnTouchReleased(const _Control& source, const _TouchInfo& touchinfo)
968 FloatPoint touchPosition = touchinfo.GetCurrentPosition();
972 FloatRectangle itemRect = __pOptionMenu->GetItemRect();
973 if (!itemRect.Contains(touchPosition))
975 __selectedIndex = -1;
976 __pOptionMenu->CloseAnimation(-1);
981 __pOptionMenu->Invalidate(true);
983 int currentSelectedIndex = GetItemIndexFromPosition(touchPosition);
984 if (__selectedIndex != -1 && (__selectedIndex == currentSelectedIndex))
986 _OptionMenuItem* pItem = null;
987 pItem = __pModel->GetItem(__selectedIndex);
988 __selectedIndex = -1;
992 if (pItem->HasSubItem())
995 __pOptionMenu->ShowSubMenu(__selectedIndex, *pItem);
1000 // Fire Action Event
1001 __pOptionMenu->CloseAnimation(pItem->GetActionId());
1002 PLAY_FEEDBACK(_RESOURCE_FEEDBACK_PATTERN_TAP, __pOptionMenu);
1011 _UiTouchEventDelivery
1012 _OptionMenuPresenter::OnPreviewTouchMoved(const _Control& source, const _TouchInfo& touchinfo)
1014 return _UI_TOUCH_EVENT_DELIVERY_FORCED_YES;
1018 _OptionMenuPresenter::OnTouchMoved(const _Control& source, const _TouchInfo& touchinfo)
1022 __selectedIndex = -1;
1024 ResetSelectedItem();
1030 _OptionMenuPresenter::OnTouchCanceled(const _Control& source, const _TouchInfo& touchinfo)
1032 __pModel->ResetAllItem();
1037 _OptionMenuPresenter::ResetSelectedItem(void)
1039 __pModel->ResetSelectedItem(__selectedIndex);
1043 _OptionMenuPresenter::OnActionPerformed(const _Control& source, int actionId)
1045 // for SubMenu Events
1046 __pOptionMenu->DestroySubMenu();
1047 __pOptionMenu->CloseAnimation(actionId);
1051 _OptionMenuPresenter::OnFontChanged(Font* pFont)
1054 String fontName = __pOptionMenu->GetFont();
1056 int itemCount = __pModel->GetItemCount();
1057 for (int i = 0; i < itemCount; i++)
1059 _OptionMenuItem* pItem = __pModel->GetItem(i);
1062 pItem->SetFont(fontName);
1068 _OptionMenuPresenter::OnFontInfoRequested(unsigned long& style, float& size)
1070 style = FONT_STYLE_PLAIN;
1071 size = __itemFontSize;
1075 _OptionMenuPresenter::SetAllAccessibilityElement(void)
1077 _AccessibilityContainer* pContainerOptionMenu = __pOptionMenu->GetAccessibilityContainer();
1078 if (pContainerOptionMenu != null)
1080 _AccessibilityElement* pElementOptionMenu = new (std::nothrow) _AccessibilityElement(true);
1081 SysTryReturnVoidResult(NID_UI_CTRL, pElementOptionMenu, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
1083 pElementOptionMenu->SetSupportOperatingGesture(false);
1084 //pElementOptionMenu->SetTraitWithStringId("IDS_TPLATFORM_BODY_CONTEXTUAL_POP_UP_T_TTS");
1085 pElementOptionMenu->SetHintWithStringId("IDS_TPLATFORM_BODY_CONTEXTUAL_POP_UP_IS_OPEN_DOUBLE_TAP_TO_CLOSE_THE_POP_UP_T_TTS");
1086 pElementOptionMenu->SetBounds(FloatRectangle(0.0f, 0.0f, __pOptionMenu->GetBoundsF().width, __pOptionMenu->GetBoundsF().height));
1087 pContainerOptionMenu->AddElement(*pElementOptionMenu);
1088 __pOptionMenu->AddAccessibilityElement(*pElementOptionMenu);
1090 int itemCount = __pModel->GetItemCount();
1091 for (int i = 0; i < itemCount; i++)
1093 _OptionMenuItem* pItem = __pModel->GetItem(i);
1096 _AccessibilityContainer* pContainer = pItem->GetAccessibilityContainer();
1097 if (pContainer != null)
1099 LinkedListT<_AccessibilityElement*> accessibilityElements;
1100 _AccessibilityElement* pElement = null;
1102 pContainer->GetElements(accessibilityElements);
1103 if (accessibilityElements.GetAt(0, pElement) == E_SUCCESS)
1105 pElement->SetName(L"OptionMenuItem" + Integer::ToString(i));
1106 if (pItem->GetType() == OPTION_MENU_ITEM_DRAWING_TYPE_BITMAP)
1109 GET_STRING_CONFIG(IDS_TPLATFORM_BODY_ICON, string);
1110 pElement->SetLabel(string + pItem->GetText());
1114 pElement->SetLabel(pItem->GetText());
1117 pElement->SetBounds(FloatRectangle(0.0f, 0.0f, pItem->GetBoundsF().width, pItem->GetBoundsF().height));
1119 pContainerOptionMenu->AddChildContainer(*pContainer);
1127 _OptionMenuPresenter::GetItemFromPosition(const FloatPoint& position)
1129 _OptionMenuItemInfo itemInfo;
1130 int index = GetItemIndexFromPosition(position);
1131 itemInfo.pOptionMenuItem = __pModel->GetItem(index);
1133 itemInfo.bListItem = false;
1134 itemInfo.pListItem = null;
1139 _OptionMenuPresenter::FindItem(int index)
1141 _OptionMenuItemInfo itemInfo;
1142 itemInfo.bListItem = false;
1143 itemInfo.pListItem = null;
1144 itemInfo.pOptionMenuItem = __pModel->GetItem(index);
1149 _OptionMenuPresenter::SetTopDrawnItemIndex(int index)
1155 _OptionMenuPresenter::DrawBitmap(Canvas& canvas, const FloatRectangle& bounds, const Bitmap& bitmap)
1157 result r = E_SUCCESS;
1158 if (_BitmapImpl::CheckNinePatchedBitmapStrictly(bitmap))
1160 r = canvas.DrawNinePatchedBitmap(bounds, bitmap);
1161 SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Fail to draw ninepatched bitmap.");
1165 r = canvas.DrawBitmap(bounds, bitmap);
1166 SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Fail to draw bitmap.");
1172 }}} // Tizen::Ui: Control