Skip to content

Instantly share code, notes, and snippets.

@dalexsoto
Created January 31, 2012 16:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save dalexsoto/1711415 to your computer and use it in GitHub Desktop.
Save dalexsoto/1711415 to your computer and use it in GitHub Desktop.
MojoDK MT.Dialog right aligned EntryElement
//
// Elements.cs: defines the various components of our view
//
// Author:
// Miguel de Icaza (miguel@gnome.org)
//
// Copyright 2010, Novell, Inc.
//
// Code licensed under the MIT X11 license
//
// TODO: StyledStringElement: merge with multi-line?
// TODO: StyledStringElement: add image scaling features?
// TODO: StyledStringElement: add sizing based on image size?
// TODO: Move image rendering to StyledImageElement, reason to do this: the image loader would only be imported in this case, linked out otherwise
//
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using MonoTouch.UIKit;
using MonoTouch.CoreGraphics;
using System.Drawing;
using MonoTouch.Foundation;
using MonoTouch.Dialog.Utilities;
namespace MonoTouch.Dialog
{
/// <summary>
/// An element that can be used to enter text.
/// </summary>
/// <remarks>
/// This element can be used to enter text both regular and password protected entries.
///
/// The Text fields in a given section are aligned with each other.
/// </remarks>
public class MojoEntryElement : Element
{
UITextField entry;
/// <summary>
/// The value of the EntryElement
/// </summary>
public string Value {
get {
return val;
}
set {
val = value;
if (entry != null)
entry.Text = value;
}
}
protected string val;
/// <summary>
/// The key used for reusable UITableViewCells.
/// </summary>
static NSString entryKey = new NSString ("MojoEntryElement");
protected virtual NSString EntryKey {
get {
return entryKey;
}
}
/// <summary>
/// The type of keyboard used for input, you can change
/// this to use this for numeric input, email addressed,
/// urls, phones.
/// </summary>
public UIKeyboardType KeyboardType {
get {
return keyboardType;
}
set {
keyboardType = value;
if (entry != null)
entry.KeyboardType = value;
}
}
/// <summary>
/// The type of Return Key that is displayed on the
/// keyboard, you can change this to use this for
/// Done, Return, Save, etc. keys on the keyboard
/// </summary>
public UIReturnKeyType? ReturnKeyType {
get {
return returnKeyType;
}
set {
returnKeyType = value;
if (entry != null && returnKeyType.HasValue)
entry.ReturnKeyType = returnKeyType.Value;
}
}
public UITextAutocapitalizationType AutocapitalizationType {
get {
return autocapitalizationType;
}
set {
autocapitalizationType = value;
if (entry != null)
entry.AutocapitalizationType = value;
}
}
public UITextAutocorrectionType AutocorrectionType {
get {
return autocorrectionType;
}
set {
autocorrectionType = value;
if (entry != null)
this.autocorrectionType = value;
}
}
UIKeyboardType keyboardType = UIKeyboardType.Default;
UIReturnKeyType? returnKeyType = null;
UITextAutocapitalizationType autocapitalizationType = UITextAutocapitalizationType.AllCharacters;
UITextAutocorrectionType autocorrectionType = UITextAutocorrectionType.Default;
bool isPassword, becomeResponder;
string placeholder;
public event EventHandler Changed;
public event Func<bool> ShouldReturn;
/// <summary>
/// Constructs an EntryElement with the given caption, placeholder and initial value.
/// </summary>
/// <param name="caption">
/// The caption to use
/// </param>
/// <param name="placeholder">
/// Placeholder to display when no value is set.
/// </param>
/// <param name="value">
/// Initial value.
/// </param>
public MojoEntryElement (string caption, string placeholder, string value) : base (caption)
{
Value = value;
this.placeholder = placeholder;
}
/// <summary>
/// Constructs an EntryElement for password entry with the given caption, placeholder and initial value.
/// </summary>
/// <param name="caption">
/// The caption to use.
/// </param>
/// <param name="placeholder">
/// Placeholder to display when no value is set.
/// </param>
/// <param name="value">
/// Initial value.
/// </param>
/// <param name="isPassword">
/// True if this should be used to enter a password.
/// </param>
public MojoEntryElement (string caption, string placeholder, string value, bool isPassword) : base (caption)
{
Value = value;
this.isPassword = isPassword;
this.placeholder = placeholder;
}
public override string Summary ()
{
return Value;
}
protected virtual UITextField CreateTextField (RectangleF frame)
{
return new UITextField (frame) {
AutoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleLeftMargin,
Placeholder = placeholder ?? "",
SecureTextEntry = isPassword,
Text = Value ?? "",
Tag = 1
};
}
static NSString cellkey = new NSString ("MojoEntryElement");
protected override NSString CellKey {
get {
return cellkey;
}
}
public override UITableViewCell GetCell (UITableView tv)
{
var cell = tv.DequeueReusableCell (cellkey);
if (cell == null) {
cell = new UITableViewCell (UITableViewCellStyle.Default, cellkey);
cell.SelectionStyle = UITableViewCellSelectionStyle.None;
SizeF captionSize = new SizeF (0, 0);
captionSize = cell.TextLabel.StringSize (Caption, UIFont.FromName (cell.TextLabel.Font.Name, UIFont.LabelFontSize + 1));
captionSize.Width += 20;
float yOffset = (cell.ContentView.Bounds.Height - captionSize.Height) / 2 - 1;
float width = cell.ContentView.Bounds.Width - captionSize.Width;
entry = CreateTextField (new RectangleF (cell.ContentView.Bounds.Width - width, yOffset, width, captionSize.Height));
entry.TextAlignment = UITextAlignment.Right;
entry.BackgroundColor = UIColor.Red;
entry.ValueChanged += delegate {
FetchValue ();
};
entry.Ended += delegate {
FetchValue ();
};
entry.ShouldReturn += delegate {
if (ShouldReturn != null)
return ShouldReturn ();
RootElement root = GetImmediateRootElement ();
MojoEntryElement focus = null;
if (root == null)
return true;
foreach (var s in root.Sections) {
foreach (var e in s.Elements) {
if (e == this) {
focus = this;
} else if (focus != null && e is MojoEntryElement) {
focus = e as MojoEntryElement;
break;
}
}
if (focus != null && focus != this)
break;
}
if (focus != this)
focus.BecomeFirstResponder (true);
else
focus.ResignFirstResponder (true);
return true;
};
entry.Started += delegate {
MojoEntryElement self = null;
if (!returnKeyType.HasValue) {
var returnType = UIReturnKeyType.Default;
foreach (var e in (Parent as Section).Elements) {
if (e == this)
self = this;
else if (self != null && e is MojoEntryElement)
returnType = UIReturnKeyType.Next;
}
entry.ReturnKeyType = returnType;
} else
entry.ReturnKeyType = returnKeyType.Value;
};
if (becomeResponder) {
entry.BecomeFirstResponder ();
becomeResponder = false;
}
entry.KeyboardType = KeyboardType;
entry.AutocapitalizationType = AutocapitalizationType;
entry.AutocorrectionType = AutocorrectionType;
entry.Tag = 101;
cell.ContentView.AddSubview (entry);
} else {
entry = cell.ContentView.ViewWithTag (101) as UITextField;
Console.WriteLine (entry);
}
cell.TextLabel.Text = Caption;
Layout (cell);
return cell;
}
void Layout (UITableViewCell cell)
{
SizeF captionSize = new SizeF (0, 0);
captionSize = cell.TextLabel.StringSize (Caption, UIFont.FromName (cell.TextLabel.Font.Name, UIFont.LabelFontSize + 1));
captionSize.Width += 20;
float yOffset = (cell.ContentView.Bounds.Height - captionSize.Height) / 2 - 1;
float width = cell.ContentView.Bounds.Width - captionSize.Width;
entry.Frame = new RectangleF (cell.ContentView.Bounds.Width - width, yOffset, width, captionSize.Height);
Console.WriteLine (entry.Frame);
}
/// <summary>
/// Copies the value from the UITextField in the EntryElement to the
// Value property and raises the Changed event if necessary.
/// </summary>
public void FetchValue ()
{
if (entry == null)
return;
var newValue = entry.Text;
if (newValue == Value)
return;
Value = newValue;
if (Changed != null)
Changed (this, EventArgs.Empty);
}
protected override void Dispose (bool disposing)
{
if (disposing) {
if (entry != null) {
entry.Dispose ();
entry = null;
}
}
}
public override bool Matches (string text)
{
return (Value != null ? Value.IndexOf (text, StringComparison.CurrentCultureIgnoreCase) != -1 : false) || base.Matches (text);
}
/// <summary>
/// Makes this cell the first responder (get the focus)
/// </summary>
/// <param name="animated">
/// Whether scrolling to the location of this cell should be animated
/// </param>
public void BecomeFirstResponder (bool animated)
{
becomeResponder = true;
var tv = GetContainerTableView ();
if (tv == null)
return;
tv.ScrollToRow (IndexPath, UITableViewScrollPosition.Middle, animated);
if (entry != null) {
entry.BecomeFirstResponder ();
becomeResponder = false;
}
}
public void ResignFirstResponder (bool animated)
{
becomeResponder = false;
var tv = GetContainerTableView ();
if (tv == null)
return;
tv.ScrollToRow (IndexPath, UITableViewScrollPosition.Middle, animated);
if (entry != null)
entry.ResignFirstResponder ();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment