CharPicker

A CharPicker is an expandable control that allows you to select a character from various Unicode character sets:

It can be created using CharPicker::new(...), CharPicker::with_set(...) or the charpicker! macro.

let c1 = CharPicker::new(None, layout!("x:1,y:1,w:30"));
let c2 = CharPicker::with_set(Some('A'), layout!("x:1,y:1,w:30"), charpicker::Set::with_interval("ASCII", 0x20, 0x7E).unwrap());
let c3 = charpicker!("char=A,x:1,y:1,w:30,sets=[Ascii]");
let c4 = charpicker!("code=65,x:1,y:1,w:30,sets=[Ascii,Arrows]");

A CharPicker supports all common parameters (as they are described in Instantiate via Macros section). Besides them, the following named parameters are also accepted:

Parameter nameTypePositional parameterPurpose
char or chStringYes (first positional parameter)The initial character to select in the CharPicker
codeNumericNoThe Unicode code point of the initial character to select
setsListNoA list of character sets to populate the CharPicker with (e.g., [Ascii, Arrows, Emoticons])

The following sets are available:

NameDescriptionExample
AnimalsAnimal emoji and symbolsπŸ€, 🐼, πŸ¦€
ArabicArabic script charactersΨ§, Ψ¨, Ψͺ
ArrowsVarious arrow symbols↑, β†’, ↔
AsciiASCII characters (0x20-0x7E)A, B, C, !, @, #
BlocksBlock drawing characters (0x2580-0x259F)β–€, β–„, β–ˆ
BoxDrawingBox drawing characters (0x2500-0x257F)β•”, β•—, β•š
BrailleBraille patterns (0x2800-0x28FF)⠁, β ƒ, β ‰
ChineseChinese (CJK) characters (0x4E00-0x9FFF)δΈ­, ζ–‡, ε­—
CurrencyCurrency symbols (0x20A0-0x20CF)€, Β£, β‚Ή
CyrillicCyrillic script charactersА, Π‘, Π’
EmoticonsEmoticons and emoji (0x1F600-0x1F64F)πŸ˜€, 😁, πŸ˜‚
GamesGaming symbols (cards, dice, chess)β™”, β™Ÿ, βš€
GreekGreek script charactersΞ‘, Ξ’, Ξ“
LatinExtended Latin charactersΓ€, Á, Γ‚
MathMathematical symbolsβˆ€, βˆ‚, βˆƒ
NumbersNumber-related symbolsβ…”, β…•, β‘ 
PictographsMiscellaneous symbols and pictographsβ˜€, ☁, πŸŒ€
PunctuationVarious punctuation marks–, β€”, …
ShapesGeometric shapesβ– , β–‘, β–²
SubscriptsSubscript characters (0x2080-0x209C)β‚€, ₁, β‚‚
SuperscriptsSuperscript characters⁰, ¹, ²
TransportTransportation symbols (0x1F680-0x1F6FF)πŸš€, 🚁, πŸš‚
UnicodeFull Unicode range (0x0020-0x10FFFF)All available Unicode characters

Remark: The sets parameter can also be set to [*] to select all available sets.

let cp = charpicker!("x:1,y:1,w:30,sets:[*]");

Events

To intercept events from a CharPicker control, the following trait has to be implemented in the Window that processes the event loop:

pub trait CharPickerEvents {
    fn on_char_changed(&mut self, handle: Handle<CharPicker>, code: Option<char>) -> EventProcessStatus {
        EventProcessStatus::Ignored
    }
}

The code parameter contains Some(char) when a character is selected, or None when no character is selected.

Methods

Besides the Common methods for all Controls a CharPicker also has the following additional methods:

MethodPurpose
add_set(...)Adds a new character set to the CharPicker
clear_sets()Removes all character sets from the CharPicker and unselects the current character
select_char(...)Selects a specific character in the CharPicker (the character must exist in one of the sets)
unselect_char()Unselects the current character (sets selection to None)
char()Returns the current character selected in the CharPicker (if any)

