Skip to content

Commit

Permalink
+SDL2, -winit (#79)
Browse files Browse the repository at this point in the history
Closes #31.

* First commit. Most of the way migrated to SDL2.

* More fixes. Needs review.

* Fix cargo.toml paths to point at remote repo.

* Moved imgui-skia-renderer to it's own repo and cleaned up main.

Fixed ctrl+Q.
Refactored main.
Moved imgui to it's own repo.

* Removed dead code.

* Guidelines and console fixed.

* Made console steal input. Removed main_winit.rs

* Fix Ctrl-Q

* rustfmt

Co-authored-by: Matthew Blanchard <[email protected]>
  • Loading branch information
ctrlcctrlv and MatthewBlanchard authored Mar 28, 2021
1 parent 63a7dad commit 75cde81
Show file tree
Hide file tree
Showing 24 changed files with 1,022 additions and 1,587 deletions.
1,148 changes: 303 additions & 845 deletions Cargo.lock

Large diffs are not rendered by default.

21 changes: 18 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,23 @@ edition = "2018"
#skulpin = { version = "0.10.0", default-features = false, features = ["skia_complete", "skulpin_winit"] }
#skulpin = { path = "../skulpin", default-features = false, features = ["skia_complete", "skulpin_winit"] }
#skulpin-plugin-imgui = { path = "../skulpin/skulpin-plugin-imgui" }
skulpin = { version = "0.11.2", default-features = false, features = ["skia_complete", "skulpin_winit", "winit-22"] }
skulpin-plugin-imgui = { version = "0.7.1" }
imgui-winit-support = "0.5.0"
skulpin = { version = "0.13.0" }
skulpin-renderer = "0.13.0"

# For windowing, contexts, and events
sdl2 = { version = ">=0.33", features = ["bundled", "static-link", "raw-window-handle"] }

# For choosing font for toolbox
font-kit = "0.10.0"

# For global state
lazy_static = "1.4.0"

# For immediate mode GUI
imgui = "0.7.0"
imgui-sdl2 = "0.14.0"
imgui-skia-renderer = {git = "https://github.com/MFEK/imgui-skia-renderer.rlib", branch = "main"}

# For argument parsing
clap = "2.33.3"
git-version = "0.3.4"
Expand Down Expand Up @@ -60,8 +67,16 @@ MFEKMath = { git = "https://github.com/MFEK/math", branch = "vws-testing" }
#glifparser = { path = "../glifparser" } # for development
mfek-ipc = { git = "https://github.com/mfek/ipc" }

#xml parsing
xmltree = "0.10.1"

#config file directory resolution
app_dirs = "1.2.1"

#converting enums to strings
strum = "0.20"
strum_macros = "0.20"

# See src/util/mod.rs::set_codepage_utf8
[target.'cfg(windows)'.dependencies]
winapi = "0.3"
65 changes: 65 additions & 0 deletions src/command/default_keymap.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<!--
Example binding:
<binding command = "ToolPen" keycode = "A"/>
Commands:
// zoom
ResetScale
ZoomIn
ZoomOut
// move camera
NudgeUp
NudgeDown
NudgeLeft
NudgeRight
// tools
ToolPen
ToolSelect
ToolZoom
ToolVWS
// view modes
TogglePointLabels
TogglePreviewMode
// mod
ShiftMod
CtrlMod
-->

<keybindings>
<!-- zoom -->
<binding command = "ResetScale" key = "1"/>
<binding command = "ZoomIn" key = "="/>
<binding command = "ZoomOut" key = "-"/>

<!-- move camera -->
<binding command = "NudgeUp" key = "Up"/>
<binding command = "NudgeDown" key = "Down"/>
<binding command = "NudgeLeft" key = "Left"/>
<binding command = "NudgeRight" key = "Right"/>

<!-- tools -->
<binding command = "ToolPen" key = "A"/>
<binding command = "ToolPen" key = "P"/>
<binding command = "ToolSelect" key = "V"/>
<binding command = "ToolZoom" key = "Z"/>
<binding command = "ToolVWS" key = "S"/>

<!-- view modes -->
<binding command = "TogglePointLabels" key = "3"/>
<binding command = "TogglePreviewMode" key = "`"/>

<!-- console -->
<binding command = "ToggleConsole" key = ";"/>

<!-- mod keys -->
<mod name = "ShiftMod" key = "LShift"/>
<mod name = "CtrlMod" key = "LCtrl"/>

<mod name = "ShiftMod" key = "RShift"/>
<mod name = "CtrlMod" key = "RCtrl"/>
</keybindings>
173 changes: 173 additions & 0 deletions src/command/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
use app_dirs::*;
use sdl2::keyboard::Keycode;
use std::fs::read_to_string;
use std::path::Path;
use std::{
cell::RefCell,
collections::{HashMap, HashSet},
str::FromStr,
};
use strum_macros::{Display, EnumString};
use xmltree;

// a command file is put into the user's config directory upon first run
// <command name="ToolPen" key = "A">
// <mod name= "Shift" key = "shift">
#[derive(Copy, Clone, EnumString, Display, Debug, PartialEq)]
pub enum Command {
// zoom
ResetScale,
ZoomIn,
ZoomOut,

// move camera
NudgeUp,
NudgeDown,
NudgeLeft,
NudgeRight,

// tools
ToolPen,
ToolSelect,
ToolZoom,
ToolVWS,

// view modes
TogglePointLabels,
TogglePreviewMode,

// console
ToggleConsole,

ShiftMod,
CtrlMod,
}

#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct CommandMod {
pub shift: bool,
pub ctrl: bool,
}

