smagacor 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/ChangeLog +62 -0
- data/Rakefile +86 -71
- data/TODO +19 -2
- data/VERSION +1 -1
- data/data/smagacor/smagacor-logo.png +0 -0
- data/data/smagacor/sokoban/crate.png +0 -0
- data/data/smagacor/sokoban/floor.png +0 -0
- data/data/smagacor/sokoban/game.info +7 -0
- data/data/smagacor/sokoban/levels/loma.lvl +288 -0
- data/data/smagacor/sokoban/levels/mas_microban.lvl +1812 -0
- data/data/smagacor/sokoban/levels/mas_sasquatch.lvl +891 -0
- data/data/smagacor/sokoban/levels/microban.lvl +1834 -0
- data/data/smagacor/sokoban/levels/sasquatch.lvl +846 -0
- data/data/smagacor/sokoban/levels/sasquatch_III.lvl +903 -0
- data/data/smagacor/sokoban/levels/sasquatch_IV.lvl +812 -0
- data/data/smagacor/sokoban/levels/sasquatch_V.lvl +868 -0
- data/data/smagacor/sokoban/levels/sasquatch_VI.lvl +902 -0
- data/data/smagacor/sokoban/levels/sasquatch_VII.lvl +898 -0
- data/data/smagacor/sokoban/man.png +0 -0
- data/data/smagacor/sokoban/sokoban.png +0 -0
- data/data/smagacor/sokoban/sokobanui.rb +597 -0
- data/data/smagacor/sokoban/storage.png +0 -0
- data/data/smagacor/sokoban/wall.png +0 -0
- data/data/smagacor/tictactoe/game.info +1 -1
- data/data/smagacor/tictactoe/tictactoe.png +0 -0
- data/data/smagacor/tictactoe/tictactoe.rb +295 -206
- data/data/smagacor/tictactoe/x.png +0 -0
- data/lib/smagacor/listener.rb +50 -0
- data/lib/smagacor/smagacor-ui.rb +208 -127
- data/lib/smagacor/{controller.rb → util.rb} +106 -7
- metadata +68 -45
- data/install.rb +0 -21
Binary file
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Listener
|
2
|
+
|
3
|
+
# Adds a new message listener for the object. The message +msgName+
|
4
|
+
# will be dispatched to either the given +callableObject+ (has to respond
|
5
|
+
# to +call+) or the given block. If both are specified the +callableObject+
|
6
|
+
# is used.
|
7
|
+
def add_msg_listener( msgName, callableObject = nil, &block )
|
8
|
+
return unless defined?( @msgNames ) && @msgNames.has_key?( msgName )
|
9
|
+
|
10
|
+
if !callableObject.nil?
|
11
|
+
raise NoMethodError, "listener needs to respond to 'call'" unless callableObject.respond_to? :call
|
12
|
+
@msgNames[msgName].push callableObject
|
13
|
+
elsif !block.nil?
|
14
|
+
@msgNames[msgName].push block
|
15
|
+
else
|
16
|
+
raise "you have to provide a callback object or a block"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# Removes the given object from the dispatcher queue of the message +msgName+.
|
21
|
+
def del_msg_listener( msgName, object )
|
22
|
+
@msgNames[msgName].delete object if defined? @msgNames
|
23
|
+
end
|
24
|
+
|
25
|
+
#######
|
26
|
+
private
|
27
|
+
#######
|
28
|
+
|
29
|
+
# Adds a new message target called +msgName+
|
30
|
+
def add_msg_name( msgName )
|
31
|
+
@msgNames = {} unless defined? @msgNames
|
32
|
+
@msgNames[msgName] = [] unless @msgNames.has_key? msgName
|
33
|
+
end
|
34
|
+
|
35
|
+
# Deletes the message target +msgName+.
|
36
|
+
def del_msg_name( msgName )
|
37
|
+
@msgNames.delete msgName if defined? @msgNames
|
38
|
+
end
|
39
|
+
|
40
|
+
# Dispatches the message +msgName+ to all listeners for this message,
|
41
|
+
# providing the given arguments
|
42
|
+
def dispatch_msg( msgName, *args )
|
43
|
+
if defined? @msgNames and @msgNames.has_key? msgName
|
44
|
+
@msgNames[msgName].each do |obj|
|
45
|
+
obj.call( *args )
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
data/lib/smagacor/smagacor-ui.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
#
|
2
2
|
#--
|
3
3
|
#
|
4
|
-
# $Id: smagacor-ui.rb
|
4
|
+
# $Id: smagacor-ui.rb 362 2005-11-26 17:56:46Z thomas $
|
5
5
|
#
|
6
6
|
# smagacor - a collection of small games in ruby
|
7
7
|
# Copyright (C) 2004 Thomas Leitner
|
@@ -19,196 +19,276 @@
|
|
19
19
|
#
|
20
20
|
#++
|
21
21
|
#
|
22
|
+
|
23
|
+
require 'Qt'
|
22
24
|
require 'logger'
|
23
|
-
require '
|
24
|
-
require '
|
25
|
-
require 'smagacor/controller'
|
25
|
+
require 'ostruct'
|
26
|
+
require 'smagacor/util'
|
26
27
|
|
27
|
-
include Fox
|
28
28
|
|
29
29
|
module Smagacor
|
30
30
|
|
31
|
-
#
|
32
|
-
class
|
31
|
+
# Used to identify a game in the list view
|
32
|
+
class GameMenuItem < Qt::ListViewItem
|
33
33
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
34
|
+
attr_reader :game_info
|
35
|
+
|
36
|
+
def initialize( parent, gameinfo )
|
37
|
+
super( parent, gameinfo.name )
|
38
|
+
@game_info = gameinfo
|
38
39
|
end
|
39
40
|
|
40
|
-
|
41
|
-
|
42
|
-
def init_game_list( switcher, controller )
|
43
|
-
each_child do |child|
|
44
|
-
removeChild( child )
|
45
|
-
child.destroy
|
46
|
-
end
|
47
|
-
controller.load_games
|
48
|
-
controller.games.each do |game|
|
49
|
-
@categories[game.category] ||= CategoryShutterItem.new( self, game.category )
|
50
|
-
btn = GameShutterButton.new( @categories[game.category].content, game.name )
|
51
|
-
btn.tipText = game.description
|
52
|
-
btn.helpText = game.description
|
53
|
-
btn.icon = SmagacorWindow.load_image( getApp(), File.join( game.directory, game.icon ) )
|
54
|
-
btn.connect( SEL_COMMAND ) { switcher.select_game( game ) }
|
55
|
-
end
|
41
|
+
def rtti
|
42
|
+
1001
|
56
43
|
end
|
57
44
|
|
58
45
|
end
|
59
46
|
|
47
|
+
# Widget for listing all installed games.
|
48
|
+
class GameMenu < Qt::ListView
|
60
49
|
|
61
|
-
|
62
|
-
class CategoryShutterItem < FXShutterItem
|
50
|
+
slots 'toggleShown()'
|
63
51
|
|
64
|
-
#
|
65
|
-
def initialize( p
|
66
|
-
super( p
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
52
|
+
# Returns a default version of the class.
|
53
|
+
def initialize( p )
|
54
|
+
super( p )
|
55
|
+
@categories = {}
|
56
|
+
setRootIsDecorated( true )
|
57
|
+
addColumn( "Games" )
|
58
|
+
setSorting( 0 )
|
59
|
+
setColumnWidthMode( 0, Qt::ListView::Maximum )
|
60
|
+
setShowToolTips( true )
|
61
|
+
setResizeMode( Qt::ListView::LastColumn )
|
62
|
+
setFixedWidth( 250 )
|
63
|
+
init_game_list
|
71
64
|
end
|
72
65
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
66
|
+
def init_game_list
|
67
|
+
clear
|
68
|
+
Config.load_games
|
69
|
+
Config.games.each do |game|
|
70
|
+
@categories[game.category] ||= Qt::ListViewItem.new( self, game.category )
|
71
|
+
item = GameMenuItem.new( @categories[game.category], game )
|
72
|
+
item.setPixmap( 0, Qt::Pixmap.new( File.join( game.directory, game.icon ) ) )
|
73
|
+
end
|
74
|
+
end
|
78
75
|
|
79
|
-
|
80
|
-
|
81
|
-
super( p, name, nil, nil, 0, BUTTON_TOOLBAR|TEXT_BELOW_ICON|FRAME_THICK|FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_TOP|LAYOUT_LEFT )
|
82
|
-
self.backColor = p.backColor
|
83
|
-
self.textColor = FXRGB(255, 255, 255)
|
76
|
+
def toggleShown
|
77
|
+
if isShown then hide else show end
|
84
78
|
end
|
85
79
|
|
86
80
|
end
|
87
81
|
|
82
|
+
class GameView < Qt::WidgetStack
|
83
|
+
|
84
|
+
slots 'select_game(QListViewItem*)', 'about()'
|
85
|
+
|
86
|
+
attr_reader :cur_game_data
|
88
87
|
|
89
|
-
|
90
|
-
|
88
|
+
# Small description of Smagacor, for the about view.
|
89
|
+
DESCRIPTION = "<p><img src=\"smagacor\" /><br /><br /><b>Smagacor #{::Smagacor::VERSION.join('.')}</b><br />
|
90
|
+
<br />
|
91
|
+
Smagacor is a collection of some small games.<br />
|
92
|
+
It provides an easy interface for adding new games and has<br />
|
93
|
+
a pleasing :-) appearance.<br />
|
94
|
+
<br />
|
95
|
+
Select a game from the menu on the left side!<br />
|
96
|
+
And have fun with Smagacor!!!<br />
|
97
|
+
<br />
|
98
|
+
<a href=\"http://smagacor.rubyforge.org\">smagacor.rubyforge.org</a>"
|
91
99
|
|
92
|
-
|
93
|
-
|
94
|
-
|
100
|
+
def initialize( p )
|
101
|
+
super( p )
|
102
|
+
@loaded = {}
|
103
|
+
Qt::MimeSourceFactory.defaultFactory.setImage( 'smagacor', Qt::Image.new( Config.get_file( 'smagacor.png' ) ) )
|
104
|
+
aboutPage = Qt::Label.new( DESCRIPTION, self )
|
105
|
+
aboutPage.setAlignment( Qt::AlignVCenter | Qt::AlignCenter )
|
106
|
+
@aboutId = addWidget( aboutPage )
|
107
|
+
@cur_game_data = nil
|
95
108
|
end
|
96
109
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
110
|
+
def select_game( item )
|
111
|
+
return if item.nil? || item.rtti < 1000
|
112
|
+
gi = item.game_info
|
113
|
+
|
114
|
+
if @cur_game_data
|
115
|
+
save_game_state( @cur_game_data )
|
116
|
+
self.parent.parent.menuBar.removeItem( @cur_game_data.menu_id ) if @cur_game_data.menu_id
|
104
117
|
end
|
105
|
-
|
118
|
+
|
119
|
+
data = OpenStruct.new
|
120
|
+
unless @loaded.has_key?( gi )
|
106
121
|
begin
|
107
|
-
require File.join(
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
122
|
+
require File.join( gi.directory, gi.file )
|
123
|
+
data.game_info = gi
|
124
|
+
data.game_obj = gi.interface_class.new( self, gi )
|
125
|
+
data.undo_manager = UndoManager.new
|
126
|
+
data.game_obj.set_undo_manager( data.undo_manager )
|
127
|
+
data.menu = data.game_obj.menu
|
128
|
+
data.widget_id = addWidget( data.game_obj.game_widget )
|
129
|
+
@loaded[gi] = data
|
112
130
|
rescue StandardError => e
|
113
|
-
|
114
|
-
|
115
|
-
|
131
|
+
Qt::MessageBox.critical( self, "Error loading game",
|
132
|
+
"Could not load the game #{gi.name}\nError: #{e.message}\n#{e.backtrace.join("\n")}",
|
133
|
+
Qt::MessageBox::Ok | Qt::MessageBox::Default, Qt::MessageBox::NoButton )
|
134
|
+
data = nil
|
116
135
|
end
|
136
|
+
else
|
137
|
+
data = @loaded[gi]
|
138
|
+
end
|
139
|
+
|
140
|
+
unless data.nil?
|
141
|
+
load_game_state( data )
|
142
|
+
data.menu_id = self.parent.parent.menuBar.insertItem( data.game_info.name, data.menu ) if data.menu
|
143
|
+
self.parent.parent.undoManager = data.undo_manager
|
144
|
+
raiseWidget( @loaded[item.game_info].widget_id )
|
145
|
+
@cur_game_data = data
|
117
146
|
end
|
118
|
-
|
147
|
+
end
|
148
|
+
|
149
|
+
def about
|
150
|
+
raiseWidget( @aboutId )
|
151
|
+
end
|
152
|
+
|
153
|
+
#######
|
154
|
+
private
|
155
|
+
#######
|
156
|
+
|
157
|
+
def load_game_state( game_data )
|
158
|
+
end
|
159
|
+
|
160
|
+
def save_game_state( game_data )
|
161
|
+
|
119
162
|
end
|
120
163
|
|
121
164
|
end
|
122
165
|
|
123
166
|
|
124
167
|
# Log window for viewing the log statements (information, error descriptions, etc ).
|
125
|
-
class LogWindow <
|
168
|
+
class LogWindow < Qt::Dialog
|
169
|
+
|
170
|
+
attr_reader :logdev
|
171
|
+
|
172
|
+
class Logdev
|
173
|
+
|
174
|
+
def initialize( window )
|
175
|
+
@window = window
|
176
|
+
end
|
177
|
+
|
178
|
+
def write( message )
|
179
|
+
@window.write( message )
|
180
|
+
end
|
181
|
+
|
182
|
+
def close(); end
|
183
|
+
|
184
|
+
end
|
126
185
|
|
127
186
|
# Create a LogWindow
|
128
187
|
def initialize( p )
|
129
|
-
super( p
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
188
|
+
super( p )
|
189
|
+
setMinimumSize( 400, 400 )
|
190
|
+
setCaption( "Log Window" )
|
191
|
+
|
192
|
+
@log = Qt::TextEdit.new( self )
|
193
|
+
@log.setTextFormat( Qt::LogText )
|
194
|
+
button = Qt::PushButton.new( "Close", self )
|
195
|
+
connect( button, SIGNAL('clicked()'), self, SLOT('hide()') )
|
196
|
+
|
197
|
+
verticalLayout = Qt::VBoxLayout.new( self )
|
198
|
+
verticalLayout.addWidget( @log )
|
199
|
+
verticalLayout.addWidget( button )
|
200
|
+
@logdev = Logdev.new( self )
|
134
201
|
end
|
135
202
|
|
136
203
|
# Invoked by the logger library for writing log messages. The +message+ is appended to log.
|
137
204
|
def write( message )
|
138
|
-
@log.
|
139
|
-
@log.makePositionVisible( @log.text.length )
|
205
|
+
@log.append( message )
|
140
206
|
end
|
141
207
|
|
142
|
-
# Invoked by the logger library for closing the log device. Does nothing.
|
143
|
-
def close() end
|
144
|
-
|
145
208
|
end
|
146
209
|
|
147
210
|
|
148
211
|
# Main window for Smagacor.
|
149
|
-
class SmagacorWindow <
|
212
|
+
class SmagacorWindow < Qt::MainWindow
|
150
213
|
|
151
|
-
|
152
|
-
DESCRIPTION = "\n\nSmagacor #{::Smagacor::VERSION.join('.')}
|
214
|
+
slots 'undo()', 'redo()'
|
153
215
|
|
154
|
-
|
155
|
-
It provides an easy interface for adding new games and has
|
156
|
-
a pleasing :-) appearance.
|
216
|
+
attr_reader :undoManager
|
157
217
|
|
158
|
-
|
159
|
-
|
218
|
+
# Create the main window
|
219
|
+
def initialize( app )
|
220
|
+
super()
|
221
|
+
setCaption( 'Smagacor Game Collection' )
|
222
|
+
setIcon( Qt::Pixmap.new( Config.get_file( 'smagacor-logo.png' ) ) )
|
223
|
+
setIconText( 'Smagacor Game Collection' )
|
160
224
|
|
161
|
-
|
225
|
+
@logwindow = LogWindow.new( self )
|
226
|
+
logger.set_log_dev( @logwindow.logdev )
|
162
227
|
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
img.create
|
168
|
-
img
|
169
|
-
end
|
228
|
+
statusBar = Qt::StatusBar.new( self )
|
229
|
+
|
230
|
+
mainWidget = Qt::Widget.new( self )
|
231
|
+
setCentralWidget( mainWidget )
|
170
232
|
|
171
|
-
|
172
|
-
def initialize( app, controller )
|
173
|
-
super( app, "Smagacor Game Collection", nil, nil, DECOR_ALL, 100, 100, 800, 600 )
|
174
|
-
@controller = controller
|
233
|
+
mainLayout = Qt::HBoxLayout.new( mainWidget )
|
175
234
|
|
176
|
-
|
177
|
-
|
235
|
+
gamelist = GameMenu.new( mainWidget )
|
236
|
+
mainLayout.addWidget( gamelist )
|
178
237
|
|
179
|
-
|
238
|
+
gameview = GameView.new( mainWidget )
|
239
|
+
mainLayout.addWidget( gameview, 1 )
|
180
240
|
|
181
|
-
|
182
|
-
FXMenuCommand.new( filemenu, "Quit\tCtl-Q", nil, getApp(), FXApp::ID_QUIT )
|
183
|
-
FXMenuTitle.new( menubar, "&File", nil, filemenu )
|
241
|
+
connect( gamelist, SIGNAL('doubleClicked(QListViewItem*, const QPoint&, int)'), gameview, SLOT('select_game(QListViewItem*)') )
|
184
242
|
|
185
|
-
|
186
|
-
|
187
|
-
|
243
|
+
quitAction = Qt::Action.new( "&Quit", Qt::KeySequence.new( CTRL+Key_Q ), self )
|
244
|
+
connect( quitAction, SIGNAL('activated()'), app, SLOT("quit()") )
|
245
|
+
@undoAction = Qt::Action.new( "&Undo", Qt::KeySequence.new( CTRL+Key_Z ), self )
|
246
|
+
@undoAction.setEnabled( false )
|
247
|
+
connect( @undoAction, SIGNAL('activated()'), self, SLOT("undo()") )
|
248
|
+
@redoAction = Qt::Action.new( "&Redo", Qt::KeySequence.new( CTRL+Key_R ), self )
|
249
|
+
@redoAction.setEnabled( false )
|
250
|
+
connect( @redoAction, SIGNAL('activated()'), self, SLOT("redo()") )
|
251
|
+
showLogWindowAction = Qt::Action.new( "Log Window...", Qt::KeySequence.new( CTRL+Key_L ), self )
|
252
|
+
connect( showLogWindowAction, SIGNAL('activated()'), @logwindow, SLOT("show()") )
|
253
|
+
showGameListAction = Qt::Action.new( "Toogle game list", Qt::KeySequence.new( CTRL+Key_G ), self )
|
254
|
+
connect( showGameListAction, SIGNAL('activated()'), gamelist, SLOT("toggleShown()") )
|
255
|
+
aboutAction = Qt::Action.new( "About Smagacor", Qt::KeySequence.new( CTRL+Key_A ), self )
|
256
|
+
connect( aboutAction, SIGNAL('activated()'), gameview, SLOT("about()") )
|
188
257
|
|
189
|
-
|
190
|
-
|
191
|
-
FXMenuCommand.new( helpmenu, "About Smagacor\tCtl-A" ).connect( SEL_COMMAND ) { @switcher.current = 0 }
|
192
|
-
FXMenuTitle.new( menubar, "&Help", nil, helpmenu )
|
258
|
+
filemenu = Qt::PopupMenu.new( self )
|
259
|
+
quitAction.addTo( filemenu )
|
193
260
|
|
194
|
-
|
261
|
+
editmenu = Qt::PopupMenu.new( self )
|
262
|
+
@undoAction.addTo( editmenu )
|
263
|
+
@redoAction.addTo( editmenu )
|
195
264
|
|
196
|
-
|
265
|
+
helpmenu = Qt::PopupMenu.new( self )
|
266
|
+
showLogWindowAction.addTo( helpmenu )
|
267
|
+
showGameListAction.addTo( helpmenu )
|
268
|
+
aboutAction.addTo( helpmenu )
|
197
269
|
|
198
|
-
|
199
|
-
|
200
|
-
|
270
|
+
self.menuBar.insertItem( "&File", filemenu )
|
271
|
+
self.menuBar.insertItem( "&Edit", editmenu )
|
272
|
+
self.menuBar.insertItem( "&Help", helpmenu )
|
273
|
+
end
|
274
|
+
|
275
|
+
def undoManager=( manager )
|
276
|
+
@undoManager.del_msg_listener( :possible_actions, method(:activateUndoRedo) ) if @undoManager
|
277
|
+
@undoManager = manager
|
278
|
+
@undoManager.add_msg_listener( :possible_actions, method(:activateUndoRedo) ) if @undoManager
|
279
|
+
end
|
201
280
|
|
202
|
-
|
281
|
+
def activateUndoRedo( actions )
|
282
|
+
@undoAction.setEnabled( actions.include?( :undo ) )
|
283
|
+
@redoAction.setEnabled( actions.include?( :redo ) )
|
203
284
|
end
|
204
285
|
|
205
|
-
def
|
206
|
-
|
207
|
-
@shutter.width = 150
|
208
|
-
show
|
286
|
+
def undo
|
287
|
+
@undoManager.undo
|
209
288
|
end
|
210
289
|
|
211
|
-
def
|
290
|
+
def redo
|
291
|
+
@undoManager.redo
|
212
292
|
end
|
213
293
|
|
214
294
|
end
|
@@ -219,10 +299,11 @@ smagacor.rubyforge.org"
|
|
219
299
|
|
220
300
|
# Builds the application and runs it.
|
221
301
|
def start
|
222
|
-
app =
|
223
|
-
|
224
|
-
app.
|
225
|
-
|
302
|
+
app = Qt::Application.new( ARGV )
|
303
|
+
main = SmagacorWindow.new( app )
|
304
|
+
app.setMainWidget( main )
|
305
|
+
main.show
|
306
|
+
app.exec
|
226
307
|
end
|
227
308
|
|
228
309
|
end
|