public TextSuggestionsControl(TextBox Input, int MaxResults, UIElement Unfocus, Canvas Container)
        {
            this.Enabled = true;
            this.Input = Input;
            this.MaxResults = MaxResults;
            this.Unfocus = Unfocus;

            var Results = new List<TextBox>();
            var ResultsLayers = new List<Rectangle>();
            var DataSelectedLastTimeDefault = new Match[0];
            var DataSelectedLastTime = DataSelectedLastTimeDefault;

            Action ClearResults =
                delegate
                {
                    Results.AsEnumerable().Orphanize();
                    Results.Clear();

                    ResultsLayers.AsEnumerable().Orphanize();
                    ResultsLayers.Clear();

                    DataSelectedLastTime = DataSelectedLastTimeDefault;
                };

            var FriendlyFocusChange = false;

            Action<UIElement> SetFriendlyFocus =
                e =>
                {
                    FriendlyFocusChange = true;
                    e.Focus();
                    FriendlyFocusChange = false;
                };

            Action CancelExitDefault = delegate { };
            Action CancelExit = CancelExitDefault;

            Action<Rectangle, TextBox> DefaultActivate =
                (r_Below, r) =>
                {
                    if (!DisableColorChange)
                    {
                        r_Below.Fill = this.ActiveResultBackground;
                        r.Foreground = this.ActiveResultForeground;
                    }

                    if (this.Activate != null)
                        this.Activate(r_Below, r);
                };

            Action<Rectangle, TextBox> DefaultDeactivate =
                (r_Below, r) =>
                {
                    if (!DisableColorChange)
                    {
                        r_Below.Fill = this.InactiveResultBackground;
                        r.Foreground = this.InactiveResultForeground;
                    }

                    if (this.Deactivate != null)
                        this.Deactivate(r_Below, r);
                };

            Action CancelUpdateDelayDefault = delegate { };
            Action CancelUpdateDelay = CancelUpdateDelayDefault;

            Action StartExit =
                delegate
                {
                    if (!FriendlyFocusChange)
                    {
                        CancelExit = 100.AtDelay(
                            delegate
                            {
                                CancelExit = CancelExitDefault;

                                CancelUpdateDelayDefault();
                                ClearResults();

                                if (this.Exit != null)
                                    this.Exit();
                            }
                        ).Stop;

                    }
                };


            Action<TextBox> ApplyFocusKeys =
                e =>
                {
                    e.KeyUp +=
                        (sender, ev) =>
                        {
                            if (!this.Enabled)
                                return;

                            if (ev.Key == Key.Escape)
                            {
                                Unfocus.Focus();
                                return;
                            }


                            if (ev.Key == Key.Down)
                            {
                                FriendlyFocusChange = true;

                                if (Results.Count > 0)
                                    if (e == Input)
                                        Results.First().Focus();
                                    else if (e == Results.Last())
                                        Input.Focus();
                                    else
                                        Results.Next(k => k == e).Focus();

                                FriendlyFocusChange = false;

                            }
                            else if (ev.Key == Key.Up)
                            {
                                FriendlyFocusChange = true;

                                if (Results.Count > 0)
                                    if (e == Input)
                                        Results.Last().Focus();
                                    else if (e == Results.First())
                                        Input.Focus();
                                    else
                                        Results.Previous(k => k == e).Focus();

                                FriendlyFocusChange = false;
                            }
                        };
                };


            var Update = default(Action);

            var t_HasFocus = false;

            Input.GotFocus +=
                delegate
                {
                    if (!this.Enabled)
                    {
                        if (UnfocusWhenDisabled)
                            Unfocus.Focus();

                        return;
                    }

                    CancelExit();

                    t_HasFocus = true;

                    //Input.Background = Brushes.White;
                    //Input.Foreground = Brushes.Black;



                    if (!FriendlyFocusChange)
                    {
                        Update();
                    }

                    if (this.Enter != null)
                        this.Enter();
                };

            Input.LostFocus +=
                (sender, ev) =>
                {
                    if (!this.Enabled)
                        return;

                    t_HasFocus = false;

                    //Input.Background = Brushes.Black;
                    //Input.Foreground = Brushes.White;

                    StartExit();
                };



            Update =
                delegate
                {
                    var Filter = Input.Text.ToLower();
                    var DataSelected = GetDataSelected(Filter);

                    if (DataSelectedLastTime.Length == DataSelected.Length)
                    {
                        var skip = true;

                        for (int i = 0; i < DataSelected.Length; i++)
                        {
                            if (DataSelected[i].Data != DataSelectedLastTime[i].Data)
                            {
                                skip = false;
                                break;
                            }
                        }

                        if (skip)
                            return;
                    }

                    ClearResults();

                    DataSelected.ForEach(
                        (Match Entry, int Index) =>
                        {
                            Action SelectEntry =
                                delegate
                                {
                                    Input.Text = Entry.Data;

                                    Unfocus.Focus();

                                    if (Select != null)
                                        Select(Input.Text);
                                };

                            var r_Margin = this.Margin;

                            var x = Canvas.GetLeft(Input);
                            var y = Canvas.GetTop(Input) + (Index + 1) * (Input.Height + r_Margin * 2);

                            var r_Below = new Rectangle
                            {
                                Fill = this.InactiveResultBackground,
                                Width = Input.Width,
                                Height = Input.Height + r_Margin * 2,
                            }.MoveTo(x, y - r_Margin).AttachTo(Container);

                            ResultsLayers.Add(r_Below);

                            var r = new TextBox
                            {
                                Text = Entry.Data,
                                Width = Input.Width - r_Margin * 2,
                                Height = Input.Height,
                                IsReadOnly = true,
                                BorderThickness = new Thickness(0),
                                Background = Brushes.Transparent,
                                TextAlignment = Input.TextAlignment
                            }.MoveTo(x + r_Margin, y).AttachTo(Container);

                            var r_Above = new Rectangle
                            {
                                Fill = Brushes.Red,
                                Opacity = 0,
                                Cursor = Cursors.Hand,
                                Width = Input.Width,
                                Height = Input.Height + r_Margin * 2,
                            }.MoveTo(x, y - r_Margin).AttachTo(Container);

                            ResultsLayers.Add(r_Above);

                            var HasFocus = false;
                            var HasMouse = false;

                            r.GotFocus +=
                                delegate
                                {
                                    if (t_HasFocus)
                                        return;

                                    HasFocus = true;

                                    CancelExit();

                                    DefaultActivate(r_Below, r);

                                    if (!FriendlyFocusChange)
                                    {

                                        SelectEntry();
                                    }



                                };

                            r.LostFocus +=
                                delegate
                                {
                                    HasFocus = false;

                                    if (!HasMouse)
                                    {
                                        DefaultDeactivate(r_Below, r);

                                    }

                                    StartExit();
                                };

                            r_Above.MouseLeftButtonDown +=
                                delegate
                                {
                                    CancelExit();
                                    r.Focus();
                                };

                            r_Above.MouseEnter +=
                                delegate
                                {
                                    HasMouse = true;

                                    if (HasFocus)
                                        return;

                                    DefaultActivate(r_Below, r);

                                };

                            r_Above.MouseLeave +=
                                delegate
                                {
                                    HasMouse = false;

                                    if (HasFocus)
                                        return;

                                    DefaultDeactivate(r_Below, r);
                                };


                            r.KeyUp +=
                                (sender, ev) =>
                                {
                                    if (ev.Key == Key.Left)
                                    {
                                        if (r == Results.First())
                                            SetFriendlyFocus(Input);
                                        else
                                            SetFriendlyFocus(Results.First());

                                    }
                                    else if (ev.Key == Key.Right)
                                    {
                                        if (r == Results.Last())
                                            SetFriendlyFocus(Input);
                                        else
                                            SetFriendlyFocus(Results.Last());

                                    }
                                    else if (ev.Key == Key.Enter)
                                    {
                                        SelectEntry();
                                    }
                                    else
                                    {
                                        SetFriendlyFocus(Input);

                                    }
                                };


                            ApplyFocusKeys(r);

                            Results.Add(r);
                        }
                    );
                };



            ApplyFocusKeys(Input);

            #region Search Exit by Enter


            Input.KeyUp +=
                (sender, ev) =>
                {
                    if (!this.Enabled)
                        return;

                    #region Handeled by ApplyFocusKeys
                    if (ev.Key == Key.Up)
                        return;

                    if (ev.Key == Key.Down)
                        return;

                    if (ev.Key == Key.Left)
                        return;

                    if (ev.Key == Key.Right)
                        return;

                    if (ev.Key == Key.Escape)
                        return;
                    #endregion

                    if (ev.Key == Key.Enter)
                    {
                        Unfocus.Focus();

                        if (Select != null)
                            Select(Input.Text);

                        return;
                    }

                    CancelUpdateDelayDefault();
                    CancelUpdateDelay = this.Delay.AtDelay(
                        delegate
                        {
                            Update();
                            CancelUpdateDelay = CancelUpdateDelayDefault;
                        }
                    ).Stop;
                };
            #endregion

        }
