2 * Copyright (c) 2018 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;
20 namespace Tizen.Applications.WatchfaceComplication
23 /// Represents the editables container for a watch application.
25 /// <since_tizen> 6 </since_tizen>
26 public abstract class EditablesContainer : IDisposable
28 internal IList<DesignElement> _deList = new List<DesignElement>();
29 internal IList<Complication> _compList = new List<Complication>();
30 internal IntPtr _container = IntPtr.Zero;
31 private Interop.WatchfaceComplication.EditableUpdateRequestedCallback _editableUpdatedCallback;
32 private readonly Interop.WatchfaceComplication.EditReadyCallback _editReadyCallback;
33 private bool _disposed = false;
34 private static string _logTag = "WatchfaceComplication";
37 /// Initializes the EditablesContainer class.
39 /// <exception cref="ArgumentException">Thrown when some parameter are invalid.</exception>
40 /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
41 /// <exception cref="NotSupportedException">Thrown when the watchface complication is not supported.</exception>
42 /// <since_tizen> 6 </since_tizen>
43 protected EditablesContainer()
45 _editReadyCallback = new Interop.WatchfaceComplication.EditReadyCallback(EditReady);
46 ComplicationError err = Interop.WatchfaceComplication.AddEditReadyCallback(_editReadyCallback, IntPtr.Zero);
47 if (err != ComplicationError.None)
48 ErrorFactory.ThrowException(err, "Fail to add edit ready callback");
49 Log.Debug(_logTag, "Edit container ready");
53 /// Destructor of the EditablesContainer class.
61 /// Adds the DesignElement to edit list.
63 /// <param name="de">The DesignElement object.</param>
64 /// <param name="editableId">The editable id.</param>
65 /// <exception cref="ArgumentException">Thrown when the invalid parameter is passed.</exception>
66 /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
67 /// <since_tizen> 6 </since_tizen>
68 public void Add(DesignElement de, int editableId)
71 ErrorFactory.ThrowException(ComplicationError.InvalidParam);
72 if (IsExist(editableId))
73 ErrorFactory.ThrowException(ComplicationError.ExistID);
76 e.EditableId = editableId;
81 /// Adds the Complication to edit list.
83 /// <param name="comp">The Complication object.</param>
84 /// <param name="editableId">The editable id.</param>
85 /// <exception cref="ArgumentException">Thrown when the invalid parameter is passed.</exception>
86 /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
87 /// <since_tizen> 6 </since_tizen>
88 public void Add(Complication comp, int editableId)
91 ErrorFactory.ThrowException(ComplicationError.InvalidParam);
92 if (IsExist(editableId))
93 ErrorFactory.ThrowException(ComplicationError.ExistID);
96 e.EditableId = editableId;
101 /// Removes the editable from edit list.
103 /// <param name="editableId">The editable id.</param>
104 /// <exception cref="ArgumentException">Thrown when the invalid parameter is passed.</exception>
107 /// if (myContainer.IsExist(_colorEditId)
108 /// myContainer.Remove(_colorEditId);
111 /// <since_tizen> 6 </since_tizen>
112 public void Remove(int editableId)
114 foreach (DesignElement de in _deList)
116 if (((IEditable)de).EditableId == editableId)
123 foreach (Complication comp in _compList)
125 if (((IEditable)comp).EditableId == editableId)
127 _compList.Remove(comp);
132 ErrorFactory.ThrowException(ComplicationError.InvalidParam, "invalid editable ID");
135 internal IEditable GetEditable(int editableId)
137 foreach (IEditable ed in _deList)
139 if (ed.EditableId == editableId)
143 foreach (IEditable ed in _compList)
145 if (ed.EditableId == editableId)
152 internal DesignElement GetDesignElement(int editableId)
154 foreach (DesignElement de in _deList)
157 if (ed.EditableId == editableId)
165 /// Checks whether editableId already exists in edit list.
167 /// <param name="editableId">The target editable Id.</param>
168 /// <returns>true if the editable already exists in edit list, otherwise false</returns>
169 /// <since_tizen> 6 </since_tizen>
170 public bool IsExist(int editableId)
172 return (GetEditable(editableId) != null);
175 private void EditReady(IntPtr container, string editorAppid, IntPtr userData)
177 OnEditReady(editorAppid);
181 private void EditableUpdatedCallback(IntPtr handle, int selectedIdx,
182 int state, IntPtr userData)
185 ComplicationError err = Interop.WatchfaceComplication.GetEditableId(handle, out editableId);
186 if (err != ComplicationError.None)
187 ErrorFactory.ThrowException(err, "fail to get current index");
190 err = Interop.WatchfaceComplication.GetCurrentIdx(handle, out currentIdx);
191 if (err != ComplicationError.None)
192 ErrorFactory.ThrowException(err, "fail to get current index");
194 DesignElement de = GetDesignElement(editableId);
197 de.SetCurrentDataIndex(currentIdx);
198 de.NotifyUpdate(currentIdx, (State)state);
203 /// Requests edit to editor application.
205 /// <privilege>http://tizen.org/privilege/datasharing</privilege>
206 /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
207 /// <exception cref="NotSupportedException">Thrown when the watchface complication is not supported.</exception>
208 /// <exception cref="UnauthorizedAccessException">Thrown when the application does not have privilege to access this method.</exception>
211 /// public class MyContainer : EditablesContainer {
212 /// public MyContainer() : base()
215 /// protected override void OnEditReady(string editorId)
217 /// this.RequestEdit();
222 /// <since_tizen> 6 </since_tizen>
223 public void RequestEdit()
225 Log.Debug(_logTag, "request edit");
226 ComplicationError ret;
228 Interop.WatchfaceComplication.GetEditableContainer(out _container);
229 if (_container == IntPtr.Zero)
231 ErrorFactory.ThrowException(ComplicationError.EditNotReady, "Editor not ready");
234 if (_editableUpdatedCallback == null)
235 _editableUpdatedCallback = new Interop.WatchfaceComplication.EditableUpdateRequestedCallback(EditableUpdatedCallback);
237 foreach (Complication comp in _compList)
240 IntPtr hi = IntPtr.Zero;
241 if (e.Highlight != null && e.Highlight.Raw != IntPtr.Zero)
242 hi = e.Highlight.Raw;
243 Interop.WatchfaceComplication.AddComplication(_container, e.EditableId, comp._handle, hi);
246 foreach (DesignElement de in _deList)
250 Interop.WatchfaceComplication.CreateCandidatesList(out candidates);
251 foreach (Bundle b in de.Candidates)
253 Interop.WatchfaceComplication.AddCandidatesListItem(candidates, b.SafeBundleHandle);
256 IntPtr hi = IntPtr.Zero;
257 if (e.Highlight != null && e.Highlight.Raw != IntPtr.Zero)
258 hi = e.Highlight.Raw;
259 Interop.WatchfaceComplication.AddDesignElement(_container, e.EditableId, e.GetCurrentDataIndex(), candidates, hi, e.Name);
260 Log.Debug(_logTag, "Add design element done :" + e.Name);
263 ret = Interop.WatchfaceComplication.RequestEdit(_container, _editableUpdatedCallback, IntPtr.Zero);
264 if (ret != ComplicationError.None)
266 ErrorFactory.ThrowException(ret, "Request edit fail");
271 /// Overrides this method if you want to handle the behavior when the editor is ready to edit.
273 /// <param name="editorId">The appid of ready to edit editor.</param>
274 /// <since_tizen> 6 </since_tizen>
275 protected abstract void OnEditReady(string editorId);
278 /// Loads the editable's current data.
280 /// <returns>The editable's latest data that selected by editor.</returns>
281 /// <exception cref="ArgumentException">Thrown when some parameter are invalid.</exception>
282 /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
283 /// <exception cref="NotSupportedException">Thrown when the watchface complication is not supported.</exception>
285 /// This method loads the last editable data which is updated by editor application.
287 /// <param name="editableId">The id of the editable.</param>
290 /// internal void InitEditables()
292 /// _container = new MyContainer();
293 /// Bundle curData = EditablesContainer.LoadCurrentData(_colorEditId);
294 /// List<Bundle> candidatesList = new List<Bundle>();
297 /// foreach (string str in _colorArr)
299 /// Bundle data = new Bundle();
300 /// data.AddItem(_colorKey, str);
301 /// candidatesList.Add(data);
302 /// if (curData != null && curData.GetItem(_colorKey) != null
303 /// && curData.GetItem(_colorKey).Equals(str))
309 /// ColorDesign colorEdit = new ColorDesign(candidatesList, curIdx, "COLOR", _complicationBtn);
310 /// colorEdit.Highlight = new Highlight(ShapeType.Circle, 0, 40, 10, 10);
311 /// _container.Add(colorEdit, _colorEditId);
315 /// <since_tizen> 6 </since_tizen>
316 public static Bundle LoadCurrentData(int editableId)
318 SafeBundleHandle handle;
319 ComplicationError err = Interop.WatchfaceComplication.LoadCurrentData(editableId, out handle);
320 if (err == ComplicationError.None)
321 return new Bundle(handle);
327 /// Releases the unmanaged resources used by the EditablesContainer class specifying whether or not to perform a normal dispose operation.
329 /// <param name="disposing">true for a normal dispose operation; false to finalize the handle.</param>
330 /// <since_tizen> 3 </since_tizen>
331 protected virtual void Dispose(bool disposing)
335 Interop.WatchfaceComplication.RemoveEditReadyCallback(_editReadyCallback);
341 /// Releases all resources used by the EditablesContainer instance.
343 /// <since_tizen> 3 </since_tizen>
344 public void Dispose()
347 GC.SuppressFinalize(this);