2 * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 using System.Collections.Generic;
23 /// It inherits <see cref="Layout"/>.
24 /// The MultiButtonEntry is a widget letting an user enter text and each chunk of text managed as a set of buttons.
25 /// 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.
26 /// 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.
27 /// 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.
29 public class MultiButtonEntry : Layout
31 HashSet<MultiButtonEntryItem> _children = new HashSet<MultiButtonEntryItem>();
32 List<Func<string, bool>> _filters = new List<Func<string, bool>>();
33 Func<int, string> _formatFunc = null;
36 Interop.Elementary.MultiButtonEntryItemFilterCallback _filterCallback;
37 Interop.Elementary.MultiButtonEntryFormatCallback _formatCallback;
41 SmartEvent _contracted;
42 SmartEvent _expandedStateChanged;
43 SmartEvent<MultiButtonEntryItemEventArgs> _itemSelected;
44 SmartEvent<MultiButtonEntryItemEventArgs> _itemClicked;
45 SmartEvent<MultiButtonEntryItemEventArgs> _itemLongPressed;
46 SmartEvent<MultiButtonEntryItemEventArgs> _itemAdded;
49 /// Creates and initializes a new instance of the MultiButtonEntry class.
51 /// <param name="parent">The parent is a given container which will be attached by MultiButtonEntry as a child. It's <see cref="EvasObject"/> type.</param>
52 public MultiButtonEntry(EvasObject parent) : base(parent)
54 _clicked = new SmartEvent(this, "clicked");
55 _expanded = new SmartEvent(this, "expanded");
56 _contracted = new SmartEvent(this, "contracted");
57 _expandedStateChanged = new SmartEvent(this, "expand,state,changed");
59 _itemSelected = new SmartEvent<MultiButtonEntryItemEventArgs>(this, "item,selected", MultiButtonEntryItemEventArgs.CreateFromSmartEvent);
60 _itemClicked = new SmartEvent<MultiButtonEntryItemEventArgs>(this, "item,clicked", MultiButtonEntryItemEventArgs.CreateFromSmartEvent);
61 _itemLongPressed = new SmartEvent<MultiButtonEntryItemEventArgs>(this, "item,longpressed", MultiButtonEntryItemEventArgs.CreateFromSmartEvent);
62 _itemAdded = new SmartEvent<MultiButtonEntryItemEventArgs>(this, "item,added", MultiButtonEntryItemEventArgs.CreateAndAddFromSmartEvent);
64 _filterCallback = new Interop.Elementary.MultiButtonEntryItemFilterCallback(FilterCallbackHandler);
65 _formatCallback = new Interop.Elementary.MultiButtonEntryFormatCallback(FormatCallbackHandler);
67 _clicked.On += (sender, e) => Clicked?.Invoke(this, EventArgs.Empty);
68 _expanded.On += (sender, e) => Expanded?.Invoke(this, EventArgs.Empty);
69 _contracted.On += (sender, e) => Contracted?.Invoke(this, EventArgs.Empty);
70 _expandedStateChanged.On += (sender, e) => ExpandedStateChanged?.Invoke(this, EventArgs.Empty);
72 _itemSelected.On += (sender, e) => { ItemSelected?.Invoke(this, e); };
73 _itemClicked.On += (sender, e) => { ItemClicked?.Invoke(this, e); };
74 _itemLongPressed.On += (sender, e) => { ItemLongPressed?.Invoke(this, e); };
75 _itemAdded.On += OnItemAdded;
79 /// Clicked is raised when a MultiButtonEntry is clicked.
81 public event EventHandler Clicked;
84 /// Expanded is raised when a MultiButtonEntry is expanded.
86 public event EventHandler Expanded;
89 /// Contracted is raised when a MultiButtonEntry is contracted.
91 public event EventHandler Contracted;
94 /// ExpandedStateChanged is raised when shrink mode state of MultiButtonEntry is changed.
96 public event EventHandler ExpandedStateChanged;
99 /// ItemSelected is raised when an item is selected by api, user interaction, and etc.
100 /// This is also raised when a user press back space while cursor is on the first field of entry.
102 public event EventHandler<MultiButtonEntryItemEventArgs> ItemSelected;
105 /// ItemClicked is raised when an item is clicked by user interaction.
107 public event EventHandler<MultiButtonEntryItemEventArgs> ItemClicked;
110 /// ItemLongPressed is raised when MultiButtonEntry item is pressed for a long time.
112 public event EventHandler<MultiButtonEntryItemEventArgs> ItemLongPressed;
115 /// ItemAdded is raised when a new MultiButtonEntry item is added.
117 public event EventHandler<MultiButtonEntryItemEventArgs> ItemAdded;
120 /// ItemDeleted is raised when a MultiButtonEntry item is deleted.
122 public event EventHandler<MultiButtonEntryItemEventArgs> ItemDeleted;
125 /// Gets the selected item in the multibuttonentry.
127 public MultiButtonEntryItem SelectedItem
131 IntPtr handle = Interop.Elementary.elm_multibuttonentry_selected_item_get(RealHandle);
132 return ItemObject.GetItemByHandle(handle) as MultiButtonEntryItem;
137 /// Gets or sets whether the multibuttonentry is editable or not.
139 public bool IsEditable
143 return Interop.Elementary.elm_multibuttonentry_editable_get(RealHandle);
147 Interop.Elementary.elm_multibuttonentry_editable_set(RealHandle, value);
152 /// Gets or sets the multibuttonentry to expanded state.
153 /// If true, expanded state.
154 /// If false, single line state.
156 public bool IsExpanded
160 return Interop.Elementary.elm_multibuttonentry_expanded_get(RealHandle);
164 Interop.Elementary.elm_multibuttonentry_expanded_set(RealHandle, value);
169 /// Gets the first item in the multibuttonentry.
171 public MultiButtonEntryItem FirstItem
175 IntPtr handle = Interop.Elementary.elm_multibuttonentry_first_item_get(RealHandle);
176 return ItemObject.GetItemByHandle(handle) as MultiButtonEntryItem;
181 /// Gets the last item in the multibuttonentry.
183 public MultiButtonEntryItem LastItem
187 IntPtr handle = Interop.Elementary.elm_multibuttonentry_last_item_get(RealHandle);
188 return ItemObject.GetItemByHandle(handle) as MultiButtonEntryItem;
193 /// Gets the entry object int the multibuttonentry.
201 _entry = new EntryInner(this);
209 /// Creates a widget handle.
211 /// <param name="parent">Parent EvasObject</param>
212 /// <returns>Handle IntPtr</returns>
213 protected override IntPtr CreateHandle(EvasObject parent)
215 return Interop.Elementary.elm_multibuttonentry_add(parent.Handle);
219 /// Append a new item to the multibuttonentry.
221 /// <param name="label">The label of new item.</param>
222 /// <returns>A MultiButtonEntryItem to the item added.</returns>
223 public MultiButtonEntryItem Append(string label)
225 var handle = Interop.Elementary.elm_multibuttonentry_item_append(RealHandle, label, null, IntPtr.Zero);
226 MultiButtonEntryItem item = ItemObject.GetItemByHandle(handle) as MultiButtonEntryItem;
231 /// Prepend a new item to the multibuttonentry.
233 /// <param name="label">The label of new item.</param>
234 /// <returns>A MultiButtonEntryItem to the item added.</returns>
235 public MultiButtonEntryItem Prepend(string label)
237 var handle = Interop.Elementary.elm_multibuttonentry_item_prepend(RealHandle, label, null, IntPtr.Zero);
238 MultiButtonEntryItem item = ItemObject.GetItemByHandle(handle) as MultiButtonEntryItem;
243 /// Add a new item to the multibuttonentry before the indicated object reference.
245 /// <param name="before">The item before which to add it.</param>
246 /// <param name="label">The label of new item.</param>
247 /// <returns>A MultiButtonEntryItem to the item added.</returns>
248 public MultiButtonEntryItem InsertBefore(MultiButtonEntryItem before, string label)
250 var handle = Interop.Elementary.elm_multibuttonentry_item_insert_before(RealHandle, before.Handle, label, null, IntPtr.Zero);
251 MultiButtonEntryItem item = ItemObject.GetItemByHandle(handle) as MultiButtonEntryItem;
256 /// Add a new item to the multibuttonentry after the indicated object.
258 /// <param name="after">The item after which to add it.</param>
259 /// <param name="label">The label of new item.</param>
260 /// <returns>A MultiButtonEntryItem to the item added.</returns>
261 public MultiButtonEntryItem InsertAfter(MultiButtonEntryItem after, string label)
263 var handle = Interop.Elementary.elm_multibuttonentry_item_insert_after(RealHandle, after.Handle, label, null, IntPtr.Zero);
264 MultiButtonEntryItem item = ItemObject.GetItemByHandle(handle) as MultiButtonEntryItem;
269 /// Remove all items in the multibuttonentry.
273 Interop.Elementary.elm_multibuttonentry_clear(RealHandle);
274 foreach (var item in _children)
276 item.Deleted -= Item_Deleted;
282 /// Append an item filter function for text inserted in the Multibuttonentry.
284 /// <param name="func">The function to use as item filter.</param>
285 public void AppendFilter(Func<string, bool> func)
288 if (_filters.Count == 1)
290 Interop.Elementary.elm_multibuttonentry_item_filter_append(RealHandle, _filterCallback, IntPtr.Zero);
295 /// Prepend a filter function for text inserted in the Multibuttonentry.
297 /// <param name="func">The function to use as text filter.</param>
298 public void PrependFilter(Func<string, bool> func)
300 _filters.Insert(0, func);
301 if (_filters.Count == 1)
303 Interop.Elementary.elm_multibuttonentry_item_filter_prepend(RealHandle, _filterCallback, IntPtr.Zero);
308 /// Remove a filter from the list.
310 /// <param name="func">The filter function to remove.</param>
311 public void RemoveFilter(Func<string, bool> func)
313 _filters.Remove(func);
314 if (_filters.Count == 0)
316 Interop.Elementary.elm_multibuttonentry_item_filter_remove(RealHandle, _filterCallback, IntPtr.Zero);
321 /// Set a function to format the string that will be used to display the hidden items counter.
322 /// If func is NULL, the default format will be used, which is "+ 'the hidden items counter'".
324 /// <param name="func">The function to return string to show</param>
325 public void SetFormatCallback(Func<int, string> func)
329 Interop.Elementary.elm_multibuttonentry_format_function_set(RealHandle, null, IntPtr.Zero);
334 Interop.Elementary.elm_multibuttonentry_format_function_set(RealHandle, _formatCallback, IntPtr.Zero);
338 string FormatCallbackHandler(int count, IntPtr data)
340 return _formatFunc(count);
343 void Item_Deleted(object sender, EventArgs e)
345 var removed = sender as MultiButtonEntryItem;
346 _children.Remove(removed);
348 // "item,deleted" event will be called after removing the item from ItemObject has been done.
349 // ItemObject will no longer have the item instance that is deleted after this.
350 // So, ItemDelete event with the removed item should be triggered here.
351 ItemDeleted?.Invoke(this, new MultiButtonEntryItemEventArgs() { Item = removed });
354 void OnItemAdded(object sender, MultiButtonEntryItemEventArgs e)
356 _children.Add(e.Item);
357 e.Item.Deleted += Item_Deleted;
358 ItemAdded?.Invoke(this, e);
361 bool FilterCallbackHandler(IntPtr obj, string label, IntPtr itemData, IntPtr data)
363 foreach (var func in _filters)
371 internal class EntryInner : Entry
374 /// Creates and initializes a new instance of the EntryInner class.
376 /// <param name="parent">The parent is a given container which will be attached by MultiButtonEntry as a child. It's <see cref="EvasObject"/> type.</param>
377 internal EntryInner(EvasObject parent) : base(parent)
382 /// Creates a widget handle.
384 /// <param name="parent">Parent EvasObject</param>
385 /// <returns>Handle IntPtr</returns>
386 protected override IntPtr CreateHandle(EvasObject parent)
388 return Interop.Elementary.elm_multibuttonentry_entry_get(parent.Handle);
394 /// It inherits System.EventArgs.
395 /// The MultiButtonEntryItemEventArgs is a argument for all events of MultiButtonEntry.
396 /// It contains Item which is <see cref="MultiButtonEntryItem"/> type.
398 public class MultiButtonEntryItemEventArgs : EventArgs
401 /// Gets or sets MultiButtonEntryItem item. The return type is <see cref="MultiButtonEntryItem"/>.
403 public MultiButtonEntryItem Item { get; set; }
405 internal static MultiButtonEntryItemEventArgs CreateFromSmartEvent(IntPtr data, IntPtr obj, IntPtr info)
407 MultiButtonEntryItem item = ItemObject.GetItemByHandle(info) as MultiButtonEntryItem;
408 return new MultiButtonEntryItemEventArgs() { Item = item };
411 internal static MultiButtonEntryItemEventArgs CreateAndAddFromSmartEvent(IntPtr data, IntPtr obj, IntPtr info)
413 // Item can be added throught calling Append method and user input.
414 // And since "item.added" event will be called before xx_append() method returns,
415 // ItemObject does NOT have an item that contains handle matched to "info" at this time.
416 // So, item should be created and added internally here.
417 MultiButtonEntryItem item = new MultiButtonEntryItem(info);
418 return new MultiButtonEntryItemEventArgs() { Item = item };