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);
+ }
}
}
}