pub struct CommandInfo {
pub command: Command,
pub command_mod: CommandMod,
}

pub fn initialize_keybinds() {
let binding_xml = load_keybinding_xml();
let mut config =
xmltree::Element::parse(binding_xml.as_bytes()).expect("Invalid keybinding XML!");

let mut hm = HashMap::new();
while let Some(binding) = config.take_child("binding") {
let keycode = binding
.attributes
.get("key")
.expect("Binding does not have a key associated!");
let command = binding
.attributes
.get("command")
.expect("Binding does not have a command associated!");

let command_enum = Command::from_str(command).expect("Invalid command string!");
let keycode_enum =
sdl2::keyboard::Keycode::from_name(keycode).expect("Invalid keycode string!");

hm.insert(keycode_enum, command_enum);
}

KEYMAP.with(|v| {
v.borrow_mut().keybindings = hm;
})
}

pub fn keycode_to_command(keycode: &Keycode, keys_down: &HashSet<Keycode>) -> Option<CommandInfo> {
let command_enum = KEYMAP.with(|v| {
if let Some(key) = v.borrow().keybindings.get(keycode) {
return Some(*key);
}

None
});

println!("{:?} {:?}", command_enum, keycode);
if let Some(command_enum) = command_enum {
return Some(CommandInfo {
command: command_enum,
command_mod: key_down_to_mod(keys_down),
});
}

return None;
}

// kinda clunky but it works
pub fn key_down_to_mod(keys_down: &HashSet<Keycode>) -> CommandMod {
let mut keymod = CommandMod {
shift: false,
ctrl: false,
};

KEYMAP.with(|v| {
for (key, value) in v.borrow().keybindings.iter() {
match value {
Command::ShiftMod => {
if keys_down.get(&key).is_some() {
keymod.shift = true;
}
}
Command::CtrlMod => {
if keys_down.get(&key).is_some() {
keymod.ctrl = true;
}
}
_ => {}
}
}
});

return keymod;
}

fn load_keybinding_xml() -> String {
// check for a keybinding file in our local directory first
let config_path = Path::new("./keybindings.xml");
let config_string = read_to_string(&config_path);

if let Ok(config_string) = config_string {
return config_string;
}

// Next we check in an OS appropriate app directory
let config_path = app_dir(AppDataType::UserConfig, &APP_INFO, "glif");

if let Ok(mut pb) = config_path {
pb.push("keybindings");
pb.set_extension("xml");

let path = pb.as_path();
let config_string = read_to_string(path);

if let Ok(config_string) = config_string {
return config_string;
}
}

// We didn't find either so we're gonna return our default
DEFAULT_KEYBINDINGS.to_owned()
}

const APP_INFO: AppInfo = AppInfo {
name: "MFEK",
author: "MFEK team",
};
const DEFAULT_KEYBINDINGS: &str = include_str!("default_keymap.xml");

struct KeyData {
keybindings: HashMap<Keycode, Command>,
}

thread_local! {
static KEYMAP: RefCell<KeyData> = RefCell::new(KeyData{ keybindings: HashMap::new() });
}
16 changes: 6 additions & 10 deletions src/events/console/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,16 @@ use log::debug;

