using System;
using ElmSharp;
using EColor = ElmSharp.Color;
using ESize = ElmSharp.Size;
using ERect = ElmSharp.Rect;
using ERectangle = ElmSharp.Rectangle;
namespace Xamarin.Forms.Platform.Tizen.Native
{
///
/// Provides implementation of the search bar widget.
///
public class SearchBar : Canvas, IMeasurable
{
///
/// The height of the background of the search bar.
///
const int BackgroundHeight = 120;
///
/// The style of the cancel button.
///
const string CancelButtonLayoutStyle = "editfield_clear";
///
/// The horizontal padding of the cancel button.
///
const int CancelButtonPaddingHorizontal = 17;
///
/// The size of the cancel button.
///
const int CancelButtonSize = 80;
///
/// The height of the entry.
///
const int EntryHeight = 54;
///
/// The horizontal padding of the entry.
///
const int EntryPaddingHorizontal = 42;
///
/// The vertical padding of the entry.
///
const int EntryPaddingVertical = 33;
///
/// The height of the rectangle used to draw underline effect.
///
const int RectangleHeight = 2;
///
/// The bottom padding of the rectangle used to draw underline effect.
///
const int RectanglePaddingBottom = 20;
///
/// The horizontal padding of the rectangle used to draw underline effect.
///
const int RectanglePaddingHorizontal = 32;
///
/// The top padding of the rectangle used to draw underline effect.
///
const int RectanglePaddingTop = 11;
//TODO: read default platform color
///
/// The color of the underline rectangle.
///
static readonly EColor s_underlineColor = EColor.Aqua;
///
/// The dimmed color of the underline rectangle.
///
static readonly EColor s_underlineDimColor = EColor.Gray;
///
/// The cancel button.
///
Button _cancelButton;
///
/// The text entry.
///
Entry _entry;
///
/// The underline rectangle.
///
ERectangle _underlineRectangle;
///
/// Initializes a new instance of the class.
///
/// Parent evas object.
public SearchBar(EvasObject parent) : base(parent)
{
_entry = new Entry(parent)
{
IsSingleLine = true,
};
_entry.SetInputPanelReturnKeyType(InputPanelReturnKeyType.Search);
_entry.TextChanged += EntryTextChanged;
_entry.Activated += EntryActivated;
_entry.Focused += EntryFocused;
_entry.Unfocused += EntryUnfocused;
_entry.Show();
_cancelButton = new Button(parent);
_cancelButton.Style = CancelButtonLayoutStyle;
_cancelButton.Clicked += CancelButtonClicked;
_underlineRectangle = new ERectangle(parent)
{
Color = IsEnabled ? s_underlineColor : s_underlineDimColor,
};
_underlineRectangle.Show();
Children.Add(_entry);
Children.Add(_cancelButton);
Children.Add(_underlineRectangle);
Show();
this.LayoutUpdated += SearchBarLayoutUpdated;
}
///
/// Occurs when the search button on the keyboard is pressed.
///
public event EventHandler SearchButtonPressed;
///
/// Occurs when the entry's text has changed.
///
public event EventHandler TextChanged;
///
/// Gets or sets the color of the cancel button.
///
/// Color of the cancel button.
public EColor CancelButtonColor
{
get
{
return _cancelButton.Color;
}
set
{
if (!_cancelButton.Color.Equals(value))
{
_cancelButton.Color = value;
}
}
}
///
/// Gets or sets the font attributes of the search bar's entry.
///
/// The font attributes.
public FontAttributes FontAttributes
{
get
{
return _entry.FontAttributes;
}
set
{
if (value != _entry.FontAttributes)
{
_entry.FontAttributes = value;
}
}
}
///
/// Gets or sets the font family of the search bar's entry.
///
/// The font family.
public string FontFamily
{
get
{
return _entry.FontFamily;
}
set
{
if (value != _entry.FontFamily)
{
_entry.FontFamily = value;
}
}
}
///
/// Gets or sets the size of the font of the search bar's entry.
///
/// The size of the font.
public double FontSize
{
get
{
return _entry.FontSize;
}
set
{
if (value != _entry.FontSize)
{
_entry.FontSize = value;
}
}
}
///
/// Gets or sets the horizontal text alignment of the search bar's entry.
///
/// The horizontal text alignment.
public TextAlignment HorizontalTextAlignment
{
get
{
return _entry.HorizontalTextAlignment;
}
set
{
if (value != _entry.HorizontalTextAlignment)
{
_entry.HorizontalTextAlignment = value;
}
}
}
///
/// Gets or sets the placeholder of the search bar's entry.
///
/// The placeholder.
public string Placeholder
{
get
{
return _entry.Placeholder;
}
set
{
if (value != _entry.Placeholder)
{
_entry.Placeholder = value;
}
}
}
///
/// Gets or sets the color of the placeholder.
///
/// The color of the placeholder.
public EColor PlaceholderColor
{
get
{
return _entry.PlaceholderColor;
}
set
{
if (!_entry.PlaceholderColor.Equals(value))
{
_entry.PlaceholderColor = value;
}
}
}
///
/// Gets or sets the text of the search bar's entry.
///
/// The text.
public override string Text
{
get
{
return _entry.Text;
}
set
{
if (value != _entry.Text)
{
_entry.Text = value;
}
}
}
///
/// Gets or sets the color of the text.
///
/// The color of the text.
public EColor TextColor
{
get
{
return _entry.TextColor;
}
set
{
if (!_entry.TextColor.Equals(value))
{
_entry.TextColor = value;
}
}
}
///
/// Implementation of the IMeasurable.Measure() method.
///
public ESize Measure(int availableWidth, int availableHeight)
{
ESize entrySize = _entry.Measure(availableWidth, availableHeight);
int width = entrySize.Width + (CancelButtonPaddingHorizontal * 2) + CancelButtonSize;
return new ESize(width, BackgroundHeight);
}
internal void BatchBegin()
{
_entry.BatchBegin();
}
internal void BatchCommit()
{
_entry.BatchCommit();
}
///
/// Handles the event triggered by the cancel button being clicked.
///
/// Sender of the event.
/// Event arguments, ignored.
void CancelButtonClicked(object sender, EventArgs e)
{
_entry.Text = string.Empty;
_cancelButton.Hide();
}
///
/// Handles the event triggered by clicking the search button on the keyboard.
///
/// Sender of the event.
/// Event arguments, ignored.
void EntryActivated(object sender, EventArgs e)
{
SearchButtonPressed?.Invoke(this, EventArgs.Empty);
}
///
/// Handles the event triggered by entry gaining the focus.
///
/// Sender of the event.
/// Event arguments, ignored.
void EntryFocused(object sender, EventArgs e)
{
_underlineRectangle.Color = s_underlineColor;
}
///
/// Handles the event triggered by entry's text being changed.
///
/// Sender of the event.
/// Event arguments.
void EntryTextChanged(object sender, TextChangedEventArgs e)
{
if (string.IsNullOrEmpty(e.NewTextValue))
{
_cancelButton.Hide();
}
else if (!_cancelButton.IsVisible)
{
_cancelButton.Show();
}
TextChanged?.Invoke(this, e);
}
///
/// Handles the event triggered by entry losing the focus.
///
/// Sender of the event.
/// Event arguments, ignored.
void EntryUnfocused(object sender, EventArgs e)
{
_underlineRectangle.Color = s_underlineDimColor;
}
///
/// Handles the event triggered by search bar's layout being changed.
///
///
/// Updates the geometry of the widgets comprising the search bar.
///
/// Sender of the event.
/// Event arguments.
void SearchBarLayoutUpdated(object sender, LayoutEventArgs e)
{
_underlineRectangle.Geometry = new ERect(e.Geometry.Left + RectanglePaddingHorizontal,
e.Geometry.Top + EntryPaddingVertical + EntryHeight + RectanglePaddingTop,
e.Geometry.Width - (RectanglePaddingHorizontal * 2),
RectangleHeight);
_entry.Geometry = new ERect(e.Geometry.Left + EntryPaddingHorizontal,
e.Geometry.Top + EntryPaddingVertical,
e.Geometry.Width - (EntryPaddingHorizontal + (CancelButtonPaddingHorizontal * 2) + CancelButtonSize),
EntryHeight);
_cancelButton.Geometry = new ERect(e.Geometry.Right - CancelButtonSize - CancelButtonPaddingHorizontal,
e.Geometry.Top + RectanglePaddingBottom,
CancelButtonSize,
CancelButtonSize);
}
}
}