Example #2
0
        public void Initialize()
        {
            Native.Document.body.style.padding = "0";
            Native.Document.body.style.margin = "0";

            var Images = new Dictionary<string, IHTMLImage>();
            var ImagesLoaded = default(Action);
            Func<string, IHTMLImage> CloneImage = name => (IHTMLImage)Images[name].cloneNode(false);

            var Zoom = Data.Zoom.ToDouble();

            var ControlSize = new ZoomedPoint
            {
                Z = Zoom,
                X = Data.ControlSize.Xint,
                Y = Data.ControlSize.Yint
            };

            Control.style.SetSize(ControlSize.ZoomedXint, ControlSize.ZoomedYint);
            Control.style.backgroundColor = Data.BackgroundColor;
            Control.style.color = Data.TextColor;
            Control.AttachAsNextOrToDocument(null);
            Control.style.position = IStyle.PositionEnum.relative;

            Action LoadImages =
                delegate
                {
                    Data.Sprites.ForEach(
                        i =>
                        {
                            Images[i.Value] = i.ImageValue;
                        }
                    );

                    ImagesLoaded();
                };

            ImagesLoaded =
                delegate
                {
                    var ClientRectPos = new ZoomedPoint
                    {
                        Z = Zoom,
                        X = Data.ClientRect.From.Xint,
                        Y = Data.ClientRect.From.Yint
                    };

                    var ClientRectSize = new ZoomedPoint
                    {
                        Z = Zoom,
                        X = Data.ClientRect.Size.Xint,
                        Y = Data.ClientRect.Size.Yint
                    };

                    var ContentLayer = new IHTMLDiv();

                    ContentLayer.style.backgroundColor = Data.ClientRectColor;
                    ContentLayer.style.overflow = IStyle.OverflowEnum.hidden;

                    ContentLayer.style.SetLocation(
                        ClientRectPos.ZoomedXint,
                        ClientRectPos.ZoomedYint,
                        ClientRectSize.ZoomedXint,
                        ClientRectSize.ZoomedYint
                        );
                    ContentLayer.AttachTo(Control);


                    //var r1 = CloneImage("room 001").AttachTo(ContentLayer);

                    //r1.style.SetLocation(0, 0, ClientRectSize.ZoomedXint, ClientRectSize.ZoomedYint);

                    Func<string, IHTMLImage> CreateRoomImage =
                        name =>
                        {
                            var r2 = CloneImage(name);
                            
                            r2.AttachTo(ContentLayer);

                            var r2_Zoom = new ZoomedPoint
                            {
                                Z = Zoom,
                                X = Images[name].width,
                                Y = Images[name].height
                            };

                            r2.Hide();
                            r2.style.SetLocation(0, 0, r2_Zoom.ZoomedXint, r2_Zoom.ZoomedYint);

                            return r2;
                        };

                    var KnownRooms = new List<IHTMLImage>();

                    KnownRooms.AddRange(
                        new [] 
                        {
                            CreateRoomImage("room 001"),
                            CreateRoomImage("room 002"),
                            CreateRoomImage("room 024"),
                            CreateRoomImage("room 031"),
                            CreateRoomImage("room 032"),
                        }
                    );

                    var CurrentRoom = KnownRooms.Random();

                    CurrentRoom.Show();

                    Action<double> SetClipTo =
                        percentage =>
                        {
                            var x = (ClientRectSize.ZoomedX * percentage / 2).ToInt32();
                            var y = (ClientRectSize.ZoomedY * percentage / 2).ToInt32();

                            var clip = new CSSClip
                            {
                                Left = x,
                                Top = y,
                                Right = (ClientRectSize.ZoomedX - x).ToInt32(),
                                Bottom = (ClientRectSize.ZoomedY - y).ToInt32()
                            };

                            Console.WriteLine(percentage + " clip: " + clip);

                            ContentLayer.style.clip = clip;

                        };

                    //ContentLayer.style.clip = "rect(15px auto auto 15px)";

                    //var timer = new ScriptCoreLib.JavaScript.Runtime.Timer(
                    //    delegate
                    //    {
                    //        var p = (Math.Sin(DateTime.Now.Ticks) + 1) / 2;

                    //        Console.WriteLine("p: " + p);
                    //        SetClipTo(p);
                    //    }
                    //    , 0, 200);

                    //var pc = 50;
                    //var px = 200;

                    //Action<double> pChange = i => { px += (i * pc).ToInt32(); timer.StartInterval(px); };

                    Action<Action, Action> FadeOut =
                        (Starting, Stopping) =>
                            new LinearTimeTween
                            {
                                Length = 300,
                                Starting = Starting,
                                Stopping = Stopping,
                                Changed = t => SetClipTo(t),
                                Percision = 20
                            }.Start();

                    Action<Action, Action> FadeIn =
                                  (Starting, Stopping) =>
                                      new LinearTimeTween
                                      {
                                          Length = 300,
                                          Starting = Starting,
                                          Stopping = Stopping,
                                          Changed = t => SetClipTo(1d - t),
                                          Percision = 20
                                      }.Start();

                    var kbd = new KeyboardEvents { Enabled = true };

                    kbd.left += ev =>
                        FadeOut(
                            () => kbd.Enabled = false,
                            () =>
                            {
                                CurrentRoom.Hide();
                                CurrentRoom = KnownRooms.Previous(i => CurrentRoom == i);
                                CurrentRoom.Show();

                                //r1.Hide();
                                //r2.Show();

                                FadeIn(null, () => kbd.Enabled = true);
                            }
                        );

                    kbd.right += ev =>
                         FadeOut(
                            () => kbd.Enabled = false,
                            () =>
                            {
                                CurrentRoom.Hide();
                                CurrentRoom = KnownRooms.Next(i => CurrentRoom == i);
                                CurrentRoom.Show();

                                FadeIn(null, () => kbd.Enabled = true);
                            }
                        );


                    Native.Document.onkeydown += kbd;

                    Native.Document.onmousedown +=
                       ev =>
                         FadeOut(
                            () => kbd.Enabled = false,
                            () =>
                            {
                                CurrentRoom.Hide();
                                CurrentRoom = KnownRooms.Next(i => CurrentRoom == i);
                                CurrentRoom.Show();

                                FadeIn(null, () => kbd.Enabled = true);
                            }
                        );

                    /*
                    var div1 = SpawnDiv(Images, false);

                    div1.style.backgroundColor = Color.Yellow;
                    div1.AttachTo(ClientRect);
                    div1.style.SetLocation(4, 4, 100, 100);

                    var div2 = SpawnDiv(Images, true);

                    div2.style.backgroundColor = Color.Gray;
                    div2.AttachTo(ClientRect);
                    div2.style.SetLocation(100, 4, 100, 100);

                    */

                };

            LoadImages();
        }
		public TextSuggestionsCanvas()
		{
			Width = DefaultWidth;
			Height = DefaultHeight;

			#region Gradient
			for (int i = 0; i < DefaultHeight; i += 4)
			{
				var green = (int)(128 * i / DefaultHeight) << 8;

				new Rectangle
				{
					Fill = ((uint)(0xff007F00 + green)).ToSolidColorBrush(),
					Width = DefaultWidth,
					Height = 4,
				}.MoveTo(0, i).AttachTo(this);
			}
			#endregion

			var t = new TextBox
			{
				Width = 200,
				Height = 22,
				Text = "we",
				BorderThickness = new Thickness(0)

			}.MoveTo(32, 32).AttachTo(this);

			var t_Unfocus = new TextBox
			{
				Width = 200,
				Height = 22,
				Text = "powered by jsc",
				BorderThickness = new Thickness(0)

			}.MoveTo(32, 4).AttachTo(this);

			var DataInput =
				@"
Action
Adventure
Animation
Biography
Comedy
Crime
Documentary
Drama
Family
Fantasy
Film-Noir
History
Horror
Independent
Music
Musical
Mystery
Romance
Sci-Fi
Short
Sport
Thriller
TV mini-series
War
Western
	".Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries).Select(k => k.Trim()).WhereNot(string.IsNullOrEmpty);


			Func<string, IEnumerable<string>> Interpolate =
				k => Enumerable.Range(1, 2).Select(i => k + " " + i).ConcatSingle(k)
				//.Concat(DataInput.Select(u => k + " vs " + u))
					;


			var Data = DataInput.SelectMany(Interpolate);






			var MaxResults = 7;
			var Results = new List<TextBox>();
			var ResultsLayers = new List<Rectangle>();
			var DataSelectedLastTimeDefault = new Match[0];
			var DataSelectedLastTime = DataSelectedLastTimeDefault;

			Action ClearResults =
				delegate
				{
					Results.AsEnumerable().Orphanize();
					Results.Clear();

					ResultsLayers.AsEnumerable().Orphanize();
					ResultsLayers.Clear();

					DataSelectedLastTime = DataSelectedLastTimeDefault;
				};

			var FriendlyFocusChange = false;

			Action<TextBox> ApplyFocusKeys =
				e =>
				{
					e.KeyUp +=
						(sender, ev) =>
						{

							if (ev.Key == Key.Down)
							{
								FriendlyFocusChange = true;

								if (Results.Count > 0)
									if (e == t)
										Results.First().Focus();
									else if (e == Results.Last())
										t.Focus();
									else
										Results.Next(k => k == e).Focus();

								FriendlyFocusChange = false;

							}
							else if (ev.Key == Key.Up)
							{
								FriendlyFocusChange = true;

								if (Results.Count > 0)
									if (e == t)
										Results.Last().Focus();
									else if (e == Results.First())
										t.Focus();
									else
										Results.Previous(k => k == e).Focus();

								FriendlyFocusChange = false;
							}
						};
				};

			Action CancelExitDefault = delegate { };
			Action CancelExit = CancelExitDefault;



			Action StartExit =
				delegate
				{
					if (!FriendlyFocusChange)
					{
						CancelExit = 100.AtDelay(
							delegate
							{
								CancelExit = CancelExitDefault;

								ClearResults();
							}
						).Stop;

					}
				};

			var Update = default(Action);

			var t_HasFocus = false;

			t.GotFocus +=
				delegate
				{
					CancelExit();

					t_HasFocus = true;

					t.Background = Brushes.White;
					t.Foreground = Brushes.Black;

					Console.WriteLine("t got focus");


					if (!FriendlyFocusChange)
					{
						Update();
					}


				};

			t.LostFocus +=
				(sender, ev) =>
				{

					t_HasFocus = false;

					t.Background = Brushes.Black;
					t.Foreground = Brushes.White;


					// to whome we lost focus?
					Console.WriteLine("t lost focus");

					StartExit();
				};



			Update =
				delegate
				{
					var Filter = t.Text.ToLower();
					var DataSelected = GetDataSelected(Data, MaxResults, Filter);

					if (DataSelectedLastTime.Length == DataSelected.Length)
					{
						var skip = true;

						for (int i = 0; i < DataSelected.Length; i++)
						{
							if (DataSelected[i].Data != DataSelectedLastTime[i].Data)
							{
								skip = false;
								break;
							}
						}

						if (skip)
							return;
					}

					ClearResults();

					DataSelected.ForEach(
						(Entry, Index) =>
						{
							Action SelectEntry =
								delegate
								{
									Console.WriteLine("select " + Entry);
									t.Text = Entry.Data;

									t_Unfocus.Focus();
								};

							var r_Margin = 4;
							var r_Below = new Rectangle
							{
								Fill = Brushes.White,
								Width = 200 + r_Margin * 2,
								Height = 24 + r_Margin * 2,
							}.MoveTo(64 - r_Margin, 64 + Index * 30 - r_Margin).AttachTo(this);

							ResultsLayers.Add(r_Below);

							var r = new TextBox
							{
								Text = Entry.Data,
								Width = 200,
								Height = 24,
								IsReadOnly = true,
								BorderThickness = new Thickness(0),
								Background = Brushes.Transparent
							}.MoveTo(64, 64 + Index * 30).AttachTo(this);

							var r_Above = new Rectangle
							{
								Fill = Brushes.Red,
								Opacity = 0,
								Cursor = Cursors.Hand,
								Width = 200 + r_Margin * 2,
								Height = 24 + r_Margin * 2,
							}.MoveTo(64 - r_Margin, 64 + Index * 30 - r_Margin).AttachTo(this);

							ResultsLayers.Add(r_Above);

							var HasFocus = false;
							var HasMouse = false;

							r.GotFocus +=
								delegate
								{
									if (t_HasFocus)
										return;

									HasFocus = true;

									CancelExit();

									Console.WriteLine("r got focus - " + Entry);

									r_Below.Fill = Brushes.Blue;
									if (Entry.Weight == 0)
										r.Foreground = Brushes.Gray;
									else
										r.Foreground = Brushes.White;

									if (!FriendlyFocusChange)
									{

										SelectEntry();
									}



								};

							r.LostFocus +=
								delegate
								{
									HasFocus = false;

									if (!HasMouse)
									{
										r_Below.Fill = Brushes.Yellow;
										if (Entry.Weight == 0)
											r.Foreground = Brushes.Gray;
										else
											r.Foreground = Brushes.Black;
									}

									StartExit();
								};

							r_Above.MouseLeftButtonDown +=
								delegate
								{
									CancelExit();
									r.Focus();
								};

							r_Above.MouseEnter +=
								delegate
								{
									HasMouse = true;

									if (HasFocus)
										return;

									r_Below.Fill = Brushes.Blue;

									if (Entry.Weight == 0)
										r.Foreground = Brushes.Gray;
									else
										r.Foreground = Brushes.White;
								};

							r_Above.MouseLeave +=
								delegate
								{
									HasMouse = false;

									if (HasFocus)
										return;

									r_Below.Fill = Brushes.White;

									if (Entry.Weight == 0)
										r.Foreground = Brushes.Gray;
									else
										r.Foreground = Brushes.Black;
								};


							r.KeyUp +=
								(sender, ev) =>
								{
									if (ev.Key == Key.Left)
									{
										FriendlyFocusChange = true;
										if (r == Results.First())
											t.Focus();
										else
											Results.First().Focus();
										FriendlyFocusChange = false;

									}
									else if (ev.Key == Key.Right)
									{
										FriendlyFocusChange = true;
										if (r == Results.Last())
											t.Focus();
										else
											Results.Last().Focus();
										FriendlyFocusChange = false;

									}
									else if (ev.Key == Key.Enter)
									{
										SelectEntry();
									}
									else
									{
										FriendlyFocusChange = true;
										t.Focus();
										FriendlyFocusChange = false;

									}
								};


							ApplyFocusKeys(r);

							Results.Add(r);
						}
					);
				};



			ApplyFocusKeys(t);



			t.Background = Brushes.Black;
			t.Foreground = Brushes.White;


			t_Unfocus.GotFocus +=
						delegate
						{
							t_Unfocus.Background = Brushes.White;
							t_Unfocus.Foreground = Brushes.Black;
						};

			t_Unfocus.LostFocus +=
				delegate
				{
					t_Unfocus.Background = Brushes.Black;
					t_Unfocus.Foreground = Brushes.White;
				};

			t_Unfocus.Background = Brushes.Black;
			t_Unfocus.Foreground = Brushes.White;

			Action CancelUpdateDelayDefault = delegate { };
			Action CancelUpdateDelay = CancelUpdateDelayDefault;

			t.KeyUp +=
				(sender, ev) =>
				{
					if (ev.Key == Key.Up)
						return;

					if (ev.Key == Key.Down)
						return;

					if (ev.Key == Key.Left)
						return;

					if (ev.Key == Key.Right)
						return;

					if (ev.Key == Key.Enter)
					{
						t_Unfocus.Focus();
						return;
					}

					CancelUpdateDelayDefault();
					CancelUpdateDelay = 300.AtDelay(
						delegate
						{
							Update();
							CancelUpdateDelay = CancelUpdateDelayDefault;
						}
					).Stop;
				};


		}