diff --git a/src/Gtk.jl b/src/Gtk.jl index eca1cbe3..e77e6127 100644 --- a/src/Gtk.jl +++ b/src/Gtk.jl @@ -90,6 +90,7 @@ using .GConstants include("windows.jl") include("gl_area.jl") +include("shortcuts.jl") # Alternative Interface (`using Gtk.ShortNames`) module ShortNames diff --git a/src/basic_exports.jl b/src/basic_exports.jl index 5a3617c6..8cefcd62 100644 --- a/src/basic_exports.jl +++ b/src/basic_exports.jl @@ -25,6 +25,9 @@ export add_events, signal_emit, on_signal_destroy, on_signal_button_press, on_signal_button_release, on_signal_motion +#Shortcuts +export Shortcut, doing + # Gdk info and manipulation export screen_size diff --git a/src/shortcuts.jl b/src/shortcuts.jl new file mode 100644 index 00000000..7719a578 --- /dev/null +++ b/src/shortcuts.jl @@ -0,0 +1,72 @@ +get_default_mod_mask() = ccall((:gtk_accelerator_get_default_mod_mask , libgtk), + typeof(GdkModifierType.CONTROL),()) + +@static if is_apple() + const PrimaryModifier = GdkModifierType.MOD2 #command key + const SecondaryModifer = GdkModifierType.CONTROL +end +@static if is_windows() + const PrimaryModifier = GdkModifierType.CONTROL + const SecondaryModifer = GdkModifierType.MOD1 #alt key +end +@static if is_linux() + const PrimaryModifier = GdkModifierType.CONTROL + const SecondaryModifer = GdkModifierType.MOD1 +end +const NoModifier = Base.zero(UInt32) + +""" +Represents a combination of keys. + +##Examples: + + Shortcut(GdkKeySyms.Tab) # Tab key + + Shortcut("c") # c key + + Shortcut("c",PrimaryModifier) # Ctrl-c (Windows & Linux) or Command-c (OS X) + + Shortcut("C",PrimaryModifier + GdkModifierType.SHIFT) # Ctrl-Shit-c (notice the capital C) + +""" +immutable Shortcut + keyval::UInt32 + state::UInt32 + + Shortcut(k::Integer,s::Integer) = new(k,s) + Shortcut(k::Integer) = new(k,NoModifier) + Shortcut(k::AbstractString) = new(keyval(k),NoModifier) + Shortcut(k::AbstractString,s::Integer) = new(keyval(k),s) +end + +""" + doing(s::Shortcut, event::GdkEvent) + +Test wether the `GdkEvent` corresponds to the given `Shortcut`. + +##Example: + + if doing(Shortcut("c",PrimaryModifier),event) + #copy... + end + +Reference : https://developer.gnome.org/gtk3/unstable/checklist-modifiers.html + +""" +function doing(s::Shortcut, event::GdkEvent) + + mod = get_default_mod_mask() + #on os x, the command key is also the meta key + @static if is_apple() + if s.state == NoModifier && event.state == NoModifier + return event.keyval == s.keyval + end + if (event.keyval == s.keyval) && (event.state & mod == s.state) + return true + end + return (event.keyval == s.keyval) && + (event.state & mod == s.state + GdkModifierType.META) + end + + return (event.keyval == s.keyval) && (event.state & mod == s.state) +end \ No newline at end of file diff --git a/test/misc.jl b/test/misc.jl index e6a526b7..a91dbbd0 100644 --- a/test/misc.jl +++ b/test/misc.jl @@ -44,4 +44,18 @@ destroy(win) @test isa(Gtk.GdkEventKey(), Gtk.GdkEventKey) +# Shortcuts + +@test Shortcut("c").keyval == keyval("c") +@test Shortcut("c",GConstants.GdkModifierType.CONTROL).state == GConstants.GdkModifierType.CONTROL + +win = GtkWindow() +event = Gtk.GdkEventKey(GdkEventType.KEY_PRESS, Gtk.gdk_window(win), + Int8(0), UInt32(0), UInt32(0), Gtk.GdkKeySyms.Return, UInt32(0), + convert(Ptr{UInt8},C_NULL), UInt16(13), UInt8(0), UInt32(0) ) + +@test doing(Shortcut(Gtk.GdkKeySyms.Return),event) == true +@test doing(Shortcut(Gtk.GdkKeySyms.Return,Gtk.PrimaryModifier),event) == false +destroy(win) + end