namespace KancolleSniffer.View\r
{\r
[DesignerCategory("Code")]\r
- public class ShipLabel : Label\r
+ public abstract class ShipLabel : GrowLeftLabel\r
{\r
- public static Color[] ColumnColors = {SystemColors.Control, Color.FromArgb(255, 250, 250, 250)};\r
- public static SizeF ScaleFactor { get; set; }\r
- public static Font LatinFont { get; set; } = new Font("Tahoma", 8f);\r
- public Color PresetColor { get; set; }\r
- public bool AnchorRight { get; set; }\r
- private int _right = Int32.MinValue;\r
- private int _left;\r
- private SlotStatus _slotStatus;\r
- private ShipStatus _status;\r
- private bool _hpPercent;\r
+ protected Color InitialBackColor;\r
\r
public override Color BackColor\r
{\r
get => base.BackColor;\r
- set => base.BackColor = value == DefaultBackColor ? PresetColor : value;\r
- }\r
-\r
- [Flags]\r
- private enum SlotStatus\r
- {\r
- Equipped = 0,\r
- SemiEquipped = 1,\r
- NormalEmpty = 2,\r
- ExtraEmpty = 4\r
+ set\r
+ {\r
+ if (InitialBackColor == Color.Empty)\r
+ InitialBackColor = value;\r
+ base.BackColor = value;\r
+ }\r
}\r
\r
- public ShipLabel()\r
+ protected ShipLabel()\r
{\r
UseMnemonic = false;\r
}\r
\r
- public void SetName(ShipStatus status, ShipNameWidth width = ShipNameWidth.Max)\r
+ public abstract void Set(ShipStatus status);\r
+\r
+ public abstract void Reset();\r
+\r
+ public new sealed class Name : ShipLabel\r
{\r
- if (status == null)\r
+ private SlotStatus _slotStatus, _prevSlotStatus;\r
+ private readonly ShipNameWidth _defaultWidth;\r
+\r
+ public static Font LatinFont { get; set; }\r
+ public static Font BaseFont { get; set; }\r
+\r
+ public Name(Point location, ShipNameWidth defaultWidth)\r
+ {\r
+ _defaultWidth = defaultWidth;\r
+ Location = location;\r
+ AutoSize = true;\r
+ }\r
+\r
+ [Flags]\r
+ private enum SlotStatus\r
+ {\r
+ Equipped = 0,\r
+ SemiEquipped = 1,\r
+ NormalEmpty = 2,\r
+ ExtraEmpty = 4\r
+ }\r
+\r
+ public override void Set(ShipStatus status)\r
+ {\r
+ SetName(status, _defaultWidth);\r
+ }\r
+\r
+ public override void Reset()\r
{\r
SetName("");\r
- return;\r
}\r
- var empty = SlotStatus.Equipped;\r
- if (!status.Empty)\r
+\r
+ public void SetName(ShipStatus status, ShipNameWidth width)\r
+ {\r
+ var slotStatus = GetSlotStatus(status);\r
+ var dcName = DameConName(status);\r
+ var sp = SpecialAttack(status);\r
+ SetName((status.Escaped ? "[避]" : dcName) + sp, status.Name, slotStatus, width);\r
+ }\r
+\r
+ private static SlotStatus GetSlotStatus(ShipStatus status)\r
{\r
+ if (status.Empty)\r
+ return SlotStatus.Equipped;\r
var slots = status.Slot.Take(status.Spec.SlotNum).ToArray();\r
- if (slots.All(item => item.Empty))\r
+ var normal = slots.Any(item => item.Empty)\r
+ ? slots.All(item => item.Empty) ? SlotStatus.NormalEmpty : SlotStatus.SemiEquipped\r
+ : SlotStatus.Equipped;\r
+ var extra = status.SlotEx.Empty ? SlotStatus.ExtraEmpty : SlotStatus.Equipped;\r
+ return normal | extra;\r
+ }\r
+\r
+ private string DameConName(ShipStatus status)\r
+ {\r
+ switch (status.PreparedDamageControl)\r
{\r
- empty |= SlotStatus.NormalEmpty;\r
+ case 42:\r
+ return "[ダ]";\r
+ case 43:\r
+ return "[メ]";\r
+ default:\r
+ return "";\r
}\r
- else if (slots.Any(item => item.Empty))\r
+ }\r
+\r
+ private string SpecialAttack(ShipStatus status)\r
+ {\r
+ switch (status.SpecialAttack)\r
{\r
- empty |= SlotStatus.SemiEquipped;\r
+ case ShipStatus.Attack.Fire:\r
+ return "+";\r
+ case ShipStatus.Attack.Fired:\r
+ return "-";\r
+ default:\r
+ return "";\r
}\r
- if (status.SlotEx.Empty)\r
- empty |= SlotStatus.ExtraEmpty;\r
- }\r
- var dc = status.PreparedDamageControl;\r
- var dcName = dc == 42 ? "[ダ]" :\r
- dc == 43 ? "[メ]" : "";\r
- var sp = "";\r
- switch (status.SpecialAttack)\r
- {\r
- case ShipStatus.Attack.Fire:\r
- sp = "+";\r
- break;\r
- case ShipStatus.Attack.Fired:\r
- sp = "-";\r
- break;\r
- }\r
- SetName((status.Escaped ? "[避]" : dcName) + sp, status.Name, empty, width);\r
- }\r
+ }\r
\r
- public void SetName(string name)\r
- {\r
- SetName("", name, SlotStatus.Equipped);\r
- }\r
+ public void SetName(string name)\r
+ {\r
+ SetName(name, _defaultWidth);\r
+ }\r
\r
- public void SetName(string name, ShipNameWidth width)\r
- {\r
- SetName("", name, SlotStatus.Equipped, width);\r
- }\r
+ public void SetName(string name, ShipNameWidth width)\r
+ {\r
+ SetName("", name, SlotStatus.Equipped, width);\r
+ }\r
\r
- private void SetName(string prefix, string name, SlotStatus slotStatus, ShipNameWidth width = ShipNameWidth.Max)\r
- {\r
- if (name == null)\r
- name = "";\r
- _slotStatus = slotStatus;\r
- var lu = new Regex(@"^\p{Lu}").IsMatch(name);\r
- var shift = (int)Round(ScaleFactor.Height);\r
- if (lu && Font.Equals(Parent.Font))\r
+ private void SetName(string prefix, string name, SlotStatus slotStatus, ShipNameWidth width)\r
{\r
- Location += new Size(0, -shift);\r
- Font = LatinFont;\r
+ _slotStatus = slotStatus;\r
+ ChangeFont(name);\r
+ var realWidth = width == ShipNameWidth.Max ? (int)width : Scaler.ScaleWidth((int)width);\r
+ Text = prefix + StringTruncator.Truncate(name, "", realWidth, Font);\r
+ if (_prevSlotStatus != _slotStatus)\r
+ Invalidate(); // OnPaintを実行させるため\r
+ _prevSlotStatus = _slotStatus;\r
}\r
- else if (!lu && !Font.Equals(Parent.Font))\r
+\r
+ private void ChangeFont(string name)\r
{\r
- Location += new Size(0, shift);\r
- Font = Parent.Font;\r
+ var lu = StartWithLetter(name);\r
+ var shift = Scaler.ScaleHeight(1);\r
+ if (lu && !Font.Equals(LatinFont))\r
+ {\r
+ Location += new Size(0, -shift);\r
+ Font = LatinFont;\r
+ }\r
+ else if (!lu && Font.Equals(LatinFont))\r
+ {\r
+ Location += new Size(0, shift);\r
+ Font = BaseFont;\r
+ }\r
}\r
- var result = prefix + name;\r
- var measured = TextRenderer.MeasureText(result, Font).Width;\r
- if (measured <= (int)width)\r
+\r
+ public static bool StartWithLetter(string name)\r
{\r
- Text = result;\r
- Invalidate(); // 必ずOnPaintを実行させるため\r
- return;\r
+ return Regex.IsMatch(name, @"^\p{Lu}");\r
}\r
- var truncated = "";\r
- foreach (var ch in name)\r
+\r
+ protected override void OnPaint(PaintEventArgs e)\r
{\r
- var tmp = truncated + ch;\r
- if (TextRenderer.MeasureText(tmp, Font).Width > (int)width * ScaleFactor.Width)\r
- break;\r
- truncated = tmp;\r
+ base.OnPaint(e);\r
+ if ((_slotStatus & SlotStatus.NormalEmpty) != 0)\r
+ {\r
+ e.Graphics.DrawRectangle(Pens.Black,\r
+ new Rectangle(Scaler.Move(ClientSize.Width, 0, -3, 0), Scaler.Scale(2, 5)));\r
+ }\r
+ else if ((_slotStatus & SlotStatus.SemiEquipped) != 0)\r
+ {\r
+ e.Graphics.DrawLine(Pens.Black,\r
+ Scaler.Move(ClientSize.Width, 0, -1, 0),\r
+ Scaler.Move(ClientSize.Width, 0, -1, 5));\r
+ }\r
+ if ((_slotStatus & SlotStatus.ExtraEmpty) != 0)\r
+ {\r
+ e.Graphics.DrawRectangle(Pens.Black,\r
+ new Rectangle(Scaler.Move(ClientSize.Width, 0, -3, 8), Scaler.Scale(2, 3)));\r
+ }\r
}\r
- Text = prefix + truncated.TrimEnd(' ');\r
- Invalidate();\r
}\r
\r
- public void SetHp(ShipStatus status)\r
+ public sealed class Hp : ShipLabel\r
{\r
- _status = status;\r
- if (status == null)\r
+ private bool _hpPercent;\r
+ private ShipStatus _status;\r
+\r
+ public Hp()\r
{\r
+ }\r
+\r
+ public Hp(Point location, int height)\r
+ {\r
+ Location = location;\r
+ MinimumSize = new Size(0, height);\r
+ TextAlign = ContentAlignment.MiddleLeft;\r
+ GrowLeft = true;\r
+ Cursor = Cursors.Hand;\r
+ }\r
+\r
+ public override void Reset()\r
+ {\r
+ _status = null;\r
Text = "";\r
- BackColor = PresetColor;\r
- return;\r
+ BackColor = InitialBackColor;\r
}\r
- Text = _hpPercent\r
- ? $"{(int)Floor(status.NowHp * 100.0 / status.MaxHp):D}%"\r
- : $"{status.NowHp:D}/{status.MaxHp:D}";\r
- BackColor = DamageColor(status, PresetColor);\r
- }\r
\r
- public void ToggleHpPercent()\r
- {\r
- _hpPercent = !_hpPercent;\r
- SetHp(_status);\r
- }\r
+ public override void Set(ShipStatus status)\r
+ {\r
+ _status = status;\r
+ Text = _hpPercent\r
+ ? $"{(int)Floor(status.NowHp * 100.0 / status.MaxHp):D}%"\r
+ : $"{status.NowHp:D}/{status.MaxHp:D}";\r
+ BackColor = DamageColor(status);\r
+ }\r
\r
- public void SetHp(int now, int max)\r
- {\r
- SetHp(new ShipStatus {NowHp = now, MaxHp = max});\r
- }\r
+ public void ToggleHpPercent()\r
+ {\r
+ _hpPercent = !_hpPercent;\r
+ if (_status != null)\r
+ Set(_status);\r
+ }\r
\r
- public static Color DamageColor(ShipStatus status, Color backColor)\r
- {\r
- switch (status.DamageLevel)\r
- {\r
- case ShipStatus.Damage.Sunk:\r
- return Color.CornflowerBlue;\r
- case ShipStatus.Damage.Badly:\r
- return CUDColors.Red;\r
- case ShipStatus.Damage.Half:\r
- return CUDColors.Orange;\r
- case ShipStatus.Damage.Small:\r
- return Color.FromArgb(240, 240, 0);\r
- default:\r
- return backColor;\r
+ public void SetHp(int now, int max)\r
+ {\r
+ Set(new ShipStatus {NowHp = now, MaxHp = max});\r
+ }\r
+\r
+ public Color DamageColor(ShipStatus status)\r
+ {\r
+ switch (status.DamageLevel)\r
+ {\r
+ case ShipStatus.Damage.Sunk:\r
+ return Color.CornflowerBlue;\r
+ case ShipStatus.Damage.Badly:\r
+ return CUDColors.Red;\r
+ case ShipStatus.Damage.Half:\r
+ return CUDColors.Orange;\r
+ case ShipStatus.Damage.Small:\r
+ return Color.FromArgb(240, 240, 0);\r
+ default:\r
+ return InitialBackColor;\r
+ }\r
+ }\r
+\r
+ public void SetColor(ShipStatus status)\r
+ {\r
+ BackColor = DamageColor(status);\r
}\r
}\r
\r
- public void SetCond(ShipStatus status)\r
+ public sealed class Cond : ShipLabel\r
{\r
- if (status == null)\r
+ public Cond(Point location, int height)\r
+ {\r
+ Location = location;\r
+ Size = new Size(24, height);\r
+ TextAlign = ContentAlignment.MiddleRight;\r
+ }\r
+\r
+ public override void Reset()\r
{\r
Text = "";\r
- BackColor = PresetColor;\r
- return;\r
- }\r
- var cond = status.Cond;\r
- Text = cond.ToString("D");\r
- BackColor = cond >= 50\r
- ? CUDColors.Yellow\r
- : cond >= 30\r
- ? PresetColor\r
- : cond >= 20\r
- ? CUDColors.Orange\r
- : CUDColors.Red;\r
- }\r
+ BackColor = InitialBackColor;\r
+ }\r
\r
- public void SetLevel(ShipStatus status)\r
- {\r
- Text = status?.Level.ToString("D");\r
+ public override void Set(ShipStatus status)\r
+ {\r
+ var cond = status.Cond;\r
+ Text = cond.ToString("D");\r
+ BackColor = cond >= 50\r
+ ? CUDColors.Yellow\r
+ : cond >= 30\r
+ ? InitialBackColor\r
+ : cond >= 20\r
+ ? CUDColors.Orange\r
+ : CUDColors.Red;\r
+ }\r
}\r
\r
- public void SetExpToNext(ShipStatus status)\r
+ public sealed class Level : ShipLabel\r
{\r
- Text = status?.ExpToNext.ToString("D");\r
- }\r
+ public Level(Point location, int height)\r
+ {\r
+ Location = location;\r
+ Size = new Size(24, height);\r
+ TextAlign = ContentAlignment.MiddleRight;\r
+ }\r
\r
- public void SetRepairTime(ShipStatus status)\r
- {\r
- if (status == null)\r
+ public override void Reset()\r
{\r
Text = "";\r
- return;\r
}\r
- SetRepairTime(status.RepairTime);\r
- }\r
\r
- public void SetRepairTime(TimeSpan span)\r
- {\r
- Text = $@"{(int)span.TotalHours:d2}:{span:mm\:ss}";\r
+ public override void Set(ShipStatus status)\r
+ {\r
+ Text = status.Level.ToString("D");\r
+ }\r
}\r
\r
- public void SetFleet(ShipStatus status)\r
+ public sealed class Exp : ShipLabel\r
{\r
- Text = status?.Fleet == null ? "" : new[] {"1", "2", "3", "4"}[status.Fleet.Number];\r
- }\r
+ public Exp(Point location, int height)\r
+ {\r
+ Location = location;\r
+ Size = new Size(42, height);\r
+ TextAlign = ContentAlignment.MiddleRight;\r
+ }\r
\r
- protected override void OnSizeChanged(EventArgs args)\r
- {\r
- base.OnSizeChanged(args);\r
- KeepAnchorRight();\r
- }\r
+ public override void Reset()\r
+ {\r
+ Text = "";\r
+ }\r
\r
- protected override void OnLayout(LayoutEventArgs args)\r
- {\r
- base.OnLayout(args);\r
- KeepAnchorRight();\r
+ public override void Set(ShipStatus status)\r
+ {\r
+ Text = status.ExpToNext.ToString("D");\r
+ }\r
}\r
\r
- private void KeepAnchorRight()\r
+ public sealed class Fleet : ShipLabel\r
{\r
- if (!AnchorRight)\r
- return;\r
- if (_right == int.MinValue || _left != Left)\r
- {\r
- _right = Right;\r
- _left = Left;\r
- return;\r
- }\r
- if (_right == Right)\r
- return;\r
- _left -= Right - _right;\r
- Location = new Point(_left, Top);\r
+ public Fleet(Point location)\r
+ {\r
+ Location = location;\r
+ AutoSize = true;\r
+ }\r
+\r
+ public override void Reset()\r
+ {\r
+ Text = "";\r
+ }\r
+\r
+ public override void Set(ShipStatus status)\r
+ {\r
+ Text = status.Fleet == null ? "" : new[] {"1", "2", "3", "4"}[status.Fleet.Number];\r
+ }\r
}\r
\r
- protected override void OnPaint(PaintEventArgs e)\r
+ public sealed class RepairTime : ShipLabel\r
{\r
- base.OnPaint(e);\r
- if ((_slotStatus & SlotStatus.NormalEmpty) != 0)\r
+ public RepairTime(Point location)\r
{\r
- e.Graphics.DrawRectangle(\r
- Pens.Black,\r
- ClientSize.Width - 3 * ScaleFactor.Width, 0,\r
- 2 * ScaleFactor.Width, 5 * ScaleFactor.Height);\r
+ Location = location;\r
+ AutoSize = true;\r
}\r
- else if ((_slotStatus & SlotStatus.SemiEquipped) != 0)\r
+\r
+ public override void Reset()\r
{\r
- e.Graphics.DrawLine(\r
- Pens.Black,\r
- ClientSize.Width - 1 * ScaleFactor.Width, 0,\r
- ClientSize.Width - 1 * ScaleFactor.Width, 5 * ScaleFactor.Height);\r
+ Text = "";\r
}\r
- if ((_slotStatus & SlotStatus.ExtraEmpty) != 0)\r
+\r
+ public override void Set(ShipStatus status)\r
{\r
- e.Graphics.DrawRectangle(\r
- Pens.Black,\r
- ClientSize.Width - 3 * ScaleFactor.Width, 8 * ScaleFactor.Height,\r
- 2 * ScaleFactor.Width, 3 * ScaleFactor.Height);\r
+ SetRepairTime(status.RepairTime);\r
}\r
- }\r
\r
- public void Scale()\r
- {\r
- Scale(ScaleFactor);\r
+ public void SetRepairTime(TimeSpan span)\r
+ {\r
+ Text = $@"{(int)span.TotalHours:d2}:{span:mm\:ss}";\r
+ }\r
}\r
}\r
}
\ No newline at end of file