Key association

The following keys are processed by a CharPicker control if it has focus:

KeyPurpose
Space or EnterExpands or collapses the CharPicker control.
Up, Down, Left, RightNavigates through the available characters in the current character set.
HomeMove the selection to the first character in the current set
EndMove the selection to the last character in the current set
PageUp, PageDownNavigates through the characters page by page when the control is expanded
Ctrl+Up, Alt+UpScrolls the view up when expanded (without changing selection)
Ctrl+Down, Alt+DownScrolls the view down when expanded (without changing selection)
Ctrl+Left, Alt+LeftSwitches to the previous character set
Ctrl+Right, Alt+RightSwitches to the next character set
Ctrl+C, Ctrl+InsertCopies the current selected character to the clipboard
Ctrl+V, Shift+InsertPastes the first character from the clipboard and selects it in the CharPicker (if that character exists in one of the sets)
EscapeCollapses the control. If the CharPicker is already collapsed, this key will not be captured

Besides these keys, typing any printable character will automatically search for and select that character in the current character sets.

When the CharPicker is expanded, you can also use the mouse to:

  • Click on characters to select them
  • Click the left/right arrow buttons to switch between character sets
  • Click the [None] button to unselect the current character
  • Use the mouse wheel to scroll through characters or switch between sets

Sets

A CharPicker can be populated with multiple character sets. The sets are displayed in the control in a tabbed interface. By default (using the CharPicker::new(...) constructor), the CharPicker is populated with the entire Unicode character set. However, you can add your own sets using the add_set(...) method.

To create a set of characters, you can use the charpicker::Set struct. The following methods are available:

  • with_interval(...) - Creates a set of characters from a Unicode interval (e.g., 0x20-0x7E)
  • from_unicode_symbols(...) - Creates a set of characters from a Unicode symbols (e.g., Ascii, Arrows, Animals, ... )
  • new(...) - Creates a set of characters from a list of characters (this allows one to create a custom set of characters - e.g. just numbers, or just vowels, etc)

Example

The following example creates a Window with a CharPicker that allows selecting from ASCII and Arrow character sets. When a character is selected, the window title is updated to show the character and its Unicode code point.

use appcui::prelude::*;

#[Window(events = CharPickerEvents)]
struct MyWin {
    picker: Handle<CharPicker>,
}

impl MyWin {
    fn new() -> Self {
        let mut w = Self {
            base: window!("x:1,y:1,w:40,h:8,caption:'Character Picker Demo'"),
            picker: Handle::None,
        };
        w.add(label!("'Select a character:',x:1,y:1,w:30"));
        
        // Create CharPicker with ASCII and Arrows character sets
        let mut cp = CharPicker::new(None, layout!("x:1,y:2,w:30"));
        cp.clear_sets(); // Remove the default Unicode set
        cp.add_set(charpicker::Set::from_unicode_symbols("ASCII", charpicker::UnicodeSymbols::Ascii));
        cp.add_set(charpicker::Set::from_unicode_symbols("Arrows", charpicker::UnicodeSymbols::Arrows));
        
        // Or use the macro for the same result:
        // let cp = charpicker!("x:1,y:2,w:30,sets:[Ascii,Arrows]");
        
        w.picker = w.add(cp);
        w
    }
}

impl CharPickerEvents for MyWin {
    fn on_char_changed(&mut self, _handle: Handle<CharPicker>, code: Option<char>) -> EventProcessStatus {
        let title = if let Some(ch) = code {
            format!("Selected: '{}' (U+{:04X})", ch, ch as u32)
        } else {
            String::from("No character selected")
        };
        self.set_title(&title);
        EventProcessStatus::Processed
    }
}

fn main() -> Result<(), appcui::system::Error> {
    let mut a = App::new().build()?;
    a.add_window(MyWin::new());
    a.run();
    Ok(())
}