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.
19 using System.Threading;
20 using System.Threading.Tasks;
25 /// The Image is a widget that allows one to load and display an image file on it,
26 /// be it from a disk file or from a memory region.
29 public class Image : Widget
31 bool _canScaleUp = true;
32 bool _canScaleDown = true;
34 Color _color = Color.Default;
36 EvasImage _imageObject = null;
39 /// Creates and initializes a new instance of Image class.
41 /// <param name="parent">The parent is a given container which will be attached by Image as a child. It's <see cref="EvasObject"/> type.</param>
42 public Image(EvasObject parent) : base(parent)
44 _clicked = new SmartEvent(this, "clicked");
45 _clicked.On += (s, e) => Clicked?.Invoke(this, EventArgs.Empty);
49 /// Clicked will be triggered when the image is clicked.
51 public event EventHandler Clicked;
54 /// LoadingCompleted will be triggered when the image is loaded completely.
56 public event EventHandler LoadingCompleted;
59 /// Clicked will be triggered when the image is fail to load.
61 public event EventHandler LoadingFailed;
64 /// Gets the file that is used as an image.
70 return Interop.Elementary.elm_image_file_get(RealHandle);
75 /// Sets or gets the smooth effect for an image.
81 return Interop.Elementary.elm_image_smooth_get(RealHandle);
85 Interop.Elementary.elm_image_smooth_set(RealHandle, value);
90 /// Sets or gets whether scaling is disabled on the object.
96 return !Interop.Elementary.elm_image_no_scale_get(RealHandle);
100 Interop.Elementary.elm_image_no_scale_set(RealHandle, !value);
105 /// Sets or gets whether the object is down resizeable.
107 public bool CanScaleDown
111 return _canScaleDown;
115 _canScaleDown = value;
116 Interop.Elementary.elm_image_resizable_set(RealHandle, _canScaleUp, _canScaleDown);
121 /// Sets or gets whether the object is up resizeable.
123 public bool CanScaleUp
132 Interop.Elementary.elm_image_resizable_set(RealHandle, _canScaleUp, _canScaleDown);
137 /// Sets or gets whether the image fills the entire object area, when keeping the aspect ratio.
139 public bool CanFillOutside
143 return Interop.Elementary.elm_image_fill_outside_get(RealHandle);
147 Interop.Elementary.elm_image_fill_outside_set(RealHandle, value);
152 /// Sets or gets the prescale size for the image.
154 public int PrescaleSize
158 return Interop.Elementary.elm_image_prescale_get(RealHandle);
162 Interop.Elementary.elm_image_prescale_set(RealHandle, value);
167 /// Sets or gets whether the original aspect ratio of the image should be kept on resize.
169 public bool IsFixedAspect
173 return Interop.Elementary.elm_image_aspect_fixed_get(RealHandle);
177 Interop.Elementary.elm_image_aspect_fixed_set(RealHandle, value);
182 /// Sets or gets whether an image object (which supports animation) is to animate itself.
184 public bool IsAnimated
188 return Interop.Elementary.elm_image_animated_get(RealHandle);
192 Interop.Elementary.elm_image_animated_set(RealHandle, value);
197 /// Gets whether an image object supports animation.
199 public bool IsAnimatedAvailable
203 return Interop.Elementary.elm_image_animated_available_get(RealHandle);
208 /// Sets or gets whether an image object is under animation.
211 /// An image object, even if it supports animation, will be displayed by default without animation.
212 /// To actually start playing any image object's animation, <see cref="IsAnimated"/> should be TRUE before setting this property true.
214 public bool IsAnimationPlaying
218 return Interop.Elementary.elm_image_animated_play_get(RealHandle);
222 Interop.Elementary.elm_image_animated_play_set(RealHandle, value);
227 /// Sets or gets whether the image is 'editable'.
229 public bool IsEditable
233 return Interop.Elementary.elm_image_editable_get(RealHandle);
237 Interop.Elementary.elm_image_editable_set(RealHandle, value);
242 /// Gets the current size of the image.
244 public Size ObjectSize
248 Interop.Elementary.elm_image_object_size_get(RealHandle, out int w, out int h);
249 return new Size(w, h);
254 /// Sets or gets whether alpha channel data is being used on the given image object.
260 if (ImageObject != null)
262 return ImageObject.IsOpaque;
268 if (ImageObject != null)
270 ImageObject.IsOpaque = value;
276 /// Sets or gets the image orientation.
278 public ImageOrientation Orientation
282 return (ImageOrientation)Interop.Elementary.elm_image_orient_get(RealHandle);
286 Interop.Elementary.elm_image_orient_set(RealHandle, (int)value);
291 /// Sets or gets the image color
293 public override Color Color
301 if (ImageObject != null)
305 ImageObject.Color = Color.FromRgba(255, 255, 255, 255);
309 ImageObject.Color = value;
317 /// Sets the background color
319 public override Color BackgroundColor
325 SetPartColor("bg", Color.Transparent);
329 SetPartColor("bg", value);
331 _backgroundColor = value;
336 /// Gets the inlined image object of the image widget.
337 /// This property allows one to get the underlying EvasObject of type Image from this elementary widget. It can be useful to do things like save the image to a file, etc.
339 /// <remarks>Be careful to not manipulate it, as it is under the control of widget.</remarks>
340 public EvasImage ImageObject
344 if (_imageObject == null)
346 IntPtr evasObj = Interop.Elementary.elm_image_object_get(RealHandle);
347 if (evasObj != IntPtr.Zero)
349 _imageObject = new EvasImage(this, evasObj);
350 _imageObject.Deleted += (s, e) => _imageObject = null;
358 /// Sets the dimensions for an image object's border, a region which is not scaled together with its center ever.
360 /// <param name="left">The border's left width</param>
361 /// <param name="right">The border's right width</param>
362 /// <param name="top">The border's top width</param>
363 /// <param name="bottom">The border's bottom width</param>
364 public void SetBorder(int left, int right, int top, int bottom)
366 ImageObject?.SetBorder(left, right, top, bottom);
370 /// Sets or gets if the center part of the given image object (not the border) should be drawn.
373 /// When rendering, the image may be scaled to fit the size of the image object.
374 /// This function sets if the center part of the scaled image is to be drawn or left completely blank, or forced to be solid.
375 /// Very useful for frames and decorations.
377 public ImageBorderFillMode BorderCenterFillMode
381 if (ImageObject != null)
383 return ImageObject.BorderCenterFillMode;
387 return default(ImageBorderFillMode);
393 if (ImageObject != null)
395 ImageObject.BorderCenterFillMode = value;
401 /// Sets the file that is used as the image's source.
403 /// <param name="file">The path to the file that is used as an image source</param>
404 /// <returns>(true = success, false = error)</returns>
405 public bool Load(string file)
408 throw new ArgumentNullException("file");
410 Interop.Elementary.elm_image_async_open_set(RealHandle, false);
411 Interop.Elementary.elm_image_preload_disabled_set(RealHandle, true);
412 return Interop.Elementary.elm_image_file_set(RealHandle, file, null);
416 /// Sets the uri that is used as the image's source.
418 /// <param name="uri">The uri to the file that is used as an image source</param>
419 /// <returns>(true = success, false = error)</returns>
420 public bool Load(Uri uri)
423 throw new ArgumentNullException("uri");
425 return Load(uri.IsFile ? uri.LocalPath : uri.AbsoluteUri);
429 /// Sets a location in the memory to be used as an image object's source bitmap.
432 /// This function is handy when the contents of an image file are mapped into the memory, for example.
433 /// The format string should be something like "png", "jpg", "tga", "tiff", "bmp" etc, when provided (null, on the contrary).
434 /// This improves the loader performance as it tries the "correct" loader first, before trying a range of other possible loaders until one succeeds.
436 /// <param name="img">The binary data that is used as an image source</param>
437 /// <param name="size">The size of the binary data blob img</param>
438 /// <returns>(true = success, false = error)</returns>
439 [Obsolete("This method will be removed. Use Load(Stream stream) instead.")]
440 public unsafe bool Load(byte* img, long size)
443 throw new ArgumentNullException("img");
445 Interop.Elementary.elm_image_async_open_set(RealHandle, false);
446 Interop.Elementary.elm_image_preload_disabled_set(RealHandle, true);
447 return Interop.Elementary.elm_image_memfile_set(RealHandle, img, size, IntPtr.Zero, IntPtr.Zero);
451 /// Sets the stream that is used as the image's source.
453 /// <param name="stream">The stream that is used as an image source</param>
454 /// <returns>(true = success, false = error)</returns>
455 public bool Load(Stream stream)
458 throw new ArgumentNullException("stream");
460 Interop.Elementary.elm_image_async_open_set(RealHandle, false);
461 Interop.Elementary.elm_image_preload_disabled_set(RealHandle, true);
462 MemoryStream memstream = new MemoryStream();
463 stream.CopyTo(memstream);
466 byte[] dataArr = memstream.ToArray();
467 fixed (byte* data = &dataArr[0])
469 return Interop.Elementary.elm_image_memfile_set(RealHandle, data, dataArr.Length, IntPtr.Zero, IntPtr.Zero);
475 /// Sets the file that is used as the image's source with async.
477 /// <param name="file">The path to the file that is used as an image source</param>
478 /// <param name="cancellationToken">cancellation token</param>
479 /// <returns>(true = success, false = error)</returns>
480 public Task<bool> LoadAsync(string file, CancellationToken cancellationToken = default(CancellationToken))
483 throw new ArgumentNullException("file");
485 Interop.Elementary.elm_image_async_open_set(RealHandle, true);
486 Interop.Elementary.elm_image_preload_disabled_set(RealHandle, false);
488 var tcs = new TaskCompletionSource<bool>();
490 cancellationToken.Register(() =>
492 if (tcs != null && !tcs.Task.IsCompleted)
498 SmartEvent loadReady = new SmartEvent(this, RealHandle, "load,ready");
499 loadReady.On += (s, e) =>
502 LoadingCompleted?.Invoke(this, EventArgs.Empty);
503 if (tcs != null && !tcs.Task.IsCompleted)
509 SmartEvent loadError = new SmartEvent(this, RealHandle, "load,error");
510 loadError.On += (s, e) =>
513 LoadingFailed?.Invoke(this, EventArgs.Empty);
514 if (tcs != null && !tcs.Task.IsCompleted)
516 tcs.SetResult(false);
520 bool ret = Interop.Elementary.elm_image_file_set(RealHandle, file, null);
523 throw new InvalidOperationException("Failed to set file to Image");
530 /// Sets the uri that is used as the image's source with async.
532 /// <param name="uri">The uri to the file that is used as an image source</param>
533 /// <param name="cancellationToken">cancellation token</param>
534 /// <returns>(true = success, false = error)</returns>
535 public Task<bool> LoadAsync(Uri uri, CancellationToken cancellationToken = default(CancellationToken))
538 throw new ArgumentNullException("uri");
540 return LoadAsync(uri.IsFile ? uri.LocalPath : uri.AbsoluteUri, cancellationToken);
544 /// Sets the stream that is used as the image's source with async.
546 /// <param name="stream">The stream that is used as an image source</param>
547 /// <param name="cancellationToken">cancellation token</param>
548 /// <returns>(true = success, false = error)</returns>
549 public async Task<bool> LoadAsync(Stream stream, CancellationToken cancellationToken = default(CancellationToken))
552 throw new ArgumentNullException("stream");
554 Interop.Elementary.elm_image_async_open_set(RealHandle, true);
555 Interop.Elementary.elm_image_preload_disabled_set(RealHandle, false);
557 var tcs = new TaskCompletionSource<bool>();
559 cancellationToken.Register(() =>
561 if (tcs != null && !tcs.Task.IsCompleted)
567 SmartEvent loadReady = new SmartEvent(this, RealHandle, "load,ready");
568 loadReady.On += (s, e) =>
571 LoadingCompleted?.Invoke(this, EventArgs.Empty);
572 if (tcs != null && !tcs.Task.IsCompleted)
578 SmartEvent loadError = new SmartEvent(this, RealHandle, "load,error");
579 loadError.On += (s, e) =>
582 LoadingFailed?.Invoke(this, EventArgs.Empty);
583 if (tcs != null && !tcs.Task.IsCompleted)
585 tcs.SetResult(false);
589 MemoryStream memstream = new MemoryStream();
590 await stream.CopyToAsync(memstream);
594 byte[] dataArr = memstream.ToArray();
595 fixed (byte* data = &dataArr[0])
597 bool ret = Interop.Elementary.elm_image_memfile_set(RealHandle, data, dataArr.Length, IntPtr.Zero, IntPtr.Zero);
607 return await tcs.Task;
611 /// Sets the color of color class for a given widget.
613 /// <param name="part">The name of color class.</param>
614 /// <param name="color">The struct of color</param>
615 public override void SetPartColor(string part, Color color)
617 Interop.Elementary.elm_object_color_class_color_set(Handle, part, color.R * color.A / 255,
618 color.G * color.A / 255,
619 color.B * color.A / 255,
624 /// Gets the color of color class for a given widget.
626 /// <param name="part">The name of color class.</param>
627 /// <returns>color object</returns>
628 public override Color GetPartColor(string part)
630 Interop.Elementary.elm_object_color_class_color_get(Handle, part, out int r, out int g, out int b, out int a);
631 return new Color((int)(r / (a / 255.0)), (int)(g / (a / 255.0)), (int)(b / (a / 255.0)), a);
635 /// Sets the content at a part of a given container widget.
637 /// <param name="parent">The parent is a given container which will be attached by Image as a child. It's <see cref="EvasObject"/> type.</param>
638 /// <returns>The new object, otherwise null if it cannot be created</returns>
639 protected override IntPtr CreateHandle(EvasObject parent)
641 IntPtr handle = Interop.Elementary.elm_layout_add(parent);
642 Interop.Elementary.elm_layout_theme_set(handle, "layout", "background", "default");
644 RealHandle = Interop.Elementary.elm_image_add(handle);
645 Interop.Elementary.elm_object_part_content_set(handle, "elm.swallow.content", RealHandle);
652 /// Enumeration for the fill mode of image border
654 public enum ImageBorderFillMode
657 /// None mode of image border
662 /// Default mode of image border
667 /// Solid mode of image border
673 /// Enumeration for the possible orientation options
675 public enum ImageOrientation : int
678 /// No orientation change
683 /// Rotate 90 degrees clockwise
688 /// Rotate 180 degrees clockwise
693 /// Rotate 90 degrees counter-clockwise (i.e. 270 degrees clockwise)
698 /// Flip image horizontally
703 /// Flip image vertically
708 /// Flip the image along the y = (width - x) line (bottom-left to top-right)
713 /// Flip the image along the y = x line (top-left to bottom-right)