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
|
/*
* Copyright 2020 elementary, Inc. (https://elementary.io)
* SPDX-License-Identifier: GPL-2.0-or-later
*/
/**
* ValidatedEntry is a {@link Gtk.Entry} subclass that is meant to be used in
* forms where input must be validated before the form can be submitted. It
* provides feedback to users about the state of input validation and keeps
* track of its own validation state. By default, input is considered invalid.
*
* ''Example''<<BR>>
* {{{
* var validated_entry = new Granite.ValidatedEntry ();
* username_entry.changed.connect (() => {
* username_entry.is_valid = username_entry.text == "valid input";
* });
* }}}
*
* If the ValidatedEntry.from_regex () constructor is used then the entry automatically
* sets its validity status. A valid regex must be passed to this constructor.
*
* ''Example''<<BR>>
* {{{
* Regex? regex = null;
* ValidatedEntry only_lower_case_letters_entry;
* try {
* regex = new Regex ("^[a-z]*$");
* only_lower_case_letters_entry = new ValidatedEntry.from_regex (regex);
* } catch (Error e) {
* critical (e.message);
* // Provide a fallback entry
* }
* }}}
*/
public class Granite.ValidatedEntry : Gtk.Entry {
/**
* Whether or not text is considered valid input
*/
public bool is_valid { get; set; default = false; }
public int min_length { get; set; default = 0; }
public Regex regex { get; construct set; default = null; }
public ValidatedEntry.from_regex (Regex regex_arg) {
Object (regex: regex_arg);
}
private void check_validity () {
is_valid = get_text_length () >= min_length;
if (is_valid && regex != null) {
is_valid = regex.match (text);
}
}
construct {
activates_default = true;
changed.connect (() => {
check_validity ();
});
changed.connect_after (() => {
unowned Gtk.StyleContext style_context = get_style_context ();
if (text == "") {
secondary_icon_name = null;
style_context.remove_class (Gtk.STYLE_CLASS_ERROR);
} else if (is_valid) {
secondary_icon_name = "process-completed-symbolic";
style_context.remove_class (Gtk.STYLE_CLASS_ERROR);
} else {
secondary_icon_name = "process-error-symbolic";
style_context.add_class (Gtk.STYLE_CLASS_ERROR);
}
});
}
}
|