aboutsummaryrefslogtreecommitdiff
path: root/src/Ryujinx.Gtk3/UI/Applet/SwkbdAppletDialog.cs
blob: 8045da91eafc916bd0e6153b27dbdf7be574d5ed (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
using Gtk;
using Ryujinx.HLE.HOS.Applets.SoftwareKeyboard;
using System;
using System.Linq;

namespace Ryujinx.UI.Applet
{
    public class SwkbdAppletDialog : MessageDialog
    {
        private int _inputMin;
        private int _inputMax;
#pragma warning disable IDE0052 // Remove unread private member
        private KeyboardMode _mode;
#pragma warning restore IDE0052

        private string _validationInfoText = "";

        private Predicate<int> _checkLength = _ => true;
        private Predicate<string> _checkInput = _ => true;

        private readonly Label _validationInfo;

        public Entry InputEntry { get; }
        public Button OkButton { get; }
        public Button CancelButton { get; }

        public SwkbdAppletDialog(Window parent) : base(parent, DialogFlags.Modal | DialogFlags.DestroyWithParent, MessageType.Question, ButtonsType.None, null)
        {
            SetDefaultSize(300, 0);

            _validationInfo = new Label()
            {
                Visible = false,
            };

            InputEntry = new Entry()
            {
                Visible = true,
            };

            InputEntry.Activated += OnInputActivated;
            InputEntry.Changed += OnInputChanged;

            OkButton = (Button)AddButton("OK", ResponseType.Ok);
            CancelButton = (Button)AddButton("Cancel", ResponseType.Cancel);

            ((Box)MessageArea).PackEnd(_validationInfo, true, true, 0);
            ((Box)MessageArea).PackEnd(InputEntry, true, true, 4);
        }

        private void ApplyValidationInfo()
        {
            _validationInfo.Visible = !string.IsNullOrEmpty(_validationInfoText);
            _validationInfo.Markup = _validationInfoText;
        }

        public void SetInputLengthValidation(int min, int max)
        {
            _inputMin = Math.Min(min, max);
            _inputMax = Math.Max(min, max);

            _validationInfo.Visible = false;

            if (_inputMin <= 0 && _inputMax == int.MaxValue) // Disable.
            {
                _validationInfo.Visible = false;

                _checkLength = _ => true;
            }
            else if (_inputMin > 0 && _inputMax == int.MaxValue)
            {
                _validationInfoText = $"<i>Must be at least {_inputMin} characters long.</i> ";

                _checkLength = length => _inputMin <= length;
            }
            else
            {
                _validationInfoText = $"<i>Must be {_inputMin}-{_inputMax} characters long.</i> ";

                _checkLength = length => _inputMin <= length && length <= _inputMax;
            }

            ApplyValidationInfo();
            OnInputChanged(this, EventArgs.Empty);
        }

        public void SetInputValidation(KeyboardMode mode)
        {
            _mode = mode;

            switch (mode)
            {
                case KeyboardMode.Numeric:
                    _validationInfoText += "<i>Must be 0-9 or '.' only.</i>";
                    _checkInput = text => text.All(NumericCharacterValidation.IsNumeric);
                    break;
                case KeyboardMode.Alphabet:
                    _validationInfoText += "<i>Must be non CJK-characters only.</i>";
                    _checkInput = text => text.All(value => !CJKCharacterValidation.IsCJK(value));
                    break;
                case KeyboardMode.ASCII:
                    _validationInfoText += "<i>Must be ASCII text only.</i>";
                    _checkInput = text => text.All(char.IsAscii);
                    break;
                default:
                    _checkInput = _ => true;
                    break;
            }

            ApplyValidationInfo();
            OnInputChanged(this, EventArgs.Empty);
        }

        private void OnInputActivated(object sender, EventArgs e)
        {
            if (OkButton.IsSensitive)
            {
                Respond(ResponseType.Ok);
            }
        }

        private void OnInputChanged(object sender, EventArgs e)
        {
            OkButton.Sensitive = _checkLength(InputEntry.Text.Length) && _checkInput(InputEntry.Text);
        }
    }
}