context 0.0.16
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile.rb +107 -0
- data/coverage/-usr-local-lib-site_ruby-1_8-atk_rb.html +612 -0
- data/coverage/-usr-local-lib-site_ruby-1_8-gdk_pixbuf2_rb.html +637 -0
- data/coverage/-usr-local-lib-site_ruby-1_8-glib2_rb.html +829 -0
- data/coverage/-usr-local-lib-site_ruby-1_8-gtk2-base_rb.html +709 -0
- data/coverage/-usr-local-lib-site_ruby-1_8-gtk2_rb.html +623 -0
- data/coverage/-usr-local-lib-site_ruby-1_8-pango_rb.html +665 -0
- data/coverage/-var-lib-gems-1_8-gems-cairo-1_7_0-src-lib-cairo-color_rb.html +865 -0
- data/coverage/-var-lib-gems-1_8-gems-cairo-1_7_0-src-lib-cairo-colors_rb.html +1266 -0
- data/coverage/-var-lib-gems-1_8-gems-cairo-1_7_0-src-lib-cairo-constants_rb.html +632 -0
- data/coverage/-var-lib-gems-1_8-gems-cairo-1_7_0-src-lib-cairo-context-blur_rb.html +655 -0
- data/coverage/-var-lib-gems-1_8-gems-cairo-1_7_0-src-lib-cairo-context-circle_rb.html +619 -0
- data/coverage/-var-lib-gems-1_8-gems-cairo-1_7_0-src-lib-cairo-context-color_rb.html +621 -0
- data/coverage/-var-lib-gems-1_8-gems-cairo-1_7_0-src-lib-cairo-context-path_rb.html +726 -0
- data/coverage/-var-lib-gems-1_8-gems-cairo-1_7_0-src-lib-cairo-context-rectangle_rb.html +643 -0
- data/coverage/-var-lib-gems-1_8-gems-cairo-1_7_0-src-lib-cairo-context-triangle_rb.html +622 -0
- data/coverage/-var-lib-gems-1_8-gems-cairo-1_7_0-src-lib-cairo-context_rb.html +639 -0
- data/coverage/-var-lib-gems-1_8-gems-cairo-1_7_0-src-lib-cairo-paper_rb.html +793 -0
- data/coverage/-var-lib-gems-1_8-gems-cairo-1_7_0-src-lib-cairo-papers_rb.html +651 -0
- data/coverage/-var-lib-gems-1_8-gems-cairo-1_7_0-src-lib-cairo-path_rb.html +625 -0
- data/coverage/-var-lib-gems-1_8-gems-cairo-1_7_0-src-lib-cairo-point_rb.html +617 -0
- data/coverage/-var-lib-gems-1_8-gems-cairo-1_7_0-src-lib-cairo_rb.html +756 -0
- data/coverage/index.html +1170 -0
- data/coverage/lib-Context-Bridge_rb.html +673 -0
- data/coverage/lib-Context-Context_rb.html +756 -0
- data/coverage/lib-Context-EnumeratedType_rb.html +661 -0
- data/coverage/lib-Context-ExecutionProxy_rb.html +671 -0
- data/coverage/lib-Context-Gtk-App_rb.html +638 -0
- data/coverage/lib-Context-Gtk-Key_rb.html +664 -0
- data/coverage/lib-Context-Gtk-Widget_rb.html +667 -0
- data/coverage/lib-Context-KeyAssignment_rb.html +641 -0
- data/coverage/lib-Context-KeyMap_rb.html +653 -0
- data/coverage/lib-Context-Key_rb.html +667 -0
- data/coverage/lib-Context-View_rb.html +659 -0
- data/coverage/lib-Context-Views-Gtk-PageView_rb.html +660 -0
- data/coverage/lib-Context-Views-PageView_rb.html +627 -0
- data/coverage/lib-Context-Widget_rb.html +650 -0
- data/coverage/lib-Context-require_all_rb.html +623 -0
- data/doc/classes/Context.html +174 -0
- data/doc/classes/Context/Bridge.html +296 -0
- data/doc/classes/Context/Context.html +564 -0
- data/doc/classes/Context/EnumeratedType.html +283 -0
- data/doc/classes/Context/ExecutionProxy.html +228 -0
- data/doc/classes/Context/Gtk.html +126 -0
- data/doc/classes/Context/Gtk/App.html +217 -0
- data/doc/classes/Context/Gtk/Key.html +292 -0
- data/doc/classes/Context/Gtk/PageView.html +245 -0
- data/doc/classes/Context/Gtk/PageView/MainWindow.html +200 -0
- data/doc/classes/Context/Gtk/Widget.html +311 -0
- data/doc/classes/Context/Key.html +305 -0
- data/doc/classes/Context/Key/Modifier.html +117 -0
- data/doc/classes/Context/KeyAssignment.html +234 -0
- data/doc/classes/Context/KeyMap.html +273 -0
- data/doc/classes/Context/PageView.html +180 -0
- data/doc/classes/Context/View.html +334 -0
- data/doc/classes/Context/Widget.html +298 -0
- data/doc/classes/Kernel.html +148 -0
- data/doc/classes/Object.html +196 -0
- data/doc/created.rid +1 -0
- data/doc/files/lib/Context/Bridge_rb.html +108 -0
- data/doc/files/lib/Context/Context_rb.html +109 -0
- data/doc/files/lib/Context/EnumeratedType_rb.html +101 -0
- data/doc/files/lib/Context/ExecutionProxy_rb.html +101 -0
- data/doc/files/lib/Context/Gtk/App_rb.html +110 -0
- data/doc/files/lib/Context/Gtk/Key_rb.html +109 -0
- data/doc/files/lib/Context/Gtk/Widget_rb.html +109 -0
- data/doc/files/lib/Context/KeyAssignment_rb.html +108 -0
- data/doc/files/lib/Context/KeyMap_rb.html +109 -0
- data/doc/files/lib/Context/Key_rb.html +108 -0
- data/doc/files/lib/Context/Version_rb.html +101 -0
- data/doc/files/lib/Context/View_rb.html +101 -0
- data/doc/files/lib/Context/Views/Gtk/PageView_rb.html +111 -0
- data/doc/files/lib/Context/Views/PageView_rb.html +108 -0
- data/doc/files/lib/Context/Widget_rb.html +101 -0
- data/doc/files/lib/Context/require_all_rb.html +101 -0
- data/doc/fr_class_index.html +46 -0
- data/doc/fr_file_index.html +42 -0
- data/doc/fr_method_index.html +103 -0
- data/doc/index.html +24 -0
- data/doc/rdoc-style.css +208 -0
- data/lib/Context/Bridge.rb +63 -0
- data/lib/Context/Context.rb +146 -0
- data/lib/Context/EnumeratedType.rb +51 -0
- data/lib/Context/ExecutionProxy.rb +61 -0
- data/lib/Context/Gtk/App.rb +28 -0
- data/lib/Context/Gtk/Key.rb +54 -0
- data/lib/Context/Gtk/Widget.rb +57 -0
- data/lib/Context/Key.rb +57 -0
- data/lib/Context/KeyAssignment.rb +31 -0
- data/lib/Context/KeyMap.rb +43 -0
- data/lib/Context/Version.rb +5 -0
- data/lib/Context/View.rb +49 -0
- data/lib/Context/Views/Gtk/PageView.rb +50 -0
- data/lib/Context/Views/PageView.rb +17 -0
- data/lib/Context/Widget.rb +40 -0
- data/lib/Context/require_all.rb +13 -0
- data/spec/Context/Bridge_spec.rb +40 -0
- data/spec/Context/Context_spec.rb +102 -0
- data/spec/Context/EnumeratedType_spec.rb +51 -0
- data/spec/Context/ExecutionProxy_spec.rb +28 -0
- data/spec/Context/Gtk/App_spec.rb +24 -0
- data/spec/Context/Gtk/Key_spec.rb +45 -0
- data/spec/Context/Gtk/Widget_spec.rb +44 -0
- data/spec/Context/KeyAssignment_spec.rb +26 -0
- data/spec/Context/KeyMap_spec.rb +64 -0
- data/spec/Context/Key_spec.rb +22 -0
- data/spec/Context/View_spec.rb +62 -0
- data/spec/Context/Views/Gtk/PageView_spec.rb +44 -0
- data/spec/Context/Views/PageView_spec.rb +20 -0
- data/spec/Context/Widget_spec.rb +15 -0
- data/spec/Context/require_all_spec.rb +13 -0
- data/test_results.html +343 -0
- metadata +179 -0
@@ -0,0 +1,146 @@
|
|
1
|
+
require 'Context/KeyMap'
|
2
|
+
require 'Context/ExecutionProxy'
|
3
|
+
|
4
|
+
module Context
|
5
|
+
|
6
|
+
# The Context is the Presenter in the Model, View, Presentor (MVP)
|
7
|
+
# model. It is an object that holds the logic for the UI
|
8
|
+
# scenario that the application is currently in. Context is
|
9
|
+
# an abstract class.
|
10
|
+
#
|
11
|
+
# A Context is made up of views, model objects and other sub-contexts.
|
12
|
+
# One of the views should be a UI widget container that contains all
|
13
|
+
# of the views for the Context. The concrete classes should define
|
14
|
+
# the logic for the Context that is either called by enter()
|
15
|
+
# or called from one of the contained views.
|
16
|
+
#
|
17
|
+
# Note that views are usually only instantiated in createViews, which
|
18
|
+
# is called on enter(), not on Context creation. However, there is
|
19
|
+
# no requirement for this.
|
20
|
+
class Context
|
21
|
+
attr_reader :parent, :mainView
|
22
|
+
attr_writer :mainView
|
23
|
+
|
24
|
+
# Create a new Context. Takes a Bridge that is used to
|
25
|
+
# create the View s in using the correct namespace.
|
26
|
+
def initialize(viewBridge)
|
27
|
+
@parent = nil
|
28
|
+
@mainView = nil
|
29
|
+
@viewBridge = viewBridge
|
30
|
+
@keyMap = KeyMap.new
|
31
|
+
@entered = false
|
32
|
+
end
|
33
|
+
|
34
|
+
# Creates the views for the context. This method is called
|
35
|
+
# automatically by enter() and probably should not be called otherwise.
|
36
|
+
# This method should be overriden by the concrete class. It
|
37
|
+
# should instantiate all the views and set @mainView
|
38
|
+
def createViews
|
39
|
+
# Nothing to do here
|
40
|
+
end
|
41
|
+
|
42
|
+
# This is intended to be private (how do I do that again?)
|
43
|
+
# Just so that it doesn't create a view if it is already created
|
44
|
+
def setupViews
|
45
|
+
if @mainView.nil?
|
46
|
+
createViews
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# Creates views and returns the main View. This is intended
|
51
|
+
# to be used by test code where entering the context executes
|
52
|
+
# code and you need to know what the view will be ahead of time.
|
53
|
+
# I can think of no reason to use this in production code.
|
54
|
+
def peekAtView
|
55
|
+
setupViews
|
56
|
+
@mainView
|
57
|
+
end
|
58
|
+
|
59
|
+
# Destroys the views for the context. This method is called
|
60
|
+
# automatically by exit() and probably should not be called otherwise.
|
61
|
+
# This method should be overriden by the concrete class. It
|
62
|
+
# should destroy all the views and set @mainView to nil
|
63
|
+
def destroyViews
|
64
|
+
@mainView = nil
|
65
|
+
end
|
66
|
+
|
67
|
+
# Adds a view to the mainView
|
68
|
+
# Since the mainView is intended to be a UI container that contains
|
69
|
+
# all the views, this method is called by a sub-context's enter()
|
70
|
+
# method to allow the parent's mainView to contain the sub-context's
|
71
|
+
# views.
|
72
|
+
def addView(view)
|
73
|
+
@mainView.addView(view) unless @mainView.nil?
|
74
|
+
end
|
75
|
+
|
76
|
+
# Enters the Context. After it is called, the Context is then
|
77
|
+
# active and can be interacted with. This method automatically
|
78
|
+
# calls createViews() and adds the mainView to the parent's view.
|
79
|
+
#
|
80
|
+
# Usually this method will be overriden by the concrete class.
|
81
|
+
# However, it should be careful to call super() in the appropriate
|
82
|
+
# place.
|
83
|
+
def enter(parent)
|
84
|
+
@parent = parent
|
85
|
+
if (@parent != nil)
|
86
|
+
@entered = true
|
87
|
+
setupViews
|
88
|
+
parent.addView(@mainView) unless @mainView.nil?
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
# Returns true if the context has been entered, but not exited.
|
93
|
+
# Returns false if the context has never been entered, or if
|
94
|
+
# it has been entered and then exited.
|
95
|
+
def isEntered?
|
96
|
+
@entered
|
97
|
+
end
|
98
|
+
|
99
|
+
# Exits the Context. After it is called, the context is no longer
|
100
|
+
# active and can't be interacted with. This method automatically
|
101
|
+
# removes the mainView from the parent's view and calls destroyViews().
|
102
|
+
#
|
103
|
+
# Usually this method will be overriden by the concrete class.
|
104
|
+
# However, it should be careful to call super() in the appropriate
|
105
|
+
# place.
|
106
|
+
def exit()
|
107
|
+
@entered = false
|
108
|
+
if !@parent.nil? && !@parent.mainView.nil?
|
109
|
+
@parent.mainView.removeView(@mainView) unless @mainView.nil?
|
110
|
+
end
|
111
|
+
destroyViews
|
112
|
+
end
|
113
|
+
|
114
|
+
# Sets a binding for a key.
|
115
|
+
# Whenever a key is pressed, the context is notified. This
|
116
|
+
# sets up a binding between the key and the block passed in.
|
117
|
+
# After that point, the block will be called everytime the
|
118
|
+
# key is pressed.
|
119
|
+
#
|
120
|
+
# Warning: This key binding mechanism is likely to be
|
121
|
+
# depracated, or at least heavily modified soon.
|
122
|
+
def setKeyBinding(key, &binding)
|
123
|
+
a = KeyAssignment.new(key, &binding)
|
124
|
+
@keyMap.add(a)
|
125
|
+
end
|
126
|
+
|
127
|
+
# Returns the existing binding for a key.
|
128
|
+
#
|
129
|
+
# Warning: This key binding mechanism is likely to be
|
130
|
+
# depracated, or at least heavily modified soon.
|
131
|
+
def getKeyBinding(key)
|
132
|
+
a = @keyMap.findKey(key)
|
133
|
+
a.unless_nil.action
|
134
|
+
end
|
135
|
+
|
136
|
+
# Called by the view to indicated that a key has been pressed.
|
137
|
+
# Runs the binding in the keymap, or returns nil if there
|
138
|
+
# isn't one.
|
139
|
+
#
|
140
|
+
# Warning: This key binding mechanism is likely to be
|
141
|
+
# depracated, or at least heavily modified soon.
|
142
|
+
def notifyKey(view, key)
|
143
|
+
@keyMap.unless_nil do press(key) end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Context
|
2
|
+
|
3
|
+
# Class that holds a series of constants that act as an
|
4
|
+
# enumerated type. The first ID added to the type is
|
5
|
+
# set to the value 0 (or at the value specified in start_at).
|
6
|
+
# each subsequent ID added to the type is automatically
|
7
|
+
# incremented
|
8
|
+
class EnumeratedType
|
9
|
+
# Use singleton class to define class methods
|
10
|
+
class << self
|
11
|
+
# Set the value that the first ID should start at.
|
12
|
+
# Note: This must called *before* add() or symbols()
|
13
|
+
def start_at(n)
|
14
|
+
@nextValue = n
|
15
|
+
end
|
16
|
+
|
17
|
+
# Add a single ID to the enumerated type
|
18
|
+
# Usually called like:
|
19
|
+
# add MY_ID
|
20
|
+
def add(id)
|
21
|
+
@nextValue ||= 0
|
22
|
+
const_set(id, @nextValue)
|
23
|
+
@nextValue += 1
|
24
|
+
end
|
25
|
+
|
26
|
+
# Add a group of IDs to the enumerated type.
|
27
|
+
# This method takes an array.
|
28
|
+
# Usually called like:
|
29
|
+
# symbols [ID1, ID2, ID3,...]
|
30
|
+
def symbols(array)
|
31
|
+
array.each do |id|
|
32
|
+
add(id)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# Returns true if the ID has been defined in the enumerated type.
|
37
|
+
def responds_to?(id)
|
38
|
+
name = id.id2name
|
39
|
+
return true if self.const_defined?(name)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Retrieve the value of the ID
|
43
|
+
# If the ID is defined, return it's value.
|
44
|
+
def method_missing(id)
|
45
|
+
name = id.id2name
|
46
|
+
self.const_get(name) if self.const_defined?(name)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Context
|
2
|
+
|
3
|
+
# A Proxy for carrying on conditional execution.
|
4
|
+
class ExecutionProxy
|
5
|
+
# Set the true object on which to execute and the condition to execute.
|
6
|
+
# NOTE: The condition is a bool. In other words it has *already*
|
7
|
+
# been evaluated before we get to this point.
|
8
|
+
def initialize(object, cond)
|
9
|
+
@object = object
|
10
|
+
@cond = cond
|
11
|
+
end
|
12
|
+
|
13
|
+
# Conditionally execute the block. If the condition is true,
|
14
|
+
# execute the block. Otherwise return the true object.
|
15
|
+
# NOTE: Crazy name is so that you don't have something with
|
16
|
+
# the same name and accidently call it with method_missing.
|
17
|
+
def execute_if_you_can(&block)
|
18
|
+
if @cond
|
19
|
+
@object.instance_eval(&block)
|
20
|
+
else
|
21
|
+
@object
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# Conditionally evaluate the symbol. If the condition is true,
|
26
|
+
# evaluate the symbol. Otherwise return the true object.
|
27
|
+
def method_missing(symbol)
|
28
|
+
if @cond
|
29
|
+
@object.instance_eval(symbol.to_s)
|
30
|
+
else
|
31
|
+
@object
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
class Object
|
38
|
+
|
39
|
+
# Execute the block if the condition is *true*. Or if there is no
|
40
|
+
# block, then return the proxy object. Usually this is so you
|
41
|
+
# can say something like:
|
42
|
+
# * object.execute_if(condition).property
|
43
|
+
# If the condition is *false*, execution of the block, or evaluation
|
44
|
+
# of the property will return the original object.
|
45
|
+
def execute_if(cond, &block)
|
46
|
+
proxy = Context::ExecutionProxy.new(self, cond)
|
47
|
+
# Note: Wouldn't it be nice if the following could be replaced by
|
48
|
+
# proxy.execute_if(!block.nil) do execute_if_you_can(&block) end
|
49
|
+
proxy_if_block_exists = Context::ExecutionProxy.new(proxy, !block.nil?)
|
50
|
+
proxy_if_block_exists.execute_if_you_can() do
|
51
|
+
execute_if_you_can(&block)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# If the object is not nil, execute the block (or evaluate
|
56
|
+
# the property). Otherwise return nil.
|
57
|
+
def unless_nil(&block)
|
58
|
+
execute_if(!nil?, &block)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'Context/Bridge'
|
2
|
+
require 'Context/Context'
|
3
|
+
require 'gtk2'
|
4
|
+
|
5
|
+
module Context::Gtk
|
6
|
+
class App < Context::Context
|
7
|
+
|
8
|
+
attr_reader :mainContext
|
9
|
+
|
10
|
+
def initialize(namespace, context)
|
11
|
+
viewBridge = Context::Bridge.new(namespace)
|
12
|
+
super(viewBridge)
|
13
|
+
Gtk.init
|
14
|
+
@mainContext = context.new(viewBridge)
|
15
|
+
end
|
16
|
+
|
17
|
+
def enter
|
18
|
+
super(nil)
|
19
|
+
@mainContext.enter(self)
|
20
|
+
Gtk.main
|
21
|
+
end
|
22
|
+
|
23
|
+
def exit
|
24
|
+
super()
|
25
|
+
Gtk.main_quit
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'Context/Key'
|
2
|
+
require 'gtk2'
|
3
|
+
|
4
|
+
module Context::Gtk
|
5
|
+
|
6
|
+
class Key < Context::Key
|
7
|
+
|
8
|
+
def Key::getModifierFromEvent(event)
|
9
|
+
case event.state
|
10
|
+
when 0
|
11
|
+
Context::Key::Modifier::NONE
|
12
|
+
when Gdk::Window::CONTROL_MASK
|
13
|
+
Context::Key::Modifier::CONTROL
|
14
|
+
else
|
15
|
+
Context::Key::Modifier::ERROR
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def getGtkState
|
20
|
+
case @modifier
|
21
|
+
when Context::Key::Modifier::CONTROL
|
22
|
+
Gdk::Window::CONTROL_MASK
|
23
|
+
else
|
24
|
+
0
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def Key::getCharacterFromEvent(event)
|
29
|
+
Gdk::Keyval::to_name(event.keyval)
|
30
|
+
end
|
31
|
+
|
32
|
+
def getGtkKeyval
|
33
|
+
Gdk::Keyval::from_name(@character)
|
34
|
+
end
|
35
|
+
|
36
|
+
def Key::createFromGtkEvent(event)
|
37
|
+
modifier = getModifierFromEvent(event)
|
38
|
+
character = getCharacterFromEvent(event)
|
39
|
+
if((modifier != Context::Key::Modifier::ERROR) &&
|
40
|
+
(!character.nil?))
|
41
|
+
Key.new(modifier, character)
|
42
|
+
else
|
43
|
+
Key.null
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def createGtkEvent
|
48
|
+
event = Gdk::EventKey.new(Gdk::Event::KEY_PRESS)
|
49
|
+
event.set_state(getGtkState)
|
50
|
+
event.set_keyval(getGtkKeyval)
|
51
|
+
event
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'Context/Widget'
|
2
|
+
require 'gtk2'
|
3
|
+
|
4
|
+
module Context::Gtk
|
5
|
+
|
6
|
+
class Widget < Context::Widget
|
7
|
+
attr_reader :mainWindow, :expandHeight, :expandWidth
|
8
|
+
attr_writer :mainWindow, :expandHeight, :expandWidth
|
9
|
+
|
10
|
+
class << self
|
11
|
+
# Redefine this in tests so that the widgets don't get displayed
|
12
|
+
# on the screen.
|
13
|
+
def inTests
|
14
|
+
false
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def initialize(delegate)
|
19
|
+
super(delegate)
|
20
|
+
@mainWindow = nil
|
21
|
+
# Packing hints for the container
|
22
|
+
@expandHeight = false
|
23
|
+
@expandWidth = false
|
24
|
+
end
|
25
|
+
|
26
|
+
def isAMainWindow
|
27
|
+
@mainWindow = @delegate
|
28
|
+
end
|
29
|
+
|
30
|
+
def add(widget)
|
31
|
+
if !widget.delegate.class.ancestors.include?(Gtk::Window)
|
32
|
+
widget.mainWindow = @mainWindow
|
33
|
+
@delegate.add(widget.delegate)
|
34
|
+
if !Widget.inTests
|
35
|
+
@delegate.show_all
|
36
|
+
end
|
37
|
+
else
|
38
|
+
widget.isAMainWindow
|
39
|
+
widget.delegate.set_transient_for(@mainWindow)
|
40
|
+
if !Widget.inTests
|
41
|
+
widget.delegate.show_all
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def remove(widget)
|
47
|
+
widget.mainWindow = nil
|
48
|
+
if !widget.delegate.class.ancestors.include?(Gtk::Window)
|
49
|
+
@delegate.remove(widget.delegate)
|
50
|
+
if !Widget.inTests
|
51
|
+
@delegate.show_all
|
52
|
+
end
|
53
|
+
end
|
54
|
+
@delegate.grab_focus
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
data/lib/Context/Key.rb
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'Context/EnumeratedType'
|
2
|
+
|
3
|
+
module Context
|
4
|
+
|
5
|
+
# Represents a keypress. Each key is represented
|
6
|
+
# by a character and a modifier (e.g., the control
|
7
|
+
# key)
|
8
|
+
#
|
9
|
+
# One could argue that this doesn't deserve to be
|
10
|
+
# here at all. It is possible that some UI types
|
11
|
+
# won't have a keyboard at all. However given that
|
12
|
+
# most will operate the same way indicates that
|
13
|
+
# it should have some level of abstraction. I have
|
14
|
+
# a feeling that this is YAGNI, though. And as such
|
15
|
+
# it might disappear at any point.
|
16
|
+
class Key
|
17
|
+
# Types of key modifiers. Currently only
|
18
|
+
# control or none is supported.
|
19
|
+
class Modifier < EnumeratedType
|
20
|
+
start_at 0
|
21
|
+
symbols [:ERROR, :NONE, :CONTROL]
|
22
|
+
end
|
23
|
+
|
24
|
+
attr_reader :modifier, :character
|
25
|
+
|
26
|
+
def initialize(modifier, character)
|
27
|
+
@modifier = modifier
|
28
|
+
@character = character
|
29
|
+
end
|
30
|
+
|
31
|
+
# A non key that can be used as an error condition.
|
32
|
+
# Note: Perhaps this should be a constant??? Currently
|
33
|
+
# key.eql?(Key.null) will work, but key == Key.null
|
34
|
+
# won't. FIXME
|
35
|
+
def Key.null
|
36
|
+
Key.new(Modifier.NONE, '\0')
|
37
|
+
end
|
38
|
+
|
39
|
+
# Returns true if the two keys have the same character and modifier.
|
40
|
+
def eql?(key)
|
41
|
+
(@modifier == key.modifier) && (@character == key.character)
|
42
|
+
end
|
43
|
+
|
44
|
+
# Creates a hash for the key. This is needed for the KeyMap
|
45
|
+
# which is implemented as a hash.
|
46
|
+
def hash
|
47
|
+
hashValue = @modifier.to_s
|
48
|
+
hashValue += @character
|
49
|
+
hashValue.hash
|
50
|
+
end
|
51
|
+
|
52
|
+
# Returns true if the key is equal to Key.null.
|
53
|
+
def null?
|
54
|
+
eql?(Key.null)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|