diff --git a/TBO/TBO.csproj b/TBO/TBO.csproj index d5e359c..9073526 100644 --- a/TBO/TBO.csproj +++ b/TBO/TBO.csproj @@ -62,6 +62,7 @@ + diff --git a/TBO/UI/Shell.cs b/TBO/UI/Shell.cs index 81c3af3..138d8bd 100644 --- a/TBO/UI/Shell.cs +++ b/TBO/UI/Shell.cs @@ -1,5 +1,7 @@ using System.Collections.Generic; using System.Drawing; +using System.Drawing.Drawing2D; +using System.Drawing.Text; using TBO.UI.tboTK; namespace TBO.UI @@ -13,7 +15,9 @@ private static Size size; public delegate void InvalidateDelegate(); + public delegate void InvalidateRegionDelegate(Rectangle r); public static InvalidateDelegate Invalidate; + public static InvalidateRegionDelegate InvalidateRegion; static Shell() { @@ -52,8 +56,17 @@ g.Clear(bgColor); g.DrawImage(bgImage, 0, 0); + g.SmoothingMode = SmoothingMode.AntiAlias; + g.TextRenderingHint = TextRenderingHint.AntiAliasGridFit; + g.InterpolationMode = InterpolationMode.High; + // Compose application - current?.Paint(g,clip); + current?.Paint(g, clip); + } + + public static void NotifyMousePos(int x, int y) + { + Control c = current?.Get(x, y, true); } public static Size Size { get => size; set => SetSize(value); } diff --git a/TBO/UI/Windows/Reader.Designer.cs b/TBO/UI/Windows/Reader.Designer.cs index d87fa5e..3db8a4c 100644 --- a/TBO/UI/Windows/Reader.Designer.cs +++ b/TBO/UI/Windows/Reader.Designer.cs @@ -43,6 +43,7 @@ this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; this.Text = "TBO"; this.Paint += new System.Windows.Forms.PaintEventHandler(this.Reader_Paint); + this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.Reader_MouseMove); this.Resize += new System.EventHandler(this.Reader_Resize); this.ResumeLayout(false); diff --git a/TBO/UI/Windows/Reader.cs b/TBO/UI/Windows/Reader.cs index aed9484..0c4f9da 100644 --- a/TBO/UI/Windows/Reader.cs +++ b/TBO/UI/Windows/Reader.cs @@ -14,6 +14,7 @@ { InitializeComponent(); Shell.Invalidate = ShellInvalidate; + Shell.InvalidateRegion = ShellInvalidateRegion; SwapFullScreen(); if (path != null) LoadTBO(path); @@ -27,6 +28,11 @@ Invalidate(); } + private void ShellInvalidateRegion(Rectangle r) + { + Invalidate(r); + } + private void ShowLibrary() { Shell.GoTo(ApplicationLibrary.ApplicationId); @@ -100,5 +106,10 @@ { Shell.Size = ClientSize; } + + private void Reader_MouseMove(object sender, MouseEventArgs e) + { + Shell.NotifyMousePos(e.X, e.Y); + } } } diff --git a/TBO/UI/tboTK/Application.cs b/TBO/UI/tboTK/Application.cs index 577fbc1..efee5fc 100644 --- a/TBO/UI/tboTK/Application.cs +++ b/TBO/UI/tboTK/Application.cs @@ -31,6 +31,23 @@ return null; } + public Control Get(int x, int y, bool deep = false) + { + Control result = null; + foreach (Control c in controls.Values) + { + if (c.Bounds.Contains(x, y)) + result = c; + } + if (deep && (result is IContiner)) + { + Control sub = ((IContiner)result).Get(x, y, deep); + if (sub != null) + result = sub; + } + return result; + } + public bool Remove(string id) { return Remove(Get(id)); diff --git a/TBO/UI/tboTK/Button.cs b/TBO/UI/tboTK/Button.cs index 68df901..82df159 100644 --- a/TBO/UI/tboTK/Button.cs +++ b/TBO/UI/tboTK/Button.cs @@ -4,6 +4,8 @@ { class Button : Control { + bool hover=false; + public Button(string id) : base(id) { Width = 75; @@ -12,7 +14,25 @@ public override void Paint(Graphics g, Rectangle clip) { - g.DrawImageKeepRatio(Image, Left, Top, Width, Height); + g.DrawImageKeepRatioEx(Image, Left, Top, Width, Height, hover ? 1f : 0.5f); + } + + public override void Handle(Event e) + { + base.Handle(e); + if (e.Done) + return; + switch (e.Id) + { + case Event.EventType.MouseEnter: + hover = true; + Invalidate(); + break; + case Event.EventType.MouseLeave: + hover = false; + Invalidate(); + break; + } } public Image Image { get; set; } diff --git a/TBO/UI/tboTK/Control.cs b/TBO/UI/tboTK/Control.cs index 70028f9..e42e282 100644 --- a/TBO/UI/tboTK/Control.cs +++ b/TBO/UI/tboTK/Control.cs @@ -1,14 +1,13 @@ -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Linq; -using System.Text; +using System.Drawing; namespace TBO.UI.tboTK { abstract class Control { - + public delegate void EventDelegate(Control c, Event e); + + public EventDelegate DoEvent; + public Control(string id) { Id = id; @@ -21,6 +20,16 @@ public abstract void Paint(Graphics g, Rectangle clip); + public virtual void Handle(Event e) + { + DoEvent?.Invoke(this, e); + } + + public void Invalidate() + { + Shell.InvalidateRegion(new Rectangle(Left, Top, Width, Height)); + } + public string Id { get; } public int Top { get; set; } public int Left { get; set; } diff --git a/TBO/UI/tboTK/Event.cs b/TBO/UI/tboTK/Event.cs new file mode 100644 index 0000000..ade4abf --- /dev/null +++ b/TBO/UI/tboTK/Event.cs @@ -0,0 +1,71 @@ +using System.Collections.Generic; + +namespace TBO.UI.tboTK +{ + class Event + { + public enum EventType + { + MouseEnter, + MouseLeave, + Click, + Scroll, + } + + public enum EventParam + { + Delta, + } + + #region Constructors + + public static Event AtMouseEnter() + { + return new Event(EventType.MouseEnter); + } + + public static Event AtMouseLeave() + { + return new Event(EventType.MouseLeave); + } + + public static Event AtClick() + { + return new Event(EventType.Click); + } + + public static Event AtScroll(int delta) + { + return new Event(EventType.Scroll).Set(EventParam.Delta, delta); + } + + #endregion + + private Dictionary data; + + private Event(EventType id) + { + Id = id; + } + + private Event Set(EventParam par, object value) + { + if (data == null) + data = new Dictionary(); + data[par] = value; + return this; + } + + private object Get(EventParam par) + { + object o; + if (data.TryGetValue(par, out o)) + return o; + return null; + } + + public EventType Id { get; } + public object this[EventParam par] => Get(par); + public bool Done { get; set; } + } +} diff --git a/TBO/UI/tboTK/IContiner.cs b/TBO/UI/tboTK/IContiner.cs index b6a33e5..d227200 100644 --- a/TBO/UI/tboTK/IContiner.cs +++ b/TBO/UI/tboTK/IContiner.cs @@ -4,6 +4,7 @@ { bool Add(Control c); Control Get(string id, bool deep = false); + Control Get(int x, int y, bool deep = false); bool Remove(string id); bool Remove(Control c); } diff --git a/TBO/UI/tboTK/Panel.cs b/TBO/UI/tboTK/Panel.cs index 484a4b1..2178e7f 100644 --- a/TBO/UI/tboTK/Panel.cs +++ b/TBO/UI/tboTK/Panel.cs @@ -35,6 +35,23 @@ return null; } + public Control Get(int x, int y, bool deep = false) + { + Control result = null; + foreach (Control c in controls.Values) + { + if (c.Bounds.Contains(x, y)) + result = c; + } + if (deep && (result is IContiner)) + { + Control sub = ((IContiner)result).Get(x, y, deep); + if (sub != null) + result = sub; + } + return result; + } + public bool Remove(string id) { return Remove(Get(id)); diff --git a/TBO/UI/tboTK/UIExtension.cs b/TBO/UI/tboTK/UIExtension.cs index c4e2631..98da41e 100644 --- a/TBO/UI/tboTK/UIExtension.cs +++ b/TBO/UI/tboTK/UIExtension.cs @@ -1,11 +1,14 @@ using System.Drawing; +using System.Drawing.Imaging; namespace TBO.UI.tboTK { static class UIExtension { - public static void DrawImageKeepRatio(this Graphics g, Image i, int x, int y, int width, int height) + public static void DrawImageKeepRatioEx(this Graphics g, Image i, int x, int y, int width, int height, float opacity = 1.0f) { + if (opacity == 0f) + return; int ww, hh, xx, yy; xx = 0; ww = width; @@ -19,7 +22,17 @@ } else yy = (height - hh) / 2; - g.DrawImage(i, x + xx, y + yy, ww, hh); + Rectangle dst = new Rectangle(x + xx, y + yy, ww, hh); + if (opacity >= 1.0f || opacity < 0f) + g.DrawImage(i, dst); + else + { + //Draw with alpha + ColorMatrix matrix = new ColorMatrix() { Matrix33 = opacity }; + ImageAttributes attributes = new ImageAttributes(); + attributes.SetColorMatrix(matrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap); + g.DrawImage(i, dst, 0, 0, i.Width, i.Height, GraphicsUnit.Pixel, attributes); + } } } }