mod commands;

use crate::winit::event::{ModifiersState, VirtualKeyCode};
use sdl2::keyboard::Keycode;
use sdl2::keyboard::Mod;

// Only called if ElementState::Pressed
pub fn set_state(vk: VirtualKeyCode, m: ModifiersState) {
pub fn set_state(vk: Keycode, m: Mod) {
CONSOLE.with(|c| match vk {
VirtualKeyCode::Semicolon => {
if !m.shift() {
return;
}
c.borrow_mut().active(true);
}
VirtualKeyCode::Escape => {
Keycode::Escape => {
c.borrow_mut().active(false);
}
VirtualKeyCode::Return => {
Keycode::Return => {
if c.borrow().active {
run_command(&mut c.borrow_mut());
}
Expand Down
41 changes: 21 additions & 20 deletions src/events/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,26 @@ pub mod vws;
pub mod zoom;

pub use self::zoom::{zoom_in_factor, zoom_out_factor};

use crate::command::CommandMod;
use sdl2::keyboard::Mod;
use sdl2::video::Window;
use sdl2::{mouse::MouseButton, Sdl};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct MouseMeta {
pub modifiers: ModifiersState,
pub modifiers: CommandMod,
pub button: MouseButton,
}

// Generic events
pub fn center_cursor(winit_window: &Window) -> Result<(), winit::error::ExternalError> {
let mut center = winit_window.inner_size();
center.width /= 2;
center.height /= 2;
STATE.with(|v| {
v.borrow_mut().absolute_mousepos = PhysicalPosition::from((center.width, center.height))
});
winit_window.set_cursor_position(winit::dpi::PhysicalPosition::new(
center.width as i32,
center.height as i32,
))
pub fn center_cursor(sdl_context: &Sdl, sdl_window: &Window) {
let mut center = sdl_window.size();
center.0 /= 2;
center.1 /= 2;
STATE.with(|v| v.borrow_mut().absolute_mousepos = (center.0 as f64, center.1 as f64));

sdl_context
.mouse()
.warp_mouse_in_window(&sdl_window, center.0 as i32, center.1 as i32);
}

pub fn update_viewport<T>(
Expand All @@ -50,19 +51,19 @@ pub fn update_viewport<T>(
}

pub fn update_mousepos<T>(
position: PhysicalPosition<f64>,
position: (f64, f64),
v: &RefCell<state::State<T>>,
pan: bool,
) -> PhysicalPosition<f64> {
) -> (f64, f64) {
let factor = 1. / v.borrow().factor as f64;
let uoffset = v.borrow().offset;
let offset = (uoffset.0 as f64, uoffset.1 as f64);

let absolute_mposition = PhysicalPosition::from(((position.x).floor(), (position.y).floor()));
let mposition = PhysicalPosition::from((
((position.x).floor() - offset.0) * factor,
((position.y).floor() - offset.1) * factor,
));
let absolute_mposition = ((position.0).floor(), (position.1).floor());
let mposition = (
((position.0).floor() - offset.0) * factor,
((position.1).floor() - offset.1) * factor,
);

v.borrow_mut().absolute_mousepos = absolute_mposition;
v.borrow_mut().mousepos = mposition;
Expand Down
6 changes: 3 additions & 3 deletions src/events/pan.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
// Pan
use super::prelude::*;

pub fn mouse_moved<T>(position: PhysicalPosition<f64>, v: &RefCell<state::State<T>>) -> bool {
pub fn mouse_moved<T>(position: (f64, f64), v: &RefCell<state::State<T>>) -> bool {
let old_mposition = v.borrow().absolute_mousepos.clone();
let mut offset = v.borrow().offset;
let mposition = update_mousepos(position, &v, true);
if !v.borrow().mousedown {
return false;
}
offset.0 += (mposition.x - old_mposition.x).floor() as f32;
offset.1 += (mposition.y - old_mposition.y).floor() as f32;
offset.0 += (mposition.0 - old_mposition.0).floor() as f32;
offset.1 += (mposition.1 - old_mposition.1).floor() as f32;
//offset = (mposition.x as f32, mposition.y as f32);
v.borrow_mut().offset = offset;
update_viewport(None, None, &v);
Expand Down
Loading

0 comments on commit 75cde81

Please sign in to comment.