{"action":"created","comment":{"url":"https://api.github.com/repos/matplotlib/matplotlib/pulls/comments/22469264","id":22469264,"diff_hunk":"@@ -3195,3 +3205,507 @@ def zoom(self, *args):\n     def set_history_buttons(self):\n         \"\"\"Enable or disable back/forward button\"\"\"\n         pass\n+\n+\n+class ToolEvent(object):\n+    \"\"\"Event for tool manipulation (add/remove)\"\"\"\n+    def __init__(self, name, sender, tool, data=None):\n+        self.name = name\n+        self.sender = sender\n+        self.tool = tool\n+        self.data = data\n+\n+\n+class ToolTriggerEvent(ToolEvent):\n+    \"\"\"Event to inform  that a tool has been triggered\"\"\"\n+    def __init__(self, name, sender, tool, canvasevent=None, data=None):\n+        ToolEvent.__init__(self, name, sender, tool, data)\n+        self.canvasevent = canvasevent\n+\n+\n+class NavigationMessageEvent(object):\n+    \"\"\"Event carring messages from navigation\n+\n+    Messages are generaly displayed to the user by the toolbar\n+    \"\"\"\n+    def __init__(self, name, sender, message):\n+        self.name = name\n+        self.sender = sender\n+        self.message = message\n+\n+\n+class NavigationBase(object):\n+    \"\"\"Helper class that groups all the user interactions for a FigureManager\n+\n+    Attributes\n+    ----------\n+    manager: `FigureManager` instance\n+    keypresslock: `LockDraw` to know if the `canvas` key_press_event is\n+     locked\n+    messagelock: `LockDraw` to know if the message is available to write\n+    \"\"\"\n+\n+    def __init__(self, manager):\n+        self.manager = manager\n+        self.canvas = manager.canvas\n+\n+        self._key_press_handler_id = self.canvas.mpl_connect(\n+            'key_press_event', self._key_press)\n+\n+        self._tools = {}\n+        self._keys = {}\n+        self._toggled = {}\n+        self._callbacks = cbook.CallbackRegistry()\n+\n+        # to process keypress event\n+        self.keypresslock = widgets.LockDraw()\n+        self.messagelock = widgets.LockDraw()\n+\n+    def mpl_connect(self, s, func):\n+        \"\"\"Connect event with string *s* to *func*.\n+\n+        Parameters\n+        -----------\n+        s : String\n+            Name of the event\n+\n+            The following events are recognized\n+\n+            - 'tool_message_event'\n+            - 'tool_removed_event'\n+            - 'tool_added_event'\n+            For every tool added a new event is created\n+            - 'tool_trigger_TOOLNAME\n+            Where TOOLNAME is the id of the tool.","path":"lib/matplotlib/backend_bases.py","position":141,"original_position":141,"commit_id":"da1ebcb98c10e1c851ca01d23ad416b69a0a35e4","original_commit_id":"da1ebcb98c10e1c851ca01d23ad416b69a0a35e4","user":{"login":"fariza","id":1490153,"avatar_url":"https://avatars.githubusercontent.com/u/1490153?v=3","gravatar_id":"","url":"https://api.github.com/users/fariza","html_url":"https://github.com/fariza","followers_url":"https://api.github.com/users/fariza/followers","following_url":"https://api.github.com/users/fariza/following{/other_user}","gists_url":"https://api.github.com/users/fariza/gists{/gist_id}","starred_url":"https://api.github.com/users/fariza/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fariza/subscriptions","organizations_url":"https://api.github.com/users/fariza/orgs","repos_url":"https://api.github.com/users/fariza/repos","events_url":"https://api.github.com/users/fariza/events{/privacy}","received_events_url":"https://api.github.com/users/fariza/received_events","type":"User","site_admin":false},"body":"Indeed we have the `name` passed inside the event, but I think for the users, it is pretty useful to be able to `connect` to a specific `tool` without having to parse by `name`","created_at":"2015-01-05T16:11:03Z","updated_at":"2015-01-05T16:11:03Z","html_url":"https://github.com/matplotlib/matplotlib/pull/3652#discussion_r22469264","pull_request_url":"https://api.github.com/repos/matplotlib/matplotlib/pulls/3652","_links":{"self":{"href":"https://api.github.com/repos/matplotlib/matplotlib/pulls/comments/22469264"},"html":{"href":"https://github.com/matplotlib/matplotlib/pull/3652#discussion_r22469264"},"pull_request":{"href":"https://api.github.com/repos/matplotlib/matplotlib/pulls/3652"}}},"pull_request":{"url":"https://api.github.com/repos/matplotlib/matplotlib/pulls/3652","id":22889335,"html_url":"https://github.com/matplotlib/matplotlib/pull/3652","diff_url":"https://github.com/matplotlib/matplotlib/pull/3652.diff","patch_url":"https://github.com/matplotlib/matplotlib/pull/3652.patch","issue_url":"https://api.github.com/repos/matplotlib/matplotlib/issues/3652","number":3652,"state":"open","locked":false,"title":"MEP22: Navigation by events","user":{"login":"fariza","id":1490153,"avatar_url":"https://avatars.githubusercontent.com/u/1490153?v=3","gravatar_id":"","url":"https://api.github.com/users/fariza","html_url":"https://github.com/fariza","followers_url":"https://api.github.com/users/fariza/followers","following_url":"https://api.github.com/users/fariza/following{/other_user}","gists_url":"https://api.github.com/users/fariza/gists{/gist_id}","starred_url":"https://api.github.com/users/fariza/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fariza/subscriptions","organizations_url":"https://api.github.com/users/fariza/orgs","repos_url":"https://api.github.com/users/fariza/repos","events_url":"https://api.github.com/users/fariza/events{/privacy}","received_events_url":"https://api.github.com/users/fariza/received_events","type":"User","site_admin":false},"body":"This PR is the implementation of MEP22, it supersedes the https://github.com/matplotlib/matplotlib/pull/2759\r\n\r\nThe main differences are:\r\n* Navigation implement events\r\n* Toolbar connects to Navigation events to change its sate (add/remove tools, change toggle state)\r\n* Toolbar used `Navigation.tool_trigger_event` to trigger tools\r\n* Rubberband and SetCursor are implemented as tools\r\n\r\n**Edited**: for clarity","created_at":"2014-10-16T21:45:29Z","updated_at":"2015-01-05T16:11:03Z","closed_at":null,"merged_at":null,"merge_commit_sha":"3594f70c3c1e4a0449f648db471ec880ca510622","assignee":null,"milestone":{"url":"https://api.github.com/repos/matplotlib/matplotlib/milestones/12","labels_url":"https://api.github.com/repos/matplotlib/matplotlib/milestones/12/labels","id":534144,"number":12,"title":"v1.5.x","description":null,"creator":{"login":"tacaswell","id":199813,"avatar_url":"https://avatars.githubusercontent.com/u/199813?v=3","gravatar_id":"","url":"https://api.github.com/users/tacaswell","html_url":"https://github.com/tacaswell","followers_url":"https://api.github.com/users/tacaswell/followers","following_url":"https://api.github.com/users/tacaswell/following{/other_user}","gists_url":"https://api.github.com/users/tacaswell/gists{/gist_id}","starred_url":"https://api.github.com/users/tacaswell/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tacaswell/subscriptions","organizations_url":"https://api.github.com/users/tacaswell/orgs","repos_url":"https://api.github.com/users/tacaswell/repos","events_url":"https://api.github.com/users/tacaswell/events{/privacy}","received_events_url":"https://api.github.com/users/tacaswell/received_events","type":"User","site_admin":false},"open_issues":231,"closed_issues":139,"state":"open","created_at":"2014-01-13T03:21:09Z","updated_at":"2015-01-03T23:39:01Z","due_on":null,"closed_at":null},"commits_url":"https://api.github.com/repos/matplotlib/matplotlib/pulls/3652/commits","review_comments_url":"https://api.github.com/repos/matplotlib/matplotlib/pulls/3652/comments","review_comment_url":"https://api.github.com/repos/matplotlib/matplotlib/pulls/comments/{number}","comments_url":"https://api.github.com/repos/matplotlib/matplotlib/issues/3652/comments","statuses_url":"https://api.github.com/repos/matplotlib/matplotlib/statuses/da1ebcb98c10e1c851ca01d23ad416b69a0a35e4","head":{"label":"fariza:navigation-by-events","ref":"navigation-by-events","sha":"da1ebcb98c10e1c851ca01d23ad416b69a0a35e4","user":{"login":"fariza","id":1490153,"avatar_url":"https://avatars.githubusercontent.com/u/1490153?v=3","gravatar_id":"","url":"https://api.github.com/users/fariza","html_url":"https://github.com/fariza","followers_url":"https://api.github.com/users/fariza/followers","following_url":"https://api.github.com/users/fariza/following{/other_user}","gists_url":"https://api.github.com/users/fariza/gists{/gist_id}","starred_url":"https://api.github.com/users/fariza/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fariza/subscriptions","organizations_url":"https://api.github.com/users/fariza/orgs","repos_url":"https://api.github.com/users/fariza/repos","events_url":"https://api.github.com/users/fariza/events{/privacy}","received_events_url":"https://api.github.com/users/fariza/received_events","type":"User","site_admin":false},"repo":{"id":12761338,"name":"matplotlib","full_name":"fariza/matplotlib","owner":{"login":"fariza","id":1490153,"avatar_url":"https://avatars.githubusercontent.com/u/1490153?v=3","gravatar_id":"","url":"https://api.github.com/users/fariza","html_url":"https://github.com/fariza","followers_url":"https://api.github.com/users/fariza/followers","following_url":"https://api.github.com/users/fariza/following{/other_user}","gists_url":"https://api.github.com/users/fariza/gists{/gist_id}","starred_url":"https://api.github.com/users/fariza/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fariza/subscriptions","organizations_url":"https://api.github.com/users/fariza/orgs","repos_url":"https://api.github.com/users/fariza/repos","events_url":"https://api.github.com/users/fariza/events{/privacy}","received_events_url":"https://api.github.com/users/fariza/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/fariza/matplotlib","description":"matplotlib: plotting with Python","fork":true,"url":"https://api.github.com/repos/fariza/matplotlib","forks_url":"https://api.github.com/repos/fariza/matplotlib/forks","keys_url":"https://api.github.com/repos/fariza/matplotlib/keys{/key_id}","collaborators_url":"https://api.github.com/repos/fariza/matplotlib/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/fariza/matplotlib/teams","hooks_url":"https://api.github.com/repos/fariza/matplotlib/hooks","issue_events_url":"https://api.github.com/repos/fariza/matplotlib/issues/events{/number}","events_url":"https://api.github.com/repos/fariza/matplotlib/events","assignees_url":"https://api.github.com/repos/fariza/matplotlib/assignees{/user}","branches_url":"https://api.github.com/repos/fariza/matplotlib/branches{/branch}","tags_url":"https://api.github.com/repos/fariza/matplotlib/tags","blobs_url":"https://api.github.com/repos/fariza/matplotlib/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/fariza/matplotlib/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/fariza/matplotlib/git/refs{/sha}","trees_url":"https://api.github.com/repos/fariza/matplotlib/git/trees{/sha}","statuses_url":"https://api.github.com/repos/fariza/matplotlib/statuses/{sha}","languages_url":"https://api.github.com/repos/fariza/matplotlib/languages","stargazers_url":"https://api.github.com/repos/fariza/matplotlib/stargazers","contributors_url":"https://api.github.com/repos/fariza/matplotlib/contributors","subscribers_url":"https://api.github.com/repos/fariza/matplotlib/subscribers","subscription_url":"https://api.github.com/repos/fariza/matplotlib/subscription","commits_url":"https://api.github.com/repos/fariza/matplotlib/commits{/sha}","git_commits_url":"https://api.github.com/repos/fariza/matplotlib/git/commits{/sha}","comments_url":"https://api.github.com/repos/fariza/matplotlib/comments{/number}","issue_comment_url":"https://api.github.com/repos/fariza/matplotlib/issues/comments/{number}","contents_url":"https://api.github.com/repos/fariza/matplotlib/contents/{+path}","compare_url":"https://api.github.com/repos/fariza/matplotlib/compare/{base}...{head}","merges_url":"https://api.github.com/repos/fariza/matplotlib/merges","archive_url":"https://api.github.com/repos/fariza/matplotlib/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/fariza/matplotlib/downloads","issues_url":"https://api.github.com/repos/fariza/matplotlib/issues{/number}","pulls_url":"https://api.github.com/repos/fariza/matplotlib/pulls{/number}","milestones_url":"https://api.github.com/repos/fariza/matplotlib/milestones{/number}","notifications_url":"https://api.github.com/repos/fariza/matplotlib/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/fariza/matplotlib/labels{/name}","releases_url":"https://api.github.com/repos/fariza/matplotlib/releases{/id}","created_at":"2013-09-11T16:28:02Z","updated_at":"2014-05-29T16:57:27Z","pushed_at":"2014-12-05T15:26:20Z","git_url":"git://github.com/fariza/matplotlib.git","ssh_url":"git@github.com:fariza/matplotlib.git","clone_url":"https://github.com/fariza/matplotlib.git","svn_url":"https://github.com/fariza/matplotlib","homepage":"http://matplotlib.org/","size":200649,"stargazers_count":1,"watchers_count":1,"language":"Python","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1,"mirror_url":null,"open_issues_count":2,"forks":1,"open_issues":2,"watchers":1,"default_branch":"master"}},"base":{"label":"matplotlib:master","ref":"master","sha":"4aa6b7eaa87af5f835e1915b3e2037045dc2820f","user":{"login":"matplotlib","id":215947,"avatar_url":"https://avatars.githubusercontent.com/u/215947?v=3","gravatar_id":"","url":"https://api.github.com/users/matplotlib","html_url":"https://github.com/matplotlib","followers_url":"https://api.github.com/users/matplotlib/followers","following_url":"https://api.github.com/users/matplotlib/following{/other_user}","gists_url":"https://api.github.com/users/matplotlib/gists{/gist_id}","starred_url":"https://api.github.com/users/matplotlib/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/matplotlib/subscriptions","organizations_url":"https://api.github.com/users/matplotlib/orgs","repos_url":"https://api.github.com/users/matplotlib/repos","events_url":"https://api.github.com/users/matplotlib/events{/privacy}","received_events_url":"https://api.github.com/users/matplotlib/received_events","type":"Organization","site_admin":false},"repo":{"id":1385122,"name":"matplotlib","full_name":"matplotlib/matplotlib","owner":{"login":"matplotlib","id":215947,"avatar_url":"https://avatars.githubusercontent.com/u/215947?v=3","gravatar_id":"","url":"https://api.github.com/users/matplotlib","html_url":"https://github.com/matplotlib","followers_url":"https://api.github.com/users/matplotlib/followers","following_url":"https://api.github.com/users/matplotlib/following{/other_user}","gists_url":"https://api.github.com/users/matplotlib/gists{/gist_id}","starred_url":"https://api.github.com/users/matplotlib/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/matplotlib/subscriptions","organizations_url":"https://api.github.com/users/matplotlib/orgs","repos_url":"https://api.github.com/users/matplotlib/repos","events_url":"https://api.github.com/users/matplotlib/events{/privacy}","received_events_url":"https://api.github.com/users/matplotlib/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/matplotlib/matplotlib","description":"matplotlib: plotting with Python","fork":false,"url":"https://api.github.com/repos/matplotlib/matplotlib","forks_url":"https://api.github.com/repos/matplotlib/matplotlib/forks","keys_url":"https://api.github.com/repos/matplotlib/matplotlib/keys{/key_id}","collaborators_url":"https://api.github.com/repos/matplotlib/matplotlib/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/matplotlib/matplotlib/teams","hooks_url":"https://api.github.com/repos/matplotlib/matplotlib/hooks","issue_events_url":"https://api.github.com/repos/matplotlib/matplotlib/issues/events{/number}","events_url":"https://api.github.com/repos/matplotlib/matplotlib/events","assignees_url":"https://api.github.com/repos/matplotlib/matplotlib/assignees{/user}","branches_url":"https://api.github.com/repos/matplotlib/matplotlib/branches{/branch}","tags_url":"https://api.github.com/repos/matplotlib/matplotlib/tags","blobs_url":"https://api.github.com/repos/matplotlib/matplotlib/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/matplotlib/matplotlib/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/matplotlib/matplotlib/git/refs{/sha}","trees_url":"https://api.github.com/repos/matplotlib/matplotlib/git/trees{/sha}","statuses_url":"https://api.github.com/repos/matplotlib/matplotlib/statuses/{sha}","languages_url":"https://api.github.com/repos/matplotlib/matplotlib/languages","stargazers_url":"https://api.github.com/repos/matplotlib/matplotlib/stargazers","contributors_url":"https://api.github.com/repos/matplotlib/matplotlib/contributors","subscribers_url":"https://api.github.com/repos/matplotlib/matplotlib/subscribers","subscription_url":"https://api.github.com/repos/matplotlib/matplotlib/subscription","commits_url":"https://api.github.com/repos/matplotlib/matplotlib/commits{/sha}","git_commits_url":"https://api.github.com/repos/matplotlib/matplotlib/git/commits{/sha}","comments_url":"https://api.github.com/repos/matplotlib/matplotlib/comments{/number}","issue_comment_url":"https://api.github.com/repos/matplotlib/matplotlib/issues/comments/{number}","contents_url":"https://api.github.com/repos/matplotlib/matplotlib/contents/{+path}","compare_url":"https://api.github.com/repos/matplotlib/matplotlib/compare/{base}...{head}","merges_url":"https://api.github.com/repos/matplotlib/matplotlib/merges","archive_url":"https://api.github.com/repos/matplotlib/matplotlib/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/matplotlib/matplotlib/downloads","issues_url":"https://api.github.com/repos/matplotlib/matplotlib/issues{/number}","pulls_url":"https://api.github.com/repos/matplotlib/matplotlib/pulls{/number}","milestones_url":"https://api.github.com/repos/matplotlib/matplotlib/milestones{/number}","notifications_url":"https://api.github.com/repos/matplotlib/matplotlib/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/matplotlib/matplotlib/labels{/name}","releases_url":"https://api.github.com/repos/matplotlib/matplotlib/releases{/id}","created_at":"2011-02-19T03:17:12Z","updated_at":"2015-01-05T15:24:11Z","pushed_at":"2015-01-05T15:24:10Z","git_url":"git://github.com/matplotlib/matplotlib.git","ssh_url":"git@github.com:matplotlib/matplotlib.git","clone_url":"https://github.com/matplotlib/matplotlib.git","svn_url":"https://github.com/matplotlib/matplotlib","homepage":"http://matplotlib.org/","size":249717,"stargazers_count":2138,"watchers_count":2138,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1045,"mirror_url":null,"open_issues_count":444,"forks":1045,"open_issues":444,"watchers":2138,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/matplotlib/matplotlib/pulls/3652"},"html":{"href":"https://github.com/matplotlib/matplotlib/pull/3652"},"issue":{"href":"https://api.github.com/repos/matplotlib/matplotlib/issues/3652"},"comments":{"href":"https://api.github.com/repos/matplotlib/matplotlib/issues/3652/comments"},"review_comments":{"href":"https://api.github.com/repos/matplotlib/matplotlib/pulls/3652/comments"},"review_comment":{"href":"https://api.github.com/repos/matplotlib/matplotlib/pulls/comments/{number}"},"commits":{"href":"https://api.github.com/repos/matplotlib/matplotlib/pulls/3652/commits"},"statuses":{"href":"https://api.github.com/repos/matplotlib/matplotlib/statuses/da1ebcb98c10e1c851ca01d23ad416b69a0a35e4"}}}}