Skip to content
This repository has been archived by the owner on Nov 4, 2019. It is now read-only.

Commit

Permalink
better and improved key bindings mechanism
Browse files Browse the repository at this point in the history
  • Loading branch information
rsms committed Jan 30, 2011
1 parent c26286f commit 612aef4
Show file tree
Hide file tree
Showing 10 changed files with 503 additions and 147 deletions.
16 changes: 14 additions & 2 deletions kod.xcodeproj/project.pbxproj
Expand Up @@ -136,6 +136,8 @@
3AB97DA612B2A00F00F4ADB2 /* BWCustomView.m in Sources */ = {isa = PBXBuildFile; fileRef = 3AB97DA512B2A00F00F4ADB2 /* BWCustomView.m */; };
3AB97DAC12B2A02300F4ADB2 /* NSApplication+BWAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 3AB97DA812B2A02300F4ADB2 /* NSApplication+BWAdditions.m */; };
3AB97DAD12B2A02300F4ADB2 /* NSWindow+BWAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 3AB97DAB12B2A02300F4ADB2 /* NSWindow+BWAdditions.m */; };
3ABAEFB012F5C781001E4A36 /* dec2bin.c in Sources */ = {isa = PBXBuildFile; fileRef = 3ABAEFAF12F5C781001E4A36 /* dec2bin.c */; };
3ABAF0A112F5DFA1001E4A36 /* NSEvent-kod.m in Sources */ = {isa = PBXBuildFile; fileRef = 3ABAF0A012F5DFA1001E4A36 /* NSEvent-kod.m */; };
3ABF49C012A450660020233C /* NSView-kod.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3ABF49BF12A450660020233C /* NSView-kod.mm */; };
3ABF4C6D12A48E7D0020233C /* NSData-kod.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3ABF4C6C12A48E7D0020233C /* NSData-kod.mm */; };
3ABF4F3E12A55AFC0020233C /* NSString-editdistance.m in Sources */ = {isa = PBXBuildFile; fileRef = 3ABF4F3D12A55AFC0020233C /* NSString-editdistance.m */; };
Expand Down Expand Up @@ -480,6 +482,10 @@
3AB97DA912B2A02300F4ADB2 /* NSCustomView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NSCustomView.h; path = deps/bwtoolkit/NSCustomView.h; sourceTree = SOURCE_ROOT; };
3AB97DAA12B2A02300F4ADB2 /* NSWindow+BWAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSWindow+BWAdditions.h"; path = "deps/bwtoolkit/NSWindow+BWAdditions.h"; sourceTree = SOURCE_ROOT; };
3AB97DAB12B2A02300F4ADB2 /* NSWindow+BWAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSWindow+BWAdditions.m"; path = "deps/bwtoolkit/NSWindow+BWAdditions.m"; sourceTree = SOURCE_ROOT; };
3ABAEFAE12F5C781001E4A36 /* dec2bin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dec2bin.h; sourceTree = "<group>"; };
3ABAEFAF12F5C781001E4A36 /* dec2bin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = dec2bin.c; sourceTree = "<group>"; };
3ABAF09F12F5DFA1001E4A36 /* NSEvent-kod.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSEvent-kod.h"; sourceTree = "<group>"; };
3ABAF0A012F5DFA1001E4A36 /* NSEvent-kod.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSEvent-kod.m"; sourceTree = "<group>"; };
3ABF483812A406AF0020233C /* hdispatch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = hdispatch.h; sourceTree = "<group>"; };
3ABF49BE12A450660020233C /* NSView-kod.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSView-kod.h"; sourceTree = "<group>"; };
3ABF49BF12A450660020233C /* NSView-kod.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSView-kod.mm"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -611,6 +617,8 @@
3A510C4A12C2ADCB00AAC1D5 /* kfs.m */,
3AF3A0A312BF7F6400FC534A /* KAnimation.h */,
3AF3A0A412BF7F6400FC534A /* KAnimation.m */,
3ABAEFAE12F5C781001E4A36 /* dec2bin.h */,
3ABAEFAF12F5C781001E4A36 /* dec2bin.c */,
);
name = Helpers;
sourceTree = "<group>";
Expand Down Expand Up @@ -778,6 +786,8 @@
3A92911A1229B96A00DA7E43 /* KDocument.mm */,
3AC2D4A51298D8050066B586 /* KTextStorage.h */,
3AC2D4A61298D8050066B586 /* KTextStorage.mm */,
3A7D86AC12F45EF6005740FF /* KInputBindings.h */,
3A7D86AD12F45EF6005740FF /* KInputBindings.mm */,
3AA8133812C36B390085F086 /* URL handlers */,
3AA819AF12C549490085F086 /* Crash reporting */,
3A5107C812C1231700AAC1D5 /* kod helper */,
Expand Down Expand Up @@ -933,8 +943,6 @@
3ABF539712A5D5360020233C /* Main views */ = {
isa = PBXGroup;
children = (
3A7D86AC12F45EF6005740FF /* KInputBindings.h */,
3A7D86AD12F45EF6005740FF /* KInputBindings.mm */,
3A7D866712F43392005740FF /* KWindow.h */,
3A7D866812F43392005740FF /* KWindow.mm */,
3ABF539412A5D52F0020233C /* KSplitView.h */,
Expand Down Expand Up @@ -1025,6 +1033,8 @@
3AA81B2312C62D270085F086 /* CIImage-kod.m */,
3AA81B2512C62D6A0085F086 /* NSImage-kod.h */,
3AA81B2612C62D6A0085F086 /* NSImage-kod.m */,
3ABAF09F12F5DFA1001E4A36 /* NSEvent-kod.h */,
3ABAF0A012F5DFA1001E4A36 /* NSEvent-kod.m */,
);
name = "NS categories";
sourceTree = "<group>";
Expand Down Expand Up @@ -1373,6 +1383,8 @@
3A1A4A8712E0A6EF00887625 /* KWindowBackgroundCoverView.m in Sources */,
3A7D866912F43392005740FF /* KWindow.mm in Sources */,
3A7D86AE12F45EF6005740FF /* KInputBindings.mm in Sources */,
3ABAEFB012F5C781001E4A36 /* dec2bin.c in Sources */,
3ABAF0A112F5DFA1001E4A36 /* NSEvent-kod.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
29 changes: 26 additions & 3 deletions src/HUnorderedMap.h
Expand Up @@ -49,28 +49,51 @@ class HUnorderedMap {

virtual ~HUnorderedMap() { }

// reference to the underlying tr1 unordered_map
inline map_type &map() { return map_; }

// adding entries
inline void insert(K key, T value) { map_.insert(entry_type(key, value)); }

// locating entries
inline iterator find(K key) { return map_.find(key); }
inline const_iterator find(K key) const { return map_.find(key); }
inline iterator findSync(K key) {
_HSLScope(spinlock_);
return map_.find(key);
}

// removing specific entries
inline iterator erase(iterator where) { return map_.erase(where); }
inline iterator erase(iterator first, iterator last) {
return map_.erase(first, last);
}
inline size_t erase(const K& key) { return map_.erase(key); }
iterator eraseSync(iterator where) {
_HSLScope(spinlock_);
return erase(where);
}
iterator eraseSync(iterator first, iterator last) {
_HSLScope(spinlock_);
return erase(first, last);
}
size_t eraseSync(const K& key) { _HSLScope(spinlock_); return erase(key); }

// removing all entries
void clear() { map_.clear(); }
void clearSync() { _HSLScope(spinlock_); clear(); }

// swapping this map with another map
inline void swap(map_type& other) { map_.swap(other.map_); }
inline void swapSync(map_type& other) { _HSLScope(spinlock_); swap(other); }

// counting entries
inline size_t size() const { return map_.size(); }
inline size_t sizeSync() const { _HSLScope(spinlock_); return size(); }

// testing for empty-ness
bool empty() const { return size() == 0; }
bool emptySync() const { return sizeSync() == 0; }

void clear() { map_.clear(); }
void clearSync() { _HSLScope(spinlock_); clear(); }
};


Expand Down
61 changes: 48 additions & 13 deletions src/KInputBindings.h
@@ -1,16 +1,17 @@
#include <map>
#include <string>
#include <tr1/memory>
#include <assert.h>
#include "HUnorderedMap.h"
#import "NSEvent-kod.h"

class KInputAction;
typedef std::tr1::shared_ptr<KInputAction> KInputActionPtr;

// an action which is associated with an input sequence in KInputBindings
class KInputAction {
public:
virtual BOOL perform(id sender) = 0;
};

typedef std::tr1::shared_ptr<KInputAction> KInputActionPtr;

// an action which invokes a Objective-C selector on its target or sender
class KSelectorInputAction : public KInputAction {
public:
KSelectorInputAction(SEL selector, id target=nil) {
Expand All @@ -35,21 +36,55 @@ class KSelectorInputAction : public KInputAction {
id target_;
};

// holds input bindings
class KInputBindings {
public:
static void set(std::string seq, KInputAction *action) {
bindings_.putSync(seq, action);
// map type
typedef HUnorderedMapSharedPtr<uint64_t, KInputAction> Map;

// level of the application where an event is bound and active
enum Level {
AppLevel = 0, // events captured when entering the app ("top level")
TextEditorLevel, // events captured in the text editor
MaxLevel // (Never use this)
};

static void set(Level level, uint64_t key, KInputAction *action) {
assert(level < MaxLevel);
bindings_[level].putSync(key, action);
}
static void set(NSString *seq, KInputAction *action) {
set(std::string([seq UTF8String]), action);
// bind |action| to a sequence (e.g. "M-S-r")
static BOOL set(Level level, NSString *seq, KInputAction *action);

// find an action for an event. returns null if not found.
static KInputAction *get(Level level, uint64_t key) {
assert(level < MaxLevel);
return bindings_[level].getSync(key);
}
static KInputAction *get(Level level, NSEvent *event) {
return get(level, [event kodHash]);
}
static KInputAction *get(Level level, NSString *seq);

// retrieve mappings for |level|. |level| must be within [0-MaxLevel)
static Map& get(Level level) { return bindings_[level]; }

static KInputAction *get(std::string seq) {
return bindings_.getSync(seq);
// remove any binding for |key|. returns true if found and removed.
static BOOL remove(Level level, uint64_t key) {
assert(level < MaxLevel);
return bindings_[level].eraseSync(key) != 0;
}

static KInputAction *get(NSEvent *event);
// removes |key| from all levels and returns the number of bindings removed
static size_t remove(uint64_t key);

// removes all bindings (from all levels if level is MaxLevel)
static void clear(Level level=MaxLevel);

// parse a single sequence (e.g. "M-S-r") into it's canonical key
// returns 0 (zero) to indicate a bad/illegal sequence.
static uint64_t parseSequence(NSString *seq);

protected:
static HUnorderedMapSharedPtr<std::string, KInputAction> bindings_;
static Map bindings_[MaxLevel];
};

0 comments on commit 612aef4

Please sign in to comment.