/* ** Copyright 2019-2021 Double Precision, Inc. ** See COPYING for distribution information. */ #include "config.h" #include "close_flag.H" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include std::string x::appid() noexcept { return "filteredinput2.examples.w.libcxx.com"; } x::w::validated_input_field create_mainwindow(const x::w::main_window &main_window, const close_flag_ref &close_flag) { auto layout=main_window->gridlayout(); layout->row_alignment(0, x::w::valign::middle); x::w::gridfactory factory=layout->append_row(); factory->create_label("Phone #:"); x::w::input_field_config config{15}; config.maximum_size=14; config.autoselect=true; config.autodeselect=true; config.direction=x::w::bidi::left_to_right; auto field=factory->create_input_field("(###) ###-####", config); field->on_default_filter(// Valid input is digits 0-9. [] (char32_t c) { return c >= '0' && c <= '9'; }, // Immutable positions in the input field. {0, 4, 5, 9}, // Character that indicates no input. '#'); factory=layout->append_row(); factory->create_canvas(); factory->create_button("Ok", x::w::default_button() ) ->on_activate([close_flag] (ONLY IN_THREAD, const auto &trigger, const auto &mcguffin) { close_flag->close(); }); // An existing input field's set_validator() is equivalent to // using create_validated_input_field_contents() for // a new input field. set_validator() has the effect of converting // a regular input field into a validated input field. // // This is less efficient, but sometimes it's not convenient to // create the validator closures until after all widgets in the window // get created. // // set_validator() takes the same parameters as // create_validated_input_field_contents() and returns a // x::w::validated_input_field. // // There's also set_string_validator() that's comparable to using // create_string_validated_input_field_contents(). return field->set_validator ([] (ONLY IN_THREAD, const std::string &value, x::w::input_lock &lock, const x::w::callback_trigger_t &trigger) -> std::optional { std::string s; s.reserve(10); for (auto c:value) { if (c >= '0' && c <= '9') s.push_back(c); } if (s.size() > 0 && s.size() < 10) { lock.stop_message("Invalid phone number"); return std::nullopt; } return s; }, [] (const std::optional &v) -> std::string { std::string s="(###) ###-####"; auto i=s.begin(); if (v && v->size() == 10) { for (char c:*v) { while (*i != '#') ++i; *i++ = c; } } return s; }); } void filteredinputfield() { x::destroy_callback::base::guard guard; auto close_flag=close_flag_ref::create(); x::w::validated_input_fieldptr char_input; x::w::validated_input_fieldptr int_input; x::w::validated_input_fieldptr validated_phone_number; auto main_window=x::w::main_window::create ([&] (const auto &main_window) { validated_phone_number= create_mainwindow(main_window, close_flag); validated_phone_number->set("2125551212"); }); main_window->on_disconnect([] { _exit(1); }); guard(main_window->connection_mcguffin()); main_window->set_window_title("Prompt"); main_window->on_delete ([close_flag] (ONLY IN_THREAD, const x::w::busy &ignore) { close_flag->close(); }); main_window->show_all(); close_flag->wait(); auto phone_number=validated_phone_number->value(); if (phone_number) std::cout << "Phone number: " << *phone_number << std::endl; } int main(int argc, char **argv) { try { filteredinputfield(); } catch (const x::exception &e) { e->caught(); exit(1); } return 0; }