/* * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the License); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; using System.Collections.Generic; namespace ElmSharp { /// /// It inherits . /// The MultiButtonEntry is a widget letting an user enter text and each chunk of text managed as a set of buttons. /// Each text button is inserted by pressing the "return" key. If there is no space in the current row, a new button is added to the next row. /// When a text button is pressed, it will become focused. Backspace removes the focus. When the multi-button entry loses focus, items longer than one line are shrunk to one line. /// The typical use case of multi-button entry is composing emails/messages to a group of addresses, each of which is an item that can be clicked for further actions. /// public class MultiButtonEntry : Layout { HashSet _children = new HashSet(); List> _filters = new List>(); Func _formatFunc = null; Entry _entry = null; Interop.Elementary.MultiButtonEntryItemFilterCallback _filterCallback; Interop.Elementary.MultiButtonEntryFormatCallback _formatCallback; SmartEvent _clicked; SmartEvent _expanded; SmartEvent _contracted; SmartEvent _expandedStateChanged; SmartEvent _itemSelected; SmartEvent _itemClicked; SmartEvent _itemLongPressed; SmartEvent _itemAdded; /// /// Creates and initializes a new instance of the MultiButtonEntry class. /// /// The parent is a given container which will be attached by MultiButtonEntry as a child. It's type. public MultiButtonEntry(EvasObject parent) : base(parent) { _clicked = new SmartEvent(this, "clicked"); _expanded = new SmartEvent(this, "expanded"); _contracted = new SmartEvent(this, "contracted"); _expandedStateChanged = new SmartEvent(this, "expand,state,changed"); _itemSelected = new SmartEvent(this, "item,selected", MultiButtonEntryItemEventArgs.CreateFromSmartEvent); _itemClicked = new SmartEvent(this, "item,clicked", MultiButtonEntryItemEventArgs.CreateFromSmartEvent); _itemLongPressed = new SmartEvent(this, "item,longpressed", MultiButtonEntryItemEventArgs.CreateFromSmartEvent); _itemAdded = new SmartEvent(this, "item,added", MultiButtonEntryItemEventArgs.CreateAndAddFromSmartEvent); _filterCallback = new Interop.Elementary.MultiButtonEntryItemFilterCallback(FilterCallbackHandler); _formatCallback = new Interop.Elementary.MultiButtonEntryFormatCallback(FormatCallbackHandler); _clicked.On += (sender, e) => Clicked?.Invoke(this, EventArgs.Empty); _expanded.On += (sender, e) => Expanded?.Invoke(this, EventArgs.Empty); _contracted.On += (sender, e) => Contracted?.Invoke(this, EventArgs.Empty); _expandedStateChanged.On += (sender, e) => ExpandedStateChanged?.Invoke(this, EventArgs.Empty); _itemSelected.On += (sender, e) => { ItemSelected?.Invoke(this, e); }; _itemClicked.On += (sender, e) => { ItemClicked?.Invoke(this, e); }; _itemLongPressed.On += (sender, e) => { ItemLongPressed?.Invoke(this, e); }; _itemAdded.On += OnItemAdded; } /// /// Clicked is raised when a MultiButtonEntry is clicked. /// public event EventHandler Clicked; /// /// Expanded is raised when a MultiButtonEntry is expanded. /// public event EventHandler Expanded; /// /// Contracted is raised when a MultiButtonEntry is contracted. /// public event EventHandler Contracted; /// /// ExpandedStateChanged is raised when shrink mode state of MultiButtonEntry is changed. /// public event EventHandler ExpandedStateChanged; /// /// ItemSelected is raised when an item is selected by api, user interaction, and etc. /// This is also raised when a user press back space while cursor is on the first field of entry. /// public event EventHandler ItemSelected; /// /// ItemClicked is raised when an item is clicked by user interaction. /// public event EventHandler ItemClicked; /// /// ItemLongPressed is raised when MultiButtonEntry item is pressed for a long time. /// public event EventHandler ItemLongPressed; /// /// ItemAdded is raised when a new MultiButtonEntry item is added. /// public event EventHandler ItemAdded; /// /// ItemDeleted is raised when a MultiButtonEntry item is deleted. /// public event EventHandler ItemDeleted; /// /// Gets the selected item in the multibuttonentry. /// public MultiButtonEntryItem SelectedItem { get { IntPtr handle = Interop.Elementary.elm_multibuttonentry_selected_item_get(RealHandle); return ItemObject.GetItemByHandle(handle) as MultiButtonEntryItem; } } /// /// Gets or sets whether the multibuttonentry is editable or not. /// public bool IsEditable { get { return Interop.Elementary.elm_multibuttonentry_editable_get(RealHandle); } set { Interop.Elementary.elm_multibuttonentry_editable_set(RealHandle, value); } } /// /// Gets or sets the multibuttonentry to expanded state. /// If true, expanded state. /// If false, single line state. /// public bool IsExpanded { get { return Interop.Elementary.elm_multibuttonentry_expanded_get(RealHandle); } set { Interop.Elementary.elm_multibuttonentry_expanded_set(RealHandle, value); } } /// /// Gets the first item in the multibuttonentry. /// public MultiButtonEntryItem FirstItem { get { IntPtr handle = Interop.Elementary.elm_multibuttonentry_first_item_get(RealHandle); return ItemObject.GetItemByHandle(handle) as MultiButtonEntryItem; } } /// /// Gets the last item in the multibuttonentry. /// public MultiButtonEntryItem LastItem { get { IntPtr handle = Interop.Elementary.elm_multibuttonentry_last_item_get(RealHandle); return ItemObject.GetItemByHandle(handle) as MultiButtonEntryItem; } } /// /// Gets the entry object int the multibuttonentry. /// public Entry Entry { get { if (_entry == null) { _entry = new EntryInner(this); } return _entry; } } protected override IntPtr CreateHandle(EvasObject parent) { return Interop.Elementary.elm_multibuttonentry_add(parent.Handle); } /// /// Append a new item to the multibuttonentry. /// /// The label of new item. /// A MultiButtonEntryItem to the item added. public MultiButtonEntryItem Append(string label) { var handle = Interop.Elementary.elm_multibuttonentry_item_append(RealHandle, label, null, IntPtr.Zero); MultiButtonEntryItem item = ItemObject.GetItemByHandle(handle) as MultiButtonEntryItem; return item; } /// /// Prepend a new item to the multibuttonentry. /// /// The label of new item. /// A MultiButtonEntryItem to the item added. public MultiButtonEntryItem Prepend(string label) { var handle = Interop.Elementary.elm_multibuttonentry_item_prepend(RealHandle, label, null, IntPtr.Zero); MultiButtonEntryItem item = ItemObject.GetItemByHandle(handle) as MultiButtonEntryItem; return item; } /// /// Add a new item to the multibuttonentry before the indicated object reference. /// /// The item before which to add it. /// The label of new item. /// A MultiButtonEntryItem to the item added. public MultiButtonEntryItem InsertBefore(MultiButtonEntryItem before, string label) { var handle = Interop.Elementary.elm_multibuttonentry_item_insert_before(RealHandle, before.Handle, label, null, IntPtr.Zero); MultiButtonEntryItem item = ItemObject.GetItemByHandle(handle) as MultiButtonEntryItem; return item; } /// /// Add a new item to the multibuttonentry after the indicated object. /// /// The item after which to add it. /// The label of new item. /// A MultiButtonEntryItem to the item added. public MultiButtonEntryItem InsertAfter(MultiButtonEntryItem after, string label) { var handle = Interop.Elementary.elm_multibuttonentry_item_insert_after(RealHandle, after.Handle, label, null, IntPtr.Zero); MultiButtonEntryItem item = ItemObject.GetItemByHandle(handle) as MultiButtonEntryItem; return item; } /// /// Remove all items in the multibuttonentry. /// public void Clear() { Interop.Elementary.elm_multibuttonentry_clear(RealHandle); foreach (var item in _children) { item.Deleted -= Item_Deleted; } _children.Clear(); } /// /// Append an item filter function for text inserted in the Multibuttonentry. /// /// The function to use as item filter. public void AppendFilter(Func func) { _filters.Add(func); if (_filters.Count == 1) { Interop.Elementary.elm_multibuttonentry_item_filter_append(RealHandle, _filterCallback, IntPtr.Zero); } } /// /// Prepend a filter function for text inserted in the Multibuttonentry. /// /// The function to use as text filter. public void PrependFilter(Func func) { _filters.Insert(0, func); if (_filters.Count == 1) { Interop.Elementary.elm_multibuttonentry_item_filter_prepend(RealHandle, _filterCallback, IntPtr.Zero); } } /// /// Remove a filter from the list. /// /// The filter function to remove. public void RemoveFilter(Func func) { _filters.Remove(func); if (_filters.Count == 0) { Interop.Elementary.elm_multibuttonentry_item_filter_remove(RealHandle, _filterCallback, IntPtr.Zero); } } /// /// Set a function to format the string that will be used to display the hidden items counter. /// If func is NULL, the default format will be used, which is "+ 'the hidden items counter'". /// /// The function to return string to show public void SetFormatCallback(Func func) { if (func == null) { Interop.Elementary.elm_multibuttonentry_format_function_set(RealHandle, null, IntPtr.Zero); } else { _formatFunc = func; Interop.Elementary.elm_multibuttonentry_format_function_set(RealHandle, _formatCallback, IntPtr.Zero); } } string FormatCallbackHandler(int count, IntPtr data) { return _formatFunc(count); } void Item_Deleted(object sender, EventArgs e) { var removed = sender as MultiButtonEntryItem; _children.Remove(removed); // "item,deleted" event will be called after removing the item from ItemObject has been done. // ItemObject will no longer have the item instance that is deleted after this. // So, ItemDelete event with the removed item should be triggered here. ItemDeleted?.Invoke(this, new MultiButtonEntryItemEventArgs() { Item = removed }); } void OnItemAdded(object sender, MultiButtonEntryItemEventArgs e) { _children.Add(e.Item); e.Item.Deleted += Item_Deleted; ItemAdded?.Invoke(this, e); } bool FilterCallbackHandler(IntPtr obj, string label, IntPtr itemData, IntPtr data) { foreach (var func in _filters) { if (!func(label)) return false; } return true; } internal class EntryInner : Entry { internal EntryInner(EvasObject parent) : base(parent) { } protected override IntPtr CreateHandle(EvasObject parent) { return Interop.Elementary.elm_multibuttonentry_entry_get(parent.Handle); } } } /// /// It inherits System.EventArgs. /// The MultiButtonEntryItemEventArgs is a argument for all events of MultiButtonEntry. /// It contains Item which is type. /// public class MultiButtonEntryItemEventArgs : EventArgs { /// /// Gets or sets MultiButtonEntryItem item. The return type is . /// public MultiButtonEntryItem Item { get; set; } internal static MultiButtonEntryItemEventArgs CreateFromSmartEvent(IntPtr data, IntPtr obj, IntPtr info) { MultiButtonEntryItem item = ItemObject.GetItemByHandle(info) as MultiButtonEntryItem; return new MultiButtonEntryItemEventArgs() { Item = item }; } internal static MultiButtonEntryItemEventArgs CreateAndAddFromSmartEvent(IntPtr data, IntPtr obj, IntPtr info) { // Item can be added throught calling Append method and user input. // And since "item.added" event will be called before xx_append() method returns, // ItemObject does NOT have an item that contains handle matched to "info" at this time. // So, item should be created and added internally here. MultiButtonEntryItem item = new MultiButtonEntryItem(info); return new MultiButtonEntryItemEventArgs() { Item = item }; } } }