Merge pull request #2169 from iced-rs/update-winit
Update `winit` to `0.29`
This commit is contained in:
commit
0001a6d636
35 changed files with 1942 additions and 1301 deletions
2
.github/workflows/audit.yml
vendored
2
.github/workflows/audit.yml
vendored
|
|
@ -27,4 +27,4 @@ jobs:
|
|||
- name: Delete `web-sys` dependency from `integration` example
|
||||
run: sed -i '$d' examples/integration/Cargo.toml
|
||||
- name: Find outdated dependencies
|
||||
run: cargo outdated --workspace --exit-code 1
|
||||
run: cargo outdated --workspace --exit-code 1 --ignore raw-window-handle
|
||||
|
|
|
|||
2
.github/workflows/document.yml
vendored
2
.github/workflows/document.yml
vendored
|
|
@ -8,7 +8,7 @@ jobs:
|
|||
steps:
|
||||
- uses: hecrj/setup-rust-action@v1
|
||||
with:
|
||||
rust-version: nightly
|
||||
rust-version: nightly-2023-12-11
|
||||
- uses: actions/checkout@v2
|
||||
- name: Generate documentation
|
||||
run: |
|
||||
|
|
|
|||
|
|
@ -130,7 +130,6 @@ glyphon = "0.4"
|
|||
guillotiere = "0.6"
|
||||
half = "2.2"
|
||||
image = "0.24"
|
||||
instant = "0.1"
|
||||
kamadak-exif = "0.5"
|
||||
kurbo = "0.9"
|
||||
log = "0.4"
|
||||
|
|
@ -145,6 +144,7 @@ raw-window-handle = "0.5"
|
|||
resvg = "0.36"
|
||||
rustc-hash = "1.0"
|
||||
smol = "1.0"
|
||||
smol_str = "0.2"
|
||||
softbuffer = "0.2"
|
||||
syntect = "5.1"
|
||||
sysinfo = "0.28"
|
||||
|
|
@ -157,7 +157,8 @@ unicode-segmentation = "1.0"
|
|||
wasm-bindgen-futures = "0.4"
|
||||
wasm-timer = "0.2"
|
||||
web-sys = "0.3"
|
||||
web-time = "0.2"
|
||||
wgpu = "0.18"
|
||||
winapi = "0.3"
|
||||
window_clipboard = "0.3"
|
||||
winit = { git = "https://github.com/iced-rs/winit.git", rev = "c52db2045d0a2f1b8d9923870de1d4ab1994146e", default-features = false }
|
||||
winit = { git = "https://github.com/iced-rs/winit.git", rev = "b91e39ece2c0d378c3b80da7f3ab50e17bb798a5", features = ["rwh_05"] }
|
||||
|
|
|
|||
|
|
@ -13,18 +13,18 @@ keywords.workspace = true
|
|||
[dependencies]
|
||||
bitflags.workspace = true
|
||||
log.workspace = true
|
||||
thiserror.workspace = true
|
||||
xxhash-rust.workspace = true
|
||||
num-traits.workspace = true
|
||||
smol_str.workspace = true
|
||||
thiserror.workspace = true
|
||||
web-time.workspace = true
|
||||
xxhash-rust.workspace = true
|
||||
|
||||
palette.workspace = true
|
||||
palette.optional = true
|
||||
|
||||
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
||||
instant.workspace = true
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
raw-window-handle.workspace = true
|
||||
# TODO: Use `workspace` dependency once `wgpu` upgrades `raw-window-handle`
|
||||
raw-window-handle = "0.6"
|
||||
|
||||
[dev-dependencies]
|
||||
approx = "0.5"
|
||||
|
|
|
|||
|
|
@ -1,8 +1,11 @@
|
|||
//! Listen to keyboard events.
|
||||
pub mod key;
|
||||
|
||||
mod event;
|
||||
mod key_code;
|
||||
mod location;
|
||||
mod modifiers;
|
||||
|
||||
pub use event::Event;
|
||||
pub use key_code::KeyCode;
|
||||
pub use key::Key;
|
||||
pub use location::Location;
|
||||
pub use modifiers::Modifiers;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use super::{KeyCode, Modifiers};
|
||||
use crate::keyboard::{Key, Location, Modifiers};
|
||||
use crate::SmolStr;
|
||||
|
||||
/// A keyboard event.
|
||||
///
|
||||
|
|
@ -6,29 +7,35 @@ use super::{KeyCode, Modifiers};
|
|||
/// additional events, feel free to [open an issue] and share your use case!_
|
||||
///
|
||||
/// [open an issue]: https://github.com/iced-rs/iced/issues
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum Event {
|
||||
/// A keyboard key was pressed.
|
||||
KeyPressed {
|
||||
/// The key identifier
|
||||
key_code: KeyCode,
|
||||
/// The key pressed.
|
||||
key: Key,
|
||||
|
||||
/// The state of the modifier keys
|
||||
/// The location of the key.
|
||||
location: Location,
|
||||
|
||||
/// The state of the modifier keys.
|
||||
modifiers: Modifiers,
|
||||
|
||||
/// The text produced by the key press, if any.
|
||||
text: Option<SmolStr>,
|
||||
},
|
||||
|
||||
/// A keyboard key was released.
|
||||
KeyReleased {
|
||||
/// The key identifier
|
||||
key_code: KeyCode,
|
||||
/// The key released.
|
||||
key: Key,
|
||||
|
||||
/// The state of the modifier keys
|
||||
/// The location of the key.
|
||||
location: Location,
|
||||
|
||||
/// The state of the modifier keys.
|
||||
modifiers: Modifiers,
|
||||
},
|
||||
|
||||
/// A unicode character was received.
|
||||
CharacterReceived(char),
|
||||
|
||||
/// The keyboard modifiers have changed.
|
||||
ModifiersChanged(Modifiers),
|
||||
}
|
||||
|
|
|
|||
744
core/src/keyboard/key.rs
Normal file
744
core/src/keyboard/key.rs
Normal file
|
|
@ -0,0 +1,744 @@
|
|||
//! Identify keyboard keys.
|
||||
use crate::SmolStr;
|
||||
|
||||
/// A key on the keyboard.
|
||||
///
|
||||
/// This is mostly the `Key` type found in [`winit`].
|
||||
///
|
||||
/// [`winit`]: https://docs.rs/winit/0.29.10/winit/keyboard/enum.Key.html
|
||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub enum Key<C = SmolStr> {
|
||||
/// A key with an established name.
|
||||
Named(Named),
|
||||
|
||||
/// A key string that corresponds to the character typed by the user, taking into account the
|
||||
/// user’s current locale setting, and any system-level keyboard mapping overrides that are in
|
||||
/// effect.
|
||||
Character(C),
|
||||
|
||||
/// An unidentified key.
|
||||
Unidentified,
|
||||
}
|
||||
|
||||
impl Key {
|
||||
/// Convert `Key::Character(SmolStr)` to `Key::Character(&str)` so you can more easily match on
|
||||
/// `Key`. All other variants remain unchanged.
|
||||
pub fn as_ref(&self) -> Key<&str> {
|
||||
match self {
|
||||
Self::Named(named) => Key::Named(*named),
|
||||
Self::Character(c) => Key::Character(c.as_ref()),
|
||||
Self::Unidentified => Key::Unidentified,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A named key.
|
||||
///
|
||||
/// This is mostly the `NamedKey` type found in [`winit`].
|
||||
///
|
||||
/// [`winit`]: https://docs.rs/winit/0.29.10/winit/keyboard/enum.Key.html
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[allow(missing_docs)]
|
||||
pub enum Named {
|
||||
/// The `Alt` (Alternative) key.
|
||||
///
|
||||
/// This key enables the alternate modifier function for interpreting concurrent or subsequent
|
||||
/// keyboard input. This key value is also used for the Apple <kbd>Option</kbd> key.
|
||||
Alt,
|
||||
/// The Alternate Graphics (<kbd>AltGr</kbd> or <kbd>AltGraph</kbd>) key.
|
||||
///
|
||||
/// This key is used enable the ISO Level 3 shift modifier (the standard `Shift` key is the
|
||||
/// level 2 modifier).
|
||||
AltGraph,
|
||||
/// The `Caps Lock` (Capital) key.
|
||||
///
|
||||
/// Toggle capital character lock function for interpreting subsequent keyboard input event.
|
||||
CapsLock,
|
||||
/// The `Control` or `Ctrl` key.
|
||||
///
|
||||
/// Used to enable control modifier function for interpreting concurrent or subsequent keyboard
|
||||
/// input.
|
||||
Control,
|
||||
/// The Function switch `Fn` key. Activating this key simultaneously with another key changes
|
||||
/// that key’s value to an alternate character or function. This key is often handled directly
|
||||
/// in the keyboard hardware and does not usually generate key events.
|
||||
Fn,
|
||||
/// The Function-Lock (`FnLock` or `F-Lock`) key. Activating this key switches the mode of the
|
||||
/// keyboard to changes some keys' values to an alternate character or function. This key is
|
||||
/// often handled directly in the keyboard hardware and does not usually generate key events.
|
||||
FnLock,
|
||||
/// The `NumLock` or Number Lock key. Used to toggle numpad mode function for interpreting
|
||||
/// subsequent keyboard input.
|
||||
NumLock,
|
||||
/// Toggle between scrolling and cursor movement modes.
|
||||
ScrollLock,
|
||||
/// Used to enable shift modifier function for interpreting concurrent or subsequent keyboard
|
||||
/// input.
|
||||
Shift,
|
||||
/// The Symbol modifier key (used on some virtual keyboards).
|
||||
Symbol,
|
||||
SymbolLock,
|
||||
// Legacy modifier key. Also called "Super" in certain places.
|
||||
Meta,
|
||||
// Legacy modifier key.
|
||||
Hyper,
|
||||
/// Used to enable "super" modifier function for interpreting concurrent or subsequent keyboard
|
||||
/// input. This key value is used for the "Windows Logo" key and the Apple `Command` or `⌘` key.
|
||||
///
|
||||
/// Note: In some contexts (e.g. the Web) this is referred to as the "Meta" key.
|
||||
Super,
|
||||
/// The `Enter` or `↵` key. Used to activate current selection or accept current input. This key
|
||||
/// value is also used for the `Return` (Macintosh numpad) key. This key value is also used for
|
||||
/// the Android `KEYCODE_DPAD_CENTER`.
|
||||
Enter,
|
||||
/// The Horizontal Tabulation `Tab` key.
|
||||
Tab,
|
||||
/// Used in text to insert a space between words. Usually located below the character keys.
|
||||
Space,
|
||||
/// Navigate or traverse downward. (`KEYCODE_DPAD_DOWN`)
|
||||
ArrowDown,
|
||||
/// Navigate or traverse leftward. (`KEYCODE_DPAD_LEFT`)
|
||||
ArrowLeft,
|
||||
/// Navigate or traverse rightward. (`KEYCODE_DPAD_RIGHT`)
|
||||
ArrowRight,
|
||||
/// Navigate or traverse upward. (`KEYCODE_DPAD_UP`)
|
||||
ArrowUp,
|
||||
/// The End key, used with keyboard entry to go to the end of content (`KEYCODE_MOVE_END`).
|
||||
End,
|
||||
/// The Home key, used with keyboard entry, to go to start of content (`KEYCODE_MOVE_HOME`).
|
||||
/// For the mobile phone `Home` key (which goes to the phone’s main screen), use [`GoHome`].
|
||||
///
|
||||
/// [`GoHome`]: Self::GoHome
|
||||
Home,
|
||||
/// Scroll down or display next page of content.
|
||||
PageDown,
|
||||
/// Scroll up or display previous page of content.
|
||||
PageUp,
|
||||
/// Used to remove the character to the left of the cursor. This key value is also used for
|
||||
/// the key labeled `Delete` on MacOS keyboards.
|
||||
Backspace,
|
||||
/// Remove the currently selected input.
|
||||
Clear,
|
||||
/// Copy the current selection. (`APPCOMMAND_COPY`)
|
||||
Copy,
|
||||
/// The Cursor Select key.
|
||||
CrSel,
|
||||
/// Cut the current selection. (`APPCOMMAND_CUT`)
|
||||
Cut,
|
||||
/// Used to delete the character to the right of the cursor. This key value is also used for the
|
||||
/// key labeled `Delete` on MacOS keyboards when `Fn` is active.
|
||||
Delete,
|
||||
/// The Erase to End of Field key. This key deletes all characters from the current cursor
|
||||
/// position to the end of the current field.
|
||||
EraseEof,
|
||||
/// The Extend Selection (Exsel) key.
|
||||
ExSel,
|
||||
/// Toggle between text modes for insertion or overtyping.
|
||||
/// (`KEYCODE_INSERT`)
|
||||
Insert,
|
||||
/// The Paste key. (`APPCOMMAND_PASTE`)
|
||||
Paste,
|
||||
/// Redo the last action. (`APPCOMMAND_REDO`)
|
||||
Redo,
|
||||
/// Undo the last action. (`APPCOMMAND_UNDO`)
|
||||
Undo,
|
||||
/// The Accept (Commit, OK) key. Accept current option or input method sequence conversion.
|
||||
Accept,
|
||||
/// Redo or repeat an action.
|
||||
Again,
|
||||
/// The Attention (Attn) key.
|
||||
Attn,
|
||||
Cancel,
|
||||
/// Show the application’s context menu.
|
||||
/// This key is commonly found between the right `Super` key and the right `Control` key.
|
||||
ContextMenu,
|
||||
/// The `Esc` key. This key was originally used to initiate an escape sequence, but is
|
||||
/// now more generally used to exit or "escape" the current context, such as closing a dialog
|
||||
/// or exiting full screen mode.
|
||||
Escape,
|
||||
Execute,
|
||||
/// Open the Find dialog. (`APPCOMMAND_FIND`)
|
||||
Find,
|
||||
/// Open a help dialog or toggle display of help information. (`APPCOMMAND_HELP`,
|
||||
/// `KEYCODE_HELP`)
|
||||
Help,
|
||||
/// Pause the current state or application (as appropriate).
|
||||
///
|
||||
/// Note: Do not use this value for the `Pause` button on media controllers. Use `"MediaPause"`
|
||||
/// instead.
|
||||
Pause,
|
||||
/// Play or resume the current state or application (as appropriate).
|
||||
///
|
||||
/// Note: Do not use this value for the `Play` button on media controllers. Use `"MediaPlay"`
|
||||
/// instead.
|
||||
Play,
|
||||
/// The properties (Props) key.
|
||||
Props,
|
||||
Select,
|
||||
/// The ZoomIn key. (`KEYCODE_ZOOM_IN`)
|
||||
ZoomIn,
|
||||
/// The ZoomOut key. (`KEYCODE_ZOOM_OUT`)
|
||||
ZoomOut,
|
||||
/// The Brightness Down key. Typically controls the display brightness.
|
||||
/// (`KEYCODE_BRIGHTNESS_DOWN`)
|
||||
BrightnessDown,
|
||||
/// The Brightness Up key. Typically controls the display brightness. (`KEYCODE_BRIGHTNESS_UP`)
|
||||
BrightnessUp,
|
||||
/// Toggle removable media to eject (open) and insert (close) state. (`KEYCODE_MEDIA_EJECT`)
|
||||
Eject,
|
||||
LogOff,
|
||||
/// Toggle power state. (`KEYCODE_POWER`)
|
||||
/// Note: Note: Some devices might not expose this key to the operating environment.
|
||||
Power,
|
||||
/// The `PowerOff` key. Sometime called `PowerDown`.
|
||||
PowerOff,
|
||||
/// Initiate print-screen function.
|
||||
PrintScreen,
|
||||
/// The Hibernate key. This key saves the current state of the computer to disk so that it can
|
||||
/// be restored. The computer will then shutdown.
|
||||
Hibernate,
|
||||
/// The Standby key. This key turns off the display and places the computer into a low-power
|
||||
/// mode without completely shutting down. It is sometimes labelled `Suspend` or `Sleep` key.
|
||||
/// (`KEYCODE_SLEEP`)
|
||||
Standby,
|
||||
/// The WakeUp key. (`KEYCODE_WAKEUP`)
|
||||
WakeUp,
|
||||
/// Initate the multi-candidate mode.
|
||||
AllCandidates,
|
||||
Alphanumeric,
|
||||
/// Initiate the Code Input mode to allow characters to be entered by
|
||||
/// their code points.
|
||||
CodeInput,
|
||||
/// The Compose key, also known as "Multi_key" on the X Window System. This key acts in a
|
||||
/// manner similar to a dead key, triggering a mode where subsequent key presses are combined to
|
||||
/// produce a different character.
|
||||
Compose,
|
||||
/// Convert the current input method sequence.
|
||||
Convert,
|
||||
/// The Final Mode `Final` key used on some Asian keyboards, to enable the final mode for IMEs.
|
||||
FinalMode,
|
||||
/// Switch to the first character group. (ISO/IEC 9995)
|
||||
GroupFirst,
|
||||
/// Switch to the last character group. (ISO/IEC 9995)
|
||||
GroupLast,
|
||||
/// Switch to the next character group. (ISO/IEC 9995)
|
||||
GroupNext,
|
||||
/// Switch to the previous character group. (ISO/IEC 9995)
|
||||
GroupPrevious,
|
||||
/// Toggle between or cycle through input modes of IMEs.
|
||||
ModeChange,
|
||||
NextCandidate,
|
||||
/// Accept current input method sequence without
|
||||
/// conversion in IMEs.
|
||||
NonConvert,
|
||||
PreviousCandidate,
|
||||
Process,
|
||||
SingleCandidate,
|
||||
/// Toggle between Hangul and English modes.
|
||||
HangulMode,
|
||||
HanjaMode,
|
||||
JunjaMode,
|
||||
/// The Eisu key. This key may close the IME, but its purpose is defined by the current IME.
|
||||
/// (`KEYCODE_EISU`)
|
||||
Eisu,
|
||||
/// The (Half-Width) Characters key.
|
||||
Hankaku,
|
||||
/// The Hiragana (Japanese Kana characters) key.
|
||||
Hiragana,
|
||||
/// The Hiragana/Katakana toggle key. (`KEYCODE_KATAKANA_HIRAGANA`)
|
||||
HiraganaKatakana,
|
||||
/// The Kana Mode (Kana Lock) key. This key is used to enter hiragana mode (typically from
|
||||
/// romaji mode).
|
||||
KanaMode,
|
||||
/// The Kanji (Japanese name for ideographic characters of Chinese origin) Mode key. This key is
|
||||
/// typically used to switch to a hiragana keyboard for the purpose of converting input into
|
||||
/// kanji. (`KEYCODE_KANA`)
|
||||
KanjiMode,
|
||||
/// The Katakana (Japanese Kana characters) key.
|
||||
Katakana,
|
||||
/// The Roman characters function key.
|
||||
Romaji,
|
||||
/// The Zenkaku (Full-Width) Characters key.
|
||||
Zenkaku,
|
||||
/// The Zenkaku/Hankaku (full-width/half-width) toggle key. (`KEYCODE_ZENKAKU_HANKAKU`)
|
||||
ZenkakuHankaku,
|
||||
/// General purpose virtual function key, as index 1.
|
||||
Soft1,
|
||||
/// General purpose virtual function key, as index 2.
|
||||
Soft2,
|
||||
/// General purpose virtual function key, as index 3.
|
||||
Soft3,
|
||||
/// General purpose virtual function key, as index 4.
|
||||
Soft4,
|
||||
/// Select next (numerically or logically) lower channel. (`APPCOMMAND_MEDIA_CHANNEL_DOWN`,
|
||||
/// `KEYCODE_CHANNEL_DOWN`)
|
||||
ChannelDown,
|
||||
/// Select next (numerically or logically) higher channel. (`APPCOMMAND_MEDIA_CHANNEL_UP`,
|
||||
/// `KEYCODE_CHANNEL_UP`)
|
||||
ChannelUp,
|
||||
/// Close the current document or message (Note: This doesn’t close the application).
|
||||
/// (`APPCOMMAND_CLOSE`)
|
||||
Close,
|
||||
/// Open an editor to forward the current message. (`APPCOMMAND_FORWARD_MAIL`)
|
||||
MailForward,
|
||||
/// Open an editor to reply to the current message. (`APPCOMMAND_REPLY_TO_MAIL`)
|
||||
MailReply,
|
||||
/// Send the current message. (`APPCOMMAND_SEND_MAIL`)
|
||||
MailSend,
|
||||
/// Close the current media, for example to close a CD or DVD tray. (`KEYCODE_MEDIA_CLOSE`)
|
||||
MediaClose,
|
||||
/// Initiate or continue forward playback at faster than normal speed, or increase speed if
|
||||
/// already fast forwarding. (`APPCOMMAND_MEDIA_FAST_FORWARD`, `KEYCODE_MEDIA_FAST_FORWARD`)
|
||||
MediaFastForward,
|
||||
/// Pause the currently playing media. (`APPCOMMAND_MEDIA_PAUSE`, `KEYCODE_MEDIA_PAUSE`)
|
||||
///
|
||||
/// Note: Media controller devices should use this value rather than `"Pause"` for their pause
|
||||
/// keys.
|
||||
MediaPause,
|
||||
/// Initiate or continue media playback at normal speed, if not currently playing at normal
|
||||
/// speed. (`APPCOMMAND_MEDIA_PLAY`, `KEYCODE_MEDIA_PLAY`)
|
||||
MediaPlay,
|
||||
/// Toggle media between play and pause states. (`APPCOMMAND_MEDIA_PLAY_PAUSE`,
|
||||
/// `KEYCODE_MEDIA_PLAY_PAUSE`)
|
||||
MediaPlayPause,
|
||||
/// Initiate or resume recording of currently selected media. (`APPCOMMAND_MEDIA_RECORD`,
|
||||
/// `KEYCODE_MEDIA_RECORD`)
|
||||
MediaRecord,
|
||||
/// Initiate or continue reverse playback at faster than normal speed, or increase speed if
|
||||
/// already rewinding. (`APPCOMMAND_MEDIA_REWIND`, `KEYCODE_MEDIA_REWIND`)
|
||||
MediaRewind,
|
||||
/// Stop media playing, pausing, forwarding, rewinding, or recording, if not already stopped.
|
||||
/// (`APPCOMMAND_MEDIA_STOP`, `KEYCODE_MEDIA_STOP`)
|
||||
MediaStop,
|
||||
/// Seek to next media or program track. (`APPCOMMAND_MEDIA_NEXTTRACK`, `KEYCODE_MEDIA_NEXT`)
|
||||
MediaTrackNext,
|
||||
/// Seek to previous media or program track. (`APPCOMMAND_MEDIA_PREVIOUSTRACK`,
|
||||
/// `KEYCODE_MEDIA_PREVIOUS`)
|
||||
MediaTrackPrevious,
|
||||
/// Open a new document or message. (`APPCOMMAND_NEW`)
|
||||
New,
|
||||
/// Open an existing document or message. (`APPCOMMAND_OPEN`)
|
||||
Open,
|
||||
/// Print the current document or message. (`APPCOMMAND_PRINT`)
|
||||
Print,
|
||||
/// Save the current document or message. (`APPCOMMAND_SAVE`)
|
||||
Save,
|
||||
/// Spellcheck the current document or selection. (`APPCOMMAND_SPELL_CHECK`)
|
||||
SpellCheck,
|
||||
/// The `11` key found on media numpads that
|
||||
/// have buttons from `1` ... `12`.
|
||||
Key11,
|
||||
/// The `12` key found on media numpads that
|
||||
/// have buttons from `1` ... `12`.
|
||||
Key12,
|
||||
/// Adjust audio balance leftward. (`VK_AUDIO_BALANCE_LEFT`)
|
||||
AudioBalanceLeft,
|
||||
/// Adjust audio balance rightward. (`VK_AUDIO_BALANCE_RIGHT`)
|
||||
AudioBalanceRight,
|
||||
/// Decrease audio bass boost or cycle down through bass boost states. (`APPCOMMAND_BASS_DOWN`,
|
||||
/// `VK_BASS_BOOST_DOWN`)
|
||||
AudioBassBoostDown,
|
||||
/// Toggle bass boost on/off. (`APPCOMMAND_BASS_BOOST`)
|
||||
AudioBassBoostToggle,
|
||||
/// Increase audio bass boost or cycle up through bass boost states. (`APPCOMMAND_BASS_UP`,
|
||||
/// `VK_BASS_BOOST_UP`)
|
||||
AudioBassBoostUp,
|
||||
/// Adjust audio fader towards front. (`VK_FADER_FRONT`)
|
||||
AudioFaderFront,
|
||||
/// Adjust audio fader towards rear. (`VK_FADER_REAR`)
|
||||
AudioFaderRear,
|
||||
/// Advance surround audio mode to next available mode. (`VK_SURROUND_MODE_NEXT`)
|
||||
AudioSurroundModeNext,
|
||||
/// Decrease treble. (`APPCOMMAND_TREBLE_DOWN`)
|
||||
AudioTrebleDown,
|
||||
/// Increase treble. (`APPCOMMAND_TREBLE_UP`)
|
||||
AudioTrebleUp,
|
||||
/// Decrease audio volume. (`APPCOMMAND_VOLUME_DOWN`, `KEYCODE_VOLUME_DOWN`)
|
||||
AudioVolumeDown,
|
||||
/// Increase audio volume. (`APPCOMMAND_VOLUME_UP`, `KEYCODE_VOLUME_UP`)
|
||||
AudioVolumeUp,
|
||||
/// Toggle between muted state and prior volume level. (`APPCOMMAND_VOLUME_MUTE`,
|
||||
/// `KEYCODE_VOLUME_MUTE`)
|
||||
AudioVolumeMute,
|
||||
/// Toggle the microphone on/off. (`APPCOMMAND_MIC_ON_OFF_TOGGLE`)
|
||||
MicrophoneToggle,
|
||||
/// Decrease microphone volume. (`APPCOMMAND_MICROPHONE_VOLUME_DOWN`)
|
||||
MicrophoneVolumeDown,
|
||||
/// Increase microphone volume. (`APPCOMMAND_MICROPHONE_VOLUME_UP`)
|
||||
MicrophoneVolumeUp,
|
||||
/// Mute the microphone. (`APPCOMMAND_MICROPHONE_VOLUME_MUTE`, `KEYCODE_MUTE`)
|
||||
MicrophoneVolumeMute,
|
||||
/// Show correction list when a word is incorrectly identified. (`APPCOMMAND_CORRECTION_LIST`)
|
||||
SpeechCorrectionList,
|
||||
/// Toggle between dictation mode and command/control mode.
|
||||
/// (`APPCOMMAND_DICTATE_OR_COMMAND_CONTROL_TOGGLE`)
|
||||
SpeechInputToggle,
|
||||
/// The first generic "LaunchApplication" key. This is commonly associated with launching "My
|
||||
/// Computer", and may have a computer symbol on the key. (`APPCOMMAND_LAUNCH_APP1`)
|
||||
LaunchApplication1,
|
||||
/// The second generic "LaunchApplication" key. This is commonly associated with launching
|
||||
/// "Calculator", and may have a calculator symbol on the key. (`APPCOMMAND_LAUNCH_APP2`,
|
||||
/// `KEYCODE_CALCULATOR`)
|
||||
LaunchApplication2,
|
||||
/// The "Calendar" key. (`KEYCODE_CALENDAR`)
|
||||
LaunchCalendar,
|
||||
/// The "Contacts" key. (`KEYCODE_CONTACTS`)
|
||||
LaunchContacts,
|
||||
/// The "Mail" key. (`APPCOMMAND_LAUNCH_MAIL`)
|
||||
LaunchMail,
|
||||
/// The "Media Player" key. (`APPCOMMAND_LAUNCH_MEDIA_SELECT`)
|
||||
LaunchMediaPlayer,
|
||||
LaunchMusicPlayer,
|
||||
LaunchPhone,
|
||||
LaunchScreenSaver,
|
||||
LaunchSpreadsheet,
|
||||
LaunchWebBrowser,
|
||||
LaunchWebCam,
|
||||
LaunchWordProcessor,
|
||||
/// Navigate to previous content or page in current history. (`APPCOMMAND_BROWSER_BACKWARD`)
|
||||
BrowserBack,
|
||||
/// Open the list of browser favorites. (`APPCOMMAND_BROWSER_FAVORITES`)
|
||||
BrowserFavorites,
|
||||
/// Navigate to next content or page in current history. (`APPCOMMAND_BROWSER_FORWARD`)
|
||||
BrowserForward,
|
||||
/// Go to the user’s preferred home page. (`APPCOMMAND_BROWSER_HOME`)
|
||||
BrowserHome,
|
||||
/// Refresh the current page or content. (`APPCOMMAND_BROWSER_REFRESH`)
|
||||
BrowserRefresh,
|
||||
/// Call up the user’s preferred search page. (`APPCOMMAND_BROWSER_SEARCH`)
|
||||
BrowserSearch,
|
||||
/// Stop loading the current page or content. (`APPCOMMAND_BROWSER_STOP`)
|
||||
BrowserStop,
|
||||
/// The Application switch key, which provides a list of recent apps to switch between.
|
||||
/// (`KEYCODE_APP_SWITCH`)
|
||||
AppSwitch,
|
||||
/// The Call key. (`KEYCODE_CALL`)
|
||||
Call,
|
||||
/// The Camera key. (`KEYCODE_CAMERA`)
|
||||
Camera,
|
||||
/// The Camera focus key. (`KEYCODE_FOCUS`)
|
||||
CameraFocus,
|
||||
/// The End Call key. (`KEYCODE_ENDCALL`)
|
||||
EndCall,
|
||||
/// The Back key. (`KEYCODE_BACK`)
|
||||
GoBack,
|
||||
/// The Home key, which goes to the phone’s main screen. (`KEYCODE_HOME`)
|
||||
GoHome,
|
||||
/// The Headset Hook key. (`KEYCODE_HEADSETHOOK`)
|
||||
HeadsetHook,
|
||||
LastNumberRedial,
|
||||
/// The Notification key. (`KEYCODE_NOTIFICATION`)
|
||||
Notification,
|
||||
/// Toggle between manner mode state: silent, vibrate, ring, ... (`KEYCODE_MANNER_MODE`)
|
||||
MannerMode,
|
||||
VoiceDial,
|
||||
/// Switch to viewing TV. (`KEYCODE_TV`)
|
||||
TV,
|
||||
/// TV 3D Mode. (`KEYCODE_3D_MODE`)
|
||||
TV3DMode,
|
||||
/// Toggle between antenna and cable input. (`KEYCODE_TV_ANTENNA_CABLE`)
|
||||
TVAntennaCable,
|
||||
/// Audio description. (`KEYCODE_TV_AUDIO_DESCRIPTION`)
|
||||
TVAudioDescription,
|
||||
/// Audio description mixing volume down. (`KEYCODE_TV_AUDIO_DESCRIPTION_MIX_DOWN`)
|
||||
TVAudioDescriptionMixDown,
|
||||
/// Audio description mixing volume up. (`KEYCODE_TV_AUDIO_DESCRIPTION_MIX_UP`)
|
||||
TVAudioDescriptionMixUp,
|
||||
/// Contents menu. (`KEYCODE_TV_CONTENTS_MENU`)
|
||||
TVContentsMenu,
|
||||
/// Contents menu. (`KEYCODE_TV_DATA_SERVICE`)
|
||||
TVDataService,
|
||||
/// Switch the input mode on an external TV. (`KEYCODE_TV_INPUT`)
|
||||
TVInput,
|
||||
/// Switch to component input #1. (`KEYCODE_TV_INPUT_COMPONENT_1`)
|
||||
TVInputComponent1,
|
||||
/// Switch to component input #2. (`KEYCODE_TV_INPUT_COMPONENT_2`)
|
||||
TVInputComponent2,
|
||||
/// Switch to composite input #1. (`KEYCODE_TV_INPUT_COMPOSITE_1`)
|
||||
TVInputComposite1,
|
||||
/// Switch to composite input #2. (`KEYCODE_TV_INPUT_COMPOSITE_2`)
|
||||
TVInputComposite2,
|
||||
/// Switch to HDMI input #1. (`KEYCODE_TV_INPUT_HDMI_1`)
|
||||
TVInputHDMI1,
|
||||
/// Switch to HDMI input #2. (`KEYCODE_TV_INPUT_HDMI_2`)
|
||||
TVInputHDMI2,
|
||||
/// Switch to HDMI input #3. (`KEYCODE_TV_INPUT_HDMI_3`)
|
||||
TVInputHDMI3,
|
||||
/// Switch to HDMI input #4. (`KEYCODE_TV_INPUT_HDMI_4`)
|
||||
TVInputHDMI4,
|
||||
/// Switch to VGA input #1. (`KEYCODE_TV_INPUT_VGA_1`)
|
||||
TVInputVGA1,
|
||||
/// Media context menu. (`KEYCODE_TV_MEDIA_CONTEXT_MENU`)
|
||||
TVMediaContext,
|
||||
/// Toggle network. (`KEYCODE_TV_NETWORK`)
|
||||
TVNetwork,
|
||||
/// Number entry. (`KEYCODE_TV_NUMBER_ENTRY`)
|
||||
TVNumberEntry,
|
||||
/// Toggle the power on an external TV. (`KEYCODE_TV_POWER`)
|
||||
TVPower,
|
||||
/// Radio. (`KEYCODE_TV_RADIO_SERVICE`)
|
||||
TVRadioService,
|
||||
/// Satellite. (`KEYCODE_TV_SATELLITE`)
|
||||
TVSatellite,
|
||||
/// Broadcast Satellite. (`KEYCODE_TV_SATELLITE_BS`)
|
||||
TVSatelliteBS,
|
||||
/// Communication Satellite. (`KEYCODE_TV_SATELLITE_CS`)
|
||||
TVSatelliteCS,
|
||||
/// Toggle between available satellites. (`KEYCODE_TV_SATELLITE_SERVICE`)
|
||||
TVSatelliteToggle,
|
||||
/// Analog Terrestrial. (`KEYCODE_TV_TERRESTRIAL_ANALOG`)
|
||||
TVTerrestrialAnalog,
|
||||
/// Digital Terrestrial. (`KEYCODE_TV_TERRESTRIAL_DIGITAL`)
|
||||
TVTerrestrialDigital,
|
||||
/// Timer programming. (`KEYCODE_TV_TIMER_PROGRAMMING`)
|
||||
TVTimer,
|
||||
/// Switch the input mode on an external AVR (audio/video receiver). (`KEYCODE_AVR_INPUT`)
|
||||
AVRInput,
|
||||
/// Toggle the power on an external AVR (audio/video receiver). (`KEYCODE_AVR_POWER`)
|
||||
AVRPower,
|
||||
/// General purpose color-coded media function key, as index 0 (red). (`VK_COLORED_KEY_0`,
|
||||
/// `KEYCODE_PROG_RED`)
|
||||
ColorF0Red,
|
||||
/// General purpose color-coded media function key, as index 1 (green). (`VK_COLORED_KEY_1`,
|
||||
/// `KEYCODE_PROG_GREEN`)
|
||||
ColorF1Green,
|
||||
/// General purpose color-coded media function key, as index 2 (yellow). (`VK_COLORED_KEY_2`,
|
||||
/// `KEYCODE_PROG_YELLOW`)
|
||||
ColorF2Yellow,
|
||||
/// General purpose color-coded media function key, as index 3 (blue). (`VK_COLORED_KEY_3`,
|
||||
/// `KEYCODE_PROG_BLUE`)
|
||||
ColorF3Blue,
|
||||
/// General purpose color-coded media function key, as index 4 (grey). (`VK_COLORED_KEY_4`)
|
||||
ColorF4Grey,
|
||||
/// General purpose color-coded media function key, as index 5 (brown). (`VK_COLORED_KEY_5`)
|
||||
ColorF5Brown,
|
||||
/// Toggle the display of Closed Captions. (`VK_CC`, `KEYCODE_CAPTIONS`)
|
||||
ClosedCaptionToggle,
|
||||
/// Adjust brightness of device, by toggling between or cycling through states. (`VK_DIMMER`)
|
||||
Dimmer,
|
||||
/// Swap video sources. (`VK_DISPLAY_SWAP`)
|
||||
DisplaySwap,
|
||||
/// Select Digital Video Rrecorder. (`KEYCODE_DVR`)
|
||||
DVR,
|
||||
/// Exit the current application. (`VK_EXIT`)
|
||||
Exit,
|
||||
/// Clear program or content stored as favorite 0. (`VK_CLEAR_FAVORITE_0`)
|
||||
FavoriteClear0,
|
||||
/// Clear program or content stored as favorite 1. (`VK_CLEAR_FAVORITE_1`)
|
||||
FavoriteClear1,
|
||||
/// Clear program or content stored as favorite 2. (`VK_CLEAR_FAVORITE_2`)
|
||||
FavoriteClear2,
|
||||
/// Clear program or content stored as favorite 3. (`VK_CLEAR_FAVORITE_3`)
|
||||
FavoriteClear3,
|
||||
/// Select (recall) program or content stored as favorite 0. (`VK_RECALL_FAVORITE_0`)
|
||||
FavoriteRecall0,
|
||||
/// Select (recall) program or content stored as favorite 1. (`VK_RECALL_FAVORITE_1`)
|
||||
FavoriteRecall1,
|
||||
/// Select (recall) program or content stored as favorite 2. (`VK_RECALL_FAVORITE_2`)
|
||||
FavoriteRecall2,
|
||||
/// Select (recall) program or content stored as favorite 3. (`VK_RECALL_FAVORITE_3`)
|
||||
FavoriteRecall3,
|
||||
/// Store current program or content as favorite 0. (`VK_STORE_FAVORITE_0`)
|
||||
FavoriteStore0,
|
||||
/// Store current program or content as favorite 1. (`VK_STORE_FAVORITE_1`)
|
||||
FavoriteStore1,
|
||||
/// Store current program or content as favorite 2. (`VK_STORE_FAVORITE_2`)
|
||||
FavoriteStore2,
|
||||
/// Store current program or content as favorite 3. (`VK_STORE_FAVORITE_3`)
|
||||
FavoriteStore3,
|
||||
/// Toggle display of program or content guide. (`VK_GUIDE`, `KEYCODE_GUIDE`)
|
||||
Guide,
|
||||
/// If guide is active and displayed, then display next day’s content. (`VK_NEXT_DAY`)
|
||||
GuideNextDay,
|
||||
/// If guide is active and displayed, then display previous day’s content. (`VK_PREV_DAY`)
|
||||
GuidePreviousDay,
|
||||
/// Toggle display of information about currently selected context or media. (`VK_INFO`,
|
||||
/// `KEYCODE_INFO`)
|
||||
Info,
|
||||
/// Toggle instant replay. (`VK_INSTANT_REPLAY`)
|
||||
InstantReplay,
|
||||
/// Launch linked content, if available and appropriate. (`VK_LINK`)
|
||||
Link,
|
||||
/// List the current program. (`VK_LIST`)
|
||||
ListProgram,
|
||||
/// Toggle display listing of currently available live content or programs. (`VK_LIVE`)
|
||||
LiveContent,
|
||||
/// Lock or unlock current content or program. (`VK_LOCK`)
|
||||
Lock,
|
||||
/// Show a list of media applications: audio/video players and image viewers. (`VK_APPS`)
|
||||
///
|
||||
/// Note: Do not confuse this key value with the Windows' `VK_APPS` / `VK_CONTEXT_MENU` key,
|
||||
/// which is encoded as `"ContextMenu"`.
|
||||
MediaApps,
|
||||
/// Audio track key. (`KEYCODE_MEDIA_AUDIO_TRACK`)
|
||||
MediaAudioTrack,
|
||||
/// Select previously selected channel or media. (`VK_LAST`, `KEYCODE_LAST_CHANNEL`)
|
||||
MediaLast,
|
||||
/// Skip backward to next content or program. (`KEYCODE_MEDIA_SKIP_BACKWARD`)
|
||||
MediaSkipBackward,
|
||||
/// Skip forward to next content or program. (`VK_SKIP`, `KEYCODE_MEDIA_SKIP_FORWARD`)
|
||||
MediaSkipForward,
|
||||
/// Step backward to next content or program. (`KEYCODE_MEDIA_STEP_BACKWARD`)
|
||||
MediaStepBackward,
|
||||
/// Step forward to next content or program. (`KEYCODE_MEDIA_STEP_FORWARD`)
|
||||
MediaStepForward,
|
||||
/// Media top menu. (`KEYCODE_MEDIA_TOP_MENU`)
|
||||
MediaTopMenu,
|
||||
/// Navigate in. (`KEYCODE_NAVIGATE_IN`)
|
||||
NavigateIn,
|
||||
/// Navigate to next key. (`KEYCODE_NAVIGATE_NEXT`)
|
||||
NavigateNext,
|
||||
/// Navigate out. (`KEYCODE_NAVIGATE_OUT`)
|
||||
NavigateOut,
|
||||
/// Navigate to previous key. (`KEYCODE_NAVIGATE_PREVIOUS`)
|
||||
NavigatePrevious,
|
||||
/// Cycle to next favorite channel (in favorites list). (`VK_NEXT_FAVORITE_CHANNEL`)
|
||||
NextFavoriteChannel,
|
||||
/// Cycle to next user profile (if there are multiple user profiles). (`VK_USER`)
|
||||
NextUserProfile,
|
||||
/// Access on-demand content or programs. (`VK_ON_DEMAND`)
|
||||
OnDemand,
|
||||
/// Pairing key to pair devices. (`KEYCODE_PAIRING`)
|
||||
Pairing,
|
||||
/// Move picture-in-picture window down. (`VK_PINP_DOWN`)
|
||||
PinPDown,
|
||||
/// Move picture-in-picture window. (`VK_PINP_MOVE`)
|
||||
PinPMove,
|
||||
/// Toggle display of picture-in-picture window. (`VK_PINP_TOGGLE`)
|
||||
PinPToggle,
|
||||
/// Move picture-in-picture window up. (`VK_PINP_UP`)
|
||||
PinPUp,
|
||||
/// Decrease media playback speed. (`VK_PLAY_SPEED_DOWN`)
|
||||
PlaySpeedDown,
|
||||
/// Reset playback to normal speed. (`VK_PLAY_SPEED_RESET`)
|
||||
PlaySpeedReset,
|
||||
/// Increase media playback speed. (`VK_PLAY_SPEED_UP`)
|
||||
PlaySpeedUp,
|
||||
/// Toggle random media or content shuffle mode. (`VK_RANDOM_TOGGLE`)
|
||||
RandomToggle,
|
||||
/// Not a physical key, but this key code is sent when the remote control battery is low.
|
||||
/// (`VK_RC_LOW_BATTERY`)
|
||||
RcLowBattery,
|
||||
/// Toggle or cycle between media recording speeds. (`VK_RECORD_SPEED_NEXT`)
|
||||
RecordSpeedNext,
|
||||
/// Toggle RF (radio frequency) input bypass mode (pass RF input directly to the RF output).
|
||||
/// (`VK_RF_BYPASS`)
|
||||
RfBypass,
|
||||
/// Toggle scan channels mode. (`VK_SCAN_CHANNELS_TOGGLE`)
|
||||
ScanChannelsToggle,
|
||||
/// Advance display screen mode to next available mode. (`VK_SCREEN_MODE_NEXT`)
|
||||
ScreenModeNext,
|
||||
/// Toggle display of device settings screen. (`VK_SETTINGS`, `KEYCODE_SETTINGS`)
|
||||
Settings,
|
||||
/// Toggle split screen mode. (`VK_SPLIT_SCREEN_TOGGLE`)
|
||||
SplitScreenToggle,
|
||||
/// Switch the input mode on an external STB (set top box). (`KEYCODE_STB_INPUT`)
|
||||
STBInput,
|
||||
/// Toggle the power on an external STB (set top box). (`KEYCODE_STB_POWER`)
|
||||
STBPower,
|
||||
/// Toggle display of subtitles, if available. (`VK_SUBTITLE`)
|
||||
Subtitle,
|
||||
/// Toggle display of teletext, if available (`VK_TELETEXT`, `KEYCODE_TV_TELETEXT`).
|
||||
Teletext,
|
||||
/// Advance video mode to next available mode. (`VK_VIDEO_MODE_NEXT`)
|
||||
VideoModeNext,
|
||||
/// Cause device to identify itself in some manner, e.g., audibly or visibly. (`VK_WINK`)
|
||||
Wink,
|
||||
/// Toggle between full-screen and scaled content, or alter magnification level. (`VK_ZOOM`,
|
||||
/// `KEYCODE_TV_ZOOM_MODE`)
|
||||
ZoomToggle,
|
||||
/// General-purpose function key.
|
||||
/// Usually found at the top of the keyboard.
|
||||
F1,
|
||||
/// General-purpose function key.
|
||||
/// Usually found at the top of the keyboard.
|
||||
F2,
|
||||
/// General-purpose function key.
|
||||
/// Usually found at the top of the keyboard.
|
||||
F3,
|
||||
/// General-purpose function key.
|
||||
/// Usually found at the top of the keyboard.
|
||||
F4,
|
||||
/// General-purpose function key.
|
||||
/// Usually found at the top of the keyboard.
|
||||
F5,
|
||||
/// General-purpose function key.
|
||||
/// Usually found at the top of the keyboard.
|
||||
F6,
|
||||
/// General-purpose function key.
|
||||
/// Usually found at the top of the keyboard.
|
||||
F7,
|
||||
/// General-purpose function key.
|
||||
/// Usually found at the top of the keyboard.
|
||||
F8,
|
||||
/// General-purpose function key.
|
||||
/// Usually found at the top of the keyboard.
|
||||
F9,
|
||||
/// General-purpose function key.
|
||||
/// Usually found at the top of the keyboard.
|
||||
F10,
|
||||
/// General-purpose function key.
|
||||
/// Usually found at the top of the keyboard.
|
||||
F11,
|
||||
/// General-purpose function key.
|
||||
/// Usually found at the top of the keyboard.
|
||||
F12,
|
||||
/// General-purpose function key.
|
||||
/// Usually found at the top of the keyboard.
|
||||
F13,
|
||||
/// General-purpose function key.
|
||||
/// Usually found at the top of the keyboard.
|
||||
F14,
|
||||
/// General-purpose function key.
|
||||
/// Usually found at the top of the keyboard.
|
||||
F15,
|
||||
/// General-purpose function key.
|
||||
/// Usually found at the top of the keyboard.
|
||||
F16,
|
||||
/// General-purpose function key.
|
||||
/// Usually found at the top of the keyboard.
|
||||
F17,
|
||||
/// General-purpose function key.
|
||||
/// Usually found at the top of the keyboard.
|
||||
F18,
|
||||
/// General-purpose function key.
|
||||
/// Usually found at the top of the keyboard.
|
||||
F19,
|
||||
/// General-purpose function key.
|
||||
/// Usually found at the top of the keyboard.
|
||||
F20,
|
||||
/// General-purpose function key.
|
||||
/// Usually found at the top of the keyboard.
|
||||
F21,
|
||||
/// General-purpose function key.
|
||||
/// Usually found at the top of the keyboard.
|
||||
F22,
|
||||
/// General-purpose function key.
|
||||
/// Usually found at the top of the keyboard.
|
||||
F23,
|
||||
/// General-purpose function key.
|
||||
/// Usually found at the top of the keyboard.
|
||||
F24,
|
||||
/// General-purpose function key.
|
||||
F25,
|
||||
/// General-purpose function key.
|
||||
F26,
|
||||
/// General-purpose function key.
|
||||
F27,
|
||||
/// General-purpose function key.
|
||||
F28,
|
||||
/// General-purpose function key.
|
||||
F29,
|
||||
/// General-purpose function key.
|
||||
F30,
|
||||
/// General-purpose function key.
|
||||
F31,
|
||||
/// General-purpose function key.
|
||||
F32,
|
||||
/// General-purpose function key.
|
||||
F33,
|
||||
/// General-purpose function key.
|
||||
F34,
|
||||
/// General-purpose function key.
|
||||
F35,
|
||||
}
|
||||
|
|
@ -1,203 +0,0 @@
|
|||
/// The symbolic name of a keyboard key.
|
||||
///
|
||||
/// This is mostly the `KeyCode` type found in [`winit`].
|
||||
///
|
||||
/// [`winit`]: https://docs.rs/winit/0.20.0-alpha3/winit/
|
||||
#[derive(Debug, Hash, Ord, PartialOrd, PartialEq, Eq, Clone, Copy)]
|
||||
#[repr(u32)]
|
||||
#[allow(missing_docs)]
|
||||
pub enum KeyCode {
|
||||
/// The '1' key over the letters.
|
||||
Key1,
|
||||
/// The '2' key over the letters.
|
||||
Key2,
|
||||
/// The '3' key over the letters.
|
||||
Key3,
|
||||
/// The '4' key over the letters.
|
||||
Key4,
|
||||
/// The '5' key over the letters.
|
||||
Key5,
|
||||
/// The '6' key over the letters.
|
||||
Key6,
|
||||
/// The '7' key over the letters.
|
||||
Key7,
|
||||
/// The '8' key over the letters.
|
||||
Key8,
|
||||
/// The '9' key over the letters.
|
||||
Key9,
|
||||
/// The '0' key over the 'O' and 'P' keys.
|
||||
Key0,
|
||||
|
||||
A,
|
||||
B,
|
||||
C,
|
||||
D,
|
||||
E,
|
||||
F,
|
||||
G,
|
||||
H,
|
||||
I,
|
||||
J,
|
||||
K,
|
||||
L,
|
||||
M,
|
||||
N,
|
||||
O,
|
||||
P,
|
||||
Q,
|
||||
R,
|
||||
S,
|
||||
T,
|
||||
U,
|
||||
V,
|
||||
W,
|
||||
X,
|
||||
Y,
|
||||
Z,
|
||||
|
||||
/// The Escape key, next to F1.
|
||||
Escape,
|
||||
|
||||
F1,
|
||||
F2,
|
||||
F3,
|
||||
F4,
|
||||
F5,
|
||||
F6,
|
||||
F7,
|
||||
F8,
|
||||
F9,
|
||||
F10,
|
||||
F11,
|
||||
F12,
|
||||
F13,
|
||||
F14,
|
||||
F15,
|
||||
F16,
|
||||
F17,
|
||||
F18,
|
||||
F19,
|
||||
F20,
|
||||
F21,
|
||||
F22,
|
||||
F23,
|
||||
F24,
|
||||
|
||||
/// Print Screen/SysRq.
|
||||
Snapshot,
|
||||
/// Scroll Lock.
|
||||
Scroll,
|
||||
/// Pause/Break key, next to Scroll lock.
|
||||
Pause,
|
||||
|
||||
/// `Insert`, next to Backspace.
|
||||
Insert,
|
||||
Home,
|
||||
Delete,
|
||||
End,
|
||||
PageDown,
|
||||
PageUp,
|
||||
|
||||
Left,
|
||||
Up,
|
||||
Right,
|
||||
Down,
|
||||
|
||||
/// The Backspace key, right over Enter.
|
||||
Backspace,
|
||||
/// The Enter key.
|
||||
Enter,
|
||||
/// The space bar.
|
||||
Space,
|
||||
|
||||
/// The "Compose" key on Linux.
|
||||
Compose,
|
||||
|
||||
Caret,
|
||||
|
||||
Numlock,
|
||||
Numpad0,
|
||||
Numpad1,
|
||||
Numpad2,
|
||||
Numpad3,
|
||||
Numpad4,
|
||||
Numpad5,
|
||||
Numpad6,
|
||||
Numpad7,
|
||||
Numpad8,
|
||||
Numpad9,
|
||||
NumpadAdd,
|
||||
NumpadDivide,
|
||||
NumpadDecimal,
|
||||
NumpadComma,
|
||||
NumpadEnter,
|
||||
NumpadEquals,
|
||||
NumpadMultiply,
|
||||
NumpadSubtract,
|
||||
|
||||
AbntC1,
|
||||
AbntC2,
|
||||
Apostrophe,
|
||||
Apps,
|
||||
Asterisk,
|
||||
At,
|
||||
Ax,
|
||||
Backslash,
|
||||
Calculator,
|
||||
Capital,
|
||||
Colon,
|
||||
Comma,
|
||||
Convert,
|
||||
Equals,
|
||||
Grave,
|
||||
Kana,
|
||||
Kanji,
|
||||
LAlt,
|
||||
LBracket,
|
||||
LControl,
|
||||
LShift,
|
||||
LWin,
|
||||
Mail,
|
||||
MediaSelect,
|
||||
MediaStop,
|
||||
Minus,
|
||||
Mute,
|
||||
MyComputer,
|
||||
NavigateForward, // also called "Next"
|
||||
NavigateBackward, // also called "Prior"
|
||||
NextTrack,
|
||||
NoConvert,
|
||||
OEM102,
|
||||
Period,
|
||||
PlayPause,
|
||||
Plus,
|
||||
Power,
|
||||
PrevTrack,
|
||||
RAlt,
|
||||
RBracket,
|
||||
RControl,
|
||||
RShift,
|
||||
RWin,
|
||||
Semicolon,
|
||||
Slash,
|
||||
Sleep,
|
||||
Stop,
|
||||
Sysrq,
|
||||
Tab,
|
||||
Underline,
|
||||
Unlabeled,
|
||||
VolumeDown,
|
||||
VolumeUp,
|
||||
Wake,
|
||||
WebBack,
|
||||
WebFavorites,
|
||||
WebForward,
|
||||
WebHome,
|
||||
WebRefresh,
|
||||
WebSearch,
|
||||
WebStop,
|
||||
Yen,
|
||||
Copy,
|
||||
Paste,
|
||||
Cut,
|
||||
}
|
||||
12
core/src/keyboard/location.rs
Normal file
12
core/src/keyboard/location.rs
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
/// The location of a key on the keyboard.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum Location {
|
||||
/// The standard group of keys on the keyboard.
|
||||
Standard,
|
||||
/// The left side of the keyboard.
|
||||
Left,
|
||||
/// The right side of the keyboard.
|
||||
Right,
|
||||
/// The numpad of the keyboard.
|
||||
Numpad,
|
||||
}
|
||||
|
|
@ -75,3 +75,5 @@ pub use size::Size;
|
|||
pub use text::Text;
|
||||
pub use vector::Vector;
|
||||
pub use widget::Widget;
|
||||
|
||||
pub use smol_str::SmolStr;
|
||||
|
|
|
|||
|
|
@ -10,6 +10,12 @@ pub enum Button {
|
|||
/// The middle (wheel) button.
|
||||
Middle,
|
||||
|
||||
/// The back mouse button.
|
||||
Back,
|
||||
|
||||
/// The forward mouse button.
|
||||
Forward,
|
||||
|
||||
/// Some other button.
|
||||
Other(u16),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,4 @@
|
|||
//! Keep track of time, both in native and web platforms!
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
pub use instant::Instant;
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
pub use instant::Duration;
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub use std::time::Instant;
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub use std::time::Duration;
|
||||
pub use web_time::Duration;
|
||||
pub use web_time::Instant;
|
||||
|
|
|
|||
|
|
@ -134,8 +134,8 @@ impl Application for Editor {
|
|||
}
|
||||
|
||||
fn subscription(&self) -> Subscription<Message> {
|
||||
keyboard::on_key_press(|key_code, modifiers| match key_code {
|
||||
keyboard::KeyCode::S if modifiers.command() => {
|
||||
keyboard::on_key_press(|key, modifiers| match key.as_ref() {
|
||||
keyboard::Key::Character("s") if modifiers.command() => {
|
||||
Some(Message::SaveFile)
|
||||
}
|
||||
_ => None,
|
||||
|
|
|
|||
|
|
@ -19,8 +19,9 @@ use iced_winit::winit;
|
|||
use iced_winit::Clipboard;
|
||||
|
||||
use winit::{
|
||||
event::{Event, ModifiersState, WindowEvent},
|
||||
event::{Event, WindowEvent},
|
||||
event_loop::{ControlFlow, EventLoop},
|
||||
keyboard::ModifiersState,
|
||||
};
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
|
|
@ -48,7 +49,7 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
tracing_subscriber::fmt::init();
|
||||
|
||||
// Initialize winit
|
||||
let event_loop = EventLoop::new();
|
||||
let event_loop = EventLoop::new()?;
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
let window = winit::window::WindowBuilder::new()
|
||||
|
|
@ -160,67 +161,15 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
);
|
||||
|
||||
// Run event loop
|
||||
event_loop.run(move |event, _, control_flow| {
|
||||
event_loop.run(move |event, window_target| {
|
||||
// You should change this if you want to render continuosly
|
||||
*control_flow = ControlFlow::Wait;
|
||||
window_target.set_control_flow(ControlFlow::Wait);
|
||||
|
||||
match event {
|
||||
Event::WindowEvent { event, .. } => {
|
||||
match event {
|
||||
WindowEvent::CursorMoved { position, .. } => {
|
||||
cursor_position = Some(position);
|
||||
}
|
||||
WindowEvent::ModifiersChanged(new_modifiers) => {
|
||||
modifiers = new_modifiers;
|
||||
}
|
||||
WindowEvent::Resized(_) => {
|
||||
resized = true;
|
||||
}
|
||||
WindowEvent::CloseRequested => {
|
||||
*control_flow = ControlFlow::Exit;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
// Map window event to iced event
|
||||
if let Some(event) = iced_winit::conversion::window_event(
|
||||
window::Id::MAIN,
|
||||
&event,
|
||||
window.scale_factor(),
|
||||
modifiers,
|
||||
) {
|
||||
state.queue_event(event);
|
||||
}
|
||||
}
|
||||
Event::MainEventsCleared => {
|
||||
// If there are events pending
|
||||
if !state.is_queue_empty() {
|
||||
// We update iced
|
||||
let _ = state.update(
|
||||
viewport.logical_size(),
|
||||
cursor_position
|
||||
.map(|p| {
|
||||
conversion::cursor_position(
|
||||
p,
|
||||
viewport.scale_factor(),
|
||||
)
|
||||
})
|
||||
.map(mouse::Cursor::Available)
|
||||
.unwrap_or(mouse::Cursor::Unavailable),
|
||||
&mut renderer,
|
||||
&Theme::Dark,
|
||||
&renderer::Style {
|
||||
text_color: Color::WHITE,
|
||||
},
|
||||
&mut clipboard,
|
||||
&mut debug,
|
||||
);
|
||||
|
||||
// and request a redraw
|
||||
window.request_redraw();
|
||||
}
|
||||
}
|
||||
Event::RedrawRequested(_) => {
|
||||
Event::WindowEvent {
|
||||
event: WindowEvent::RedrawRequested,
|
||||
..
|
||||
} => {
|
||||
if resized {
|
||||
let size = window.inner_size();
|
||||
|
||||
|
|
@ -309,7 +258,60 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
},
|
||||
}
|
||||
}
|
||||
Event::WindowEvent { event, .. } => {
|
||||
match event {
|
||||
WindowEvent::CursorMoved { position, .. } => {
|
||||
cursor_position = Some(position);
|
||||
}
|
||||
WindowEvent::ModifiersChanged(new_modifiers) => {
|
||||
modifiers = new_modifiers.state();
|
||||
}
|
||||
WindowEvent::Resized(_) => {
|
||||
resized = true;
|
||||
}
|
||||
WindowEvent::CloseRequested => {
|
||||
window_target.exit();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
// Map window event to iced event
|
||||
if let Some(event) = iced_winit::conversion::window_event(
|
||||
window::Id::MAIN,
|
||||
event,
|
||||
window.scale_factor(),
|
||||
modifiers,
|
||||
) {
|
||||
state.queue_event(event);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
})
|
||||
|
||||
// If there are events pending
|
||||
if !state.is_queue_empty() {
|
||||
// We update iced
|
||||
let _ = state.update(
|
||||
viewport.logical_size(),
|
||||
cursor_position
|
||||
.map(|p| {
|
||||
conversion::cursor_position(p, viewport.scale_factor())
|
||||
})
|
||||
.map(mouse::Cursor::Available)
|
||||
.unwrap_or(mouse::Cursor::Unavailable),
|
||||
&mut renderer,
|
||||
&Theme::Dark,
|
||||
&renderer::Style {
|
||||
text_color: Color::WHITE,
|
||||
},
|
||||
&mut clipboard,
|
||||
&mut debug,
|
||||
);
|
||||
|
||||
// and request a redraw
|
||||
window.request_redraw();
|
||||
}
|
||||
})?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,9 +71,13 @@ impl Application for Layout {
|
|||
}
|
||||
|
||||
fn subscription(&self) -> Subscription<Message> {
|
||||
keyboard::on_key_release(|key_code, _modifiers| match key_code {
|
||||
keyboard::KeyCode::Left => Some(Message::Previous),
|
||||
keyboard::KeyCode::Right => Some(Message::Next),
|
||||
use keyboard::key;
|
||||
|
||||
keyboard::on_key_release(|key, _modifiers| match key {
|
||||
keyboard::Key::Named(key::Named::ArrowLeft) => {
|
||||
Some(Message::Previous)
|
||||
}
|
||||
keyboard::Key::Named(key::Named::ArrowRight) => Some(Message::Next),
|
||||
_ => None,
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -271,8 +271,6 @@ where
|
|||
shell: &mut Shell<'_, Message>,
|
||||
_viewport: &Rectangle,
|
||||
) -> event::Status {
|
||||
const FRAME_RATE: u64 = 60;
|
||||
|
||||
let state = tree.state.downcast_mut::<State>();
|
||||
|
||||
if let Event::Window(_, window::Event::RedrawRequested(now)) = event {
|
||||
|
|
@ -283,9 +281,7 @@ where
|
|||
);
|
||||
|
||||
state.cache.clear();
|
||||
shell.request_redraw(RedrawRequest::At(
|
||||
now + Duration::from_millis(1000 / FRAME_RATE),
|
||||
));
|
||||
shell.request_redraw(RedrawRequest::NextFrame);
|
||||
}
|
||||
|
||||
event::Status::Ignored
|
||||
|
|
|
|||
|
|
@ -192,16 +192,12 @@ where
|
|||
shell: &mut Shell<'_, Message>,
|
||||
_viewport: &Rectangle,
|
||||
) -> event::Status {
|
||||
const FRAME_RATE: u64 = 60;
|
||||
|
||||
let state = tree.state.downcast_mut::<State>();
|
||||
|
||||
if let Event::Window(_, window::Event::RedrawRequested(now)) = event {
|
||||
*state = state.timed_transition(self.cycle_duration, now);
|
||||
|
||||
shell.request_redraw(RedrawRequest::At(
|
||||
now + Duration::from_millis(1000 / FRAME_RATE),
|
||||
));
|
||||
shell.request_redraw(RedrawRequest::NextFrame);
|
||||
}
|
||||
|
||||
event::Status::Ignored
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use iced::event::{self, Event};
|
||||
use iced::executor;
|
||||
use iced::keyboard;
|
||||
use iced::keyboard::key;
|
||||
use iced::theme;
|
||||
use iced::widget::{
|
||||
self, button, column, container, horizontal_space, pick_list, row, text,
|
||||
|
|
@ -85,8 +86,9 @@ impl Application for App {
|
|||
}
|
||||
Message::Event(event) => match event {
|
||||
Event::Keyboard(keyboard::Event::KeyPressed {
|
||||
key_code: keyboard::KeyCode::Tab,
|
||||
key: keyboard::Key::Named(key::Named::Tab),
|
||||
modifiers,
|
||||
..
|
||||
}) => {
|
||||
if modifiers.shift() {
|
||||
widget::focus_previous()
|
||||
|
|
@ -95,7 +97,7 @@ impl Application for App {
|
|||
}
|
||||
}
|
||||
Event::Keyboard(keyboard::Event::KeyPressed {
|
||||
key_code: keyboard::KeyCode::Escape,
|
||||
key: keyboard::Key::Named(key::Named::Escape),
|
||||
..
|
||||
}) => {
|
||||
self.hide_modal();
|
||||
|
|
|
|||
|
|
@ -220,23 +220,26 @@ const PANE_ID_COLOR_FOCUSED: Color = Color::from_rgb(
|
|||
0x47 as f32 / 255.0,
|
||||
);
|
||||
|
||||
fn handle_hotkey(key_code: keyboard::KeyCode) -> Option<Message> {
|
||||
use keyboard::KeyCode;
|
||||
fn handle_hotkey(key: keyboard::Key) -> Option<Message> {
|
||||
use keyboard::key::{self, Key};
|
||||
use pane_grid::{Axis, Direction};
|
||||
|
||||
let direction = match key_code {
|
||||
KeyCode::Up => Some(Direction::Up),
|
||||
KeyCode::Down => Some(Direction::Down),
|
||||
KeyCode::Left => Some(Direction::Left),
|
||||
KeyCode::Right => Some(Direction::Right),
|
||||
_ => None,
|
||||
};
|
||||
match key.as_ref() {
|
||||
Key::Character("v") => Some(Message::SplitFocused(Axis::Vertical)),
|
||||
Key::Character("h") => Some(Message::SplitFocused(Axis::Horizontal)),
|
||||
Key::Character("w") => Some(Message::CloseFocused),
|
||||
Key::Named(key) => {
|
||||
let direction = match key {
|
||||
key::Named::ArrowUp => Some(Direction::Up),
|
||||
key::Named::ArrowDown => Some(Direction::Down),
|
||||
key::Named::ArrowLeft => Some(Direction::Left),
|
||||
key::Named::ArrowRight => Some(Direction::Right),
|
||||
_ => None,
|
||||
};
|
||||
|
||||
match key_code {
|
||||
KeyCode::V => Some(Message::SplitFocused(Axis::Vertical)),
|
||||
KeyCode::H => Some(Message::SplitFocused(Axis::Horizontal)),
|
||||
KeyCode::W => Some(Message::CloseFocused),
|
||||
_ => direction.map(Message::FocusAdjacent),
|
||||
direction.map(Message::FocusAdjacent)
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
use iced::keyboard::KeyCode;
|
||||
use iced::theme::{Button, Container};
|
||||
use iced::alignment;
|
||||
use iced::executor;
|
||||
use iced::keyboard;
|
||||
use iced::theme;
|
||||
use iced::widget::{button, column, container, image, row, text, text_input};
|
||||
use iced::window;
|
||||
use iced::window::screenshot::{self, Screenshot};
|
||||
use iced::{alignment, window};
|
||||
use iced::{
|
||||
event, executor, keyboard, Alignment, Application, Command, ContentFit,
|
||||
Element, Event, Length, Rectangle, Renderer, Subscription, Theme,
|
||||
Alignment, Application, Command, ContentFit, Element, Length, Rectangle,
|
||||
Renderer, Subscription, Theme,
|
||||
};
|
||||
|
||||
use ::image as img;
|
||||
|
|
@ -147,7 +149,7 @@ impl Application for Example {
|
|||
|
||||
let image = container(image)
|
||||
.padding(10)
|
||||
.style(Container::Box)
|
||||
.style(theme::Container::Box)
|
||||
.width(Length::FillPortion(2))
|
||||
.height(Length::Fill)
|
||||
.center_x()
|
||||
|
|
@ -202,9 +204,10 @@ impl Application for Example {
|
|||
self.screenshot.is_some().then(|| Message::Png),
|
||||
)
|
||||
} else {
|
||||
button(centered_text("Saving...")).style(Button::Secondary)
|
||||
button(centered_text("Saving..."))
|
||||
.style(theme::Button::Secondary)
|
||||
}
|
||||
.style(Button::Secondary)
|
||||
.style(theme::Button::Secondary)
|
||||
.padding([10, 20, 10, 20])
|
||||
.width(Length::Fill)
|
||||
]
|
||||
|
|
@ -213,7 +216,7 @@ impl Application for Example {
|
|||
crop_controls,
|
||||
button(centered_text("Crop"))
|
||||
.on_press(Message::Crop)
|
||||
.style(Button::Destructive)
|
||||
.style(theme::Button::Destructive)
|
||||
.padding([10, 20, 10, 20])
|
||||
.width(Length::Fill),
|
||||
]
|
||||
|
|
@ -256,16 +259,10 @@ impl Application for Example {
|
|||
}
|
||||
|
||||
fn subscription(&self) -> Subscription<Self::Message> {
|
||||
event::listen_with(|event, status| {
|
||||
if let event::Status::Captured = status {
|
||||
return None;
|
||||
}
|
||||
use keyboard::key;
|
||||
|
||||
if let Event::Keyboard(keyboard::Event::KeyPressed {
|
||||
key_code: KeyCode::F5,
|
||||
..
|
||||
}) = event
|
||||
{
|
||||
keyboard::on_key_press(|key, _modifiers| {
|
||||
if let keyboard::Key::Named(key::Named::F5) = key {
|
||||
Some(Message::Screenshot)
|
||||
} else {
|
||||
None
|
||||
|
|
|
|||
|
|
@ -86,12 +86,16 @@ impl Application for Stopwatch {
|
|||
};
|
||||
|
||||
fn handle_hotkey(
|
||||
key_code: keyboard::KeyCode,
|
||||
key: keyboard::Key,
|
||||
_modifiers: keyboard::Modifiers,
|
||||
) -> Option<Message> {
|
||||
match key_code {
|
||||
keyboard::KeyCode::Space => Some(Message::Toggle),
|
||||
keyboard::KeyCode::R => Some(Message::Reset),
|
||||
use keyboard::key;
|
||||
|
||||
match key.as_ref() {
|
||||
keyboard::Key::Named(key::Named::Space) => {
|
||||
Some(Message::Toggle)
|
||||
}
|
||||
keyboard::Key::Character("r") => Some(Message::Reset),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use iced::event::{self, Event};
|
||||
use iced::executor;
|
||||
use iced::keyboard;
|
||||
use iced::keyboard::key;
|
||||
use iced::widget::{
|
||||
self, button, column, container, pick_list, row, slider, text, text_input,
|
||||
};
|
||||
|
|
@ -93,11 +94,12 @@ impl Application for App {
|
|||
Command::none()
|
||||
}
|
||||
Message::Event(Event::Keyboard(keyboard::Event::KeyPressed {
|
||||
key_code: keyboard::KeyCode::Tab,
|
||||
key: keyboard::Key::Named(key::Named::Tab),
|
||||
modifiers,
|
||||
..
|
||||
})) if modifiers.shift() => widget::focus_previous(),
|
||||
Message::Event(Event::Keyboard(keyboard::Event::KeyPressed {
|
||||
key_code: keyboard::KeyCode::Tab,
|
||||
key: keyboard::Key::Named(key::Named::Tab),
|
||||
..
|
||||
})) => widget::focus_next(),
|
||||
Message::Event(_) => Command::none(),
|
||||
|
|
|
|||
|
|
@ -260,15 +260,21 @@ impl Application for Todos {
|
|||
}
|
||||
|
||||
fn subscription(&self) -> Subscription<Message> {
|
||||
keyboard::on_key_press(|key_code, modifiers| {
|
||||
match (key_code, modifiers) {
|
||||
(keyboard::KeyCode::Tab, _) => Some(Message::TabPressed {
|
||||
use keyboard::key;
|
||||
|
||||
keyboard::on_key_press(|key, modifiers| {
|
||||
let keyboard::Key::Named(key) = key else {
|
||||
return None;
|
||||
};
|
||||
|
||||
match (key, modifiers) {
|
||||
(key::Named::Tab, _) => Some(Message::TabPressed {
|
||||
shift: modifiers.shift(),
|
||||
}),
|
||||
(keyboard::KeyCode::Up, keyboard::Modifiers::SHIFT) => {
|
||||
(key::Named::ArrowUp, keyboard::Modifiers::SHIFT) => {
|
||||
Some(Message::ToggleFullscreen(window::Mode::Fullscreen))
|
||||
}
|
||||
(keyboard::KeyCode::Down, keyboard::Modifiers::SHIFT) => {
|
||||
(key::Named::ArrowDown, keyboard::Modifiers::SHIFT) => {
|
||||
Some(Message::ToggleFullscreen(window::Mode::Windowed))
|
||||
}
|
||||
_ => None,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
//! Listen to keyboard events.
|
||||
use crate::core;
|
||||
use crate::core::keyboard::{Event, KeyCode, Modifiers};
|
||||
use crate::core::keyboard::{Event, Key, Modifiers};
|
||||
use crate::subscription::{self, Subscription};
|
||||
use crate::MaybeSend;
|
||||
|
||||
|
|
@ -10,7 +10,7 @@ use crate::MaybeSend;
|
|||
/// If the function returns `None`, the key press will be simply
|
||||
/// ignored.
|
||||
pub fn on_key_press<Message>(
|
||||
f: fn(KeyCode, Modifiers) -> Option<Message>,
|
||||
f: fn(Key, Modifiers) -> Option<Message>,
|
||||
) -> Subscription<Message>
|
||||
where
|
||||
Message: MaybeSend + 'static,
|
||||
|
|
@ -22,11 +22,10 @@ where
|
|||
match (event, status) {
|
||||
(
|
||||
core::Event::Keyboard(Event::KeyPressed {
|
||||
key_code,
|
||||
modifiers,
|
||||
key, modifiers, ..
|
||||
}),
|
||||
core::event::Status::Ignored,
|
||||
) => f(key_code, modifiers),
|
||||
) => f(key, modifiers),
|
||||
_ => None,
|
||||
}
|
||||
})
|
||||
|
|
@ -38,7 +37,7 @@ where
|
|||
/// If the function returns `None`, the key release will be simply
|
||||
/// ignored.
|
||||
pub fn on_key_release<Message>(
|
||||
f: fn(KeyCode, Modifiers) -> Option<Message>,
|
||||
f: fn(Key, Modifiers) -> Option<Message>,
|
||||
) -> Subscription<Message>
|
||||
where
|
||||
Message: MaybeSend + 'static,
|
||||
|
|
@ -50,11 +49,12 @@ where
|
|||
match (event, status) {
|
||||
(
|
||||
core::Event::Keyboard(Event::KeyReleased {
|
||||
key_code,
|
||||
key,
|
||||
modifiers,
|
||||
..
|
||||
}),
|
||||
core::event::Status::Ignored,
|
||||
) => f(key_code, modifiers),
|
||||
) => f(key, modifiers),
|
||||
_ => None,
|
||||
}
|
||||
})
|
||||
|
|
|
|||
|
|
@ -230,7 +230,8 @@ pub mod event {
|
|||
|
||||
pub mod keyboard {
|
||||
//! Listen and react to keyboard events.
|
||||
pub use crate::core::keyboard::{Event, KeyCode, Modifiers};
|
||||
pub use crate::core::keyboard::key;
|
||||
pub use crate::core::keyboard::{Event, Key, Location, Modifiers};
|
||||
pub use iced_futures::keyboard::{on_key_press, on_key_release};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ pub use crate::core::event::Status;
|
|||
/// A [`Canvas`] event.
|
||||
///
|
||||
/// [`Canvas`]: crate::Canvas
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum Event {
|
||||
/// A mouse event.
|
||||
Mouse(mouse::Event),
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
//! Display a dropdown list of searchable and selectable options.
|
||||
use crate::core::event::{self, Event};
|
||||
use crate::core::keyboard;
|
||||
use crate::core::keyboard::key;
|
||||
use crate::core::layout::{self, Layout};
|
||||
use crate::core::mouse;
|
||||
use crate::core::overlay;
|
||||
|
|
@ -436,14 +437,14 @@ where
|
|||
}
|
||||
|
||||
if let Event::Keyboard(keyboard::Event::KeyPressed {
|
||||
key_code,
|
||||
key: keyboard::Key::Named(named_key),
|
||||
modifiers,
|
||||
..
|
||||
}) = event
|
||||
{
|
||||
let shift_modifer = modifiers.shift();
|
||||
match (key_code, shift_modifer) {
|
||||
(keyboard::KeyCode::Enter, _) => {
|
||||
match (named_key, shift_modifer) {
|
||||
(key::Named::Enter, _) => {
|
||||
if let Some(index) = &menu.hovered_option {
|
||||
if let Some(option) =
|
||||
state.filtered_options.options.get(*index)
|
||||
|
|
@ -455,8 +456,7 @@ where
|
|||
event_status = event::Status::Captured;
|
||||
}
|
||||
|
||||
(keyboard::KeyCode::Up, _)
|
||||
| (keyboard::KeyCode::Tab, true) => {
|
||||
(key::Named::ArrowUp, _) | (key::Named::Tab, true) => {
|
||||
if let Some(index) = &mut menu.hovered_option {
|
||||
if *index == 0 {
|
||||
*index = state
|
||||
|
|
@ -492,8 +492,8 @@ where
|
|||
|
||||
event_status = event::Status::Captured;
|
||||
}
|
||||
(keyboard::KeyCode::Down, _)
|
||||
| (keyboard::KeyCode::Tab, false)
|
||||
(key::Named::ArrowDown, _)
|
||||
| (key::Named::Tab, false)
|
||||
if !modifiers.shift() =>
|
||||
{
|
||||
if let Some(index) = &mut menu.hovered_option {
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ pub use crate::core::event::Status;
|
|||
/// A [`Shader`] event.
|
||||
///
|
||||
/// [`Shader`]: crate::Shader
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum Event {
|
||||
/// A mouse event.
|
||||
Mouse(mouse::Event),
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
//! Display a multi-line text input for text editing.
|
||||
use crate::core::event::{self, Event};
|
||||
use crate::core::keyboard;
|
||||
use crate::core::keyboard::key;
|
||||
use crate::core::layout::{self, Layout};
|
||||
use crate::core::mouse;
|
||||
use crate::core::renderer;
|
||||
|
|
@ -646,43 +647,61 @@ impl Update {
|
|||
},
|
||||
Event::Keyboard(event) => match event {
|
||||
keyboard::Event::KeyPressed {
|
||||
key_code,
|
||||
key,
|
||||
modifiers,
|
||||
text,
|
||||
..
|
||||
} if state.is_focused => {
|
||||
if let Some(motion) = motion(key_code) {
|
||||
let motion =
|
||||
if platform::is_jump_modifier_pressed(modifiers) {
|
||||
if let keyboard::Key::Named(named_key) = key.as_ref() {
|
||||
if let Some(motion) = motion(named_key) {
|
||||
let motion = if platform::is_jump_modifier_pressed(
|
||||
modifiers,
|
||||
) {
|
||||
motion.widen()
|
||||
} else {
|
||||
motion
|
||||
};
|
||||
|
||||
return action(if modifiers.shift() {
|
||||
Action::Select(motion)
|
||||
} else {
|
||||
Action::Move(motion)
|
||||
});
|
||||
return action(if modifiers.shift() {
|
||||
Action::Select(motion)
|
||||
} else {
|
||||
Action::Move(motion)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
match key_code {
|
||||
keyboard::KeyCode::Enter => edit(Edit::Enter),
|
||||
keyboard::KeyCode::Backspace => edit(Edit::Backspace),
|
||||
keyboard::KeyCode::Delete => edit(Edit::Delete),
|
||||
keyboard::KeyCode::Escape => Some(Self::Unfocus),
|
||||
keyboard::KeyCode::C if modifiers.command() => {
|
||||
match key.as_ref() {
|
||||
keyboard::Key::Named(key::Named::Enter) => {
|
||||
edit(Edit::Enter)
|
||||
}
|
||||
keyboard::Key::Named(key::Named::Backspace) => {
|
||||
edit(Edit::Backspace)
|
||||
}
|
||||
keyboard::Key::Named(key::Named::Delete) => {
|
||||
edit(Edit::Delete)
|
||||
}
|
||||
keyboard::Key::Named(key::Named::Escape) => {
|
||||
Some(Self::Unfocus)
|
||||
}
|
||||
keyboard::Key::Character("c")
|
||||
if modifiers.command() =>
|
||||
{
|
||||
Some(Self::Copy)
|
||||
}
|
||||
keyboard::KeyCode::V
|
||||
keyboard::Key::Character("v")
|
||||
if modifiers.command() && !modifiers.alt() =>
|
||||
{
|
||||
Some(Self::Paste)
|
||||
}
|
||||
_ => None,
|
||||
_ => {
|
||||
let text = text?;
|
||||
|
||||
edit(Edit::Insert(
|
||||
text.chars().next().unwrap_or_default(),
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
keyboard::Event::CharacterReceived(c) if state.is_focused => {
|
||||
edit(Edit::Insert(c))
|
||||
}
|
||||
_ => None,
|
||||
},
|
||||
_ => None,
|
||||
|
|
@ -690,16 +709,16 @@ impl Update {
|
|||
}
|
||||
}
|
||||
|
||||
fn motion(key_code: keyboard::KeyCode) -> Option<Motion> {
|
||||
match key_code {
|
||||
keyboard::KeyCode::Left => Some(Motion::Left),
|
||||
keyboard::KeyCode::Right => Some(Motion::Right),
|
||||
keyboard::KeyCode::Up => Some(Motion::Up),
|
||||
keyboard::KeyCode::Down => Some(Motion::Down),
|
||||
keyboard::KeyCode::Home => Some(Motion::Home),
|
||||
keyboard::KeyCode::End => Some(Motion::End),
|
||||
keyboard::KeyCode::PageUp => Some(Motion::PageUp),
|
||||
keyboard::KeyCode::PageDown => Some(Motion::PageDown),
|
||||
fn motion(key: key::Named) -> Option<Motion> {
|
||||
match key {
|
||||
key::Named::ArrowLeft => Some(Motion::Left),
|
||||
key::Named::ArrowRight => Some(Motion::Right),
|
||||
key::Named::ArrowUp => Some(Motion::Up),
|
||||
key::Named::ArrowDown => Some(Motion::Down),
|
||||
key::Named::Home => Some(Motion::Home),
|
||||
key::Named::End => Some(Motion::End),
|
||||
key::Named::PageUp => Some(Motion::PageUp),
|
||||
key::Named::PageDown => Some(Motion::PageDown),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ use editor::Editor;
|
|||
use crate::core::alignment;
|
||||
use crate::core::event::{self, Event};
|
||||
use crate::core::keyboard;
|
||||
use crate::core::keyboard::key;
|
||||
use crate::core::layout;
|
||||
use crate::core::mouse::{self, click};
|
||||
use crate::core::renderer;
|
||||
|
|
@ -748,34 +749,7 @@ where
|
|||
return event::Status::Captured;
|
||||
}
|
||||
}
|
||||
Event::Keyboard(keyboard::Event::CharacterReceived(c)) => {
|
||||
let state = state();
|
||||
|
||||
if let Some(focus) = &mut state.is_focused {
|
||||
let Some(on_input) = on_input else {
|
||||
return event::Status::Ignored;
|
||||
};
|
||||
|
||||
if state.is_pasting.is_none()
|
||||
&& !state.keyboard_modifiers.command()
|
||||
&& !c.is_control()
|
||||
{
|
||||
let mut editor = Editor::new(value, &mut state.cursor);
|
||||
|
||||
editor.insert(c);
|
||||
|
||||
let message = (on_input)(editor.contents());
|
||||
shell.publish(message);
|
||||
|
||||
focus.updated_at = Instant::now();
|
||||
|
||||
update_cache(state, value);
|
||||
|
||||
return event::Status::Captured;
|
||||
}
|
||||
}
|
||||
}
|
||||
Event::Keyboard(keyboard::Event::KeyPressed { key_code, .. }) => {
|
||||
Event::Keyboard(keyboard::Event::KeyPressed { key, text, .. }) => {
|
||||
let state = state();
|
||||
|
||||
if let Some(focus) = &mut state.is_focused {
|
||||
|
|
@ -786,14 +760,13 @@ where
|
|||
let modifiers = state.keyboard_modifiers;
|
||||
focus.updated_at = Instant::now();
|
||||
|
||||
match key_code {
|
||||
keyboard::KeyCode::Enter
|
||||
| keyboard::KeyCode::NumpadEnter => {
|
||||
match key.as_ref() {
|
||||
keyboard::Key::Named(key::Named::Enter) => {
|
||||
if let Some(on_submit) = on_submit.clone() {
|
||||
shell.publish(on_submit);
|
||||
}
|
||||
}
|
||||
keyboard::KeyCode::Backspace => {
|
||||
keyboard::Key::Named(key::Named::Backspace) => {
|
||||
if platform::is_jump_modifier_pressed(modifiers)
|
||||
&& state.cursor.selection(value).is_none()
|
||||
{
|
||||
|
|
@ -813,7 +786,7 @@ where
|
|||
|
||||
update_cache(state, value);
|
||||
}
|
||||
keyboard::KeyCode::Delete => {
|
||||
keyboard::Key::Named(key::Named::Delete) => {
|
||||
if platform::is_jump_modifier_pressed(modifiers)
|
||||
&& state.cursor.selection(value).is_none()
|
||||
{
|
||||
|
|
@ -835,7 +808,7 @@ where
|
|||
|
||||
update_cache(state, value);
|
||||
}
|
||||
keyboard::KeyCode::Left => {
|
||||
keyboard::Key::Named(key::Named::ArrowLeft) => {
|
||||
if platform::is_jump_modifier_pressed(modifiers)
|
||||
&& !is_secure
|
||||
{
|
||||
|
|
@ -850,7 +823,7 @@ where
|
|||
state.cursor.move_left(value);
|
||||
}
|
||||
}
|
||||
keyboard::KeyCode::Right => {
|
||||
keyboard::Key::Named(key::Named::ArrowRight) => {
|
||||
if platform::is_jump_modifier_pressed(modifiers)
|
||||
&& !is_secure
|
||||
{
|
||||
|
|
@ -865,7 +838,7 @@ where
|
|||
state.cursor.move_right(value);
|
||||
}
|
||||
}
|
||||
keyboard::KeyCode::Home => {
|
||||
keyboard::Key::Named(key::Named::Home) => {
|
||||
if modifiers.shift() {
|
||||
state
|
||||
.cursor
|
||||
|
|
@ -874,7 +847,7 @@ where
|
|||
state.cursor.move_to(0);
|
||||
}
|
||||
}
|
||||
keyboard::KeyCode::End => {
|
||||
keyboard::Key::Named(key::Named::End) => {
|
||||
if modifiers.shift() {
|
||||
state.cursor.select_range(
|
||||
state.cursor.start(value),
|
||||
|
|
@ -884,7 +857,7 @@ where
|
|||
state.cursor.move_to(value.len());
|
||||
}
|
||||
}
|
||||
keyboard::KeyCode::C
|
||||
keyboard::Key::Character("c")
|
||||
if state.keyboard_modifiers.command() =>
|
||||
{
|
||||
if let Some((start, end)) =
|
||||
|
|
@ -894,7 +867,7 @@ where
|
|||
.write(value.select(start, end).to_string());
|
||||
}
|
||||
}
|
||||
keyboard::KeyCode::X
|
||||
keyboard::Key::Character("x")
|
||||
if state.keyboard_modifiers.command() =>
|
||||
{
|
||||
if let Some((start, end)) =
|
||||
|
|
@ -912,7 +885,7 @@ where
|
|||
|
||||
update_cache(state, value);
|
||||
}
|
||||
keyboard::KeyCode::V => {
|
||||
keyboard::Key::Character("v") => {
|
||||
if state.keyboard_modifiers.command()
|
||||
&& !state.keyboard_modifiers.alt()
|
||||
{
|
||||
|
|
@ -949,12 +922,12 @@ where
|
|||
state.is_pasting = None;
|
||||
}
|
||||
}
|
||||
keyboard::KeyCode::A
|
||||
keyboard::Key::Character("a")
|
||||
if state.keyboard_modifiers.command() =>
|
||||
{
|
||||
state.cursor.select_all(value);
|
||||
}
|
||||
keyboard::KeyCode::Escape => {
|
||||
keyboard::Key::Named(key::Named::Escape) => {
|
||||
state.is_focused = None;
|
||||
state.is_dragging = false;
|
||||
state.is_pasting = None;
|
||||
|
|
@ -962,28 +935,55 @@ where
|
|||
state.keyboard_modifiers =
|
||||
keyboard::Modifiers::default();
|
||||
}
|
||||
keyboard::KeyCode::Tab
|
||||
| keyboard::KeyCode::Up
|
||||
| keyboard::KeyCode::Down => {
|
||||
keyboard::Key::Named(
|
||||
key::Named::Tab
|
||||
| key::Named::ArrowUp
|
||||
| key::Named::ArrowDown,
|
||||
) => {
|
||||
return event::Status::Ignored;
|
||||
}
|
||||
_ => {}
|
||||
_ => {
|
||||
if let Some(text) = text {
|
||||
let c = text.chars().next().unwrap_or_default();
|
||||
|
||||
if state.is_pasting.is_none()
|
||||
&& !state.keyboard_modifiers.command()
|
||||
&& !c.is_control()
|
||||
{
|
||||
let mut editor =
|
||||
Editor::new(value, &mut state.cursor);
|
||||
|
||||
editor.insert(c);
|
||||
|
||||
let message = (on_input)(editor.contents());
|
||||
shell.publish(message);
|
||||
|
||||
focus.updated_at = Instant::now();
|
||||
|
||||
update_cache(state, value);
|
||||
|
||||
return event::Status::Captured;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return event::Status::Captured;
|
||||
}
|
||||
}
|
||||
Event::Keyboard(keyboard::Event::KeyReleased { key_code, .. }) => {
|
||||
Event::Keyboard(keyboard::Event::KeyReleased { key, .. }) => {
|
||||
let state = state();
|
||||
|
||||
if state.is_focused.is_some() {
|
||||
match key_code {
|
||||
keyboard::KeyCode::V => {
|
||||
match key.as_ref() {
|
||||
keyboard::Key::Character("v") => {
|
||||
state.is_pasting = None;
|
||||
}
|
||||
keyboard::KeyCode::Tab
|
||||
| keyboard::KeyCode::Up
|
||||
| keyboard::KeyCode::Down => {
|
||||
keyboard::Key::Named(
|
||||
key::Named::Tab
|
||||
| key::Named::ArrowUp
|
||||
| key::Named::ArrowDown,
|
||||
) => {
|
||||
return event::Status::Ignored;
|
||||
}
|
||||
_ => {}
|
||||
|
|
|
|||
|
|
@ -115,7 +115,9 @@ where
|
|||
let mut debug = Debug::new();
|
||||
debug.startup_started();
|
||||
|
||||
let event_loop = EventLoopBuilder::with_user_event().build();
|
||||
let event_loop = EventLoopBuilder::with_user_event()
|
||||
.build()
|
||||
.expect("Create event loop");
|
||||
let proxy = event_loop.create_proxy();
|
||||
|
||||
let runtime = {
|
||||
|
|
@ -155,7 +157,7 @@ where
|
|||
{
|
||||
use winit::platform::web::WindowExtWebSys;
|
||||
|
||||
let canvas = window.canvas();
|
||||
let canvas = window.canvas().expect("Get window canvas");
|
||||
|
||||
let window = web_sys::window().unwrap();
|
||||
let document = window.document().unwrap();
|
||||
|
|
@ -210,45 +212,28 @@ where
|
|||
|
||||
let mut context = task::Context::from_waker(task::noop_waker_ref());
|
||||
|
||||
platform::run(event_loop, move |event, _, control_flow| {
|
||||
use winit::event_loop::ControlFlow;
|
||||
|
||||
if let ControlFlow::ExitWithCode(_) = control_flow {
|
||||
let _ = event_loop.run(move |event, event_loop| {
|
||||
if event_loop.exiting() {
|
||||
return;
|
||||
}
|
||||
|
||||
let event = match event {
|
||||
winit::event::Event::WindowEvent {
|
||||
event:
|
||||
winit::event::WindowEvent::ScaleFactorChanged {
|
||||
new_inner_size,
|
||||
..
|
||||
},
|
||||
window_id,
|
||||
} => Some(winit::event::Event::WindowEvent {
|
||||
event: winit::event::WindowEvent::Resized(*new_inner_size),
|
||||
window_id,
|
||||
}),
|
||||
_ => event.to_static(),
|
||||
event_sender.start_send(event).expect("Send event");
|
||||
|
||||
let poll = instance.as_mut().poll(&mut context);
|
||||
|
||||
match poll {
|
||||
task::Poll::Pending => {
|
||||
if let Ok(Some(flow)) = control_receiver.try_next() {
|
||||
event_loop.set_control_flow(flow);
|
||||
}
|
||||
}
|
||||
task::Poll::Ready(_) => {
|
||||
event_loop.exit();
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
if let Some(event) = event {
|
||||
event_sender.start_send(event).expect("Send event");
|
||||
|
||||
let poll = instance.as_mut().poll(&mut context);
|
||||
|
||||
match poll {
|
||||
task::Poll::Pending => {
|
||||
if let Ok(Some(flow)) = control_receiver.try_next() {
|
||||
*control_flow = flow;
|
||||
}
|
||||
}
|
||||
task::Poll::Ready(_) => {
|
||||
*control_flow = ControlFlow::Exit;
|
||||
}
|
||||
};
|
||||
}
|
||||
})
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn run_instance<A, E, C>(
|
||||
|
|
@ -259,7 +244,7 @@ async fn run_instance<A, E, C>(
|
|||
mut proxy: winit::event_loop::EventLoopProxy<A::Message>,
|
||||
mut debug: Debug,
|
||||
mut event_receiver: mpsc::UnboundedReceiver<
|
||||
winit::event::Event<'_, A::Message>,
|
||||
winit::event::Event<A::Message>,
|
||||
>,
|
||||
mut control_sender: mpsc::UnboundedSender<winit::event_loop::ControlFlow>,
|
||||
init_command: Command<A::Message>,
|
||||
|
|
@ -327,77 +312,56 @@ async fn run_instance<A, E, C>(
|
|||
|
||||
while let Some(event) = event_receiver.next().await {
|
||||
match event {
|
||||
event::Event::NewEvents(start_cause) => {
|
||||
redraw_pending = matches!(
|
||||
start_cause,
|
||||
event::StartCause::Init
|
||||
| event::StartCause::Poll
|
||||
| event::StartCause::ResumeTimeReached { .. }
|
||||
);
|
||||
event::Event::NewEvents(
|
||||
event::StartCause::Init
|
||||
| event::StartCause::ResumeTimeReached { .. },
|
||||
) if !redraw_pending => {
|
||||
window.request_redraw();
|
||||
redraw_pending = true;
|
||||
}
|
||||
event::Event::MainEventsCleared => {
|
||||
if !redraw_pending && events.is_empty() && messages.is_empty() {
|
||||
event::Event::PlatformSpecific(event::PlatformSpecific::MacOS(
|
||||
event::MacOS::ReceivedUrl(url),
|
||||
)) => {
|
||||
use crate::core::event;
|
||||
|
||||
events.push(Event::PlatformSpecific(
|
||||
event::PlatformSpecific::MacOS(event::MacOS::ReceivedUrl(
|
||||
url,
|
||||
)),
|
||||
));
|
||||
}
|
||||
event::Event::UserEvent(message) => {
|
||||
messages.push(message);
|
||||
}
|
||||
event::Event::WindowEvent {
|
||||
event: event::WindowEvent::RedrawRequested { .. },
|
||||
..
|
||||
} => {
|
||||
let physical_size = state.physical_size();
|
||||
|
||||
if physical_size.width == 0 || physical_size.height == 0 {
|
||||
continue;
|
||||
}
|
||||
|
||||
debug.event_processing_started();
|
||||
let current_viewport_version = state.viewport_version();
|
||||
|
||||
let (interface_state, statuses) = user_interface.update(
|
||||
&events,
|
||||
state.cursor(),
|
||||
&mut renderer,
|
||||
&mut clipboard,
|
||||
&mut messages,
|
||||
);
|
||||
if viewport_version != current_viewport_version {
|
||||
let logical_size = state.logical_size();
|
||||
|
||||
debug.event_processing_finished();
|
||||
debug.layout_started();
|
||||
user_interface = ManuallyDrop::new(
|
||||
ManuallyDrop::into_inner(user_interface)
|
||||
.relayout(logical_size, &mut renderer),
|
||||
);
|
||||
debug.layout_finished();
|
||||
|
||||
for (event, status) in
|
||||
events.drain(..).zip(statuses.into_iter())
|
||||
{
|
||||
runtime.broadcast(event, status);
|
||||
}
|
||||
|
||||
if !messages.is_empty()
|
||||
|| matches!(
|
||||
interface_state,
|
||||
user_interface::State::Outdated
|
||||
)
|
||||
{
|
||||
let mut cache =
|
||||
ManuallyDrop::into_inner(user_interface).into_cache();
|
||||
|
||||
// Update application
|
||||
update(
|
||||
&mut application,
|
||||
&mut compositor,
|
||||
compositor.configure_surface(
|
||||
&mut surface,
|
||||
&mut cache,
|
||||
&state,
|
||||
&mut renderer,
|
||||
&mut runtime,
|
||||
&mut clipboard,
|
||||
&mut should_exit,
|
||||
&mut proxy,
|
||||
&mut debug,
|
||||
&mut messages,
|
||||
&window,
|
||||
physical_size.width,
|
||||
physical_size.height,
|
||||
);
|
||||
|
||||
// Update window
|
||||
state.synchronize(&application, &window);
|
||||
|
||||
user_interface = ManuallyDrop::new(build_user_interface(
|
||||
&application,
|
||||
cache,
|
||||
&mut renderer,
|
||||
state.logical_size(),
|
||||
&mut debug,
|
||||
));
|
||||
|
||||
if should_exit {
|
||||
break;
|
||||
}
|
||||
viewport_version = current_viewport_version;
|
||||
}
|
||||
|
||||
// TODO: Avoid redrawing all the time by forcing widgets to
|
||||
|
|
@ -418,6 +382,24 @@ async fn run_instance<A, E, C>(
|
|||
&mut messages,
|
||||
);
|
||||
|
||||
let _ = control_sender.start_send(match interface_state {
|
||||
user_interface::State::Updated {
|
||||
redraw_request: Some(redraw_request),
|
||||
} => match redraw_request {
|
||||
window::RedrawRequest::NextFrame => {
|
||||
window.request_redraw();
|
||||
|
||||
ControlFlow::Wait
|
||||
}
|
||||
window::RedrawRequest::At(at) => {
|
||||
ControlFlow::WaitUntil(at)
|
||||
}
|
||||
},
|
||||
_ => ControlFlow::Wait,
|
||||
});
|
||||
|
||||
runtime.broadcast(redraw_event, core::event::Status::Ignored);
|
||||
|
||||
debug.draw_started();
|
||||
let new_mouse_interaction = user_interface.draw(
|
||||
&mut renderer,
|
||||
|
|
@ -427,6 +409,7 @@ async fn run_instance<A, E, C>(
|
|||
},
|
||||
state.cursor(),
|
||||
);
|
||||
redraw_pending = false;
|
||||
debug.draw_finished();
|
||||
|
||||
if new_mouse_interaction != mouse_interaction {
|
||||
|
|
@ -437,85 +420,7 @@ async fn run_instance<A, E, C>(
|
|||
mouse_interaction = new_mouse_interaction;
|
||||
}
|
||||
|
||||
window.request_redraw();
|
||||
runtime.broadcast(redraw_event, core::event::Status::Ignored);
|
||||
|
||||
let _ = control_sender.start_send(match interface_state {
|
||||
user_interface::State::Updated {
|
||||
redraw_request: Some(redraw_request),
|
||||
} => match redraw_request {
|
||||
window::RedrawRequest::NextFrame => ControlFlow::Poll,
|
||||
window::RedrawRequest::At(at) => {
|
||||
ControlFlow::WaitUntil(at)
|
||||
}
|
||||
},
|
||||
_ => ControlFlow::Wait,
|
||||
});
|
||||
|
||||
redraw_pending = false;
|
||||
}
|
||||
event::Event::PlatformSpecific(event::PlatformSpecific::MacOS(
|
||||
event::MacOS::ReceivedUrl(url),
|
||||
)) => {
|
||||
use crate::core::event;
|
||||
|
||||
events.push(Event::PlatformSpecific(
|
||||
event::PlatformSpecific::MacOS(event::MacOS::ReceivedUrl(
|
||||
url,
|
||||
)),
|
||||
));
|
||||
}
|
||||
event::Event::UserEvent(message) => {
|
||||
messages.push(message);
|
||||
}
|
||||
event::Event::RedrawRequested(_) => {
|
||||
let physical_size = state.physical_size();
|
||||
|
||||
if physical_size.width == 0 || physical_size.height == 0 {
|
||||
continue;
|
||||
}
|
||||
|
||||
debug.render_started();
|
||||
let current_viewport_version = state.viewport_version();
|
||||
|
||||
if viewport_version != current_viewport_version {
|
||||
let logical_size = state.logical_size();
|
||||
|
||||
debug.layout_started();
|
||||
user_interface = ManuallyDrop::new(
|
||||
ManuallyDrop::into_inner(user_interface)
|
||||
.relayout(logical_size, &mut renderer),
|
||||
);
|
||||
debug.layout_finished();
|
||||
|
||||
debug.draw_started();
|
||||
let new_mouse_interaction = user_interface.draw(
|
||||
&mut renderer,
|
||||
state.theme(),
|
||||
&renderer::Style {
|
||||
text_color: state.text_color(),
|
||||
},
|
||||
state.cursor(),
|
||||
);
|
||||
|
||||
if new_mouse_interaction != mouse_interaction {
|
||||
window.set_cursor_icon(conversion::mouse_interaction(
|
||||
new_mouse_interaction,
|
||||
));
|
||||
|
||||
mouse_interaction = new_mouse_interaction;
|
||||
}
|
||||
debug.draw_finished();
|
||||
|
||||
compositor.configure_surface(
|
||||
&mut surface,
|
||||
physical_size.width,
|
||||
physical_size.height,
|
||||
);
|
||||
|
||||
viewport_version = current_viewport_version;
|
||||
}
|
||||
|
||||
match compositor.present(
|
||||
&mut renderer,
|
||||
&mut surface,
|
||||
|
|
@ -557,13 +462,80 @@ async fn run_instance<A, E, C>(
|
|||
|
||||
if let Some(event) = conversion::window_event(
|
||||
window::Id::MAIN,
|
||||
&window_event,
|
||||
window_event,
|
||||
state.scale_factor(),
|
||||
state.modifiers(),
|
||||
) {
|
||||
events.push(event);
|
||||
}
|
||||
}
|
||||
event::Event::AboutToWait => {
|
||||
if events.is_empty() && messages.is_empty() {
|
||||
continue;
|
||||
}
|
||||
|
||||
debug.event_processing_started();
|
||||
|
||||
let (interface_state, statuses) = user_interface.update(
|
||||
&events,
|
||||
state.cursor(),
|
||||
&mut renderer,
|
||||
&mut clipboard,
|
||||
&mut messages,
|
||||
);
|
||||
|
||||
debug.event_processing_finished();
|
||||
|
||||
for (event, status) in
|
||||
events.drain(..).zip(statuses.into_iter())
|
||||
{
|
||||
runtime.broadcast(event, status);
|
||||
}
|
||||
|
||||
if !messages.is_empty()
|
||||
|| matches!(
|
||||
interface_state,
|
||||
user_interface::State::Outdated
|
||||
)
|
||||
{
|
||||
let mut cache =
|
||||
ManuallyDrop::into_inner(user_interface).into_cache();
|
||||
|
||||
// Update application
|
||||
update(
|
||||
&mut application,
|
||||
&mut compositor,
|
||||
&mut surface,
|
||||
&mut cache,
|
||||
&mut state,
|
||||
&mut renderer,
|
||||
&mut runtime,
|
||||
&mut clipboard,
|
||||
&mut should_exit,
|
||||
&mut proxy,
|
||||
&mut debug,
|
||||
&mut messages,
|
||||
&window,
|
||||
);
|
||||
|
||||
user_interface = ManuallyDrop::new(build_user_interface(
|
||||
&application,
|
||||
cache,
|
||||
&mut renderer,
|
||||
state.logical_size(),
|
||||
&mut debug,
|
||||
));
|
||||
|
||||
if should_exit {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if !redraw_pending {
|
||||
window.request_redraw();
|
||||
redraw_pending = true;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
|
@ -575,8 +547,8 @@ async fn run_instance<A, E, C>(
|
|||
/// Returns true if the provided event should cause an [`Application`] to
|
||||
/// exit.
|
||||
pub fn requests_exit(
|
||||
event: &winit::event::WindowEvent<'_>,
|
||||
_modifiers: winit::event::ModifiersState,
|
||||
event: &winit::event::WindowEvent,
|
||||
_modifiers: winit::keyboard::ModifiersState,
|
||||
) -> bool {
|
||||
use winit::event::WindowEvent;
|
||||
|
||||
|
|
@ -584,14 +556,14 @@ pub fn requests_exit(
|
|||
WindowEvent::CloseRequested => true,
|
||||
#[cfg(target_os = "macos")]
|
||||
WindowEvent::KeyboardInput {
|
||||
input:
|
||||
winit::event::KeyboardInput {
|
||||
virtual_keycode: Some(winit::event::VirtualKeyCode::Q),
|
||||
event:
|
||||
winit::event::KeyEvent {
|
||||
logical_key: winit::keyboard::Key::Character(c),
|
||||
state: winit::event::ElementState::Pressed,
|
||||
..
|
||||
},
|
||||
..
|
||||
} if _modifiers.logo() => true,
|
||||
} if c == "q" && _modifiers.super_key() => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
|
@ -626,7 +598,7 @@ pub fn update<A: Application, C, E: Executor>(
|
|||
compositor: &mut C,
|
||||
surface: &mut C::Surface,
|
||||
cache: &mut user_interface::Cache,
|
||||
state: &State<A>,
|
||||
state: &mut State<A>,
|
||||
renderer: &mut A::Renderer,
|
||||
runtime: &mut Runtime<E, Proxy<A::Message>, A::Message>,
|
||||
clipboard: &mut Clipboard,
|
||||
|
|
@ -663,6 +635,8 @@ pub fn update<A: Application, C, E: Executor>(
|
|||
);
|
||||
}
|
||||
|
||||
state.synchronize(application, window);
|
||||
|
||||
let subscription = application.subscription();
|
||||
runtime.track(subscription.into_recipes());
|
||||
}
|
||||
|
|
@ -726,10 +700,11 @@ pub fn run_command<A, C, E>(
|
|||
);
|
||||
}
|
||||
window::Action::Resize(_id, size) => {
|
||||
window.set_inner_size(winit::dpi::LogicalSize {
|
||||
width: size.width,
|
||||
height: size.height,
|
||||
});
|
||||
let _ =
|
||||
window.request_inner_size(winit::dpi::LogicalSize {
|
||||
width: size.width,
|
||||
height: size.height,
|
||||
});
|
||||
}
|
||||
window::Action::FetchSize(_id, callback) => {
|
||||
let size =
|
||||
|
|
@ -888,43 +863,3 @@ pub fn run_command<A, C, E>(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
mod platform {
|
||||
pub fn run<T, F>(
|
||||
mut event_loop: winit::event_loop::EventLoop<T>,
|
||||
event_handler: F,
|
||||
) -> Result<(), super::Error>
|
||||
where
|
||||
F: 'static
|
||||
+ FnMut(
|
||||
winit::event::Event<'_, T>,
|
||||
&winit::event_loop::EventLoopWindowTarget<T>,
|
||||
&mut winit::event_loop::ControlFlow,
|
||||
),
|
||||
{
|
||||
use winit::platform::run_return::EventLoopExtRunReturn;
|
||||
|
||||
let _ = event_loop.run_return(event_handler);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
mod platform {
|
||||
pub fn run<T, F>(
|
||||
event_loop: winit::event_loop::EventLoop<T>,
|
||||
event_handler: F,
|
||||
) -> !
|
||||
where
|
||||
F: 'static
|
||||
+ FnMut(
|
||||
winit::event::Event<'_, T>,
|
||||
&winit::event_loop::EventLoopWindowTarget<T>,
|
||||
&mut winit::event_loop::ControlFlow,
|
||||
),
|
||||
{
|
||||
event_loop.run(event_handler)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ where
|
|||
viewport: Viewport,
|
||||
viewport_version: usize,
|
||||
cursor_position: Option<winit::dpi::PhysicalPosition<f64>>,
|
||||
modifiers: winit::event::ModifiersState,
|
||||
modifiers: winit::keyboard::ModifiersState,
|
||||
theme: <A::Renderer as core::Renderer>::Theme,
|
||||
appearance: application::Appearance,
|
||||
application: PhantomData<A>,
|
||||
|
|
@ -54,7 +54,7 @@ where
|
|||
viewport,
|
||||
viewport_version: 0,
|
||||
cursor_position: None,
|
||||
modifiers: winit::event::ModifiersState::default(),
|
||||
modifiers: winit::keyboard::ModifiersState::default(),
|
||||
theme,
|
||||
appearance,
|
||||
application: PhantomData,
|
||||
|
|
@ -102,7 +102,7 @@ where
|
|||
}
|
||||
|
||||
/// Returns the current keyboard modifiers of the [`State`].
|
||||
pub fn modifiers(&self) -> winit::event::ModifiersState {
|
||||
pub fn modifiers(&self) -> winit::keyboard::ModifiersState {
|
||||
self.modifiers
|
||||
}
|
||||
|
||||
|
|
@ -126,7 +126,7 @@ where
|
|||
pub fn update(
|
||||
&mut self,
|
||||
window: &Window,
|
||||
event: &WindowEvent<'_>,
|
||||
event: &WindowEvent,
|
||||
_debug: &mut Debug,
|
||||
) {
|
||||
match event {
|
||||
|
|
@ -142,10 +142,9 @@ where
|
|||
}
|
||||
WindowEvent::ScaleFactorChanged {
|
||||
scale_factor: new_scale_factor,
|
||||
new_inner_size,
|
||||
..
|
||||
} => {
|
||||
let size =
|
||||
Size::new(new_inner_size.width, new_inner_size.height);
|
||||
let size = self.viewport.physical_size();
|
||||
|
||||
self.viewport = Viewport::with_physical_size(
|
||||
size,
|
||||
|
|
@ -164,13 +163,16 @@ where
|
|||
self.cursor_position = None;
|
||||
}
|
||||
WindowEvent::ModifiersChanged(new_modifiers) => {
|
||||
self.modifiers = *new_modifiers;
|
||||
self.modifiers = new_modifiers.state();
|
||||
}
|
||||
#[cfg(feature = "debug")]
|
||||
WindowEvent::KeyboardInput {
|
||||
input:
|
||||
winit::event::KeyboardInput {
|
||||
virtual_keycode: Some(winit::event::VirtualKeyCode::F12),
|
||||
event:
|
||||
winit::event::KeyEvent {
|
||||
logical_key:
|
||||
winit::keyboard::Key::Named(
|
||||
winit::keyboard::NamedKey::F12,
|
||||
),
|
||||
state: winit::event::ElementState::Pressed,
|
||||
..
|
||||
},
|
||||
|
|
|
|||
|
|
@ -128,9 +128,9 @@ pub fn window_settings(
|
|||
/// Converts a winit window event into an iced event.
|
||||
pub fn window_event(
|
||||
id: window::Id,
|
||||
event: &winit::event::WindowEvent<'_>,
|
||||
event: winit::event::WindowEvent,
|
||||
scale_factor: f64,
|
||||
modifiers: winit::event::ModifiersState,
|
||||
modifiers: winit::keyboard::ModifiersState,
|
||||
) -> Option<Event> {
|
||||
use winit::event::WindowEvent;
|
||||
|
||||
|
|
@ -146,17 +146,6 @@ pub fn window_event(
|
|||
},
|
||||
))
|
||||
}
|
||||
WindowEvent::ScaleFactorChanged { new_inner_size, .. } => {
|
||||
let logical_size = new_inner_size.to_logical(scale_factor);
|
||||
|
||||
Some(Event::Window(
|
||||
id,
|
||||
window::Event::Resized {
|
||||
width: logical_size.width,
|
||||
height: logical_size.height,
|
||||
},
|
||||
))
|
||||
}
|
||||
WindowEvent::CloseRequested => {
|
||||
Some(Event::Window(id, window::Event::CloseRequested))
|
||||
}
|
||||
|
|
@ -174,7 +163,7 @@ pub fn window_event(
|
|||
Some(Event::Mouse(mouse::Event::CursorLeft))
|
||||
}
|
||||
WindowEvent::MouseInput { button, state, .. } => {
|
||||
let button = mouse_button(*button);
|
||||
let button = mouse_button(button);
|
||||
|
||||
Some(Event::Mouse(match state {
|
||||
winit::event::ElementState::Pressed => {
|
||||
|
|
@ -189,8 +178,8 @@ pub fn window_event(
|
|||
winit::event::MouseScrollDelta::LineDelta(delta_x, delta_y) => {
|
||||
Some(Event::Mouse(mouse::Event::WheelScrolled {
|
||||
delta: mouse::ScrollDelta::Lines {
|
||||
x: *delta_x,
|
||||
y: *delta_y,
|
||||
x: delta_x,
|
||||
y: delta_y,
|
||||
},
|
||||
}))
|
||||
}
|
||||
|
|
@ -203,42 +192,59 @@ pub fn window_event(
|
|||
}))
|
||||
}
|
||||
},
|
||||
WindowEvent::ReceivedCharacter(c) if !is_private_use_character(*c) => {
|
||||
Some(Event::Keyboard(keyboard::Event::CharacterReceived(*c)))
|
||||
}
|
||||
WindowEvent::KeyboardInput {
|
||||
input:
|
||||
winit::event::KeyboardInput {
|
||||
virtual_keycode: Some(virtual_keycode),
|
||||
event:
|
||||
winit::event::KeyEvent {
|
||||
logical_key,
|
||||
state,
|
||||
text,
|
||||
location,
|
||||
..
|
||||
},
|
||||
..
|
||||
} => Some(Event::Keyboard({
|
||||
let key_code = key_code(*virtual_keycode);
|
||||
let key = key(logical_key);
|
||||
let modifiers = self::modifiers(modifiers);
|
||||
|
||||
let location = match location {
|
||||
winit::keyboard::KeyLocation::Standard => {
|
||||
keyboard::Location::Standard
|
||||
}
|
||||
winit::keyboard::KeyLocation::Left => keyboard::Location::Left,
|
||||
winit::keyboard::KeyLocation::Right => {
|
||||
keyboard::Location::Right
|
||||
}
|
||||
winit::keyboard::KeyLocation::Numpad => {
|
||||
keyboard::Location::Numpad
|
||||
}
|
||||
};
|
||||
|
||||
match state {
|
||||
winit::event::ElementState::Pressed => {
|
||||
keyboard::Event::KeyPressed {
|
||||
key_code,
|
||||
key,
|
||||
modifiers,
|
||||
location,
|
||||
text,
|
||||
}
|
||||
}
|
||||
winit::event::ElementState::Released => {
|
||||
keyboard::Event::KeyReleased {
|
||||
key_code,
|
||||
key,
|
||||
modifiers,
|
||||
location,
|
||||
}
|
||||
}
|
||||
}
|
||||
})),
|
||||
WindowEvent::ModifiersChanged(new_modifiers) => Some(Event::Keyboard(
|
||||
keyboard::Event::ModifiersChanged(self::modifiers(*new_modifiers)),
|
||||
)),
|
||||
WindowEvent::ModifiersChanged(new_modifiers) => {
|
||||
Some(Event::Keyboard(keyboard::Event::ModifiersChanged(
|
||||
self::modifiers(new_modifiers.state()),
|
||||
)))
|
||||
}
|
||||
WindowEvent::Focused(focused) => Some(Event::Window(
|
||||
id,
|
||||
if *focused {
|
||||
if focused {
|
||||
window::Event::Focused
|
||||
} else {
|
||||
window::Event::Unfocused
|
||||
|
|
@ -254,7 +260,7 @@ pub fn window_event(
|
|||
Some(Event::Window(id, window::Event::FilesHoveredLeft))
|
||||
}
|
||||
WindowEvent::Touch(touch) => {
|
||||
Some(Event::Touch(touch_event(*touch, scale_factor)))
|
||||
Some(Event::Touch(touch_event(touch, scale_factor)))
|
||||
}
|
||||
WindowEvent::Moved(position) => {
|
||||
let winit::dpi::LogicalPosition { x, y } =
|
||||
|
|
@ -365,7 +371,7 @@ pub fn mouse_interaction(
|
|||
|
||||
match interaction {
|
||||
Interaction::Idle => winit::window::CursorIcon::Default,
|
||||
Interaction::Pointer => winit::window::CursorIcon::Hand,
|
||||
Interaction::Pointer => winit::window::CursorIcon::Pointer,
|
||||
Interaction::Working => winit::window::CursorIcon::Progress,
|
||||
Interaction::Grab => winit::window::CursorIcon::Grab,
|
||||
Interaction::Grabbing => winit::window::CursorIcon::Grabbing,
|
||||
|
|
@ -388,6 +394,8 @@ pub fn mouse_button(mouse_button: winit::event::MouseButton) -> mouse::Button {
|
|||
winit::event::MouseButton::Left => mouse::Button::Left,
|
||||
winit::event::MouseButton::Right => mouse::Button::Right,
|
||||
winit::event::MouseButton::Middle => mouse::Button::Middle,
|
||||
winit::event::MouseButton::Back => mouse::Button::Back,
|
||||
winit::event::MouseButton::Forward => mouse::Button::Forward,
|
||||
winit::event::MouseButton::Other(other) => mouse::Button::Other(other),
|
||||
}
|
||||
}
|
||||
|
|
@ -398,14 +406,14 @@ pub fn mouse_button(mouse_button: winit::event::MouseButton) -> mouse::Button {
|
|||
/// [`winit`]: https://github.com/rust-windowing/winit
|
||||
/// [`iced`]: https://github.com/iced-rs/iced/tree/0.10
|
||||
pub fn modifiers(
|
||||
modifiers: winit::event::ModifiersState,
|
||||
modifiers: winit::keyboard::ModifiersState,
|
||||
) -> keyboard::Modifiers {
|
||||
let mut result = keyboard::Modifiers::empty();
|
||||
|
||||
result.set(keyboard::Modifiers::SHIFT, modifiers.shift());
|
||||
result.set(keyboard::Modifiers::CTRL, modifiers.ctrl());
|
||||
result.set(keyboard::Modifiers::ALT, modifiers.alt());
|
||||
result.set(keyboard::Modifiers::LOGO, modifiers.logo());
|
||||
result.set(keyboard::Modifiers::SHIFT, modifiers.shift_key());
|
||||
result.set(keyboard::Modifiers::CTRL, modifiers.control_key());
|
||||
result.set(keyboard::Modifiers::ALT, modifiers.alt_key());
|
||||
result.set(keyboard::Modifiers::LOGO, modifiers.super_key());
|
||||
|
||||
result
|
||||
}
|
||||
|
|
@ -455,179 +463,328 @@ pub fn touch_event(
|
|||
///
|
||||
/// [`winit`]: https://github.com/rust-windowing/winit
|
||||
/// [`iced`]: https://github.com/iced-rs/iced/tree/0.10
|
||||
pub fn key_code(
|
||||
virtual_keycode: winit::event::VirtualKeyCode,
|
||||
) -> keyboard::KeyCode {
|
||||
use keyboard::KeyCode;
|
||||
pub fn key(key: winit::keyboard::Key) -> keyboard::Key {
|
||||
use keyboard::key::Named;
|
||||
use winit::keyboard::NamedKey;
|
||||
|
||||
match virtual_keycode {
|
||||
winit::event::VirtualKeyCode::Key1 => KeyCode::Key1,
|
||||
winit::event::VirtualKeyCode::Key2 => KeyCode::Key2,
|
||||
winit::event::VirtualKeyCode::Key3 => KeyCode::Key3,
|
||||
winit::event::VirtualKeyCode::Key4 => KeyCode::Key4,
|
||||
winit::event::VirtualKeyCode::Key5 => KeyCode::Key5,
|
||||
winit::event::VirtualKeyCode::Key6 => KeyCode::Key6,
|
||||
winit::event::VirtualKeyCode::Key7 => KeyCode::Key7,
|
||||
winit::event::VirtualKeyCode::Key8 => KeyCode::Key8,
|
||||
winit::event::VirtualKeyCode::Key9 => KeyCode::Key9,
|
||||
winit::event::VirtualKeyCode::Key0 => KeyCode::Key0,
|
||||
winit::event::VirtualKeyCode::A => KeyCode::A,
|
||||
winit::event::VirtualKeyCode::B => KeyCode::B,
|
||||
winit::event::VirtualKeyCode::C => KeyCode::C,
|
||||
winit::event::VirtualKeyCode::D => KeyCode::D,
|
||||
winit::event::VirtualKeyCode::E => KeyCode::E,
|
||||
winit::event::VirtualKeyCode::F => KeyCode::F,
|
||||
winit::event::VirtualKeyCode::G => KeyCode::G,
|
||||
winit::event::VirtualKeyCode::H => KeyCode::H,
|
||||
winit::event::VirtualKeyCode::I => KeyCode::I,
|
||||
winit::event::VirtualKeyCode::J => KeyCode::J,
|
||||
winit::event::VirtualKeyCode::K => KeyCode::K,
|
||||
winit::event::VirtualKeyCode::L => KeyCode::L,
|
||||
winit::event::VirtualKeyCode::M => KeyCode::M,
|
||||
winit::event::VirtualKeyCode::N => KeyCode::N,
|
||||
winit::event::VirtualKeyCode::O => KeyCode::O,
|
||||
winit::event::VirtualKeyCode::P => KeyCode::P,
|
||||
winit::event::VirtualKeyCode::Q => KeyCode::Q,
|
||||
winit::event::VirtualKeyCode::R => KeyCode::R,
|
||||
winit::event::VirtualKeyCode::S => KeyCode::S,
|
||||
winit::event::VirtualKeyCode::T => KeyCode::T,
|
||||
winit::event::VirtualKeyCode::U => KeyCode::U,
|
||||
winit::event::VirtualKeyCode::V => KeyCode::V,
|
||||
winit::event::VirtualKeyCode::W => KeyCode::W,
|
||||
winit::event::VirtualKeyCode::X => KeyCode::X,
|
||||
winit::event::VirtualKeyCode::Y => KeyCode::Y,
|
||||
winit::event::VirtualKeyCode::Z => KeyCode::Z,
|
||||
winit::event::VirtualKeyCode::Escape => KeyCode::Escape,
|
||||
winit::event::VirtualKeyCode::F1 => KeyCode::F1,
|
||||
winit::event::VirtualKeyCode::F2 => KeyCode::F2,
|
||||
winit::event::VirtualKeyCode::F3 => KeyCode::F3,
|
||||
winit::event::VirtualKeyCode::F4 => KeyCode::F4,
|
||||
winit::event::VirtualKeyCode::F5 => KeyCode::F5,
|
||||
winit::event::VirtualKeyCode::F6 => KeyCode::F6,
|
||||
winit::event::VirtualKeyCode::F7 => KeyCode::F7,
|
||||
winit::event::VirtualKeyCode::F8 => KeyCode::F8,
|
||||
winit::event::VirtualKeyCode::F9 => KeyCode::F9,
|
||||
winit::event::VirtualKeyCode::F10 => KeyCode::F10,
|
||||
winit::event::VirtualKeyCode::F11 => KeyCode::F11,
|
||||
winit::event::VirtualKeyCode::F12 => KeyCode::F12,
|
||||
winit::event::VirtualKeyCode::F13 => KeyCode::F13,
|
||||
winit::event::VirtualKeyCode::F14 => KeyCode::F14,
|
||||
winit::event::VirtualKeyCode::F15 => KeyCode::F15,
|
||||
winit::event::VirtualKeyCode::F16 => KeyCode::F16,
|
||||
winit::event::VirtualKeyCode::F17 => KeyCode::F17,
|
||||
winit::event::VirtualKeyCode::F18 => KeyCode::F18,
|
||||
winit::event::VirtualKeyCode::F19 => KeyCode::F19,
|
||||
winit::event::VirtualKeyCode::F20 => KeyCode::F20,
|
||||
winit::event::VirtualKeyCode::F21 => KeyCode::F21,
|
||||
winit::event::VirtualKeyCode::F22 => KeyCode::F22,
|
||||
winit::event::VirtualKeyCode::F23 => KeyCode::F23,
|
||||
winit::event::VirtualKeyCode::F24 => KeyCode::F24,
|
||||
winit::event::VirtualKeyCode::Snapshot => KeyCode::Snapshot,
|
||||
winit::event::VirtualKeyCode::Scroll => KeyCode::Scroll,
|
||||
winit::event::VirtualKeyCode::Pause => KeyCode::Pause,
|
||||
winit::event::VirtualKeyCode::Insert => KeyCode::Insert,
|
||||
winit::event::VirtualKeyCode::Home => KeyCode::Home,
|
||||
winit::event::VirtualKeyCode::Delete => KeyCode::Delete,
|
||||
winit::event::VirtualKeyCode::End => KeyCode::End,
|
||||
winit::event::VirtualKeyCode::PageDown => KeyCode::PageDown,
|
||||
winit::event::VirtualKeyCode::PageUp => KeyCode::PageUp,
|
||||
winit::event::VirtualKeyCode::Left => KeyCode::Left,
|
||||
winit::event::VirtualKeyCode::Up => KeyCode::Up,
|
||||
winit::event::VirtualKeyCode::Right => KeyCode::Right,
|
||||
winit::event::VirtualKeyCode::Down => KeyCode::Down,
|
||||
winit::event::VirtualKeyCode::Back => KeyCode::Backspace,
|
||||
winit::event::VirtualKeyCode::Return => KeyCode::Enter,
|
||||
winit::event::VirtualKeyCode::Space => KeyCode::Space,
|
||||
winit::event::VirtualKeyCode::Compose => KeyCode::Compose,
|
||||
winit::event::VirtualKeyCode::Caret => KeyCode::Caret,
|
||||
winit::event::VirtualKeyCode::Numlock => KeyCode::Numlock,
|
||||
winit::event::VirtualKeyCode::Numpad0 => KeyCode::Numpad0,
|
||||
winit::event::VirtualKeyCode::Numpad1 => KeyCode::Numpad1,
|
||||
winit::event::VirtualKeyCode::Numpad2 => KeyCode::Numpad2,
|
||||
winit::event::VirtualKeyCode::Numpad3 => KeyCode::Numpad3,
|
||||
winit::event::VirtualKeyCode::Numpad4 => KeyCode::Numpad4,
|
||||
winit::event::VirtualKeyCode::Numpad5 => KeyCode::Numpad5,
|
||||
winit::event::VirtualKeyCode::Numpad6 => KeyCode::Numpad6,
|
||||
winit::event::VirtualKeyCode::Numpad7 => KeyCode::Numpad7,
|
||||
winit::event::VirtualKeyCode::Numpad8 => KeyCode::Numpad8,
|
||||
winit::event::VirtualKeyCode::Numpad9 => KeyCode::Numpad9,
|
||||
winit::event::VirtualKeyCode::AbntC1 => KeyCode::AbntC1,
|
||||
winit::event::VirtualKeyCode::AbntC2 => KeyCode::AbntC2,
|
||||
winit::event::VirtualKeyCode::NumpadAdd => KeyCode::NumpadAdd,
|
||||
winit::event::VirtualKeyCode::Plus => KeyCode::Plus,
|
||||
winit::event::VirtualKeyCode::Apostrophe => KeyCode::Apostrophe,
|
||||
winit::event::VirtualKeyCode::Apps => KeyCode::Apps,
|
||||
winit::event::VirtualKeyCode::At => KeyCode::At,
|
||||
winit::event::VirtualKeyCode::Ax => KeyCode::Ax,
|
||||
winit::event::VirtualKeyCode::Backslash => KeyCode::Backslash,
|
||||
winit::event::VirtualKeyCode::Calculator => KeyCode::Calculator,
|
||||
winit::event::VirtualKeyCode::Capital => KeyCode::Capital,
|
||||
winit::event::VirtualKeyCode::Colon => KeyCode::Colon,
|
||||
winit::event::VirtualKeyCode::Comma => KeyCode::Comma,
|
||||
winit::event::VirtualKeyCode::Convert => KeyCode::Convert,
|
||||
winit::event::VirtualKeyCode::NumpadDecimal => KeyCode::NumpadDecimal,
|
||||
winit::event::VirtualKeyCode::NumpadDivide => KeyCode::NumpadDivide,
|
||||
winit::event::VirtualKeyCode::Equals => KeyCode::Equals,
|
||||
winit::event::VirtualKeyCode::Grave => KeyCode::Grave,
|
||||
winit::event::VirtualKeyCode::Kana => KeyCode::Kana,
|
||||
winit::event::VirtualKeyCode::Kanji => KeyCode::Kanji,
|
||||
winit::event::VirtualKeyCode::LAlt => KeyCode::LAlt,
|
||||
winit::event::VirtualKeyCode::LBracket => KeyCode::LBracket,
|
||||
winit::event::VirtualKeyCode::LControl => KeyCode::LControl,
|
||||
winit::event::VirtualKeyCode::LShift => KeyCode::LShift,
|
||||
winit::event::VirtualKeyCode::LWin => KeyCode::LWin,
|
||||
winit::event::VirtualKeyCode::Mail => KeyCode::Mail,
|
||||
winit::event::VirtualKeyCode::MediaSelect => KeyCode::MediaSelect,
|
||||
winit::event::VirtualKeyCode::MediaStop => KeyCode::MediaStop,
|
||||
winit::event::VirtualKeyCode::Minus => KeyCode::Minus,
|
||||
winit::event::VirtualKeyCode::NumpadMultiply => KeyCode::NumpadMultiply,
|
||||
winit::event::VirtualKeyCode::Mute => KeyCode::Mute,
|
||||
winit::event::VirtualKeyCode::MyComputer => KeyCode::MyComputer,
|
||||
winit::event::VirtualKeyCode::NavigateForward => {
|
||||
KeyCode::NavigateForward
|
||||
match key {
|
||||
winit::keyboard::Key::Character(c) => keyboard::Key::Character(c),
|
||||
winit::keyboard::Key::Named(named_key) => {
|
||||
keyboard::Key::Named(match named_key {
|
||||
NamedKey::Alt => Named::Alt,
|
||||
NamedKey::AltGraph => Named::AltGraph,
|
||||
NamedKey::CapsLock => Named::CapsLock,
|
||||
NamedKey::Control => Named::Control,
|
||||
NamedKey::Fn => Named::Fn,
|
||||
NamedKey::FnLock => Named::FnLock,
|
||||
NamedKey::NumLock => Named::NumLock,
|
||||
NamedKey::ScrollLock => Named::ScrollLock,
|
||||
NamedKey::Shift => Named::Shift,
|
||||
NamedKey::Symbol => Named::Symbol,
|
||||
NamedKey::SymbolLock => Named::SymbolLock,
|
||||
NamedKey::Meta => Named::Meta,
|
||||
NamedKey::Hyper => Named::Hyper,
|
||||
NamedKey::Super => Named::Super,
|
||||
NamedKey::Enter => Named::Enter,
|
||||
NamedKey::Tab => Named::Tab,
|
||||
NamedKey::Space => Named::Space,
|
||||
NamedKey::ArrowDown => Named::ArrowDown,
|
||||
NamedKey::ArrowLeft => Named::ArrowLeft,
|
||||
NamedKey::ArrowRight => Named::ArrowRight,
|
||||
NamedKey::ArrowUp => Named::ArrowUp,
|
||||
NamedKey::End => Named::End,
|
||||
NamedKey::Home => Named::Home,
|
||||
NamedKey::PageDown => Named::PageDown,
|
||||
NamedKey::PageUp => Named::PageUp,
|
||||
NamedKey::Backspace => Named::Backspace,
|
||||
NamedKey::Clear => Named::Clear,
|
||||
NamedKey::Copy => Named::Copy,
|
||||
NamedKey::CrSel => Named::CrSel,
|
||||
NamedKey::Cut => Named::Cut,
|
||||
NamedKey::Delete => Named::Delete,
|
||||
NamedKey::EraseEof => Named::EraseEof,
|
||||
NamedKey::ExSel => Named::ExSel,
|
||||
NamedKey::Insert => Named::Insert,
|
||||
NamedKey::Paste => Named::Paste,
|
||||
NamedKey::Redo => Named::Redo,
|
||||
NamedKey::Undo => Named::Undo,
|
||||
NamedKey::Accept => Named::Accept,
|
||||
NamedKey::Again => Named::Again,
|
||||
NamedKey::Attn => Named::Attn,
|
||||
NamedKey::Cancel => Named::Cancel,
|
||||
NamedKey::ContextMenu => Named::ContextMenu,
|
||||
NamedKey::Escape => Named::Escape,
|
||||
NamedKey::Execute => Named::Execute,
|
||||
NamedKey::Find => Named::Find,
|
||||
NamedKey::Help => Named::Help,
|
||||
NamedKey::Pause => Named::Pause,
|
||||
NamedKey::Play => Named::Play,
|
||||
NamedKey::Props => Named::Props,
|
||||
NamedKey::Select => Named::Select,
|
||||
NamedKey::ZoomIn => Named::ZoomIn,
|
||||
NamedKey::ZoomOut => Named::ZoomOut,
|
||||
NamedKey::BrightnessDown => Named::BrightnessDown,
|
||||
NamedKey::BrightnessUp => Named::BrightnessUp,
|
||||
NamedKey::Eject => Named::Eject,
|
||||
NamedKey::LogOff => Named::LogOff,
|
||||
NamedKey::Power => Named::Power,
|
||||
NamedKey::PowerOff => Named::PowerOff,
|
||||
NamedKey::PrintScreen => Named::PrintScreen,
|
||||
NamedKey::Hibernate => Named::Hibernate,
|
||||
NamedKey::Standby => Named::Standby,
|
||||
NamedKey::WakeUp => Named::WakeUp,
|
||||
NamedKey::AllCandidates => Named::AllCandidates,
|
||||
NamedKey::Alphanumeric => Named::Alphanumeric,
|
||||
NamedKey::CodeInput => Named::CodeInput,
|
||||
NamedKey::Compose => Named::Compose,
|
||||
NamedKey::Convert => Named::Convert,
|
||||
NamedKey::FinalMode => Named::FinalMode,
|
||||
NamedKey::GroupFirst => Named::GroupFirst,
|
||||
NamedKey::GroupLast => Named::GroupLast,
|
||||
NamedKey::GroupNext => Named::GroupNext,
|
||||
NamedKey::GroupPrevious => Named::GroupPrevious,
|
||||
NamedKey::ModeChange => Named::ModeChange,
|
||||
NamedKey::NextCandidate => Named::NextCandidate,
|
||||
NamedKey::NonConvert => Named::NonConvert,
|
||||
NamedKey::PreviousCandidate => Named::PreviousCandidate,
|
||||
NamedKey::Process => Named::Process,
|
||||
NamedKey::SingleCandidate => Named::SingleCandidate,
|
||||
NamedKey::HangulMode => Named::HangulMode,
|
||||
NamedKey::HanjaMode => Named::HanjaMode,
|
||||
NamedKey::JunjaMode => Named::JunjaMode,
|
||||
NamedKey::Eisu => Named::Eisu,
|
||||
NamedKey::Hankaku => Named::Hankaku,
|
||||
NamedKey::Hiragana => Named::Hiragana,
|
||||
NamedKey::HiraganaKatakana => Named::HiraganaKatakana,
|
||||
NamedKey::KanaMode => Named::KanaMode,
|
||||
NamedKey::KanjiMode => Named::KanjiMode,
|
||||
NamedKey::Katakana => Named::Katakana,
|
||||
NamedKey::Romaji => Named::Romaji,
|
||||
NamedKey::Zenkaku => Named::Zenkaku,
|
||||
NamedKey::ZenkakuHankaku => Named::ZenkakuHankaku,
|
||||
NamedKey::Soft1 => Named::Soft1,
|
||||
NamedKey::Soft2 => Named::Soft2,
|
||||
NamedKey::Soft3 => Named::Soft3,
|
||||
NamedKey::Soft4 => Named::Soft4,
|
||||
NamedKey::ChannelDown => Named::ChannelDown,
|
||||
NamedKey::ChannelUp => Named::ChannelUp,
|
||||
NamedKey::Close => Named::Close,
|
||||
NamedKey::MailForward => Named::MailForward,
|
||||
NamedKey::MailReply => Named::MailReply,
|
||||
NamedKey::MailSend => Named::MailSend,
|
||||
NamedKey::MediaClose => Named::MediaClose,
|
||||
NamedKey::MediaFastForward => Named::MediaFastForward,
|
||||
NamedKey::MediaPause => Named::MediaPause,
|
||||
NamedKey::MediaPlay => Named::MediaPlay,
|
||||
NamedKey::MediaPlayPause => Named::MediaPlayPause,
|
||||
NamedKey::MediaRecord => Named::MediaRecord,
|
||||
NamedKey::MediaRewind => Named::MediaRewind,
|
||||
NamedKey::MediaStop => Named::MediaStop,
|
||||
NamedKey::MediaTrackNext => Named::MediaTrackNext,
|
||||
NamedKey::MediaTrackPrevious => Named::MediaTrackPrevious,
|
||||
NamedKey::New => Named::New,
|
||||
NamedKey::Open => Named::Open,
|
||||
NamedKey::Print => Named::Print,
|
||||
NamedKey::Save => Named::Save,
|
||||
NamedKey::SpellCheck => Named::SpellCheck,
|
||||
NamedKey::Key11 => Named::Key11,
|
||||
NamedKey::Key12 => Named::Key12,
|
||||
NamedKey::AudioBalanceLeft => Named::AudioBalanceLeft,
|
||||
NamedKey::AudioBalanceRight => Named::AudioBalanceRight,
|
||||
NamedKey::AudioBassBoostDown => Named::AudioBassBoostDown,
|
||||
NamedKey::AudioBassBoostToggle => Named::AudioBassBoostToggle,
|
||||
NamedKey::AudioBassBoostUp => Named::AudioBassBoostUp,
|
||||
NamedKey::AudioFaderFront => Named::AudioFaderFront,
|
||||
NamedKey::AudioFaderRear => Named::AudioFaderRear,
|
||||
NamedKey::AudioSurroundModeNext => Named::AudioSurroundModeNext,
|
||||
NamedKey::AudioTrebleDown => Named::AudioTrebleDown,
|
||||
NamedKey::AudioTrebleUp => Named::AudioTrebleUp,
|
||||
NamedKey::AudioVolumeDown => Named::AudioVolumeDown,
|
||||
NamedKey::AudioVolumeUp => Named::AudioVolumeUp,
|
||||
NamedKey::AudioVolumeMute => Named::AudioVolumeMute,
|
||||
NamedKey::MicrophoneToggle => Named::MicrophoneToggle,
|
||||
NamedKey::MicrophoneVolumeDown => Named::MicrophoneVolumeDown,
|
||||
NamedKey::MicrophoneVolumeUp => Named::MicrophoneVolumeUp,
|
||||
NamedKey::MicrophoneVolumeMute => Named::MicrophoneVolumeMute,
|
||||
NamedKey::SpeechCorrectionList => Named::SpeechCorrectionList,
|
||||
NamedKey::SpeechInputToggle => Named::SpeechInputToggle,
|
||||
NamedKey::LaunchApplication1 => Named::LaunchApplication1,
|
||||
NamedKey::LaunchApplication2 => Named::LaunchApplication2,
|
||||
NamedKey::LaunchCalendar => Named::LaunchCalendar,
|
||||
NamedKey::LaunchContacts => Named::LaunchContacts,
|
||||
NamedKey::LaunchMail => Named::LaunchMail,
|
||||
NamedKey::LaunchMediaPlayer => Named::LaunchMediaPlayer,
|
||||
NamedKey::LaunchMusicPlayer => Named::LaunchMusicPlayer,
|
||||
NamedKey::LaunchPhone => Named::LaunchPhone,
|
||||
NamedKey::LaunchScreenSaver => Named::LaunchScreenSaver,
|
||||
NamedKey::LaunchSpreadsheet => Named::LaunchSpreadsheet,
|
||||
NamedKey::LaunchWebBrowser => Named::LaunchWebBrowser,
|
||||
NamedKey::LaunchWebCam => Named::LaunchWebCam,
|
||||
NamedKey::LaunchWordProcessor => Named::LaunchWordProcessor,
|
||||
NamedKey::BrowserBack => Named::BrowserBack,
|
||||
NamedKey::BrowserFavorites => Named::BrowserFavorites,
|
||||
NamedKey::BrowserForward => Named::BrowserForward,
|
||||
NamedKey::BrowserHome => Named::BrowserHome,
|
||||
NamedKey::BrowserRefresh => Named::BrowserRefresh,
|
||||
NamedKey::BrowserSearch => Named::BrowserSearch,
|
||||
NamedKey::BrowserStop => Named::BrowserStop,
|
||||
NamedKey::AppSwitch => Named::AppSwitch,
|
||||
NamedKey::Call => Named::Call,
|
||||
NamedKey::Camera => Named::Camera,
|
||||
NamedKey::CameraFocus => Named::CameraFocus,
|
||||
NamedKey::EndCall => Named::EndCall,
|
||||
NamedKey::GoBack => Named::GoBack,
|
||||
NamedKey::GoHome => Named::GoHome,
|
||||
NamedKey::HeadsetHook => Named::HeadsetHook,
|
||||
NamedKey::LastNumberRedial => Named::LastNumberRedial,
|
||||
NamedKey::Notification => Named::Notification,
|
||||
NamedKey::MannerMode => Named::MannerMode,
|
||||
NamedKey::VoiceDial => Named::VoiceDial,
|
||||
NamedKey::TV => Named::TV,
|
||||
NamedKey::TV3DMode => Named::TV3DMode,
|
||||
NamedKey::TVAntennaCable => Named::TVAntennaCable,
|
||||
NamedKey::TVAudioDescription => Named::TVAudioDescription,
|
||||
NamedKey::TVAudioDescriptionMixDown => {
|
||||
Named::TVAudioDescriptionMixDown
|
||||
}
|
||||
NamedKey::TVAudioDescriptionMixUp => {
|
||||
Named::TVAudioDescriptionMixUp
|
||||
}
|
||||
NamedKey::TVContentsMenu => Named::TVContentsMenu,
|
||||
NamedKey::TVDataService => Named::TVDataService,
|
||||
NamedKey::TVInput => Named::TVInput,
|
||||
NamedKey::TVInputComponent1 => Named::TVInputComponent1,
|
||||
NamedKey::TVInputComponent2 => Named::TVInputComponent2,
|
||||
NamedKey::TVInputComposite1 => Named::TVInputComposite1,
|
||||
NamedKey::TVInputComposite2 => Named::TVInputComposite2,
|
||||
NamedKey::TVInputHDMI1 => Named::TVInputHDMI1,
|
||||
NamedKey::TVInputHDMI2 => Named::TVInputHDMI2,
|
||||
NamedKey::TVInputHDMI3 => Named::TVInputHDMI3,
|
||||
NamedKey::TVInputHDMI4 => Named::TVInputHDMI4,
|
||||
NamedKey::TVInputVGA1 => Named::TVInputVGA1,
|
||||
NamedKey::TVMediaContext => Named::TVMediaContext,
|
||||
NamedKey::TVNetwork => Named::TVNetwork,
|
||||
NamedKey::TVNumberEntry => Named::TVNumberEntry,
|
||||
NamedKey::TVPower => Named::TVPower,
|
||||
NamedKey::TVRadioService => Named::TVRadioService,
|
||||
NamedKey::TVSatellite => Named::TVSatellite,
|
||||
NamedKey::TVSatelliteBS => Named::TVSatelliteBS,
|
||||
NamedKey::TVSatelliteCS => Named::TVSatelliteCS,
|
||||
NamedKey::TVSatelliteToggle => Named::TVSatelliteToggle,
|
||||
NamedKey::TVTerrestrialAnalog => Named::TVTerrestrialAnalog,
|
||||
NamedKey::TVTerrestrialDigital => Named::TVTerrestrialDigital,
|
||||
NamedKey::TVTimer => Named::TVTimer,
|
||||
NamedKey::AVRInput => Named::AVRInput,
|
||||
NamedKey::AVRPower => Named::AVRPower,
|
||||
NamedKey::ColorF0Red => Named::ColorF0Red,
|
||||
NamedKey::ColorF1Green => Named::ColorF1Green,
|
||||
NamedKey::ColorF2Yellow => Named::ColorF2Yellow,
|
||||
NamedKey::ColorF3Blue => Named::ColorF3Blue,
|
||||
NamedKey::ColorF4Grey => Named::ColorF4Grey,
|
||||
NamedKey::ColorF5Brown => Named::ColorF5Brown,
|
||||
NamedKey::ClosedCaptionToggle => Named::ClosedCaptionToggle,
|
||||
NamedKey::Dimmer => Named::Dimmer,
|
||||
NamedKey::DisplaySwap => Named::DisplaySwap,
|
||||
NamedKey::DVR => Named::DVR,
|
||||
NamedKey::Exit => Named::Exit,
|
||||
NamedKey::FavoriteClear0 => Named::FavoriteClear0,
|
||||
NamedKey::FavoriteClear1 => Named::FavoriteClear1,
|
||||
NamedKey::FavoriteClear2 => Named::FavoriteClear2,
|
||||
NamedKey::FavoriteClear3 => Named::FavoriteClear3,
|
||||
NamedKey::FavoriteRecall0 => Named::FavoriteRecall0,
|
||||
NamedKey::FavoriteRecall1 => Named::FavoriteRecall1,
|
||||
NamedKey::FavoriteRecall2 => Named::FavoriteRecall2,
|
||||
NamedKey::FavoriteRecall3 => Named::FavoriteRecall3,
|
||||
NamedKey::FavoriteStore0 => Named::FavoriteStore0,
|
||||
NamedKey::FavoriteStore1 => Named::FavoriteStore1,
|
||||
NamedKey::FavoriteStore2 => Named::FavoriteStore2,
|
||||
NamedKey::FavoriteStore3 => Named::FavoriteStore3,
|
||||
NamedKey::Guide => Named::Guide,
|
||||
NamedKey::GuideNextDay => Named::GuideNextDay,
|
||||
NamedKey::GuidePreviousDay => Named::GuidePreviousDay,
|
||||
NamedKey::Info => Named::Info,
|
||||
NamedKey::InstantReplay => Named::InstantReplay,
|
||||
NamedKey::Link => Named::Link,
|
||||
NamedKey::ListProgram => Named::ListProgram,
|
||||
NamedKey::LiveContent => Named::LiveContent,
|
||||
NamedKey::Lock => Named::Lock,
|
||||
NamedKey::MediaApps => Named::MediaApps,
|
||||
NamedKey::MediaAudioTrack => Named::MediaAudioTrack,
|
||||
NamedKey::MediaLast => Named::MediaLast,
|
||||
NamedKey::MediaSkipBackward => Named::MediaSkipBackward,
|
||||
NamedKey::MediaSkipForward => Named::MediaSkipForward,
|
||||
NamedKey::MediaStepBackward => Named::MediaStepBackward,
|
||||
NamedKey::MediaStepForward => Named::MediaStepForward,
|
||||
NamedKey::MediaTopMenu => Named::MediaTopMenu,
|
||||
NamedKey::NavigateIn => Named::NavigateIn,
|
||||
NamedKey::NavigateNext => Named::NavigateNext,
|
||||
NamedKey::NavigateOut => Named::NavigateOut,
|
||||
NamedKey::NavigatePrevious => Named::NavigatePrevious,
|
||||
NamedKey::NextFavoriteChannel => Named::NextFavoriteChannel,
|
||||
NamedKey::NextUserProfile => Named::NextUserProfile,
|
||||
NamedKey::OnDemand => Named::OnDemand,
|
||||
NamedKey::Pairing => Named::Pairing,
|
||||
NamedKey::PinPDown => Named::PinPDown,
|
||||
NamedKey::PinPMove => Named::PinPMove,
|
||||
NamedKey::PinPToggle => Named::PinPToggle,
|
||||
NamedKey::PinPUp => Named::PinPUp,
|
||||
NamedKey::PlaySpeedDown => Named::PlaySpeedDown,
|
||||
NamedKey::PlaySpeedReset => Named::PlaySpeedReset,
|
||||
NamedKey::PlaySpeedUp => Named::PlaySpeedUp,
|
||||
NamedKey::RandomToggle => Named::RandomToggle,
|
||||
NamedKey::RcLowBattery => Named::RcLowBattery,
|
||||
NamedKey::RecordSpeedNext => Named::RecordSpeedNext,
|
||||
NamedKey::RfBypass => Named::RfBypass,
|
||||
NamedKey::ScanChannelsToggle => Named::ScanChannelsToggle,
|
||||
NamedKey::ScreenModeNext => Named::ScreenModeNext,
|
||||
NamedKey::Settings => Named::Settings,
|
||||
NamedKey::SplitScreenToggle => Named::SplitScreenToggle,
|
||||
NamedKey::STBInput => Named::STBInput,
|
||||
NamedKey::STBPower => Named::STBPower,
|
||||
NamedKey::Subtitle => Named::Subtitle,
|
||||
NamedKey::Teletext => Named::Teletext,
|
||||
NamedKey::VideoModeNext => Named::VideoModeNext,
|
||||
NamedKey::Wink => Named::Wink,
|
||||
NamedKey::ZoomToggle => Named::ZoomToggle,
|
||||
NamedKey::F1 => Named::F1,
|
||||
NamedKey::F2 => Named::F2,
|
||||
NamedKey::F3 => Named::F3,
|
||||
NamedKey::F4 => Named::F4,
|
||||
NamedKey::F5 => Named::F5,
|
||||
NamedKey::F6 => Named::F6,
|
||||
NamedKey::F7 => Named::F7,
|
||||
NamedKey::F8 => Named::F8,
|
||||
NamedKey::F9 => Named::F9,
|
||||
NamedKey::F10 => Named::F10,
|
||||
NamedKey::F11 => Named::F11,
|
||||
NamedKey::F12 => Named::F12,
|
||||
NamedKey::F13 => Named::F13,
|
||||
NamedKey::F14 => Named::F14,
|
||||
NamedKey::F15 => Named::F15,
|
||||
NamedKey::F16 => Named::F16,
|
||||
NamedKey::F17 => Named::F17,
|
||||
NamedKey::F18 => Named::F18,
|
||||
NamedKey::F19 => Named::F19,
|
||||
NamedKey::F20 => Named::F20,
|
||||
NamedKey::F21 => Named::F21,
|
||||
NamedKey::F22 => Named::F22,
|
||||
NamedKey::F23 => Named::F23,
|
||||
NamedKey::F24 => Named::F24,
|
||||
NamedKey::F25 => Named::F25,
|
||||
NamedKey::F26 => Named::F26,
|
||||
NamedKey::F27 => Named::F27,
|
||||
NamedKey::F28 => Named::F28,
|
||||
NamedKey::F29 => Named::F29,
|
||||
NamedKey::F30 => Named::F30,
|
||||
NamedKey::F31 => Named::F31,
|
||||
NamedKey::F32 => Named::F32,
|
||||
NamedKey::F33 => Named::F33,
|
||||
NamedKey::F34 => Named::F34,
|
||||
NamedKey::F35 => Named::F35,
|
||||
_ => return keyboard::Key::Unidentified,
|
||||
})
|
||||
}
|
||||
winit::event::VirtualKeyCode::NavigateBackward => {
|
||||
KeyCode::NavigateBackward
|
||||
}
|
||||
winit::event::VirtualKeyCode::NextTrack => KeyCode::NextTrack,
|
||||
winit::event::VirtualKeyCode::NoConvert => KeyCode::NoConvert,
|
||||
winit::event::VirtualKeyCode::NumpadComma => KeyCode::NumpadComma,
|
||||
winit::event::VirtualKeyCode::NumpadEnter => KeyCode::NumpadEnter,
|
||||
winit::event::VirtualKeyCode::NumpadEquals => KeyCode::NumpadEquals,
|
||||
winit::event::VirtualKeyCode::OEM102 => KeyCode::OEM102,
|
||||
winit::event::VirtualKeyCode::Period => KeyCode::Period,
|
||||
winit::event::VirtualKeyCode::PlayPause => KeyCode::PlayPause,
|
||||
winit::event::VirtualKeyCode::Power => KeyCode::Power,
|
||||
winit::event::VirtualKeyCode::PrevTrack => KeyCode::PrevTrack,
|
||||
winit::event::VirtualKeyCode::RAlt => KeyCode::RAlt,
|
||||
winit::event::VirtualKeyCode::RBracket => KeyCode::RBracket,
|
||||
winit::event::VirtualKeyCode::RControl => KeyCode::RControl,
|
||||
winit::event::VirtualKeyCode::RShift => KeyCode::RShift,
|
||||
winit::event::VirtualKeyCode::RWin => KeyCode::RWin,
|
||||
winit::event::VirtualKeyCode::Semicolon => KeyCode::Semicolon,
|
||||
winit::event::VirtualKeyCode::Slash => KeyCode::Slash,
|
||||
winit::event::VirtualKeyCode::Sleep => KeyCode::Sleep,
|
||||
winit::event::VirtualKeyCode::Stop => KeyCode::Stop,
|
||||
winit::event::VirtualKeyCode::NumpadSubtract => KeyCode::NumpadSubtract,
|
||||
winit::event::VirtualKeyCode::Sysrq => KeyCode::Sysrq,
|
||||
winit::event::VirtualKeyCode::Tab => KeyCode::Tab,
|
||||
winit::event::VirtualKeyCode::Underline => KeyCode::Underline,
|
||||
winit::event::VirtualKeyCode::Unlabeled => KeyCode::Unlabeled,
|
||||
winit::event::VirtualKeyCode::VolumeDown => KeyCode::VolumeDown,
|
||||
winit::event::VirtualKeyCode::VolumeUp => KeyCode::VolumeUp,
|
||||
winit::event::VirtualKeyCode::Wake => KeyCode::Wake,
|
||||
winit::event::VirtualKeyCode::WebBack => KeyCode::WebBack,
|
||||
winit::event::VirtualKeyCode::WebFavorites => KeyCode::WebFavorites,
|
||||
winit::event::VirtualKeyCode::WebForward => KeyCode::WebForward,
|
||||
winit::event::VirtualKeyCode::WebHome => KeyCode::WebHome,
|
||||
winit::event::VirtualKeyCode::WebRefresh => KeyCode::WebRefresh,
|
||||
winit::event::VirtualKeyCode::WebSearch => KeyCode::WebSearch,
|
||||
winit::event::VirtualKeyCode::WebStop => KeyCode::WebStop,
|
||||
winit::event::VirtualKeyCode::Yen => KeyCode::Yen,
|
||||
winit::event::VirtualKeyCode::Copy => KeyCode::Copy,
|
||||
winit::event::VirtualKeyCode::Paste => KeyCode::Paste,
|
||||
winit::event::VirtualKeyCode::Cut => KeyCode::Cut,
|
||||
winit::event::VirtualKeyCode::Asterisk => KeyCode::Asterisk,
|
||||
_ => keyboard::Key::Unidentified,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -655,13 +812,3 @@ pub fn icon(icon: window::Icon) -> Option<winit::window::Icon> {
|
|||
|
||||
winit::window::Icon::from_rgba(pixels, size.width, size.height).ok()
|
||||
}
|
||||
|
||||
// As defined in: http://www.unicode.org/faq/private_use.html
|
||||
pub(crate) fn is_private_use_character(c: char) -> bool {
|
||||
matches!(
|
||||
c,
|
||||
'\u{E000}'..='\u{F8FF}'
|
||||
| '\u{F0000}'..='\u{FFFFD}'
|
||||
| '\u{100000}'..='\u{10FFFD}'
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -118,7 +118,10 @@ where
|
|||
let mut debug = Debug::new();
|
||||
debug.startup_started();
|
||||
|
||||
let event_loop = EventLoopBuilder::with_user_event().build();
|
||||
let event_loop = EventLoopBuilder::with_user_event()
|
||||
.build()
|
||||
.expect("Create event loop");
|
||||
|
||||
let proxy = event_loop.create_proxy();
|
||||
|
||||
let runtime = {
|
||||
|
|
@ -210,78 +213,78 @@ where
|
|||
|
||||
let mut context = task::Context::from_waker(task::noop_waker_ref());
|
||||
|
||||
platform::run(event_loop, move |event, window_target, control_flow| {
|
||||
use winit::event_loop::ControlFlow;
|
||||
|
||||
if let ControlFlow::ExitWithCode(_) = control_flow {
|
||||
let _ = event_loop.run(move |event, event_loop| {
|
||||
if event_loop.exiting() {
|
||||
return;
|
||||
}
|
||||
|
||||
let event = match event {
|
||||
winit::event::Event::WindowEvent {
|
||||
event:
|
||||
winit::event::WindowEvent::ScaleFactorChanged {
|
||||
new_inner_size,
|
||||
..
|
||||
},
|
||||
window_id,
|
||||
} => Some(winit::event::Event::WindowEvent {
|
||||
event: winit::event::WindowEvent::Resized(*new_inner_size),
|
||||
window_id,
|
||||
}),
|
||||
_ => event.to_static(),
|
||||
};
|
||||
event_sender
|
||||
.start_send(Event::EventLoopAwakened(event))
|
||||
.expect("Send event");
|
||||
|
||||
if let Some(event) = event {
|
||||
event_sender
|
||||
.start_send(Event::EventLoopAwakened(event))
|
||||
.expect("Send event");
|
||||
loop {
|
||||
let poll = instance.as_mut().poll(&mut context);
|
||||
|
||||
loop {
|
||||
let poll = instance.as_mut().poll(&mut context);
|
||||
match poll {
|
||||
task::Poll::Pending => match control_receiver.try_next() {
|
||||
Ok(Some(control)) => match control {
|
||||
Control::ChangeFlow(flow) => {
|
||||
use winit::event_loop::ControlFlow;
|
||||
|
||||
match poll {
|
||||
task::Poll::Pending => match control_receiver.try_next() {
|
||||
Ok(Some(control)) => match control {
|
||||
Control::ChangeFlow(flow) => {
|
||||
*control_flow = flow;
|
||||
match (event_loop.control_flow(), flow) {
|
||||
(
|
||||
ControlFlow::WaitUntil(current),
|
||||
ControlFlow::WaitUntil(new),
|
||||
) if new < current => {}
|
||||
(
|
||||
ControlFlow::WaitUntil(target),
|
||||
ControlFlow::Wait,
|
||||
) if target > Instant::now() => {}
|
||||
_ => {
|
||||
event_loop.set_control_flow(flow);
|
||||
}
|
||||
}
|
||||
Control::CreateWindow {
|
||||
id,
|
||||
settings,
|
||||
title,
|
||||
monitor,
|
||||
} => {
|
||||
let exit_on_close_request =
|
||||
settings.exit_on_close_request;
|
||||
}
|
||||
Control::CreateWindow {
|
||||
id,
|
||||
settings,
|
||||
title,
|
||||
monitor,
|
||||
} => {
|
||||
let exit_on_close_request =
|
||||
settings.exit_on_close_request;
|
||||
|
||||
let window = conversion::window_settings(
|
||||
settings, &title, monitor, None,
|
||||
)
|
||||
.build(window_target)
|
||||
.expect("Failed to build window");
|
||||
let window = conversion::window_settings(
|
||||
settings, &title, monitor, None,
|
||||
)
|
||||
.build(event_loop)
|
||||
.expect("Failed to build window");
|
||||
|
||||
event_sender
|
||||
.start_send(Event::WindowCreated {
|
||||
id,
|
||||
window,
|
||||
exit_on_close_request,
|
||||
})
|
||||
.expect("Send event");
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
break;
|
||||
event_sender
|
||||
.start_send(Event::WindowCreated {
|
||||
id,
|
||||
window,
|
||||
exit_on_close_request,
|
||||
})
|
||||
.expect("Send event");
|
||||
}
|
||||
Control::Exit => {
|
||||
event_loop.exit();
|
||||
}
|
||||
},
|
||||
task::Poll::Ready(_) => {
|
||||
*control_flow = ControlFlow::Exit;
|
||||
_ => {
|
||||
break;
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
task::Poll::Ready(_) => {
|
||||
event_loop.exit();
|
||||
break;
|
||||
}
|
||||
};
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
enum Event<Message: 'static> {
|
||||
|
|
@ -290,11 +293,12 @@ enum Event<Message: 'static> {
|
|||
window: winit::window::Window,
|
||||
exit_on_close_request: bool,
|
||||
},
|
||||
EventLoopAwakened(winit::event::Event<'static, Message>),
|
||||
EventLoopAwakened(winit::event::Event<Message>),
|
||||
}
|
||||
|
||||
enum Control {
|
||||
ChangeFlow(winit::event_loop::ControlFlow),
|
||||
Exit,
|
||||
CreateWindow {
|
||||
id: window::Id,
|
||||
settings: window::Settings,
|
||||
|
|
@ -372,7 +376,6 @@ async fn run_instance<A, E, C>(
|
|||
runtime.track(application.subscription().into_recipes());
|
||||
|
||||
let mut messages = Vec::new();
|
||||
let mut redraw_pending = false;
|
||||
|
||||
debug.startup_finished();
|
||||
|
||||
|
|
@ -419,15 +422,259 @@ async fn run_instance<A, E, C>(
|
|||
}
|
||||
Event::EventLoopAwakened(event) => {
|
||||
match event {
|
||||
event::Event::NewEvents(start_cause) => {
|
||||
redraw_pending = matches!(
|
||||
start_cause,
|
||||
event::StartCause::Init
|
||||
| event::StartCause::Poll
|
||||
| event::StartCause::ResumeTimeReached { .. }
|
||||
);
|
||||
event::Event::NewEvents(
|
||||
event::StartCause::Init
|
||||
| event::StartCause::ResumeTimeReached { .. },
|
||||
) => {
|
||||
for (_id, window) in window_manager.iter_mut() {
|
||||
// TODO once widgets can request to be redrawn, we can avoid always requesting a
|
||||
// redraw
|
||||
window.raw.request_redraw();
|
||||
}
|
||||
}
|
||||
event::Event::MainEventsCleared => {
|
||||
event::Event::PlatformSpecific(
|
||||
event::PlatformSpecific::MacOS(
|
||||
event::MacOS::ReceivedUrl(url),
|
||||
),
|
||||
) => {
|
||||
use crate::core::event;
|
||||
|
||||
events.push((
|
||||
None,
|
||||
event::Event::PlatformSpecific(
|
||||
event::PlatformSpecific::MacOS(
|
||||
event::MacOS::ReceivedUrl(url),
|
||||
),
|
||||
),
|
||||
));
|
||||
}
|
||||
event::Event::UserEvent(message) => {
|
||||
messages.push(message);
|
||||
}
|
||||
event::Event::WindowEvent {
|
||||
window_id: id,
|
||||
event: event::WindowEvent::RedrawRequested,
|
||||
..
|
||||
} => {
|
||||
let Some((id, window)) =
|
||||
window_manager.get_mut_alias(id)
|
||||
else {
|
||||
continue;
|
||||
};
|
||||
|
||||
// TODO: Avoid redrawing all the time by forcing widgets to
|
||||
// request redraws on state changes
|
||||
//
|
||||
// Then, we can use the `interface_state` here to decide if a redraw
|
||||
// is needed right away, or simply wait until a specific time.
|
||||
let redraw_event = core::Event::Window(
|
||||
id,
|
||||
window::Event::RedrawRequested(Instant::now()),
|
||||
);
|
||||
|
||||
let cursor = window.state.cursor();
|
||||
|
||||
let ui = user_interfaces
|
||||
.get_mut(&id)
|
||||
.expect("Get user interface");
|
||||
|
||||
let (ui_state, _) = ui.update(
|
||||
&[redraw_event.clone()],
|
||||
cursor,
|
||||
&mut window.renderer,
|
||||
&mut clipboard,
|
||||
&mut messages,
|
||||
);
|
||||
|
||||
debug.draw_started();
|
||||
let new_mouse_interaction = ui.draw(
|
||||
&mut window.renderer,
|
||||
window.state.theme(),
|
||||
&renderer::Style {
|
||||
text_color: window.state.text_color(),
|
||||
},
|
||||
cursor,
|
||||
);
|
||||
debug.draw_finished();
|
||||
|
||||
if new_mouse_interaction != window.mouse_interaction {
|
||||
window.raw.set_cursor_icon(
|
||||
conversion::mouse_interaction(
|
||||
new_mouse_interaction,
|
||||
),
|
||||
);
|
||||
|
||||
window.mouse_interaction = new_mouse_interaction;
|
||||
}
|
||||
|
||||
runtime.broadcast(
|
||||
redraw_event.clone(),
|
||||
core::event::Status::Ignored,
|
||||
);
|
||||
|
||||
let _ = control_sender.start_send(Control::ChangeFlow(
|
||||
match ui_state {
|
||||
user_interface::State::Updated {
|
||||
redraw_request: Some(redraw_request),
|
||||
} => match redraw_request {
|
||||
window::RedrawRequest::NextFrame => {
|
||||
window.raw.request_redraw();
|
||||
|
||||
ControlFlow::Wait
|
||||
}
|
||||
window::RedrawRequest::At(at) => {
|
||||
ControlFlow::WaitUntil(at)
|
||||
}
|
||||
},
|
||||
_ => ControlFlow::Wait,
|
||||
},
|
||||
));
|
||||
|
||||
let physical_size = window.state.physical_size();
|
||||
|
||||
if physical_size.width == 0 || physical_size.height == 0
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if window.viewport_version
|
||||
!= window.state.viewport_version()
|
||||
{
|
||||
let logical_size = window.state.logical_size();
|
||||
|
||||
debug.layout_started();
|
||||
let ui = user_interfaces
|
||||
.remove(&id)
|
||||
.expect("Remove user interface");
|
||||
|
||||
let _ = user_interfaces.insert(
|
||||
id,
|
||||
ui.relayout(logical_size, &mut window.renderer),
|
||||
);
|
||||
debug.layout_finished();
|
||||
|
||||
debug.draw_started();
|
||||
let new_mouse_interaction = user_interfaces
|
||||
.get_mut(&id)
|
||||
.expect("Get user interface")
|
||||
.draw(
|
||||
&mut window.renderer,
|
||||
window.state.theme(),
|
||||
&renderer::Style {
|
||||
text_color: window.state.text_color(),
|
||||
},
|
||||
window.state.cursor(),
|
||||
);
|
||||
debug.draw_finished();
|
||||
|
||||
if new_mouse_interaction != window.mouse_interaction
|
||||
{
|
||||
window.raw.set_cursor_icon(
|
||||
conversion::mouse_interaction(
|
||||
new_mouse_interaction,
|
||||
),
|
||||
);
|
||||
|
||||
window.mouse_interaction =
|
||||
new_mouse_interaction;
|
||||
}
|
||||
|
||||
compositor.configure_surface(
|
||||
&mut window.surface,
|
||||
physical_size.width,
|
||||
physical_size.height,
|
||||
);
|
||||
|
||||
window.viewport_version =
|
||||
window.state.viewport_version();
|
||||
}
|
||||
|
||||
debug.render_started();
|
||||
match compositor.present(
|
||||
&mut window.renderer,
|
||||
&mut window.surface,
|
||||
window.state.viewport(),
|
||||
window.state.background_color(),
|
||||
&debug.overlay(),
|
||||
) {
|
||||
Ok(()) => {
|
||||
debug.render_finished();
|
||||
|
||||
// TODO: Handle animations!
|
||||
// Maybe we can use `ControlFlow::WaitUntil` for this.
|
||||
}
|
||||
Err(error) => match error {
|
||||
// This is an unrecoverable error.
|
||||
compositor::SurfaceError::OutOfMemory => {
|
||||
panic!("{:?}", error);
|
||||
}
|
||||
_ => {
|
||||
debug.render_finished();
|
||||
|
||||
log::error!(
|
||||
"Error {error:?} when \
|
||||
presenting surface."
|
||||
);
|
||||
|
||||
// Try rendering all windows again next frame.
|
||||
for (_id, window) in
|
||||
window_manager.iter_mut()
|
||||
{
|
||||
window.raw.request_redraw();
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
event::Event::WindowEvent {
|
||||
event: window_event,
|
||||
window_id,
|
||||
} => {
|
||||
let Some((id, window)) =
|
||||
window_manager.get_mut_alias(window_id)
|
||||
else {
|
||||
continue;
|
||||
};
|
||||
|
||||
if matches!(
|
||||
window_event,
|
||||
winit::event::WindowEvent::CloseRequested
|
||||
) && window.exit_on_close_request
|
||||
{
|
||||
let _ = window_manager.remove(id);
|
||||
let _ = user_interfaces.remove(&id);
|
||||
let _ = ui_caches.remove(&id);
|
||||
|
||||
events.push((
|
||||
None,
|
||||
core::Event::Window(id, window::Event::Closed),
|
||||
));
|
||||
|
||||
if window_manager.is_empty() {
|
||||
break 'main;
|
||||
}
|
||||
} else {
|
||||
window.state.update(
|
||||
&window.raw,
|
||||
&window_event,
|
||||
&mut debug,
|
||||
);
|
||||
|
||||
if let Some(event) = conversion::window_event(
|
||||
id,
|
||||
window_event,
|
||||
window.state.scale_factor(),
|
||||
window.state.modifiers(),
|
||||
) {
|
||||
events.push((Some(id), event));
|
||||
}
|
||||
}
|
||||
}
|
||||
event::Event::AboutToWait => {
|
||||
if events.is_empty() && messages.is_empty() {
|
||||
continue;
|
||||
}
|
||||
|
||||
debug.event_processing_started();
|
||||
let mut uis_stale = false;
|
||||
|
||||
|
|
@ -444,10 +691,7 @@ async fn run_instance<A, E, C>(
|
|||
}
|
||||
});
|
||||
|
||||
if !redraw_pending
|
||||
&& window_events.is_empty()
|
||||
&& messages.is_empty()
|
||||
{
|
||||
if window_events.is_empty() && messages.is_empty() {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -462,6 +706,8 @@ async fn run_instance<A, E, C>(
|
|||
&mut messages,
|
||||
);
|
||||
|
||||
window.raw.request_redraw();
|
||||
|
||||
if !uis_stale {
|
||||
uis_stale = matches!(
|
||||
ui_state,
|
||||
|
|
@ -511,6 +757,10 @@ async fn run_instance<A, E, C>(
|
|||
id,
|
||||
&window.raw,
|
||||
);
|
||||
|
||||
// TODO once widgets can request to be redrawn, we can avoid always requesting a
|
||||
// redraw
|
||||
window.raw.request_redraw();
|
||||
}
|
||||
|
||||
// rebuild UIs with the synchronized states
|
||||
|
|
@ -522,254 +772,6 @@ async fn run_instance<A, E, C>(
|
|||
cached_interfaces,
|
||||
));
|
||||
}
|
||||
|
||||
debug.draw_started();
|
||||
|
||||
for (id, window) in window_manager.iter_mut() {
|
||||
// TODO: Avoid redrawing all the time by forcing widgets to
|
||||
// request redraws on state changes
|
||||
//
|
||||
// Then, we can use the `interface_state` here to decide if a redraw
|
||||
// is needed right away, or simply wait until a specific time.
|
||||
let redraw_event = core::Event::Window(
|
||||
id,
|
||||
window::Event::RedrawRequested(Instant::now()),
|
||||
);
|
||||
|
||||
let cursor = window.state.cursor();
|
||||
|
||||
let ui = user_interfaces
|
||||
.get_mut(&id)
|
||||
.expect("Get user interface");
|
||||
|
||||
let (ui_state, _) = ui.update(
|
||||
&[redraw_event.clone()],
|
||||
cursor,
|
||||
&mut window.renderer,
|
||||
&mut clipboard,
|
||||
&mut messages,
|
||||
);
|
||||
|
||||
let new_mouse_interaction = {
|
||||
let state = &window.state;
|
||||
|
||||
ui.draw(
|
||||
&mut window.renderer,
|
||||
state.theme(),
|
||||
&renderer::Style {
|
||||
text_color: state.text_color(),
|
||||
},
|
||||
cursor,
|
||||
)
|
||||
};
|
||||
|
||||
if new_mouse_interaction != window.mouse_interaction
|
||||
{
|
||||
window.raw.set_cursor_icon(
|
||||
conversion::mouse_interaction(
|
||||
new_mouse_interaction,
|
||||
),
|
||||
);
|
||||
|
||||
window.mouse_interaction =
|
||||
new_mouse_interaction;
|
||||
}
|
||||
|
||||
// TODO once widgets can request to be redrawn, we can avoid always requesting a
|
||||
// redraw
|
||||
window.raw.request_redraw();
|
||||
|
||||
runtime.broadcast(
|
||||
redraw_event.clone(),
|
||||
core::event::Status::Ignored,
|
||||
);
|
||||
|
||||
let _ = control_sender.start_send(
|
||||
Control::ChangeFlow(match ui_state {
|
||||
user_interface::State::Updated {
|
||||
redraw_request: Some(redraw_request),
|
||||
} => match redraw_request {
|
||||
window::RedrawRequest::NextFrame => {
|
||||
ControlFlow::Poll
|
||||
}
|
||||
window::RedrawRequest::At(at) => {
|
||||
ControlFlow::WaitUntil(at)
|
||||
}
|
||||
},
|
||||
_ => ControlFlow::Wait,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
redraw_pending = false;
|
||||
|
||||
debug.draw_finished();
|
||||
}
|
||||
event::Event::PlatformSpecific(
|
||||
event::PlatformSpecific::MacOS(
|
||||
event::MacOS::ReceivedUrl(url),
|
||||
),
|
||||
) => {
|
||||
use crate::core::event;
|
||||
|
||||
events.push((
|
||||
None,
|
||||
event::Event::PlatformSpecific(
|
||||
event::PlatformSpecific::MacOS(
|
||||
event::MacOS::ReceivedUrl(url),
|
||||
),
|
||||
),
|
||||
));
|
||||
}
|
||||
event::Event::UserEvent(message) => {
|
||||
messages.push(message);
|
||||
}
|
||||
event::Event::RedrawRequested(id) => {
|
||||
let Some((id, window)) =
|
||||
window_manager.get_mut_alias(id)
|
||||
else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let physical_size = window.state.physical_size();
|
||||
|
||||
if physical_size.width == 0 || physical_size.height == 0
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
debug.render_started();
|
||||
if window.viewport_version
|
||||
!= window.state.viewport_version()
|
||||
{
|
||||
let logical_size = window.state.logical_size();
|
||||
|
||||
debug.layout_started();
|
||||
|
||||
let ui = user_interfaces
|
||||
.remove(&id)
|
||||
.expect("Remove user interface");
|
||||
|
||||
let _ = user_interfaces.insert(
|
||||
id,
|
||||
ui.relayout(logical_size, &mut window.renderer),
|
||||
);
|
||||
|
||||
debug.layout_finished();
|
||||
|
||||
debug.draw_started();
|
||||
let new_mouse_interaction = user_interfaces
|
||||
.get_mut(&id)
|
||||
.expect("Get user interface")
|
||||
.draw(
|
||||
&mut window.renderer,
|
||||
window.state.theme(),
|
||||
&renderer::Style {
|
||||
text_color: window.state.text_color(),
|
||||
},
|
||||
window.state.cursor(),
|
||||
);
|
||||
|
||||
if new_mouse_interaction != window.mouse_interaction
|
||||
{
|
||||
window.raw.set_cursor_icon(
|
||||
conversion::mouse_interaction(
|
||||
new_mouse_interaction,
|
||||
),
|
||||
);
|
||||
|
||||
window.mouse_interaction =
|
||||
new_mouse_interaction;
|
||||
}
|
||||
debug.draw_finished();
|
||||
|
||||
compositor.configure_surface(
|
||||
&mut window.surface,
|
||||
physical_size.width,
|
||||
physical_size.height,
|
||||
);
|
||||
|
||||
window.viewport_version =
|
||||
window.state.viewport_version();
|
||||
}
|
||||
|
||||
match compositor.present(
|
||||
&mut window.renderer,
|
||||
&mut window.surface,
|
||||
window.state.viewport(),
|
||||
window.state.background_color(),
|
||||
&debug.overlay(),
|
||||
) {
|
||||
Ok(()) => {
|
||||
debug.render_finished();
|
||||
|
||||
// TODO: Handle animations!
|
||||
// Maybe we can use `ControlFlow::WaitUntil` for this.
|
||||
}
|
||||
Err(error) => match error {
|
||||
// This is an unrecoverable error.
|
||||
compositor::SurfaceError::OutOfMemory => {
|
||||
panic!("{:?}", error);
|
||||
}
|
||||
_ => {
|
||||
debug.render_finished();
|
||||
log::error!(
|
||||
"Error {error:?} when presenting surface."
|
||||
);
|
||||
|
||||
// Try rendering all windows again next frame.
|
||||
for (_id, window) in
|
||||
window_manager.iter_mut()
|
||||
{
|
||||
window.raw.request_redraw();
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
event::Event::WindowEvent {
|
||||
event: window_event,
|
||||
window_id,
|
||||
} => {
|
||||
let Some((id, window)) =
|
||||
window_manager.get_mut_alias(window_id)
|
||||
else {
|
||||
continue;
|
||||
};
|
||||
|
||||
if matches!(
|
||||
window_event,
|
||||
winit::event::WindowEvent::CloseRequested
|
||||
) && window.exit_on_close_request
|
||||
{
|
||||
let _ = window_manager.remove(id);
|
||||
let _ = user_interfaces.remove(&id);
|
||||
let _ = ui_caches.remove(&id);
|
||||
|
||||
events.push((
|
||||
None,
|
||||
core::Event::Window(id, window::Event::Closed),
|
||||
));
|
||||
|
||||
if window_manager.is_empty() {
|
||||
break 'main;
|
||||
}
|
||||
} else {
|
||||
window.state.update(
|
||||
&window.raw,
|
||||
&window_event,
|
||||
&mut debug,
|
||||
);
|
||||
|
||||
if let Some(event) = conversion::window_event(
|
||||
id,
|
||||
&window_event,
|
||||
window.state.scale_factor(),
|
||||
window.state.modifiers(),
|
||||
) {
|
||||
events.push((Some(id), event));
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
|
@ -901,16 +903,12 @@ fn run_command<A, C, E>(
|
|||
.expect("Send control action");
|
||||
}
|
||||
window::Action::Close(id) => {
|
||||
use winit::event_loop::ControlFlow;
|
||||
|
||||
let _ = window_manager.remove(id);
|
||||
let _ = ui_caches.remove(&id);
|
||||
|
||||
if window_manager.is_empty() {
|
||||
control_sender
|
||||
.start_send(Control::ChangeFlow(
|
||||
ControlFlow::ExitWithCode(0),
|
||||
))
|
||||
.start_send(Control::Exit)
|
||||
.expect("Send control action");
|
||||
}
|
||||
}
|
||||
|
|
@ -921,10 +919,12 @@ fn run_command<A, C, E>(
|
|||
}
|
||||
window::Action::Resize(id, size) => {
|
||||
if let Some(window) = window_manager.get_mut(id) {
|
||||
window.raw.set_inner_size(winit::dpi::LogicalSize {
|
||||
width: size.width,
|
||||
height: size.height,
|
||||
});
|
||||
let _ = window.raw.request_inner_size(
|
||||
winit::dpi::LogicalSize {
|
||||
width: size.width,
|
||||
height: size.height,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
window::Action::FetchSize(id, callback) => {
|
||||
|
|
@ -1167,60 +1167,20 @@ where
|
|||
/// Returns true if the provided event should cause an [`Application`] to
|
||||
/// exit.
|
||||
pub fn user_force_quit(
|
||||
event: &winit::event::WindowEvent<'_>,
|
||||
_modifiers: winit::event::ModifiersState,
|
||||
event: &winit::event::WindowEvent,
|
||||
_modifiers: winit::keyboard::ModifiersState,
|
||||
) -> bool {
|
||||
match event {
|
||||
#[cfg(target_os = "macos")]
|
||||
winit::event::WindowEvent::KeyboardInput {
|
||||
input:
|
||||
winit::event::KeyboardInput {
|
||||
virtual_keycode: Some(winit::event::VirtualKeyCode::Q),
|
||||
event:
|
||||
winit::event::KeyEvent {
|
||||
logical_key: winit::keyboard::Key::Character(c),
|
||||
state: winit::event::ElementState::Pressed,
|
||||
..
|
||||
},
|
||||
..
|
||||
} if _modifiers.logo() => true,
|
||||
} if c == "q" && _modifiers.super_key() => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
mod platform {
|
||||
pub fn run<T, F>(
|
||||
mut event_loop: winit::event_loop::EventLoop<T>,
|
||||
event_handler: F,
|
||||
) -> Result<(), super::Error>
|
||||
where
|
||||
F: 'static
|
||||
+ FnMut(
|
||||
winit::event::Event<'_, T>,
|
||||
&winit::event_loop::EventLoopWindowTarget<T>,
|
||||
&mut winit::event_loop::ControlFlow,
|
||||
),
|
||||
{
|
||||
use winit::platform::run_return::EventLoopExtRunReturn;
|
||||
|
||||
let _ = event_loop.run_return(event_handler);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
mod platform {
|
||||
pub fn run<T, F>(
|
||||
event_loop: winit::event_loop::EventLoop<T>,
|
||||
event_handler: F,
|
||||
) -> !
|
||||
where
|
||||
F: 'static
|
||||
+ FnMut(
|
||||
winit::event::Event<'_, T>,
|
||||
&winit::event_loop::EventLoopWindowTarget<T>,
|
||||
&mut winit::event_loop::ControlFlow,
|
||||
),
|
||||
{
|
||||
event_loop.run(event_handler)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ where
|
|||
viewport: Viewport,
|
||||
viewport_version: u64,
|
||||
cursor_position: Option<winit::dpi::PhysicalPosition<f64>>,
|
||||
modifiers: winit::event::ModifiersState,
|
||||
modifiers: winit::keyboard::ModifiersState,
|
||||
theme: <A::Renderer as core::Renderer>::Theme,
|
||||
appearance: application::Appearance,
|
||||
}
|
||||
|
|
@ -72,7 +72,7 @@ where
|
|||
viewport,
|
||||
viewport_version: 0,
|
||||
cursor_position: None,
|
||||
modifiers: winit::event::ModifiersState::default(),
|
||||
modifiers: winit::keyboard::ModifiersState::default(),
|
||||
theme,
|
||||
appearance,
|
||||
}
|
||||
|
|
@ -119,7 +119,7 @@ where
|
|||
}
|
||||
|
||||
/// Returns the current keyboard modifiers of the [`State`].
|
||||
pub fn modifiers(&self) -> winit::event::ModifiersState {
|
||||
pub fn modifiers(&self) -> winit::keyboard::ModifiersState {
|
||||
self.modifiers
|
||||
}
|
||||
|
||||
|
|
@ -142,7 +142,7 @@ where
|
|||
pub fn update(
|
||||
&mut self,
|
||||
window: &Window,
|
||||
event: &WindowEvent<'_>,
|
||||
event: &WindowEvent,
|
||||
_debug: &mut crate::runtime::Debug,
|
||||
) {
|
||||
match event {
|
||||
|
|
@ -158,10 +158,9 @@ where
|
|||
}
|
||||
WindowEvent::ScaleFactorChanged {
|
||||
scale_factor: new_scale_factor,
|
||||
new_inner_size,
|
||||
..
|
||||
} => {
|
||||
let size =
|
||||
Size::new(new_inner_size.width, new_inner_size.height);
|
||||
let size = self.viewport.physical_size();
|
||||
|
||||
self.viewport = Viewport::with_physical_size(
|
||||
size,
|
||||
|
|
@ -180,13 +179,16 @@ where
|
|||
self.cursor_position = None;
|
||||
}
|
||||
WindowEvent::ModifiersChanged(new_modifiers) => {
|
||||
self.modifiers = *new_modifiers;
|
||||
self.modifiers = new_modifiers.state();
|
||||
}
|
||||
#[cfg(feature = "debug")]
|
||||
WindowEvent::KeyboardInput {
|
||||
input:
|
||||
winit::event::KeyboardInput {
|
||||
virtual_keycode: Some(winit::event::VirtualKeyCode::F12),
|
||||
event:
|
||||
winit::event::KeyEvent {
|
||||
logical_key:
|
||||
winit::keyboard::Key::Named(
|
||||
winit::keyboard::NamedKey::F12,
|
||||
),
|
||||
state: winit::event::ElementState::Pressed,
|
||||
..
|
||||
},
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue