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, that lets a user enter text and each chunk of the 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 /// <since_tizen> preview </since_tizen>
30 public class MultiButtonEntry : Layout
32 HashSet<MultiButtonEntryItem> _children = new HashSet<MultiButtonEntryItem>();
33 List<Func<string, bool>> _filters = new List<Func<string, bool>>();
34 Func<int, string> _formatFunc = null;
37 Interop.Elementary.MultiButtonEntryItemFilterCallback _filterCallback;
38 Interop.Elementary.MultiButtonEntryFormatCallback _formatCallback;
42 SmartEvent _contracted;
43 SmartEvent _expandedStateChanged;
44 SmartEvent<MultiButtonEntryItemEventArgs> _itemSelected;
45 SmartEvent<MultiButtonEntryItemEventArgs> _itemClicked;
46 SmartEvent<MultiButtonEntryItemEventArgs> _itemLongPressed;
47 SmartEvent<MultiButtonEntryItemEventArgs> _itemAdded;
50 /// Creates and initializes a new instance of the MultiButtonEntry class.
52 /// <param name="parent">The parent is a given container, which will be attached by the MultiButtonEntry as a child. It's <see cref="EvasObject"/> type.</param>
53 /// <since_tizen> preview </since_tizen>
54 public MultiButtonEntry(EvasObject parent) : base(parent)
56 _clicked = new SmartEvent(this, "clicked");
57 _expanded = new SmartEvent(this, "expanded");
58 _contracted = new SmartEvent(this, "contracted");
59 _expandedStateChanged = new SmartEvent(this, "expand,state,changed");
61 _itemSelected = new SmartEvent<MultiButtonEntryItemEventArgs>(this, "item,selected", MultiButtonEntryItemEventArgs.CreateFromSmartEvent);
62 _itemClicked = new SmartEvent<MultiButtonEntryItemEventArgs>(this, "item,clicked", MultiButtonEntryItemEventArgs.CreateFromSmartEvent);
63 _itemLongPressed = new SmartEvent<MultiButtonEntryItemEventArgs>(this, "item,longpressed", MultiButtonEntryItemEventArgs.CreateFromSmartEvent);
64 _itemAdded = new SmartEvent<MultiButtonEntryItemEventArgs>(this, "item,added", MultiButtonEntryItemEventArgs.CreateAndAddFromSmartEvent);
66 _filterCallback = new Interop.Elementary.MultiButtonEntryItemFilterCallback(FilterCallbackHandler);
67 _formatCallback = new Interop.Elementary.MultiButtonEntryFormatCallback(FormatCallbackHandler);
69 _clicked.On += (sender, e) => Clicked?.Invoke(this, EventArgs.Empty);
70 _expanded.On += (sender, e) => Expanded?.Invoke(this, EventArgs.Empty);
71 _contracted.On += (sender, e) => Contracted?.Invoke(this, EventArgs.Empty);
72 _expandedStateChanged.On += (sender, e) => ExpandedStateChanged?.Invoke(this, EventArgs.Empty);
74 _itemSelected.On += (sender, e) => { ItemSelected?.Invoke(this, e); };
75 _itemClicked.On += (sender, e) => { ItemClicked?.Invoke(this, e); };
76 _itemLongPressed.On += (sender, e) => { ItemLongPressed?.Invoke(this, e); };
77 _itemAdded.On += OnItemAdded;
81 /// Clicked is raised when a MultiButtonEntry is clicked.
83 /// <since_tizen> preview </since_tizen>
84 public event EventHandler Clicked;
87 /// Expanded is raised when a MultiButtonEntry is expanded.
89 /// <since_tizen> preview </since_tizen>
90 public event EventHandler Expanded;
93 /// Contracted is raised when a MultiButtonEntry is contracted.
95 /// <since_tizen> preview </since_tizen>
96 public event EventHandler Contracted;
99 /// ExpandedStateChanged is raised when shrink mode state of MultiButtonEntry is changed.
101 /// <since_tizen> preview </since_tizen>
102 public event EventHandler ExpandedStateChanged;
105 /// ItemSelected is raised when an item is selected by API, user interaction, and etc.
106 /// This is also raised when a user presses backspace, while the cursor is on the first field of the entry.
108 /// <since_tizen> preview </since_tizen>
109 public event EventHandler<MultiButtonEntryItemEventArgs> ItemSelected;
112 /// ItemClicked is raised when an item is clicked by user interaction.
114 /// <since_tizen> preview </since_tizen>
115 public event EventHandler<MultiButtonEntryItemEventArgs> ItemClicked;
118 /// ItemLongPressed is raised when MultiButtonEntry item is pressed for a long time.
120 /// <since_tizen> preview </since_tizen>
121 public event EventHandler<MultiButtonEntryItemEventArgs> ItemLongPressed;
124 /// ItemAdded is raised when a new MultiButtonEntry item is added.
126 /// <since_tizen> preview </since_tizen>
127 public event EventHandler<MultiButtonEntryItemEventArgs> ItemAdded;
130 /// ItemDeleted is raised when a MultiButtonEntry item is deleted.
132 /// <since_tizen> preview </since_tizen>
133 public event EventHandler<MultiButtonEntryItemEventArgs> ItemDeleted;
136 /// Gets the selected item in the MultiButtonEntry.
138 /// <since_tizen> preview </since_tizen>
139 public MultiButtonEntryItem SelectedItem
143 IntPtr handle = Interop.Elementary.elm_multibuttonentry_selected_item_get(RealHandle);
144 return ItemObject.GetItemByHandle(handle) as MultiButtonEntryItem;
149 /// Gets or sets whether the MultiButtonEntry is editable or not.
151 /// <since_tizen> preview </since_tizen>
152 public bool IsEditable
156 return Interop.Elementary.elm_multibuttonentry_editable_get(RealHandle);
160 Interop.Elementary.elm_multibuttonentry_editable_set(RealHandle, value);
165 /// Gets or sets the MultiButtonEntry to expanded state.
166 /// If true, expanded state.
167 /// If false, single line state.
169 /// <since_tizen> preview </since_tizen>
170 public bool IsExpanded
174 return Interop.Elementary.elm_multibuttonentry_expanded_get(RealHandle);
178 Interop.Elementary.elm_multibuttonentry_expanded_set(RealHandle, value);
183 /// Gets the first item in the MultiButtonEntry.
185 /// <since_tizen> preview </since_tizen>
186 public MultiButtonEntryItem FirstItem
190 IntPtr handle = Interop.Elementary.elm_multibuttonentry_first_item_get(RealHandle);
191 return ItemObject.GetItemByHandle(handle) as MultiButtonEntryItem;
196 /// Gets the last item in the MultiButtonEntry.
198 /// <since_tizen> preview </since_tizen>
199 public MultiButtonEntryItem LastItem
203 IntPtr handle = Interop.Elementary.elm_multibuttonentry_last_item_get(RealHandle);
204 return ItemObject.GetItemByHandle(handle) as MultiButtonEntryItem;
209 /// Gets the entry object int the MultiButtonEntry.
211 /// <since_tizen> preview </since_tizen>
218 _entry = new EntryInner(this);
226 /// Creates a widget handle.
228 /// <param name="parent">Parent EvasObject.</param>
229 /// <returns>Handle IntPtr.</returns>
230 /// <since_tizen> preview </since_tizen>
231 protected override IntPtr CreateHandle(EvasObject parent)
233 return Interop.Elementary.elm_multibuttonentry_add(parent.Handle);
237 /// Appends a new item to the multibuttonentry.
239 /// <param name="label">The label of the new item.</param>
240 /// <returns>A MultiButtonEntryItem to the item added.</returns>
241 /// <since_tizen> preview </since_tizen>
242 public MultiButtonEntryItem Append(string label)
244 var handle = Interop.Elementary.elm_multibuttonentry_item_append(RealHandle, label, null, IntPtr.Zero);
245 MultiButtonEntryItem item = ItemObject.GetItemByHandle(handle) as MultiButtonEntryItem;
250 /// Prepends a new item to the MultiButtonEntry.
252 /// <param name="label">The label of the new item.</param>
253 /// <returns>A MultiButtonEntryItem to the item added.</returns>
254 /// <since_tizen> preview </since_tizen>
255 public MultiButtonEntryItem Prepend(string label)
257 var handle = Interop.Elementary.elm_multibuttonentry_item_prepend(RealHandle, label, null, IntPtr.Zero);
258 MultiButtonEntryItem item = ItemObject.GetItemByHandle(handle) as MultiButtonEntryItem;
263 /// Adds a new item to the MultiButtonEntry before the indicated object reference.
265 /// <param name="before">The item before which to add it.</param>
266 /// <param name="label">The label of new item.</param>
267 /// <returns>A MultiButtonEntryItem to the item added.</returns>
268 /// <since_tizen> preview </since_tizen>
269 public MultiButtonEntryItem InsertBefore(MultiButtonEntryItem before, string label)
271 var handle = Interop.Elementary.elm_multibuttonentry_item_insert_before(RealHandle, before.Handle, label, null, IntPtr.Zero);
272 MultiButtonEntryItem item = ItemObject.GetItemByHandle(handle) as MultiButtonEntryItem;
277 /// Adds a new item to the MultiButtonEntry after the indicated object.
279 /// <param name="after">The item after which to add it.</param>
280 /// <param name="label">The label of new item.</param>
281 /// <returns>A MultiButtonEntryItem to the item added.</returns>
282 /// <since_tizen> preview </since_tizen>
283 public MultiButtonEntryItem InsertAfter(MultiButtonEntryItem after, string label)
285 var handle = Interop.Elementary.elm_multibuttonentry_item_insert_after(RealHandle, after.Handle, label, null, IntPtr.Zero);
286 MultiButtonEntryItem item = ItemObject.GetItemByHandle(handle) as MultiButtonEntryItem;
291 /// Removes all items in the MultiButtonEntry.
293 /// <since_tizen> preview </since_tizen>
296 Interop.Elementary.elm_multibuttonentry_clear(RealHandle);
297 foreach (var item in _children)
299 item.Deleted -= Item_Deleted;
305 /// Appends an item filter function for the text inserted in the multibuttonentry.
307 /// <param name="func">The function to use as item filter.</param>
308 /// <since_tizen> preview </since_tizen>
309 public void AppendFilter(Func<string, bool> func)
312 if (_filters.Count == 1)
314 Interop.Elementary.elm_multibuttonentry_item_filter_append(RealHandle, _filterCallback, IntPtr.Zero);
319 /// Prepends a filter function for the text inserted in the MultiButtonEntry.
321 /// <param name="func">The function to use as text filter.</param>
322 /// <since_tizen> preview </since_tizen>
323 public void PrependFilter(Func<string, bool> func)
325 _filters.Insert(0, func);
326 if (_filters.Count == 1)
328 Interop.Elementary.elm_multibuttonentry_item_filter_prepend(RealHandle, _filterCallback, IntPtr.Zero);
333 /// Removes a filter from the list.
335 /// <param name="func">The filter function to remove.</param>
336 /// <since_tizen> preview </since_tizen>
337 public void RemoveFilter(Func<string, bool> func)
339 _filters.Remove(func);
340 if (_filters.Count == 0)
342 Interop.Elementary.elm_multibuttonentry_item_filter_remove(RealHandle, _filterCallback, IntPtr.Zero);
347 /// Sets a function to format the string that will be used to display the hidden items counter.
348 /// If func is NULL, the default format will be used, which is "+ 'the hidden items counter'".
350 /// <param name="func">The function to return string to show.</param>
351 /// <since_tizen> preview </since_tizen>
352 public void SetFormatCallback(Func<int, string> func)
356 Interop.Elementary.elm_multibuttonentry_format_function_set(RealHandle, null, IntPtr.Zero);
361 Interop.Elementary.elm_multibuttonentry_format_function_set(RealHandle, _formatCallback, IntPtr.Zero);
365 string FormatCallbackHandler(int count, IntPtr data)
367 return _formatFunc(count);
370 void Item_Deleted(object sender, EventArgs e)
372 var removed = sender as MultiButtonEntryItem;
373 _children.Remove(removed);
375 // "item,deleted" event will be called after removing the item from ItemObject has been done.
376 // ItemObject will no longer have the item instance that is deleted after this.
377 // So, ItemDelete event with the removed item should be triggered here.
378 ItemDeleted?.Invoke(this, new MultiButtonEntryItemEventArgs { Item = removed });
381 void OnItemAdded(object sender, MultiButtonEntryItemEventArgs e)
383 e.Item.Parent = this;
384 _children.Add(e.Item);
385 e.Item.Deleted += Item_Deleted;
386 ItemAdded?.Invoke(this, e);
389 bool FilterCallbackHandler(IntPtr obj, string label, IntPtr itemData, IntPtr data)
391 foreach (var func in _filters)
399 internal class EntryInner : Entry
402 /// Creates and initializes a new instance of the EntryInner class.
404 /// <param name="parent">The parent is a given container, which will be attached by the MultiButtonEntry as a child. It's <see cref="EvasObject"/> type.</param>
405 internal EntryInner(EvasObject parent) : base(parent)
410 /// Creates a widget handle.
412 /// <param name="parent">Parent EvasObject.</param>
413 /// <returns>Handle IntPtr.</returns>
414 protected override IntPtr CreateHandle(EvasObject parent)
416 return Interop.Elementary.elm_multibuttonentry_entry_get(parent.Handle);
422 /// It inherits System.EventArgs.
423 /// The MultiButtonEntryItemEventArgs is a argument for all events of MultiButtonEntry.
424 /// It contains the Item which is <see cref="MultiButtonEntryItem"/> type.
426 /// <since_tizen> preview </since_tizen>
427 public class MultiButtonEntryItemEventArgs : EventArgs
430 /// Gets or sets the MultiButtonEntryItem item. The return type is <see cref="MultiButtonEntryItem"/>.
432 /// <since_tizen> preview </since_tizen>
433 public MultiButtonEntryItem Item { get; set; }
435 internal static MultiButtonEntryItemEventArgs CreateFromSmartEvent(IntPtr data, IntPtr obj, IntPtr info)
437 MultiButtonEntryItem item = ItemObject.GetItemByHandle(info) as MultiButtonEntryItem;
438 return new MultiButtonEntryItemEventArgs { Item = item };
441 internal static MultiButtonEntryItemEventArgs CreateAndAddFromSmartEvent(IntPtr data, IntPtr obj, IntPtr info)
443 // Item can be added throught calling Append method and user input.
444 // And since "item.added" event will be called before xx_append() method returns,
445 // ItemObject does NOT have an item that contains handle matched to "info" at this time.
446 // So, item should be created and added internally here.
448 MultiButtonEntryItem item = new MultiButtonEntryItem(info);
449 return new MultiButtonEntryItemEventArgs { Item = item };