- RFC:http://suprem.sec.samsung.net/confluence/display/SPTDTLC/%5BFormsTizen%5D+RFC+6+-+Radio+Button
- Depands on:https://review.tizen.org/gerrit/#/c/109686/
Change-Id: I6be453af733c9bf04049375452252616d5f6cc1b
--- /dev/null
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using ElmSharp;
+using Xamarin.Forms.Platform.Tizen;
+using Xamarin.Forms.Platform.Tizen.Native;
+using Tizen.Xamarin.Forms.Extension;
+using Tizen.Xamarin.Forms.Extension.Renderer;
+using TForms = Xamarin.Forms.Platform.Tizen.Forms;
+
+[assembly: ExportRenderer(typeof(RadioButton), typeof(RadioButtonRenderer))]
+namespace Tizen.Xamarin.Forms.Extension.Renderer
+{
+ public class RadioButtonRenderer : ViewRenderer<RadioButton, Radio>
+ {
+ readonly Span _span = new Span();
+
+ static Lazy<RadioGroupManager> s_GroupManager = new Lazy<RadioGroupManager>();
+
+ int _changedCallbackDepth = 0;
+
+ public RadioButtonRenderer()
+ {
+ }
+
+ protected override void OnElementChanged(ElementChangedEventArgs<RadioButton> e)
+ {
+ if (Control == null)
+ {
+ var radio = new Radio(TForms.Context.MainWindow) { StateValue = 1 };
+ SetNativeControl(radio);
+ }
+ if (e.OldElement != null)
+ {
+ Control.ValueChanged -= ChangedEventHandler;
+ }
+ if (e.NewElement != null)
+ {
+ Control.ValueChanged += ChangedEventHandler;
+ UpdateAll();
+ }
+ base.OnElementChanged(e);
+ }
+
+ protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
+ {
+ if (e.PropertyName == RadioButton.TextProperty.PropertyName)
+ {
+ UpdateText();
+ }
+ else if (e.PropertyName == RadioButton.TextColorProperty.PropertyName)
+ {
+ UpdateTextColor();
+ }
+ else if (e.PropertyName == RadioButton.FontProperty.PropertyName)
+ {
+ UpdateFont();
+ }
+ else if (e.PropertyName == RadioButton.FontFamilyProperty.PropertyName)
+ {
+ UpdateFontFamily();
+ }
+ else if (e.PropertyName == RadioButton.FontSizeProperty.PropertyName)
+ {
+ UpdateFontSize();
+ }
+ else if (e.PropertyName == RadioButton.FontAttributesProperty.PropertyName)
+ {
+ UpdateFontAttributes();
+ }
+ else if (e.PropertyName == RadioButton.GroupNameProperty.PropertyName)
+ {
+ UpdateGroupName();
+ }
+ else if (e.PropertyName == RadioButton.IsSelectedProperty.PropertyName)
+ {
+ UpdateIsSelected();
+ }
+
+ if (e.PropertyName == RadioButton.TextProperty.PropertyName || e.PropertyName == RadioButton.TextColorProperty.PropertyName ||
+ e.PropertyName == RadioButton.FontProperty.PropertyName || e.PropertyName == RadioButton.FontFamilyProperty.PropertyName ||
+ e.PropertyName == RadioButton.FontSizeProperty.PropertyName || e.PropertyName == RadioButton.FontAttributesProperty.PropertyName)
+ {
+ ApplyTextAndStyle();
+ }
+
+ base.OnElementPropertyChanged(sender, e);
+ }
+
+ void ChangedEventHandler(object sender, EventArgs e)
+ {
+ _changedCallbackDepth++;
+ Element.IsSelected = Control.GroupValue == 1 ? true : false;
+ _changedCallbackDepth--;
+ }
+
+ void UpdateAll()
+ {
+ UpdateText();
+ UpdateTextColor();
+ UpdateFont();
+ UpdateGroupName();
+ UpdateIsSelected();
+ ApplyTextAndStyle();
+ }
+
+ void UpdateText()
+ {
+ _span.Text = Element.Text;
+ }
+
+ void UpdateTextColor()
+ {
+ _span.ForegroundColor = Element.TextColor.ToNative();
+ }
+
+ void UpdateFont()
+ {
+ _span.FontSize = Element.FontSize;
+ _span.FontAttributes = Element.FontAttributes;
+ _span.FontFamily = Element.FontFamily;
+ }
+
+ void UpdateFontFamily()
+ {
+ _span.FontFamily = Element.FontFamily;
+ }
+
+ void UpdateFontSize()
+ {
+ _span.FontSize = Element.FontSize;
+ }
+
+ void UpdateFontAttributes()
+ {
+ _span.FontAttributes = Element.FontAttributes;
+ }
+
+ void UpdateGroupName()
+ {
+ s_GroupManager.Value.PartGroup(Element);
+ s_GroupManager.Value.JoinGroup(Element.GroupName, Element);
+ }
+
+ void UpdateIsSelected()
+ {
+ if (_changedCallbackDepth == 0)
+ {
+ Control.GroupValue = Element.IsSelected ? 1 : 0;
+ }
+ s_GroupManager.Value.UpdateChecked(Element.GroupName, Element);
+ }
+
+ void ApplyTextAndStyle()
+ {
+ SetInternalTextAndStyle(_span.GetDecoratedText(), _span.GetStyle());
+ }
+
+ void SetInternalTextAndStyle(string formattedText, string textStyle)
+ {
+ string emission = "elm,state,text,visible";
+ if (string.IsNullOrEmpty(formattedText))
+ {
+ formattedText = null;
+ textStyle = null;
+ emission = "elm,state,text,hidden";
+ }
+ Control.Text = formattedText;
+
+ var textblock = Control.EdjeObject["elm.text"];
+ if (textblock != null)
+ {
+ textblock.TextStyle = textStyle;
+ }
+ Control.EdjeObject.EmitSignal(emission, "elm");
+ }
+ }
+
+ internal class RadioGroupManager
+ {
+ Dictionary<string, List<RadioButton>> _groupMap = new Dictionary<string, List<RadioButton>>();
+
+ public void JoinGroup(string groupName, RadioButton button)
+ {
+ if (string.IsNullOrEmpty(groupName))
+ {
+ return;
+ }
+
+ if (!_groupMap.ContainsKey(groupName))
+ {
+ _groupMap.Add(groupName, new List<RadioButton>());
+ }
+ _groupMap[groupName].Add(button);
+ UpdateChecked(groupName, button);
+ }
+
+ public void PartGroup(RadioButton button)
+ {
+ string groupName = null;
+ foreach (var list in _groupMap)
+ {
+ if (list.Value.Contains(button))
+ {
+ groupName = list.Key;
+ }
+ }
+ PartGroup(groupName, button);
+ }
+
+ public void PartGroup(string groupName, RadioButton button)
+ {
+ if (string.IsNullOrEmpty(groupName))
+ {
+ return;
+ }
+
+ if (_groupMap.ContainsKey(groupName))
+ {
+ _groupMap[groupName].Remove(button);
+ }
+ }
+
+ public void UpdateChecked(string groupName, RadioButton button)
+ {
+ if (string.IsNullOrEmpty(groupName))
+ {
+ return;
+ }
+
+ if (button.IsSelected)
+ {
+ foreach (var btn in _groupMap[groupName].Where(b => b.IsSelected && b != button))
+ {
+ btn.IsSelected = false;
+ }
+ }
+ }
+ }
+}
<Compile Include="Cells\DoubleLabelCellRenderer.cs" />\r
<Compile Include="Cells\MultilineCellRenderer.cs" />\r
<Compile Include="Cells\TypeCellRenderer.cs" />\r
+ <Compile Include="RadioButtonRenderer.cs" />\r
<Compile Include="TizenExtension.cs" />\r
<Compile Include="Properties\AssemblyInfo.cs" />\r
</ItemGroup>\r
--- /dev/null
+using System;
+using Xamarin.Forms;
+
+namespace Tizen.Xamarin.Forms.Extension
+{
+ /// <summary>
+ /// The RadioButton is a widget that allows for 1 or more options to be displayed and have the user choose only 1 of them.
+ /// </summary>
+ public class RadioButton : View
+ {
+ /// <summary>
+ /// BindableProperty. Backing store for the Text bindable property.
+ /// </summary>
+ public static readonly BindableProperty TextProperty = BindableProperty.Create("Text", typeof(string), typeof(RadioButton), default(string));
+
+ /// <summary>
+ /// BindableProperty. Backing store for the TextColor bindable property.
+ /// </summary>
+ public static readonly BindableProperty TextColorProperty = BindableProperty.Create("TextColor", typeof(Color), typeof(RadioButton), Color.Default);
+
+ /// <summary>
+ /// BindableProperty. Backing store for the Font bindable property.
+ /// </summary>
+ public static readonly BindableProperty FontProperty = BindableProperty.Create("Font", typeof(Font), typeof(RadioButton), default(Font),
+ propertyChanged: FontStructPropertyChanged);
+
+ /// <summary>
+ /// BindableProperty. Backing store for the FontFamily bindable property.
+ /// </summary>
+ public static readonly BindableProperty FontFamilyProperty = BindableProperty.Create("FontFamily", typeof(string), typeof(RadioButton), default(string),
+ propertyChanged: SpecificFontPropertyChanged);
+
+ /// <summary>
+ /// BindableProperty. Backing store for the FontSize bindable property.
+ /// </summary>
+ public static readonly BindableProperty FontSizeProperty = BindableProperty.Create("FontSize", typeof(double), typeof(RadioButton), -1.0,
+ propertyChanged: SpecificFontPropertyChanged,
+ defaultValueCreator: bindable => Device.GetNamedSize(NamedSize.Default, (RadioButton)bindable));
+
+ /// <summary>
+ /// BindableProperty. Backing store for the FontAttributes bindable property.
+ /// </summary>
+ public static readonly BindableProperty FontAttributesProperty = BindableProperty.Create("FontAttributes", typeof(FontAttributes), typeof(RadioButton), FontAttributes.None,
+ propertyChanged: SpecificFontPropertyChanged);
+
+ /// <summary>
+ /// BindableProperty. Backing store for the IsSelected bindable property.
+ /// </summary>
+ public static readonly BindableProperty IsSelectedProperty = BindableProperty.Create("IsSelected", typeof(bool), typeof(RadioButton), false,
+ propertyChanged: IsSelectedPropertyChanged);
+
+ /// <summary>
+ /// BindableProperty. Backing store for the GroupName bindable property.
+ /// </summary>
+ public static readonly BindableProperty GroupNameProperty = BindableProperty.Create("GroupName", typeof(string), typeof(RadioButton), default(string));
+
+ /// <summary>
+ /// Gets or sets the Text displayed as the content of the RadioButton. This is a bindable property.
+ /// </summary>
+ public string Text
+ {
+ get { return (string)GetValue(TextProperty); }
+ set { SetValue(TextProperty, value); }
+ }
+
+ /// <summary>
+ /// Gets or sets the Color for the text of the RadioButton. This is a bindable property.
+ /// </summary>
+ public Color TextColor
+ {
+ get { return (Color)GetValue(TextColorProperty); }
+ set { SetValue(TextColorProperty, value); }
+ }
+
+ /// <summary>
+ /// Gets or sets the Font for the RadioButton text. This is a bindable property.
+ /// </summary>
+ public Font Font
+ {
+ get { return (Font)GetValue(FontProperty); }
+ set { SetValue(FontProperty, value); }
+ }
+
+ /// <summary>
+ /// Gets the font family to which the font for the RadioButton text belongs.
+ /// </summary>
+ public string FontFamily
+ {
+ get { return (string)GetValue(FontFamilyProperty); }
+ set { SetValue(FontFamilyProperty, value); }
+ }
+
+ /// <summary>
+ /// Gets or sets the size of the font of the RadioButton text.
+ /// </summary>
+ public double FontSize
+ {
+ get { return (double)GetValue(FontSizeProperty); }
+ set { SetValue(FontSizeProperty, value); }
+ }
+
+ /// <summary>
+ /// Gets a value that indicates whether the font for the RadioButton text is bold, italic, or neither.
+ /// </summary>
+ public FontAttributes FontAttributes
+ {
+ get { return (FontAttributes)GetValue(FontAttributesProperty); }
+ set { SetValue(FontAttributesProperty, value); }
+ }
+
+ /// <summary>
+ /// Gets or sets the name that specifies which RadioButton controls are mutually exclusive.
+ /// </summary>
+ public string GroupName
+ {
+ get { return (string)GetValue(GroupNameProperty); }
+ set { SetValue(GroupNameProperty, value ?? default(string)); }
+ }
+
+ /// <summary>
+ /// Gets or sets a Boolean value that indicates whether this RadioButton is Selected.
+ /// </summary>
+ public bool IsSelected
+ {
+ get { return (bool)GetValue(IsSelectedProperty); }
+ set { SetValue(IsSelectedProperty, value); }
+ }
+
+ /// <summary>
+ /// Occurs when the RadioButton selection was changed.
+ /// </summary>
+ public event EventHandler<SelectedEventArgs> Selected;
+
+ static void FontStructPropertyChanged(BindableObject bindable, object oldValue, object newValue)
+ {
+ var radioButton = (RadioButton)bindable;
+
+ if (radioButton.Font == Font.Default)
+ {
+ radioButton.FontFamily = null;
+ radioButton.FontSize = Device.GetNamedSize(NamedSize.Default, radioButton);
+ radioButton.FontAttributes = FontAttributes.None;
+ }
+ else
+ {
+ radioButton.FontFamily = radioButton.Font.FontFamily;
+ if (radioButton.Font.UseNamedSize)
+ {
+ radioButton.FontSize = Device.GetNamedSize(radioButton.Font.NamedSize, radioButton.GetType());
+ }
+ else
+ {
+ radioButton.FontSize = radioButton.Font.FontSize;
+ }
+ radioButton.FontAttributes = radioButton.Font.FontAttributes;
+ }
+ }
+
+ static void SpecificFontPropertyChanged(BindableObject bindable, object oldValue, object newValue)
+ {
+ var radioButton = (RadioButton)bindable;
+
+ if (radioButton.FontFamily != null)
+ {
+ radioButton.Font = Font.OfSize(radioButton.FontFamily, radioButton.FontSize).WithAttributes(radioButton.FontAttributes);
+ }
+ else
+ {
+ radioButton.Font = Font.SystemFontOfSize(radioButton.FontSize, radioButton.FontAttributes);
+ }
+ }
+
+ static void IsSelectedPropertyChanged(BindableObject bindable, object oldValue, object newValue)
+ {
+ var radioButton = (RadioButton)bindable;
+ radioButton.Selected?.Invoke(radioButton, new SelectedEventArgs((bool)newValue));
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+using System;
+
+namespace Tizen.Xamarin.Forms.Extension
+{
+ /// <summary>
+ /// Event arguments for events of RadioButton.
+ /// </summary>
+ public class SelectedEventArgs : EventArgs
+ {
+ /// <summary>
+ /// Creates a new SelectedEventArgs object that represents a change from RadioButton.
+ /// </summary>
+ /// <param name="value">The boolean value that whether the RadioButton is selected.</param>
+ public SelectedEventArgs(bool value)
+ {
+ Value = value;
+ }
+
+ /// <summary>
+ /// Gets the Value object for this SelectedEventArgs object.
+ /// </summary>
+ public bool Value { get; private set; }
+ }
+}
<Compile Include="Cells\BaseTypeCell.cs" />\r
<Compile Include="Cells\MultilineCell.cs" />\r
<Compile Include="Properties\AssemblyInfo.cs" />\r
+ <Compile Include="RadioButton.cs" />\r
+ <Compile Include="SelectedEventArgs.cs" />\r
</ItemGroup>\r
<ItemGroup>\r
<Reference Include="Xamarin.Forms.Core, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL">\r