namespace KancolleSniffer.View\r
{\r
[DesignerCategory("Code")]\r
- public class ShipLabel : GrowLeftLabel\r
+ public abstract class ShipLabel : GrowLeftLabel\r
{\r
protected Color InitialBackColor;\r
- protected ShipStatus Status;\r
-\r
- protected Font BaseFont => Parent.Font;\r
\r
public override Color BackColor\r
{\r
}\r
}\r
\r
- public ShipLabel()\r
+ protected ShipLabel()\r
{\r
UseMnemonic = false;\r
}\r
\r
- public void SetRepairTime(ShipStatus status)\r
- {\r
- if (status == null)\r
- {\r
- Text = "";\r
- return;\r
- }\r
- SetRepairTime(status.RepairTime);\r
- }\r
+ public abstract void Set(ShipStatus status);\r
\r
- public void SetRepairTime(TimeSpan span)\r
- {\r
- Text = $@"{(int)span.TotalHours:d2}:{span:mm\:ss}";\r
- }\r
+ public abstract void Reset();\r
\r
public new sealed class Name : ShipLabel\r
{\r
- private SlotStatus _slotStatus;\r
+ private SlotStatus _slotStatus, _prevSlotStatus;\r
+ private readonly ShipNameWidth _defaultWidth;\r
\r
- public static Font LatinFont { get; set; } = new Font("Tahoma", 8f);\r
+ public static Font LatinFont { get; set; }\r
+ public static Font BaseFont { get; set; }\r
\r
- public Name(Point location)\r
+ public Name(Point location, ShipNameWidth defaultWidth)\r
{\r
+ _defaultWidth = defaultWidth;\r
Location = location;\r
AutoSize = true;\r
}\r
ExtraEmpty = 4\r
}\r
\r
- public void SetName(ShipStatus status, ShipNameWidth width = ShipNameWidth.Max)\r
+ public override void Set(ShipStatus status)\r
{\r
- if (status == null)\r
- {\r
- SetName("");\r
- return;\r
- }\r
- var empty = SlotStatus.Equipped;\r
- if (!status.Empty)\r
+ SetName(status, _defaultWidth);\r
+ }\r
+\r
+ public override void Reset()\r
+ {\r
+ SetName("");\r
+ }\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
+ 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
- var slots = status.Slot.Take(status.Spec.SlotNum).ToArray();\r
- if (slots.Any(item => item.Empty))\r
- empty |= slots.All(item => item.Empty) ? SlotStatus.NormalEmpty : SlotStatus.SemiEquipped;\r
- if (status.SlotEx.Empty)\r
- empty |= SlotStatus.ExtraEmpty;\r
+ case 42:\r
+ return "[ダ]";\r
+ case 43:\r
+ return "[メ]";\r
+ default:\r
+ return "";\r
}\r
- var dc = status.PreparedDamageControl;\r
- var dcName = dc == 42 ? "[ダ]" :\r
- dc == 43 ? "[メ]" : "";\r
- var sp = "";\r
+ }\r
+\r
+ private string SpecialAttack(ShipStatus status)\r
+ {\r
switch (status.SpecialAttack)\r
{\r
case ShipStatus.Attack.Fire:\r
- sp = "+";\r
- break;\r
+ return "+";\r
case ShipStatus.Attack.Fired:\r
- sp = "-";\r
- break;\r
+ return "-";\r
+ default:\r
+ return "";\r
}\r
- SetName((status.Escaped ? "[避]" : dcName) + sp, status.Name, empty, width);\r
}\r
\r
public void SetName(string name)\r
{\r
- SetName("", name, SlotStatus.Equipped);\r
+ SetName(name, _defaultWidth);\r
}\r
\r
public void SetName(string name, ShipNameWidth width)\r
SetName("", name, SlotStatus.Equipped, width);\r
}\r
\r
- private void SetName(string prefix, string name, SlotStatus slotStatus,\r
- ShipNameWidth width = ShipNameWidth.Max)\r
+ private void SetName(string prefix, string name, SlotStatus slotStatus, ShipNameWidth width)\r
{\r
- if (name == null)\r
- name = "";\r
_slotStatus = slotStatus;\r
- var lu = new Regex(@"^\p{Lu}").IsMatch(name);\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
+\r
+ private void ChangeFont(string name)\r
+ {\r
+ var lu = StartWithLetter(name);\r
var shift = Scaler.ScaleHeight(1);\r
- if (lu && Font.Equals(BaseFont))\r
+ if (lu && !Font.Equals(LatinFont))\r
{\r
Location += new Size(0, -shift);\r
Font = LatinFont;\r
}\r
- else if (!lu && !Font.Equals(BaseFont))\r
+ else if (!lu && Font.Equals(LatinFont))\r
{\r
Location += new Size(0, shift);\r
Font = BaseFont;\r
}\r
- var result = prefix + name;\r
- var measured = TextRenderer.MeasureText(result, Font).Width;\r
- if (measured <= (int)width)\r
- {\r
- Text = result;\r
- Invalidate(); // 必ずOnPaintを実行させるため\r
- return;\r
- }\r
- var truncated = "";\r
- foreach (var ch in name)\r
- {\r
- var tmp = truncated + ch;\r
- if (TextRenderer.MeasureText(tmp, Font).Width > Scaler.ScaleWidth((float)width))\r
- break;\r
- truncated = tmp;\r
- }\r
- Text = prefix + truncated.TrimEnd(' ');\r
- Invalidate();\r
+ }\r
+\r
+ public static bool StartWithLetter(string name)\r
+ {\r
+ return Regex.IsMatch(name, @"^\p{Lu}");\r
}\r
\r
protected override void OnPaint(PaintEventArgs e)\r
public sealed class Hp : ShipLabel\r
{\r
private bool _hpPercent;\r
- private Font _strongFont;\r
- private ShipLabel _hpStrongLabel;\r
- private Font StrongFont => _strongFont ?? (_strongFont = new Font("Leelawadee", BaseFont.Size));\r
+ private ShipStatus _status;\r
\r
public Hp()\r
{\r
Cursor = Cursors.Hand;\r
}\r
\r
- public void SetHp(ShipStatus status)\r
+ public override void Reset()\r
{\r
- Status = status;\r
- if (_hpStrongLabel != null)\r
- _hpStrongLabel.Text = "";\r
- Font = BaseFont;\r
- if (status == null)\r
- {\r
- Text = "";\r
- BackColor = InitialBackColor;\r
- return;\r
- }\r
- if (_hpPercent)\r
- {\r
- var percent = $"{(int)Floor(status.NowHp * 100.0 / status.MaxHp):D}";\r
- if (status.DamageLevel == ShipStatus.Damage.Badly)\r
- {\r
- Text = "%";\r
- if (_hpStrongLabel == null)\r
- CreateHpStrongLabel();\r
- _hpStrongLabel.Text = percent;\r
- }\r
- else\r
- {\r
- Text = percent + "%";\r
- }\r
- }\r
- else\r
- {\r
- Text = $"{status.NowHp:D}/{status.MaxHp:D}";\r
- if (status.DamageLevel == ShipStatus.Damage.Badly)\r
- Font = StrongFont;\r
- }\r
- BackColor = DamageColor(status);\r
+ _status = null;\r
+ Text = "";\r
+ BackColor = InitialBackColor;\r
}\r
\r
- private void CreateHpStrongLabel()\r
+ public override void Set(ShipStatus status)\r
{\r
- _hpStrongLabel = new Hp(Scaler.Move(Left, Top, 4, 0), Height)\r
- {\r
- Font = StrongFont,\r
- BackColor = CUDColors.Red\r
- };\r
- _hpStrongLabel.DoubleClick += (sender, e) => { OnDoubleClick(e); };\r
- Parent.Controls.Add(_hpStrongLabel);\r
- var index = Parent.Controls.GetChildIndex(this);\r
- Parent.Controls.SetChildIndex(_hpStrongLabel, index + 1);\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 ToggleHpPercent()\r
{\r
_hpPercent = !_hpPercent;\r
- SetHp(Status);\r
+ if (_status != null)\r
+ Set(_status);\r
}\r
\r
public void SetHp(int now, int max)\r
{\r
- SetHp(new ShipStatus {NowHp = now, MaxHp = max});\r
+ Set(new ShipStatus {NowHp = now, MaxHp = max});\r
}\r
\r
public Color DamageColor(ShipStatus status)\r
TextAlign = ContentAlignment.MiddleRight;\r
}\r
\r
- public void SetCond(ShipStatus status)\r
+ public override void Reset()\r
+ {\r
+ Text = "";\r
+ BackColor = InitialBackColor;\r
+ }\r
+\r
+ public override void Set(ShipStatus status)\r
{\r
- if (status == null)\r
- {\r
- Text = "";\r
- BackColor = InitialBackColor;\r
- return;\r
- }\r
var cond = status.Cond;\r
Text = cond.ToString("D");\r
BackColor = cond >= 50\r
TextAlign = ContentAlignment.MiddleRight;\r
}\r
\r
- public void SetLevel(ShipStatus status)\r
+ public override void Reset()\r
+ {\r
+ Text = "";\r
+ }\r
+\r
+ public override void Set(ShipStatus status)\r
{\r
- Text = status?.Level.ToString("D");\r
+ Text = status.Level.ToString("D");\r
}\r
}\r
\r
TextAlign = ContentAlignment.MiddleRight;\r
}\r
\r
- public void SetExpToNext(ShipStatus status)\r
+ public override void Reset()\r
{\r
- Text = status?.ExpToNext.ToString("D");\r
+ Text = "";\r
+ }\r
+\r
+ public override void Set(ShipStatus status)\r
+ {\r
+ Text = status.ExpToNext.ToString("D");\r
}\r
}\r
\r
AutoSize = true;\r
}\r
\r
- public void SetFleet(ShipStatus status)\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
+ public sealed class RepairTime : ShipLabel\r
+ {\r
+ public RepairTime(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
+ SetRepairTime(status.RepairTime);\r
+ }\r
+\r
+ public void SetRepairTime(TimeSpan span)\r
{\r
- Text = status?.Fleet == null ? "" : new[] {"1", "2", "3", "4"}[status.Fleet.Number];\r
+ Text = $@"{(int)span.TotalHours:d2}:{span:mm\:ss}";\r
}\r
}\r
}\r