2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
5 // Licensed under the Flora License, Version 1.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://floralicense.org/license/
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.
18 * @file FUiCtrl_ContextMenuListPresenter.cpp
19 * @brief This is the implementation file for the _ContextMenuListPresenter class.
22 #include <FBaseErrorDefine.h>
23 #include <FBaseSysLog.h>
24 #include <FGrp_CanvasImpl.h>
25 #include <FGrp_BitmapImpl.h>
26 #include <FGrp_TextTextSimple.h>
27 #include "FUiCtrl_ContextMenuListPresenter.h"
28 #include "FUiCtrl_IActionEventListener.h"
29 #include "FUiCtrl_ActionEvent.h"
30 #include "FUi_ResourceManager.h"
31 #include "FUi_AccessibilityContainer.h"
32 #include "FUi_AccessibilityElement.h"
34 using namespace Tizen::Graphics;
35 using namespace Tizen::Ui;
36 using namespace Tizen::Base;
37 using namespace Tizen::Base::Runtime;
38 using namespace Tizen::Graphics::_Text;
40 static const int CONTEXT_MENU_LIST_ELEMENT_TEXT = 0;
41 static const int CONTEXT_MENU_LIST_ELEMENT_BITMAP = 1;
43 namespace Tizen { namespace Ui { namespace Controls
46 _ContextMenuListPresenter::_ContextMenuListPresenter(_ContextMenu* pContextMenu)
47 : __pContextMenu(pContextMenu)
50 , __layoutSize(Dimension(0, 0))
51 , __touchOutRect(false)
53 , __scrollEnable(false)
60 , __screenTopMargin(0)
61 , __screenBottomMargin(0)
62 , __screenLeftMargin(0)
63 , __screenRightMargin(0)
72 , __itemBitmapWidth(0)
73 , __itemBitmapHeight(0)
80 _ContextMenuListPresenter::~_ContextMenuListPresenter(void)
82 __pContextMenu = null;
92 _ContextMenuListPresenter::Install(void)
98 __pModel = new (std::nothrow) _ContextMenuModel;
99 SysTryCatch(NID_UI_CTRL, __pModel != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory shortage.");
101 r = __pModel->Construct();
102 SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Unable to create data instance.");
104 __pFont = __pContextMenu->GetFallbackFont();
106 SysTryCatch(NID_UI_CTRL, (__pFont != null), , r, "[%s] Propagating.", GetErrorMessage(r));
121 _ContextMenuListPresenter::LoadShape(void)
123 GET_SHAPE_CONFIG(CONTEXTMENU::LIST_MIN_WIDTH, _CONTROL_ORIENTATION_PORTRAIT, __itemMinWidth);
124 GET_SHAPE_CONFIG(CONTEXTMENU::LIST_MAX_WIDTH, _CONTROL_ORIENTATION_PORTRAIT, __itemMaxWidth);
125 GET_SHAPE_CONFIG(CONTEXTMENU::LIST_ITEM_HEIGHT, _CONTROL_ORIENTATION_PORTRAIT, __itemHeight);
126 GET_SHAPE_CONFIG(CONTEXTMENU::LIST_ITEM_GAP, _CONTROL_ORIENTATION_PORTRAIT, __itemGap);
128 GET_SHAPE_CONFIG(CONTEXTMENU::LIST_TOP_MARGIN, _CONTROL_ORIENTATION_PORTRAIT, __topMargin);
129 GET_SHAPE_CONFIG(CONTEXTMENU::LIST_BOTTOM_MARGIN, _CONTROL_ORIENTATION_PORTRAIT, __bottomMargin);
130 GET_SHAPE_CONFIG(CONTEXTMENU::LIST_LEFT_MARGIN, _CONTROL_ORIENTATION_PORTRAIT, __leftMargin);
131 GET_SHAPE_CONFIG(CONTEXTMENU::LIST_RIGHT_MARGIN, _CONTROL_ORIENTATION_PORTRAIT, __rightMargin);
133 GET_SHAPE_CONFIG(CONTEXTMENU::SCREEN_TOP_MARGIN, _CONTROL_ORIENTATION_PORTRAIT, __screenTopMargin);
134 GET_SHAPE_CONFIG(CONTEXTMENU::SCREEN_BOTTOM_MARGIN, _CONTROL_ORIENTATION_PORTRAIT, __screenBottomMargin);
135 GET_SHAPE_CONFIG(CONTEXTMENU::SCREEN_LEFT_MARGIN, _CONTROL_ORIENTATION_PORTRAIT, __screenLeftMargin);
136 GET_SHAPE_CONFIG(CONTEXTMENU::SCREEN_RIGHT_MARGIN, _CONTROL_ORIENTATION_PORTRAIT, __screenRightMargin);
137 GET_SHAPE_CONFIG(CONTEXTMENU::ANCHOR_MARGIN, _CONTROL_ORIENTATION_PORTRAIT, __arrowMargin);
138 GET_SHAPE_CONFIG(CONTEXTMENU::ANCHOR_WIDTH, _CONTROL_ORIENTATION_PORTRAIT, __arrowWidth);
139 GET_SHAPE_CONFIG(CONTEXTMENU::ANCHOR_HEIGHT, _CONTROL_ORIENTATION_PORTRAIT, __arrowHeight);
140 GET_SHAPE_CONFIG(CONTEXTMENU::LIST_ICON_WIDTH, _CONTROL_ORIENTATION_PORTRAIT, __itemBitmapWidth);
141 GET_SHAPE_CONFIG(CONTEXTMENU::LIST_ICON_HEIGHT, _CONTROL_ORIENTATION_PORTRAIT, __itemBitmapHeight);
143 GET_SHAPE_CONFIG(CONTEXTMENU::LIST_ITEM_FONT_SIZE, _CONTROL_ORIENTATION_PORTRAIT, __itemFontSize);
144 GET_SHAPE_CONFIG(CONTEXTMENU::LIST_DIVIDER_HEIGHT, _CONTROL_ORIENTATION_PORTRAIT, __dividerHeight);
146 __itemWidth = __itemMinWidth;
150 _ContextMenuListPresenter::CreateItem(const Base::String& text, int actionId, const Tizen::Graphics::Bitmap* pNormalBitmap, const Tizen::Graphics::Bitmap* pPressedBitmap, const Tizen::Graphics::Bitmap* pHighlightedBitmap)
152 _ContextMenuItem* pItem = _ContextMenuItem::CreateContextMenuItemN();
153 SysTryReturn(NID_UI_CTRL, pItem != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
155 ContextMenuItemDrawingType itemType = CONTEXT_MENU_ITEM_DRAWING_TYPE_TEXT;
157 result r = E_SUCCESS;
158 _Label* pLabel = null;
160 if (pNormalBitmap != null)
162 r = pItem->SetBitmap(CONTEXT_MENU_ITEM_DRAWING_STATUS_NORMAL, pNormalBitmap);
170 pLabel = _Label::CreateLabelN();
171 pLabel->SetBackgroundBitmap(*pNormalBitmap);
172 pLabel->SetBackgroundColor(Color(0, 0, 0, 0));
174 int bitmapY = (__itemHeight - __itemBitmapHeight ) / 2;
175 pLabel->SetBounds(Rectangle(__leftMargin, bitmapY, __itemBitmapWidth, __itemBitmapHeight));
176 pItem->AttachChild(*pLabel);
177 _AccessibilityContainer* pContainer = pLabel->GetAccessibilityContainer();
180 pContainer->Activate(false);
182 pItem->SetBitmapLabel(pLabel);
184 itemType = CONTEXT_MENU_ITEM_DRAWING_TYPE_BITMAP;
187 if (pPressedBitmap != null)
189 r = pItem->SetBitmap(CONTEXT_MENU_ITEM_DRAWING_STATUS_PRESSED, pPressedBitmap);
197 pItem->SetType(itemType);
198 pItem->SetActionId(actionId);
200 pItem->SetTextSize(__itemFontSize);
201 r = pItem->SetText(text);
208 // calculate item size
209 int bitmapWidth = (itemType == CONTEXT_MENU_ITEM_DRAWING_TYPE_BITMAP) ? __itemBitmapWidth : 0;
211 Dimension textArea(0, 0);
212 Dimension itemSize(0, 0);
214 __pFont->GetTextExtent(text, text.GetLength(), textArea);
215 int labelLeftMargin, labelTopMargin;
216 GET_SHAPE_CONFIG(LABEL::LEFT_MARGIN, _CONTROL_ORIENTATION_PORTRAIT, labelLeftMargin);
217 GET_SHAPE_CONFIG(LABEL::TOP_MARGIN, _CONTROL_ORIENTATION_PORTRAIT, labelTopMargin);
218 textArea.width += 2 * labelLeftMargin;
219 textArea.height += 2 * labelTopMargin;
220 itemSize.height = __itemHeight + __dividerHeight;
221 itemSize.width = __leftMargin + textArea.width + __rightMargin + bitmapWidth;
223 itemSize.width = itemSize.width < __itemMinWidth ? __itemMinWidth : itemSize.width;
224 itemSize.width = itemSize.width > __itemMaxWidth ? __itemMaxWidth : itemSize.width;
226 pItem->SetSize(itemSize);
229 int textLabelX = __leftMargin + bitmapWidth;
230 int textLabelWidth = textArea.width;
232 pLabel = _Label::CreateLabelN();
233 pLabel->SetText(text);
234 ContextMenuCoreItemStatus itemStatus = CONTEXT_MENU_CORE_ITEM_STATUS_NORMAL;
235 pLabel->SetTextColor(__pContextMenu->GetTextColor(itemStatus));
236 pLabel->SetBackgroundColor(Color(0, 0, 0, 0));
238 itemSize = pItem->GetSize();
239 pLabel->SetBounds(Rectangle(textLabelX, (itemSize.height - textArea.height) / 2, textLabelWidth, textArea.height));
240 pLabel->SetTextVerticalAlignment(ALIGNMENT_MIDDLE);
241 pLabel->SetTextHorizontalAlignment(ALIGNMENT_LEFT);
242 pLabel->SetTextConfig(__itemFontSize, LABEL_TEXT_STYLE_NORMAL);
244 pItem->AttachChild(*pLabel);
245 _AccessibilityContainer* pContainer = pLabel->GetAccessibilityContainer();
248 pContainer->Activate(false);
250 pItem->SetTextLabel(pLabel);
252 __itemWidth = __itemWidth < itemSize.width ? itemSize.width : __itemWidth;
258 _ContextMenuListPresenter::AddItem(const Base::String& text, int actionId, const Tizen::Graphics::Bitmap* normalBitmap,
259 const Tizen::Graphics::Bitmap* pPressedBitmap,
260 const Tizen::Graphics::Bitmap* pHighlightedBitmap)
262 _ContextMenuItem* pItem = CreateItem(text, actionId, normalBitmap, pPressedBitmap, pHighlightedBitmap);
263 SysTryReturn(NID_UI_CTRL, pItem != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "The memory is insufficient.");
265 result r = __pModel->AddItem(pItem);
270 SysTryReturn(NID_UI_CTRL, false, r, r, "Failed to add item.");
277 _ContextMenuListPresenter::InsertItem(int index, const Tizen::Base::String& text, int actionId,
278 const Tizen::Graphics::Bitmap* normalBitmap, const Tizen::Graphics::Bitmap* pPressedBitmap,
279 const Tizen::Graphics::Bitmap* pHighlightedBitmap)
281 if (text.GetLength() == 0 && normalBitmap == null && pPressedBitmap == null)
283 return E_INVALID_ARG;
286 _ContextMenuItem* pItem = null;
288 pItem = CreateItem(text, actionId, normalBitmap, pPressedBitmap, pHighlightedBitmap);
289 SysTryReturn(NID_UI_CTRL, pItem != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "The memory is insufficient.");
291 result r = __pModel->InsertItem(pItem, index);
295 SysTryReturn(NID_UI_CTRL, false, r, r, "Failed to add item.");
302 _ContextMenuListPresenter::SetItem(int index, const Tizen::Base::String& text, int actionId,
303 const Tizen::Graphics::Bitmap* normalBitmap, const Tizen::Graphics::Bitmap* pPressedBitmap,
304 const Tizen::Graphics::Bitmap* pHighlightedBitmap)
306 if (text.GetLength() == 0 && normalBitmap == null && pPressedBitmap == null)
308 return E_INVALID_ARG;
311 result r = __pContextMenu->GetScrollPanel()->DetachChild(*__pModel->GetItem(index));
312 SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, r, r, "Failed to detach item.");
314 _ContextMenuItem* pItem = null;
315 pItem = CreateItem(text, actionId, normalBitmap, pPressedBitmap, pHighlightedBitmap);
316 SysTryReturn(NID_UI_CTRL, pItem != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "The memory is insufficient.");
318 r = __pModel->SetItem(pItem, index);
322 SysTryReturn(NID_UI_CTRL, false, r, r, "Failed to add item.");
329 _ContextMenuListPresenter::DeleteItem(int index)
331 if (__pContextMenu->GetItemCount() <= 0)
333 SysLogException(NID_UI_CTRL, E_INVALID_STATE, "Invalid argument.");
334 return E_INVALID_STATE;
337 result r = __pContextMenu->GetScrollPanel()->DetachChild(*__pModel->GetItem(index));
338 SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, r, r, "Failed to detach item.");
340 r = __pModel->RemoveItem(index);
341 SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, r, r, "Failed to delete item.");
347 _ContextMenuListPresenter::DeleteItemAll(void)
349 if (__pContextMenu->GetItemCount() <= 0)
351 SysLogException(NID_UI_CTRL, E_INVALID_STATE, "Invalid argument.");
352 return E_INVALID_STATE;
355 __pContextMenu->GetScrollPanel()->DetachAllChildren();
357 result r = __pModel->RemoveAllItem();
358 SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, r, r, "Failed to delete item all.");
365 _ContextMenuListPresenter::CalculateShowItemCount(void)
367 int itemMaxCount = 0;
368 GET_SHAPE_CONFIG(CONTEXTMENU::ITEM_MAX_COUNT, _CONTROL_ORIENTATION_PORTRAIT, itemMaxCount);
370 int maxVisibleCount = __pContextMenu->GetShowItemCount();
372 return maxVisibleCount > itemMaxCount ? itemMaxCount : maxVisibleCount;
376 _ContextMenuListPresenter::CalculateWindowRect(void)
378 result r = CalculateRect();
379 AdjustItemPosition();
385 _ContextMenuListPresenter::ApplyColorProperty(void)
392 _ContextMenuListPresenter::CalculateRect(void)
394 Tizen::Graphics::Rectangle windowRect = Tizen::Graphics::Rectangle(0, 0, 0, 0); // Window Rect is bodyRect + arrowRect
395 Tizen::Graphics::Rectangle bodyRect = Tizen::Graphics::Rectangle(0, 0, 0, 0); // ContextMenu rect except arrowRect
396 Tizen::Graphics::Rectangle arrowRect = Tizen::Graphics::Rectangle(0, 0, 0, 0); // Arrow rect of the ContextMenu
398 int bodyTopMargin = __topMargin;
399 int bodyBottomMargin = __bottomMargin;
400 int bodyLeftMargin = __leftMargin;
401 int bodyRightMargin = __rightMargin;
403 int screenTopMargin = __screenTopMargin;
404 int screenBottomMargin = __screenBottomMargin;
405 int screenLeftMargin = __screenLeftMargin;
406 int screenRightMargin = __screenRightMargin;
407 int arrowMargin = __arrowMargin;
409 Point anchorPosition = __pContextMenu->GetAnchorPosition();
411 Dimension screen = _ControlManager::GetInstance()->GetScreenSize();
412 if (__pContextMenu->GetLayout() == _CONTROL_ORIENTATION_LANDSCAPE)
414 screen.SetSize(screen.height, screen.width);
417 // calculate arrow area
418 enum ContextMenuCoreDropPosition dropPosition = __pContextMenu->GetDropPosition();
419 if (dropPosition == CONTEXT_MENU_CORE_DROP_POSITION_UP || dropPosition == CONTEXT_MENU_CORE_DROP_POSITION_DOWN) // down, up Arrow
421 arrowRect.width = __arrowWidth;
422 arrowRect.height = __arrowHeight;
424 else // left, right Arrow
426 arrowRect.width = __arrowHeight;
427 arrowRect.height = __arrowWidth;
430 // calculate body rect
431 // calculate real drawing margin for contextmenu
432 int leftMargin = screenLeftMargin;
433 int rightMargin = screen.width - screenRightMargin;
434 int topMargin = screenTopMargin;
435 int bottomMargin = screen.height - screenBottomMargin;
437 // calculate layout size (__layoutSize)
440 bodyRect.width = __layoutSize.width + bodyLeftMargin + bodyRightMargin;
441 bodyRect.height = __layoutSize.height + bodyTopMargin + bodyBottomMargin;
443 // calculate the position of the arrow and body rect.
444 if (dropPosition == CONTEXT_MENU_CORE_DROP_POSITION_UP) // down Arrow
446 // Check touch position
447 // - Check left margin
448 if (anchorPosition.x <= leftMargin + arrowRect.width)
450 anchorPosition.x = leftMargin + arrowRect.width;
452 // - check right margin
453 if (anchorPosition.x >= (rightMargin - arrowRect.width))
455 anchorPosition.x = rightMargin - arrowRect.width;
457 // - check top margin
458 if (anchorPosition.y <= topMargin)
460 anchorPosition.y = topMargin + bodyRect.height;
462 // - check bottom margin
463 if (anchorPosition.y >= bottomMargin)
465 anchorPosition.y = bottomMargin;
468 // Set body position x
469 bodyRect.x = anchorPosition.x - (bodyRect.width / 2);
470 // - Check left margin
471 if (bodyRect.x <= leftMargin)
473 bodyRect.x = leftMargin;
475 // - check right margin
476 if ((bodyRect.x + bodyRect.width) >= rightMargin)
478 bodyRect.x = rightMargin - bodyRect.width;
480 // Set body position y
481 bodyRect.y = anchorPosition.y - arrowRect.height - bodyRect.height;
482 // - check top margin
483 if (bodyRect.y <= topMargin)
485 bodyRect.y = topMargin;
488 windowRect.x = bodyRect.x;
489 windowRect.y = bodyRect.y;
490 windowRect.width = bodyRect.width;
491 windowRect.height = bodyRect.height + arrowRect.height;
494 bodyRect.y = arrowMargin;
496 // Set arrow position
497 arrowRect.x = anchorPosition.x - (arrowRect.width / 2) - windowRect.x;
498 arrowRect.y = bodyRect.height;
500 else if (dropPosition == CONTEXT_MENU_CORE_DROP_POSITION_DOWN) // up Arrow
502 // Check touch position
503 // - Check left margin
504 if (anchorPosition.x <= leftMargin + arrowRect.width)
506 anchorPosition.x = leftMargin + arrowRect.width;
508 // - check right margin
509 if (anchorPosition.x >= (rightMargin - arrowRect.width))
511 anchorPosition.x = rightMargin - arrowRect.width;
513 // - check top margin
514 if (anchorPosition.y <= topMargin)
516 anchorPosition.y = topMargin;
518 // - check bottom margin
519 if (anchorPosition.y >= bottomMargin)
521 anchorPosition.y = bottomMargin;
524 // Set body position x
525 bodyRect.x = anchorPosition.x - (bodyRect.width / 2);
526 // - Check left margin
527 if (bodyRect.x <= leftMargin)
529 bodyRect.x = leftMargin;
531 // - check right margin
532 if ((bodyRect.x + bodyRect.width) >= rightMargin)
534 bodyRect.x = rightMargin - bodyRect.width;
536 // Set body position y
537 bodyRect.y = anchorPosition.y + arrowRect.height;
538 // - Check bottom margin
539 if ((bodyRect.y + bodyRect.height) >= bottomMargin)
541 bodyRect.y = bottomMargin - bodyRect.height;
544 windowRect.x = bodyRect.x;
545 windowRect.y = bodyRect.y - arrowRect.height;
546 windowRect.width = bodyRect.width;
547 windowRect.height = bodyRect.height + arrowRect.height;
550 bodyRect.y = arrowRect.height - arrowMargin;
552 // Set arrow position
553 arrowRect.x = anchorPosition.x - (arrowRect.width / 2) - windowRect.x;
556 else if (dropPosition == CONTEXT_MENU_CORE_DROP_POSITION_LEFT) // right Arrow
558 // Check touch position
559 // - Check left margin
560 if (anchorPosition.x <= leftMargin)
562 anchorPosition.x = leftMargin + bodyRect.width;
564 // - check right margin
565 if (anchorPosition.x >= rightMargin)
567 anchorPosition.x = rightMargin;
569 // - Check top margin
570 if (anchorPosition.y <= topMargin + arrowRect.height)
572 anchorPosition.y = topMargin + arrowRect.height;
574 // - check bottom margin
575 if (anchorPosition.y >= (bottomMargin - arrowRect.height))
577 anchorPosition.y = bottomMargin - arrowRect.height;
580 // Set body position x
581 bodyRect.x = anchorPosition.x - arrowRect.width - bodyRect.width;
582 // - Check left margin
583 if (bodyRect.x <= leftMargin)
585 bodyRect.x = leftMargin;
587 // - check right margin
588 if ((bodyRect.x + bodyRect.width + arrowRect.width) >= rightMargin)
590 bodyRect.x = rightMargin - bodyRect.width - arrowRect.width;
593 // Set body position y
594 bodyRect.y = anchorPosition.y - (bodyRect.height / 2);
595 // - check top margin
596 if (bodyRect.y <= topMargin)
598 bodyRect.y = topMargin;
600 // - check bottom margin
601 if ((bodyRect.y + bodyRect.height) >= bottomMargin)
603 bodyRect.y = bottomMargin - bodyRect.height;
606 windowRect.x = bodyRect.x;
607 windowRect.y = bodyRect.y;
608 windowRect.width = bodyRect.width + arrowRect.width;
609 windowRect.height = bodyRect.height;
611 bodyRect.x = arrowMargin;
614 // Set arrow position
615 arrowRect.x = bodyRect.width;
616 arrowRect.y = anchorPosition.y - (arrowRect.height / 2) - windowRect.y;
620 // Check touch position
621 // - Check top margin
622 if (anchorPosition.x <= leftMargin)
624 anchorPosition.x = leftMargin;
626 // - check right margin
627 if (anchorPosition.x >= rightMargin)
629 anchorPosition.x = rightMargin - bodyRect.width;
631 // - Check top margin
632 if (anchorPosition.y <= topMargin + arrowRect.height)
634 anchorPosition.y = topMargin + arrowRect.height;
636 // - check bottom margin
637 if (anchorPosition.y >= (bottomMargin - arrowRect.height))
639 anchorPosition.y = bottomMargin - arrowRect.height;
642 // Set body position x
643 bodyRect.x = anchorPosition.x + arrowRect.width;
644 // - Check left margin
645 if (bodyRect.x <= leftMargin)
647 bodyRect.x = leftMargin;
649 // - check right margin
650 if ((bodyRect.x + bodyRect.width) >= rightMargin)
652 bodyRect.x = rightMargin - bodyRect.width;
654 // Set body position y
655 bodyRect.y = anchorPosition.y - (bodyRect.height / 2);
656 // - check top margin
657 if (bodyRect.y <= topMargin)
659 bodyRect.y = topMargin;
661 // - check bottom margin
662 if ((bodyRect.y + bodyRect.height) >= bottomMargin)
664 bodyRect.y = bottomMargin - bodyRect.height;
667 windowRect.x = bodyRect.x + arrowRect.width;
668 windowRect.y = bodyRect.y;
669 windowRect.width = bodyRect.width + arrowRect.width;
670 windowRect.height = bodyRect.height;
672 bodyRect.x = arrowRect.width - arrowMargin;
675 // Set arrow position
677 arrowRect.y = anchorPosition.y - (arrowRect.height / 2) - windowRect.y;
680 __pContextMenu->SetBodyRect(bodyRect);
681 __pContextMenu->SetArrowRect(arrowRect);
682 __pContextMenu->SetWindowRect(windowRect);
684 // _ScrollPanel API call sequence: SetBounds() -> SetScrollAreaBounds()
685 // _Scroll visual interaction if Bounds < ScrollAreaBounds
686 if (__pContextMenu->IsVisible()) {
687 __pContextMenu->GetScrollPanel()->SetBounds(Rectangle(bodyRect.x + bodyLeftMargin, bodyRect.y + bodyTopMargin, __layoutSize.width, __layoutSize.height));
688 int itemCount = __pModel->GetItemCount();
689 int itemHeight = __itemHeight + __dividerHeight;
690 int layoutClientHeight = itemCount * itemHeight - __dividerHeight;
691 __pContextMenu->GetScrollPanel()->SetClientAreaHeight(layoutClientHeight);
694 __pContextMenu->SetMovable(true); // To do Modify a enabling
695 __pContextMenu->SetResizable(true); // To do Modify a enabling
696 __pContextMenu->SetMinimumSize(Dimension(0, 0)); // To do Modify
697 __pContextMenu->SetMaximumSize(screen); // To do Modify
698 __pContextMenu->SetBounds(windowRect);
699 __pContextMenu->SetMovable(false); // To do Modify a enabling
700 __pContextMenu->SetResizable(false); // To do Modify a enabling
706 _ContextMenuListPresenter::AdjustItemLayout(void)
708 Dimension layoutSize(0, 0);
710 int itemCount = __pModel->GetItemCount();
713 __layoutSize.width = __itemWidth;
714 __layoutSize.height = __itemHeight;
718 layoutSize = AdjustItemLayoutStyle();
720 Dimension screen = _ControlManager::GetInstance()->GetScreenSize();
721 if (__pContextMenu->GetLayout() == _CONTROL_ORIENTATION_LANDSCAPE)
723 screen.SetSize(screen.height, screen.width);
726 int maxHeight = screen.height - __screenTopMargin - __screenBottomMargin - __arrowHeight;
727 if (layoutSize.height > maxHeight)
729 layoutSize.height = maxHeight;
732 __layoutSize = layoutSize;
736 Tizen::Graphics::Dimension
737 _ContextMenuListPresenter::AdjustItemLayoutStyle(void)
739 int itemMaxCount = CalculateShowItemCount();
741 int itemCount = __pModel->GetItemCount();
742 int itemHeight = __itemHeight + __dividerHeight;
744 Dimension layoutSize(__itemWidth, 0);
746 int layoutClientHeight = itemCount * itemHeight - __dividerHeight;
747 int layoutMaxHeight = itemMaxCount * itemHeight - __dividerHeight;
748 if (layoutClientHeight > layoutMaxHeight)
750 __scrollEnable = true;
751 layoutSize.height = layoutMaxHeight;
755 __scrollEnable = false;
756 layoutSize.height = layoutClientHeight;
763 _ContextMenuListPresenter::AdjustItemPosition(void)
765 int itemCount = __pModel->GetItemCount();
771 int itemHeight = __itemHeight + __dividerHeight;
774 int x = __pContextMenu->GetBodyRect().x + __leftMargin;
775 int y = __pContextMenu->GetBodyRect().y + __topMargin;
777 _ContextMenuItem* pItem = null;
779 for (int i = 0; i < itemCount; i++)
781 pItem = __pModel->GetItem(i);
788 Rectangle drawRect(x, drawItemY + y, __itemWidth, itemHeight);
790 pItem->SetDrawRect(drawRect);
791 pItem->SetDivider(true);
792 pItem->SetParentScrollEnable(__scrollEnable);
793 pItem->SetBounds(Rectangle(0, drawItemY, drawRect.width, drawRect.height));
795 if (pItem->HasParent() == false)
797 __pContextMenu->GetScrollPanel()->AttachChild(*pItem);
800 drawItemY += itemHeight;
805 _ContextMenuListPresenter::GetItemIndexFromPosition(const Tizen::Graphics::Point& point) const
808 int itemCount = __pModel->GetItemCount();
815 _ContextMenuItem* pItem = null;
817 int scrollPosition = __pContextMenu->GetScrollPanel()->GetScrollPosition();
818 Point position(point.x, point.y + scrollPosition);
820 for (int i = 0; i < itemCount; i++)
822 pItem = __pModel->GetItem(i);
829 Rectangle drawRect = pItem->GetDrawRect();
831 if (drawRect.Contains(position) == true)
843 _ContextMenuListPresenter::Draw(void)
845 result r = E_SUCCESS;
847 Canvas* pCanvas = __pContextMenu->GetCanvasN();
848 SysTryReturn(NID_UI_CTRL, pCanvas != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "The memory is insufficient.");
850 // Clear canvas for drawing area of the ContextMenu.
851 pCanvas->SetBackgroundColor(Color(0, 0, 0, 0));
852 Tizen::Graphics::Rectangle bounds(__pContextMenu->GetWindowRect());
853 pCanvas->Clear(Tizen::Graphics::Rectangle(0, 0, bounds.width, bounds.height));
855 r = DrawBackground(pCanvas);
856 SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, r, r, "Failed to draw background.");
858 r = DrawArrow(pCanvas);
859 SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, r, r, "Failed to draw arrow.");
867 _ContextMenuListPresenter::DrawBackground(Canvas* pCanvas)
869 SysTryReturn(NID_UI_CTRL, pCanvas != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
871 result r = E_SUCCESS;
873 Tizen::Graphics::Rectangle bodyRect = __pContextMenu->GetBodyRect();
875 const Bitmap* pBackgroundNormalBitmap = __pContextMenu->GetBackgroundNormalBitmap();
876 const Bitmap* pBackgroundEffectBitmap = __pContextMenu->GetBackgroundEffectBitmap();
878 if (pBackgroundNormalBitmap == null && pBackgroundEffectBitmap == null)
880 pCanvas->SetForegroundColor(__pContextMenu->GetColor());
881 pCanvas->DrawRectangle(bodyRect);
885 if (pBackgroundNormalBitmap != null)
887 r = pCanvas->DrawNinePatchedBitmap(bodyRect, *pBackgroundNormalBitmap);
890 if (pBackgroundEffectBitmap != null)
892 r = pCanvas->DrawNinePatchedBitmap(bodyRect, *pBackgroundEffectBitmap);
901 _ContextMenuListPresenter::DrawArrow(Canvas* pCanvas)
903 SysTryReturn(NID_UI_CTRL, pCanvas != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
905 result r = E_SUCCESS;
906 Tizen::Graphics::Rectangle arrowRect = __pContextMenu->GetArrowRect();
907 ContextMenuCoreDropPosition dropPosition = __pContextMenu->GetDropPosition();
909 const Bitmap* pArrowNormalBitmap = __pContextMenu->GetArrowNormalBitmap(dropPosition);
910 const Bitmap* pEffectArrowBitmap = __pContextMenu->GetArrowEffectBitmap(dropPosition);
912 if (pArrowNormalBitmap != null)
914 r = DrawBitmap(*pCanvas, arrowRect, *pArrowNormalBitmap);
917 if (pEffectArrowBitmap != null)
919 r = DrawBitmap(*pCanvas, arrowRect, *pEffectArrowBitmap);
925 _UiTouchEventDelivery
926 _ContextMenuListPresenter::OnPreviewTouchPressed(const _Control& source, const _TouchInfo& touchinfo)
928 return _UI_TOUCH_EVENT_DELIVERY_FORCED_YES;
932 _ContextMenuListPresenter::OnTouchPressed(const _Control& source, const _TouchInfo& touchinfo)
934 Rectangle bodyRect = __pContextMenu->GetBodyRect();
935 if (!bodyRect.Contains(touchinfo.GetCurrentPosition()))
937 __selectedIndex = -1;
938 __touchOutRect = true;
942 __selectedIndex = GetItemIndexFromPosition(touchinfo.GetCurrentPosition());
943 __touchOutRect = false;
947 _UiTouchEventDelivery
948 _ContextMenuListPresenter::OnPreviewTouchReleased(const _Control& source, const _TouchInfo& touchinfo)
950 return _UI_TOUCH_EVENT_DELIVERY_FORCED_YES;
954 _ContextMenuListPresenter::OnTouchReleased(const _Control& source, const _TouchInfo& touchinfo)
958 Rectangle bodyRect = __pContextMenu->GetBodyRect();
959 if (!bodyRect.Contains(touchinfo.GetCurrentPosition()))
961 __pContextMenu->SetVisibleState(false);
965 int currentSelectedIndex = GetItemIndexFromPosition(touchinfo.GetCurrentPosition());
966 if (__selectedIndex != -1 && (__selectedIndex == currentSelectedIndex))
968 _ContextMenuItem* pItem = null;
969 pItem = __pModel->GetItem(__selectedIndex);
971 __selectedIndex = -1;
972 __pContextMenu->SetVisibleState(false);
974 int actionId = pItem->GetActionId();
976 _ActionEvent* pActionEvent = __pContextMenu->GetActionEvent();
977 if (pActionEvent == null)
982 IEventArg* pEventArg = _ActionEvent::CreateActionEventArgN(actionId);
983 if (pEventArg == null)
988 pActionEvent->Fire(*pEventArg);
994 _UiTouchEventDelivery
995 _ContextMenuListPresenter::OnPreviewTouchMoved(const _Control& source, const _TouchInfo& touchinfo)
999 __selectedIndex = -1;
1002 return _UI_TOUCH_EVENT_DELIVERY_FORCED_YES;
1006 _ContextMenuListPresenter::OnTouchMoved(const _Control& source, const _TouchInfo& touchinfo)
1010 __selectedIndex = -1;
1017 _ContextMenuListPresenter::OnTouchCanceled(const _Control& source, const _TouchInfo& touchinfo)
1019 __pModel->ResetAllItem();
1025 _ContextMenuListPresenter::OnFontChanged(Tizen::Graphics::Font* pFont)
1028 String fontName = __pContextMenu->GetFont();
1030 int itemCount = __pModel->GetItemCount();
1031 for (int i = 0; i < itemCount; i++)
1033 _ContextMenuItem* pItem = __pModel->GetItem(i);
1036 pItem->SetFont(fontName);
1042 _ContextMenuListPresenter::OnFontInfoRequested(unsigned long& style, int& size)
1044 style = FONT_STYLE_PLAIN;
1045 size = __itemFontSize;
1049 _ContextMenuListPresenter::SetAllAccessibilityElement(void)
1051 _AccessibilityContainer* pContainer = __pContextMenu->GetAccessibilityContainer();
1052 if (pContainer != null)
1054 int itemCount = __pModel->GetItemCount();
1055 for (int i = 0; i < itemCount; i++)
1057 _ContextMenuItem* pItem = __pModel->GetItem(i);
1058 _AccessibilityElement* pElement = new (std::nothrow) _AccessibilityElement(true);
1059 if (pItem != null && pElement != null)
1061 pElement->SetLabel(pItem->GetText());
1062 // pElement->SetTrait(ACCESSIBILITY_TRAITS_CONTEXTMENU);
1063 pElement->SetTrait(ACCESSIBILITY_TRAITS_LIST); // not yet
1064 pElement->SetBounds(pItem->GetDrawRect());
1067 pElement->SetHint(L"The first of Contextual popup");
1069 else if(i == itemCount - 1)
1071 pElement->SetHint(L"The last of Contextual popup");
1073 pContainer->AddElement(*pElement);
1074 __pContextMenu->AddAccessibilityElement(*pElement);
1085 _ContextMenuItemInfo
1086 _ContextMenuListPresenter::GetItemFromPosition(const Point& position)
1088 _ContextMenuItemInfo itemInfo;
1089 int index = GetItemIndexFromPosition(position);
1090 itemInfo.pContextMenuItem = __pModel->GetItem(index);
1092 itemInfo.bListItem = false;
1093 itemInfo.pListItem = null;
1097 _ContextMenuItemInfo
1098 _ContextMenuListPresenter::FindItem(int index)
1100 _ContextMenuItemInfo itemInfo;
1101 itemInfo.bListItem = false;
1102 itemInfo.pListItem = null;
1103 itemInfo.pContextMenuItem = __pModel->GetItem(index);
1108 _ContextMenuListPresenter::SetTopDrawnItemIndex(int index)
1114 _ContextMenuListPresenter::DrawBitmap(Tizen::Graphics::Canvas& canvas, const Tizen::Graphics::Rectangle& bounds, const Tizen::Graphics::Bitmap& bitmap)
1116 result r = E_SUCCESS;
1117 if (bitmap.IsNinePatchedBitmap())
1119 r = canvas.DrawNinePatchedBitmap(bounds, bitmap);
1120 SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Fail to draw ninepatched bitmap.")
1124 r = canvas.DrawBitmap(bounds, bitmap);
1125 SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Fail to draw bitmap.")
1131 }}} // Tizen::Ui: Control