<feed xmlns='http://www.w3.org/2005/Atom'>
<title>MASShortcut/Demo, branch 2.0.0</title>
<subtitle>Modern framework for managing global keyboard shortcuts compatible with Mac App Store. More details:</subtitle>
<link rel='alternate' type='text/html' href='https://git.teddywing.com/fork/MASShortcut/'/>
<entry>
<title>Expanded demo functionality (preparing for 2.0.0, see #54).</title>
<updated>2015-01-09T09:53:45+00:00</updated>
<author>
<name>Tomáš Znamenáček</name>
</author>
<published>2015-01-09T09:51:08+00:00</published>
<link rel='alternate' type='text/html' href='https://git.teddywing.com/fork/MASShortcut/commit/?id=f63c21e11cfad4fb8408effae2efb07164ad5760'/>
<id>f63c21e11cfad4fb8408effae2efb07164ad5760</id>
<content type='text'>
Mostly back to the previous version with enable/disable checkboxes &amp;
one settable and one hard-coded shortcut. I have tried to come up with
a nicer pattern to watch the enabled/disabled checkboxes, but without
external dependencies like Facebook’s KVOController I didn’t come up
with anything better than plain old KVO.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Mostly back to the previous version with enable/disable checkboxes &amp;
one settable and one hard-coded shortcut. I have tried to come up with
a nicer pattern to watch the enabled/disabled checkboxes, but without
external dependencies like Facebook’s KVOController I didn’t come up
with anything better than plain old KVO.
</pre>
</div>
</content>
</entry>
<entry>
<title>Simplified and updated the demo project.</title>
<updated>2015-01-08T13:16:26+00:00</updated>
<author>
<name>Tomáš Znamenáček</name>
</author>
<published>2015-01-08T13:16:26+00:00</published>
<link rel='alternate' type='text/html' href='https://git.teddywing.com/fork/MASShortcut/commit/?id=fc43b570c7ea4802c648670b39586425ce330cec'/>
<id>fc43b570c7ea4802c648670b39586425ce330cec</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Added a simplified binding API for MASShortcutView.</title>
<updated>2015-01-07T14:42:22+00:00</updated>
<author>
<name>Tomáš Znamenáček</name>
</author>
<published>2014-08-07T10:55:59+00:00</published>
<link rel='alternate' type='text/html' href='https://git.teddywing.com/fork/MASShortcut/commit/?id=46aa323115c2ebe7128aba39c0296634d232bbf6'/>
<id>46aa323115c2ebe7128aba39c0296634d232bbf6</id>
<content type='text'>
This returns the associatedUserDefaultsKey property used in previous code
versions, only the implementation uses less magic.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This returns the associatedUserDefaultsKey property used in previous code
versions, only the implementation uses less magic.
</pre>
</div>
</content>
</entry>
<entry>
<title>Redesigned demo app layout &amp; feedback.</title>
<updated>2015-01-07T14:42:22+00:00</updated>
<author>
<name>Tomáš Znamenáček</name>
</author>
<published>2014-08-07T10:23:43+00:00</published>
<link rel='alternate' type='text/html' href='https://git.teddywing.com/fork/MASShortcut/commit/?id=5f5f6cb9d086853065b2546e72d71a38230c6b59'/>
<id>5f5f6cb9d086853065b2546e72d71a38230c6b59</id>
<content type='text'>
I have replaced the modal alert with a beep, it’s faster to test
without having to close the alert.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
I have replaced the modal alert with a beep, it’s faster to test
without having to close the alert.
</pre>
</div>
</content>
</entry>
<entry>
<title>Added a shared binder instance singleton.</title>
<updated>2015-01-07T14:42:22+00:00</updated>
<author>
<name>Tomáš Znamenáček</name>
</author>
<published>2014-08-07T10:12:06+00:00</published>
<link rel='alternate' type='text/html' href='https://git.teddywing.com/fork/MASShortcut/commit/?id=118abba104a1eeabc5c449ac86e25a6d87f1954c'/>
<id>118abba104a1eeabc5c449ac86e25a6d87f1954c</id>
<content type='text'>
This adds a really simple API to set up some bindings without having
to keep a binder instance around by hand. If somebody wants to, it’s
not a problem to allocate a separate instance and have precise control
over its lifetime.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This adds a really simple API to set up some bindings without having
to keep a binder instance around by hand. If somebody wants to, it’s
not a problem to allocate a separate instance and have precise control
over its lifetime.
</pre>
</div>
</content>
</entry>
<entry>
<title>Turned MASShortcutMonitor into a singleton.</title>
<updated>2015-01-07T14:42:21+00:00</updated>
<author>
<name>Tomáš Znamenáček</name>
</author>
<published>2014-08-07T08:10:08+00:00</published>
<link rel='alternate' type='text/html' href='https://git.teddywing.com/fork/MASShortcut/commit/?id=be9358bf32dc402f3bc77c6cc20957047ab363af'/>
<id>be9358bf32dc402f3bc77c6cc20957047ab363af</id>
<content type='text'>
There can only be one Carbon event handler, so it doesn’t make sense
to create multiple instances of the shortcut monitor.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
There can only be one Carbon event handler, so it doesn’t make sense
to create multiple instances of the shortcut monitor.
</pre>
</div>
</content>
</entry>
<entry>
<title>Refactored the shortcut dispatcher and bindings to user defaults.</title>
<updated>2015-01-07T14:39:39+00:00</updated>
<author>
<name>Tomáš Znamenáček</name>
</author>
<published>2014-08-06T16:05:43+00:00</published>
<link rel='alternate' type='text/html' href='https://git.teddywing.com/fork/MASShortcut/commit/?id=444d1bccb9770738fa4ea40383c23f44a55089c2'/>
<id>444d1bccb9770738fa4ea40383c23f44a55089c2</id>
<content type='text'>
This is a big change that was hard to split into smaller commits. There’s now
a new class to bind shortcuts to actions, a new class to bind user defaults’
keys to actions, and a new way to associate user defaults with the recorder
control (MASShortcutView). I have also updated the demo app to go with the
changes.

The new class to associate shortcuts with actions is called MASShortcutMonitor.
It wraps the Carbon hotkey magic and offers a simple interface to add a
shortcut along with a block that should be run when the shortcut is pressed.
It’s the lowest-level interface.

Since the usual requirement is to store the shortcuts into user defaults,
there’s also a higher-level interface offered by the MASShortcutBinder class.
That takes a defaults key and associates it with a block. When the shortcut
stored under the defaults key changes, the binder automatically switches to the
new shortcut. The class is a wrapper built atop of the previous one, the
MASShortcutMonitor – it simply adds, updates and removes shortcuts as the
user defaults change.

I have removed the special user defaults integration code from the recorder
control (MASShortcutView) and replaced it with a small Cocoa Bindings shim.
This means that in order to keep the recorder control in sync with the defaults
you just have to call the usual bind:toObject:withKeyPath:options: method,
like this:

[_shortcutView bind:MASShortcutBinding
    toObject:[NSUserDefaultsController sharedUserDefaultsController]
    withKeyPath[@"values.ExampleDefaultsKey"
    options:@{NSValueTransformerNameBindingOption:NSKeyedUnarchiveFromDataTransformerName}];

That’s more verbose than the previous solution, but it’s much cleaner and can
be swept under a convenience call if needed. I might also add a dictionaryValue
property later that would make it possible to bind the value to user defaults
directly, without a transformer, and would enable backward compatibility with
Shortcut Recorder.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This is a big change that was hard to split into smaller commits. There’s now
a new class to bind shortcuts to actions, a new class to bind user defaults’
keys to actions, and a new way to associate user defaults with the recorder
control (MASShortcutView). I have also updated the demo app to go with the
changes.

The new class to associate shortcuts with actions is called MASShortcutMonitor.
It wraps the Carbon hotkey magic and offers a simple interface to add a
shortcut along with a block that should be run when the shortcut is pressed.
It’s the lowest-level interface.

Since the usual requirement is to store the shortcuts into user defaults,
there’s also a higher-level interface offered by the MASShortcutBinder class.
That takes a defaults key and associates it with a block. When the shortcut
stored under the defaults key changes, the binder automatically switches to the
new shortcut. The class is a wrapper built atop of the previous one, the
MASShortcutMonitor – it simply adds, updates and removes shortcuts as the
user defaults change.

I have removed the special user defaults integration code from the recorder
control (MASShortcutView) and replaced it with a small Cocoa Bindings shim.
This means that in order to keep the recorder control in sync with the defaults
you just have to call the usual bind:toObject:withKeyPath:options: method,
like this:

[_shortcutView bind:MASShortcutBinding
    toObject:[NSUserDefaultsController sharedUserDefaultsController]
    withKeyPath[@"values.ExampleDefaultsKey"
    options:@{NSValueTransformerNameBindingOption:NSKeyedUnarchiveFromDataTransformerName}];

That’s more verbose than the previous solution, but it’s much cleaner and can
be swept under a convenience call if needed. I might also add a dictionaryValue
property later that would make it possible to bind the value to user defaults
directly, without a transformer, and would enable backward compatibility with
Shortcut Recorder.
</pre>
</div>
</content>
</entry>
<entry>
<title>Created an umbrella header.</title>
<updated>2015-01-07T14:05:11+00:00</updated>
<author>
<name>Tomáš Znamenáček</name>
</author>
<published>2014-08-05T11:34:21+00:00</published>
<link rel='alternate' type='text/html' href='https://git.teddywing.com/fork/MASShortcut/commit/?id=0b08de641530f6537e4a3b7dbf26601fc927e1ad'/>
<id>0b08de641530f6537e4a3b7dbf26601fc927e1ad</id>
<content type='text'>
Now you can just `#import &lt;MASShortcut/Shortcut.h&gt;`.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Now you can just `#import &lt;MASShortcut/Shortcut.h&gt;`.
</pre>
</div>
</content>
</entry>
<entry>
<title>Repackaged the code as a framework and included the demo.</title>
<updated>2015-01-07T14:05:11+00:00</updated>
<author>
<name>Tomáš Znamenáček</name>
</author>
<published>2014-08-05T09:13:13+00:00</published>
<link rel='alternate' type='text/html' href='https://git.teddywing.com/fork/MASShortcut/commit/?id=377b44220f2a4a8b7ffc3eda9e93cf073e8a74da'/>
<id>377b44220f2a4a8b7ffc3eda9e93cf073e8a74da</id>
<content type='text'>
Packaging the code as a framework is mostly just a formality. It doesn’t
really change much, it just turns the code into a regular component.
What it does change is that the code now has its own Xcode settings,
which could make compatibility easier in the long run.

Including the demo in the main repository makes it easier to hack on
the library, since you can try the changes immediately. It also shows
how to bundle the framework into an app that uses it.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Packaging the code as a framework is mostly just a formality. It doesn’t
really change much, it just turns the code into a regular component.
What it does change is that the code now has its own Xcode settings,
which could make compatibility easier in the long run.

Including the demo in the main repository makes it easier to hack on
the library, since you can try the changes immediately. It also shows
how to bundle the framework into an app that uses it.
</pre>
</div>
</content>
</entry>
</feed>
