File: Platform\Tizen\MauiSearchBar.cs
Web Access
Project: src\src\Core\src\Core.csproj (Microsoft.Maui)
using System;
using Microsoft.Maui.Graphics;
using Microsoft.Maui.Graphics.Skia.Views;
using Tizen.NUI;
using Tizen.UIExtensions.Common;
using Tizen.UIExtensions.NUI;
using NColor = Tizen.NUI.Color;
using TSize = Tizen.UIExtensions.Common.Size;
using TTextAlignment = Tizen.UIExtensions.Common.TextAlignment;
 
namespace Microsoft.Maui.Platform
{
	public class MauiSearchBar : ViewGroup, IMeasurable
	{
		const double IconSize = 24;
		const double IconMargin = 8;
 
		public readonly double Radius = 8;
		public readonly NColor DefaultBackgroundColor = new NColor(0.9f, 0.9f, 0.9f, 1);
 
		Entry _entry;
		SkiaGraphicsView _searchButton;
		PointStateType _lastPointState;
 
		public MauiSearchBar()
		{
			BackgroundColor = DefaultBackgroundColor;
 
			_entry = new Entry
			{
				Padding = new Extents(10),
				VerticalTextAlignment = TTextAlignment.Center,
			};
			_entry.KeyEvent += OnKeyEvent;
			_searchButton = new SkiaGraphicsView
			{
				Focusable = true,
				Drawable = new SearchIcon(),
			};
			_searchButton.TouchEvent += OnSearchButtonTouchEvent;
			_searchButton.KeyEvent += OnSearchButtonKeyEvent;
 
			Children.Add(_entry);
			Children.Add(_searchButton);
			LayoutUpdated += OnLayoutUpdated;
		}
 
		public Entry Entry => _entry;
 
		public event EventHandler? SearchButtonPressed;
 
		protected override void OnEnabled(bool enabled)
		{
			base.OnEnabled(enabled);
			_entry.IsEnabled = enabled;
		}
 
		TSize IMeasurable.Measure(double availableWidth, double availableHeight)
		{
			if (!string.IsNullOrEmpty(Entry.Text) || !string.IsNullOrEmpty(Entry.Placeholder))
			{
				return new TSize(availableWidth, Math.Max(Entry.NaturalSize.Height, IconSize.ToScaledPixel() + IconMargin.ToScaledPixel()));
			}
			else
			{
				return new TSize(Math.Max(Entry.PixelSize + 10, availableWidth), Math.Max(Entry.PixelSize + 10, IconSize.ToScaledPixel() + IconMargin.ToScaledPixel()));
			}
		}
 
		void OnSearchButtonClicked(object? sender, EventArgs e)
		{
			SearchButtonPressed?.Invoke(this, EventArgs.Empty);
		}
 
		bool OnKeyEvent(object source, KeyEventArgs e)
		{
			if (e.Key.IsAcceptKeyEvent())
			{
				SearchButtonPressed?.Invoke(this, EventArgs.Empty);
				return true;
			}
			return false;
		}
 
		bool OnSearchButtonTouchEvent(object source, TouchEventArgs e)
		{
			var state = e.Touch.GetState(0);
 
			if (state == PointStateType.Up && _lastPointState == PointStateType.Down)
			{
				SearchButtonPressed?.Invoke(this, EventArgs.Empty);
			}
 
			_lastPointState = state;
			return state == PointStateType.Up || state == PointStateType.Down;
		}
 
		bool OnSearchButtonKeyEvent(object source, KeyEventArgs e)
		{
			if (e.Key.IsAcceptKeyEvent())
			{
				SearchButtonPressed?.Invoke(this, EventArgs.Empty);
				return true;
			}
			return false;
		}
 
		void OnLayoutUpdated(object? sender, LayoutEventArgs e)
		{
			var margin = (float)IconMargin.ToScaledPixel();
			var halfMargin = margin / 2.0f;
			var iconSize = (float)IconSize.ToScaledPixel();
			var iconArea = iconSize + margin;
 
			CornerRadius = Radius.ToScaledPixel();
 
			_entry.Position = new Position(halfMargin, 0);
			_entry.SizeHeight = SizeHeight;
			_entry.SizeWidth = SizeWidth - iconArea - halfMargin;
			_searchButton.Position = new Position(_entry.SizeWidth + _entry.Position.X + halfMargin, (float)(SizeHeight - iconSize) / 2.0f);
			_searchButton.SizeHeight = iconSize;
			_searchButton.SizeWidth = iconSize;
		}
 
		class SearchIcon : IDrawable
		{
			public void Draw(ICanvas canvas, RectF dirtyRect)
			{
				canvas.SaveState();
 
				var width = dirtyRect.Width;
				var height = dirtyRect.Height;
				var imgWidth = (float)IconSize;
				var imgHeight = (float)IconSize;
 
				var transX = (width - imgWidth) / 2.0f;
				var transY = (height - imgHeight) / 2.0f;
				canvas.Translate(transX, transY);
 
				var vBuilder = new PathBuilder();
				var path = vBuilder.BuildPath("M9.5,3A6.5,6.5 0 0,1 16,9.5C16,11.11 15.41,12.59 14.44,13.73L14.71,14H15.5L20.5,19L19,20.5L14,15.5V14.71L13.73,14.44C12.59,15.41 11.11,16 9.5,16A6.5,6.5 0 0,1 3,9.5A6.5,6.5 0 0,1 9.5,3M9.5,5C7,5 5,7 5,9.5C5,12 7,14 9.5,14C12,14 14,12 14,9.5C14,7 12,5 9.5,5Z");
 
				canvas.FillColor = Colors.Black;
				canvas.FillPath(path);
				canvas.RestoreState();
			}
		}
	}
}