A game framework written with osu! in mind.
at master 145 lines 4.7 kB view raw
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 osu.Framework.Bindables; 5using osu.Framework.Graphics.Containers; 6using osu.Framework.Graphics.Shapes; 7 8namespace osu.Framework.Graphics.UserInterface 9{ 10 public abstract class HexColourPicker : CompositeDrawable, IHasCurrentValue<Colour4> 11 { 12 private readonly BindableWithCurrent<Colour4> current = new BindableWithCurrent<Colour4>(); 13 14 public Bindable<Colour4> Current 15 { 16 get => current.Current; 17 set => current.Current = value; 18 } 19 20 public new MarginPadding Padding 21 { 22 get => content.Padding; 23 set => content.Padding = value; 24 } 25 26 /// <summary> 27 /// Sets the spacing between the hex input text box and the colour preview. 28 /// </summary> 29 public float Spacing 30 { 31 get => spacer.Width; 32 set => spacer.Width = value; 33 } 34 35 /// <summary> 36 /// The background of the control. 37 /// </summary> 38 protected readonly Box Background; 39 40 private readonly Container content; 41 42 private readonly TextBox hexCodeTextBox; 43 private readonly Drawable spacer; 44 private readonly ColourPreview colourPreview; 45 46 protected HexColourPicker() 47 { 48 Current.Value = Colour4.White; 49 50 Width = 300; 51 AutoSizeAxes = Axes.Y; 52 53 InternalChildren = new Drawable[] 54 { 55 Background = new Box 56 { 57 RelativeSizeAxes = Axes.Both 58 }, 59 content = new Container 60 { 61 RelativeSizeAxes = Axes.X, 62 AutoSizeAxes = Axes.Y, 63 Child = new GridContainer 64 { 65 RelativeSizeAxes = Axes.X, 66 AutoSizeAxes = Axes.Y, 67 ColumnDimensions = new[] 68 { 69 new Dimension(), 70 new Dimension(GridSizeMode.AutoSize), 71 new Dimension() 72 }, 73 RowDimensions = new[] 74 { 75 new Dimension(GridSizeMode.AutoSize) 76 }, 77 Content = new[] 78 { 79 new[] 80 { 81 hexCodeTextBox = CreateHexCodeTextBox().With(d => 82 { 83 d.RelativeSizeAxes = Axes.X; 84 d.CommitOnFocusLost = true; 85 }), 86 spacer = Empty(), 87 colourPreview = CreateColourPreview().With(d => d.RelativeSizeAxes = Axes.Both) 88 } 89 } 90 } 91 } 92 }; 93 } 94 95 /// <summary> 96 /// Creates the text box to be used for specifying the hex code of the target colour. 97 /// </summary> 98 protected abstract TextBox CreateHexCodeTextBox(); 99 100 /// <summary> 101 /// Creates the control that will be used for displaying the preview of the target colour. 102 /// </summary> 103 protected abstract ColourPreview CreateColourPreview(); 104 105 protected override void LoadComplete() 106 { 107 base.LoadComplete(); 108 109 Current.BindValueChanged(_ => updateState(), true); 110 111 hexCodeTextBox.Current.BindValueChanged(_ => tryPreviewColour()); 112 hexCodeTextBox.OnCommit += commitColour; 113 } 114 115 private void updateState() 116 { 117 hexCodeTextBox.Text = Current.Value.ToHex(); 118 colourPreview.Current.Value = Current.Value; 119 } 120 121 private void tryPreviewColour() 122 { 123 if (!Colour4.TryParseHex(hexCodeTextBox.Text, out var colour) || colour.A < 1) 124 return; 125 126 colourPreview.Current.Value = colour; 127 } 128 129 private void commitColour(TextBox sender, bool newText) 130 { 131 if (!Colour4.TryParseHex(sender.Text, out var colour) || colour.A < 1) 132 { 133 Current.TriggerChange(); // restore previous value. 134 return; 135 } 136 137 Current.Value = colour; 138 } 139 140 public abstract class ColourPreview : CompositeDrawable 141 { 142 public Bindable<Colour4> Current = new Bindable<Colour4>(); 143 } 144 } 145}