2009-07-21 05:51:13 +00:00
|
|
|
|
|
|
|
|
|
#region ================== Copyright (c) 2007 Pascal vd Heiden
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Copyright (c) 2007 Pascal vd Heiden, www.codeimp.com
|
|
|
|
|
* This program is released under GNU General Public License
|
|
|
|
|
*
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region ================== Namespaces
|
|
|
|
|
|
|
|
|
|
using System;
|
|
|
|
|
using System.Drawing;
|
|
|
|
|
using System.Drawing.Imaging;
|
2009-07-21 13:42:36 +00:00
|
|
|
|
using System.Drawing.Text;
|
2015-08-31 22:06:44 +00:00
|
|
|
|
using System.Windows.Forms;
|
|
|
|
|
using System.Windows.Forms.VisualStyles;
|
2009-07-21 05:51:13 +00:00
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
namespace CodeImp.DoomBuilder.Controls
|
|
|
|
|
{
|
|
|
|
|
internal class DockersTabsControl : TabControl
|
|
|
|
|
{
|
|
|
|
|
#region ================== Constants
|
|
|
|
|
|
2016-04-15 14:24:18 +00:00
|
|
|
|
private const int NOTIFY_BLINK_COUNT = 8; //mxd
|
|
|
|
|
|
2009-07-21 05:51:13 +00:00
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region ================== Variables
|
2009-08-21 08:37:02 +00:00
|
|
|
|
|
2009-07-21 13:42:36 +00:00
|
|
|
|
private int highlighttab;
|
2015-08-31 22:06:44 +00:00
|
|
|
|
private readonly StringFormat stringformat;
|
2016-04-15 14:24:18 +00:00
|
|
|
|
|
|
|
|
|
//mxd. Tab notify anmimation
|
|
|
|
|
private int notifytab;
|
|
|
|
|
private int notifycounter;
|
|
|
|
|
private Timer notifytimer;
|
2009-07-21 13:42:36 +00:00
|
|
|
|
|
2009-07-21 05:51:13 +00:00
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region ================== Constructor
|
|
|
|
|
|
|
|
|
|
// Constructor
|
|
|
|
|
public DockersTabsControl()
|
|
|
|
|
{
|
|
|
|
|
if(VisualStyleInformation.IsSupportedByOS && VisualStyleInformation.IsEnabledByUser)
|
|
|
|
|
{
|
2009-07-21 13:42:36 +00:00
|
|
|
|
// Style settings
|
2015-08-31 22:06:44 +00:00
|
|
|
|
this.SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.DoubleBuffer, true);
|
|
|
|
|
this.DrawMode = TabDrawMode.OwnerDrawFixed;
|
2009-07-21 05:51:13 +00:00
|
|
|
|
}
|
2009-07-21 13:42:36 +00:00
|
|
|
|
|
2015-08-31 22:06:44 +00:00
|
|
|
|
stringformat = new StringFormat {Alignment = StringAlignment.Center, HotkeyPrefix = HotkeyPrefix.None, LineAlignment = StringAlignment.Center};
|
2009-07-21 13:42:36 +00:00
|
|
|
|
highlighttab = -1;
|
2016-04-15 14:24:18 +00:00
|
|
|
|
|
|
|
|
|
//mxd. Tab notify anmimation
|
|
|
|
|
notifytimer = new Timer { Interval = 500 };
|
|
|
|
|
notifytimer.Tick += NotifyTimerOnTick;
|
2009-07-21 05:51:13 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region ================== Methods
|
2015-08-31 22:06:44 +00:00
|
|
|
|
|
2016-04-15 14:24:18 +00:00
|
|
|
|
//mxd. Start notify animation
|
|
|
|
|
internal void PlayNotifyAnimation(int tabindex)
|
|
|
|
|
{
|
|
|
|
|
notifytab = tabindex;
|
|
|
|
|
notifycounter = 1;
|
|
|
|
|
notifytimer.Start();
|
|
|
|
|
}
|
|
|
|
|
|
2015-08-31 22:06:44 +00:00
|
|
|
|
//mxd
|
|
|
|
|
private void DrawTab(Graphics graphics, int index)
|
2009-07-21 05:51:13 +00:00
|
|
|
|
{
|
2015-08-31 22:06:44 +00:00
|
|
|
|
Rectangle bounds = this.GetTabRect(index);
|
|
|
|
|
VisualStyleRenderer renderer;
|
|
|
|
|
bool selected = (index == this.SelectedIndex);
|
|
|
|
|
|
|
|
|
|
// Transform bounds?
|
|
|
|
|
switch(this.Alignment)
|
2009-07-21 13:42:36 +00:00
|
|
|
|
{
|
2015-08-31 22:06:44 +00:00
|
|
|
|
case TabAlignment.Right:
|
|
|
|
|
bounds = new Rectangle((selected ? bounds.X - 1 : bounds.X + 1), bounds.Y, bounds.Height, bounds.Width);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case TabAlignment.Left:
|
|
|
|
|
bounds = new Rectangle(bounds.X, bounds.Y, bounds.Height, bounds.Width);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
if(selected) bounds.Y -= 2;
|
|
|
|
|
break;
|
2009-07-21 13:42:36 +00:00
|
|
|
|
}
|
2015-08-31 22:06:44 +00:00
|
|
|
|
|
|
|
|
|
if(selected)
|
2009-07-21 05:51:13 +00:00
|
|
|
|
{
|
2015-08-31 22:06:44 +00:00
|
|
|
|
bounds.Height += 2;
|
|
|
|
|
renderer = new VisualStyleRenderer(VisualStyleElement.Tab.TabItem.Pressed);
|
2009-07-21 05:51:13 +00:00
|
|
|
|
}
|
2015-08-31 22:06:44 +00:00
|
|
|
|
else
|
2009-07-21 05:51:13 +00:00
|
|
|
|
{
|
2015-08-31 22:06:44 +00:00
|
|
|
|
renderer = new VisualStyleRenderer(index == highlighttab ? VisualStyleElement.Tab.TabItem.Hot : VisualStyleElement.Tab.TabItem.Normal);
|
|
|
|
|
}
|
Visual mode, UDMF: added "Scale Texture Up (X)", "Scale Texture Down (X)", "Scale Texture Up (Y)", "Scale Texture Down (Y)" actions. Default keys are Num6, Num4, Num8, Num5.
Visual mode, UDMF: renamed "Rotate Thing Clockwise" and "Rotate Thing Counterclockwise" actions to "Rotate Clockwise" and "Rotate Counterclockwise". These actions can now be used to change rotation of floor/ceiling textures.
Visual mode, UDMF: "Reset Texture Offsets" action now also resets sidedef's scale and floor/ceiling's scale and rotation.
Visual mode, UDMF: control line's OffsetX and OffsetY were not taken into account when calculating texture offsets of 3d floors' sides.
Visual mode, UDMF: fixed a ton of bugs in Auto align functions.
Visual mode, UDMF: when using "Move Texture Left/Right/Up/Down by 1" actions texture offsets were not updated properly when texture's scale was < 1.0.
Visual mode, UDMF: OffsetX and OffsetY were not taken into account in "Fit Texture Width/Height" actions.
Dockers Panel: added Pin/Unpin button, which acts the same as "Preferences -> Interface -> Side panels -> Auto hide" checkbox.
Texture size labels can now be disabled by unchecking "Preferences -> Interface -> Show texture and flat sizes in browsers" checkbox.
Texture size labels now are not shown for unknown textures.
Most of texture size labels had incorrect bg color.
ZDoom_linedefs.cfg: action specials 223 and 224 had incorrect Arg0.
2013-06-24 14:21:13 +00:00
|
|
|
|
|
2015-08-31 22:06:44 +00:00
|
|
|
|
Bitmap drawimage = new Bitmap(bounds.Width, bounds.Height, PixelFormat.Format32bppArgb);
|
|
|
|
|
|
|
|
|
|
// Draw tab
|
|
|
|
|
using(Graphics g = Graphics.FromImage(drawimage))
|
|
|
|
|
{
|
|
|
|
|
Rectangle bgbounds = new Rectangle(0, 0, bounds.Width, bounds.Height + 1);
|
|
|
|
|
bgbounds.Inflate(-1, 0);
|
2016-04-15 14:24:18 +00:00
|
|
|
|
|
|
|
|
|
// Use alternate colors on odd numbers
|
|
|
|
|
if(notifytab == index && notifycounter % 2 != 0)
|
|
|
|
|
{
|
|
|
|
|
g.FillRectangle(SystemBrushes.Highlight, bgbounds);
|
|
|
|
|
g.DrawString(this.TabPages[index].Text, this.Font, SystemBrushes.ControlLightLight, new RectangleF(bgbounds.Location, bounds.Size), stringformat);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
renderer.DrawBackground(g, bgbounds);
|
|
|
|
|
g.DrawString(this.TabPages[index].Text, this.Font, SystemBrushes.ControlText, new RectangleF(bgbounds.Location, bounds.Size), stringformat);
|
|
|
|
|
}
|
2009-07-21 05:51:13 +00:00
|
|
|
|
}
|
2015-08-31 22:06:44 +00:00
|
|
|
|
|
|
|
|
|
// Rotate image?
|
|
|
|
|
switch(this.Alignment)
|
|
|
|
|
{
|
|
|
|
|
case TabAlignment.Right:
|
|
|
|
|
drawimage.RotateFlip(RotateFlipType.Rotate270FlipNone);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case TabAlignment.Left:
|
|
|
|
|
drawimage.RotateFlip(RotateFlipType.Rotate90FlipNone);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
graphics.DrawImage(drawimage, bounds.X, bounds.Y);
|
2016-07-02 22:27:20 +00:00
|
|
|
|
drawimage.Dispose();
|
2009-07-21 05:51:13 +00:00
|
|
|
|
}
|
2009-07-21 13:42:36 +00:00
|
|
|
|
|
2009-07-21 05:51:13 +00:00
|
|
|
|
#endregion
|
2009-07-21 13:42:36 +00:00
|
|
|
|
|
2009-07-21 05:51:13 +00:00
|
|
|
|
#region ================== Events
|
2016-04-15 14:24:18 +00:00
|
|
|
|
|
|
|
|
|
//mxd. Stop notify animation if user selects animated tab
|
|
|
|
|
protected override void OnSelectedIndexChanged(EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
// Stop animation
|
|
|
|
|
if(notifytab != -1 && this.SelectedIndex == notifytab)
|
|
|
|
|
{
|
|
|
|
|
notifytimer.Stop();
|
|
|
|
|
notifytab = -1;
|
|
|
|
|
|
|
|
|
|
// Redraw needed?
|
|
|
|
|
if(notifycounter % 2 != 0) this.Invalidate();
|
|
|
|
|
notifycounter = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
base.OnSelectedIndexChanged(e);
|
|
|
|
|
}
|
2009-07-21 13:42:36 +00:00
|
|
|
|
|
2015-08-31 22:06:44 +00:00
|
|
|
|
//mxd. Redrawing needed
|
2009-07-21 05:51:13 +00:00
|
|
|
|
protected override void OnPaint(PaintEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if(VisualStyleInformation.IsSupportedByOS && VisualStyleInformation.IsEnabledByUser)
|
|
|
|
|
{
|
2015-08-31 22:06:44 +00:00
|
|
|
|
// Draw tabs
|
|
|
|
|
for(int i = 0; i < this.TabPages.Count; i++)
|
2009-07-21 05:51:13 +00:00
|
|
|
|
{
|
2015-08-31 22:06:44 +00:00
|
|
|
|
if(i == this.SelectedIndex) continue;
|
|
|
|
|
DrawTab(e.Graphics, i);
|
2009-07-21 05:51:13 +00:00
|
|
|
|
}
|
2015-08-31 22:06:44 +00:00
|
|
|
|
|
|
|
|
|
// Draw selected tab
|
|
|
|
|
if(this.SelectedIndex != -1) DrawTab(e.Graphics, this.SelectedIndex);
|
2009-07-21 05:51:13 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
base.OnPaint(e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2009-07-21 13:42:36 +00:00
|
|
|
|
// Mouse moves
|
|
|
|
|
protected override void OnMouseMove(MouseEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if(VisualStyleInformation.IsSupportedByOS && VisualStyleInformation.IsEnabledByUser)
|
|
|
|
|
{
|
|
|
|
|
int foundindex = -1;
|
|
|
|
|
Rectangle prect = new Rectangle(e.Location, Size.Empty);
|
|
|
|
|
|
|
|
|
|
// Check in which tab the mouse is
|
2009-07-21 18:48:00 +00:00
|
|
|
|
for(int i = this.TabPages.Count - 1; i >= 0; i--)
|
2009-07-21 13:42:36 +00:00
|
|
|
|
{
|
|
|
|
|
Rectangle tabrect = this.GetTabRect(i);
|
2009-07-21 18:48:00 +00:00
|
|
|
|
tabrect.Inflate(1, 1);
|
2009-07-21 13:42:36 +00:00
|
|
|
|
if(tabrect.IntersectsWith(prect))
|
|
|
|
|
{
|
|
|
|
|
foundindex = i;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Redraw?
|
|
|
|
|
if(foundindex != highlighttab)
|
|
|
|
|
{
|
|
|
|
|
highlighttab = foundindex;
|
|
|
|
|
this.Invalidate();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
base.OnMouseMove(e);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Mouse leaves
|
|
|
|
|
protected override void OnMouseLeave(EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if(VisualStyleInformation.IsSupportedByOS && VisualStyleInformation.IsEnabledByUser)
|
|
|
|
|
{
|
|
|
|
|
// Redraw?
|
|
|
|
|
if(highlighttab != -1)
|
|
|
|
|
{
|
|
|
|
|
highlighttab = -1;
|
|
|
|
|
this.Invalidate();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
base.OnMouseLeave(e);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Tabs don't process keys
|
|
|
|
|
protected override void OnKeyDown(KeyEventArgs ke)
|
|
|
|
|
{
|
2016-03-18 12:52:12 +00:00
|
|
|
|
DockersControl docker = this.Parent as DockersControl;
|
|
|
|
|
|
|
|
|
|
// Only absorb the key press when no focused on an input control, otherwise
|
|
|
|
|
// the input controls may not receive certain keys such as delete and arrow keys
|
|
|
|
|
if(docker != null && !docker.IsFocused) ke.Handled = true;
|
2009-07-21 13:42:36 +00:00
|
|
|
|
}
|
2016-03-18 12:52:12 +00:00
|
|
|
|
|
2009-07-21 13:42:36 +00:00
|
|
|
|
// Tabs don't process keys
|
|
|
|
|
protected override void OnKeyUp(KeyEventArgs e)
|
|
|
|
|
{
|
2016-03-18 12:52:12 +00:00
|
|
|
|
DockersControl docker = this.Parent as DockersControl;
|
|
|
|
|
|
|
|
|
|
// Only absorb the key press when no focused on an input control, otherwise
|
|
|
|
|
// the input controls may not receive certain keys such as delete and arrow keys
|
|
|
|
|
if(docker != null && !docker.IsFocused) e.Handled = true;
|
2009-07-21 13:42:36 +00:00
|
|
|
|
}
|
2016-04-15 14:24:18 +00:00
|
|
|
|
|
|
|
|
|
//mxd. Update notyfy animation
|
|
|
|
|
private void NotifyTimerOnTick(object sender, EventArgs eventArgs)
|
|
|
|
|
{
|
|
|
|
|
if(notifycounter++ == NOTIFY_BLINK_COUNT)
|
|
|
|
|
{
|
|
|
|
|
notifytimer.Stop();
|
|
|
|
|
notifycounter = 0;
|
|
|
|
|
notifytab = -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Trigger redraw
|
|
|
|
|
this.Invalidate();
|
|
|
|
|
}
|
2009-08-21 08:37:02 +00:00
|
|
|
|
|
2009-07-21 05:51:13 +00:00
|
|
|
|
#endregion
|
|
|
|
|
}
|
|
|
|
|
}
|