A game framework written with osu! in mind.
1// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
2// See the LICENCE file in the repository root for full licence text.
3
4using osuTK.Graphics;
5using System;
6using osu.Framework.Graphics.Containers;
7using osu.Framework.Graphics.Shapes;
8using osu.Framework.Input;
9using osu.Framework.Input.Bindings;
10using osu.Framework.Input.Events;
11using osu.Framework.Localisation;
12using osuTK.Input;
13
14namespace osu.Framework.Graphics.UserInterface
15{
16 public abstract class DropdownHeader : ClickableContainer, IKeyBindingHandler<PlatformAction>
17 {
18 public event Action<DropdownSelectionAction> ChangeSelection;
19
20 protected Container Background;
21 protected Container Foreground;
22
23 private Color4 backgroundColour = Color4.DarkGray;
24
25 protected Color4 BackgroundColour
26 {
27 get => backgroundColour;
28 set
29 {
30 backgroundColour = value;
31 updateState();
32 }
33 }
34
35 private Color4 disabledColour = Color4.Gray;
36
37 protected Color4 DisabledColour
38 {
39 get => disabledColour;
40 set
41 {
42 disabledColour = value;
43 updateState();
44 }
45 }
46
47 protected Color4 BackgroundColourHover { get; set; } = Color4.Gray;
48
49 protected override Container<Drawable> Content => Foreground;
50
51 protected internal abstract LocalisableString Label { get; set; }
52
53 protected DropdownHeader()
54 {
55 Masking = true;
56 RelativeSizeAxes = Axes.X;
57 AutoSizeAxes = Axes.Y;
58 Width = 1;
59 InternalChildren = new Drawable[]
60 {
61 Background = new Container
62 {
63 Anchor = Anchor.CentreLeft,
64 Origin = Anchor.CentreLeft,
65 RelativeSizeAxes = Axes.Both,
66 Colour = Color4.DarkGray,
67 Child = new Box
68 {
69 RelativeSizeAxes = Axes.Both,
70 Colour = Color4.White,
71 },
72 },
73 Foreground = new Container
74 {
75 Anchor = Anchor.CentreLeft,
76 Origin = Anchor.CentreLeft,
77 RelativeSizeAxes = Axes.X,
78 AutoSizeAxes = Axes.Y
79 },
80 };
81 }
82
83 protected override void LoadComplete()
84 {
85 base.LoadComplete();
86 Enabled.BindValueChanged(_ => updateState(), true);
87 }
88
89 protected override bool OnHover(HoverEvent e)
90 {
91 updateState();
92 return base.OnHover(e);
93 }
94
95 protected override void OnHoverLost(HoverLostEvent e)
96 {
97 updateState();
98 base.OnHoverLost(e);
99 }
100
101 private void updateState()
102 {
103 Colour = Enabled.Value ? Color4.White : DisabledColour;
104 Background.Colour = IsHovered && Enabled.Value ? BackgroundColourHover : BackgroundColour;
105 }
106
107 public override bool HandleNonPositionalInput => IsHovered;
108
109 protected override bool OnKeyDown(KeyDownEvent e)
110 {
111 if (!Enabled.Value)
112 return true;
113
114 switch (e.Key)
115 {
116 case Key.Up:
117 ChangeSelection?.Invoke(DropdownSelectionAction.Previous);
118 return true;
119
120 case Key.Down:
121 ChangeSelection?.Invoke(DropdownSelectionAction.Next);
122 return true;
123
124 default:
125 return base.OnKeyDown(e);
126 }
127 }
128
129 public bool OnPressed(PlatformAction action)
130 {
131 if (!Enabled.Value)
132 return true;
133
134 switch (action)
135 {
136 case PlatformAction.MoveToListStart:
137 ChangeSelection?.Invoke(DropdownSelectionAction.First);
138 return true;
139
140 case PlatformAction.MoveToListEnd:
141 ChangeSelection?.Invoke(DropdownSelectionAction.Last);
142 return true;
143
144 default:
145 return false;
146 }
147 }
148
149 public void OnReleased(PlatformAction action)
150 {
151 }
152
153 public enum DropdownSelectionAction
154 {
155 Previous,
156 Next,
157 First,
158 Last,
159 FirstVisible,
160 LastVisible
161 }
162 }
163}