smagacor 0.0.1

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.
@@ -0,0 +1,129 @@
1
+ #
2
+ #--
3
+ #
4
+ # $Id: controller.rb 197 2005-02-09 13:42:17Z thomas $
5
+ #
6
+ # smagacor - a collection of small games in ruby
7
+ # Copyright (C) 2004 Thomas Leitner
8
+ #
9
+ # This program is free software; you can redistribute it and/or modify it under the terms of the GNU
10
+ # General Public License as published by the Free Software Foundation; either version 2 of the
11
+ # License, or (at your option) any later version.
12
+ #
13
+ # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
14
+ # even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
+ # General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU General Public License along with this program; if not,
18
+ # write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
+ #
20
+ #++
21
+ #
22
+ require 'rbconfig'
23
+ require "yaml"
24
+ require 'logger'
25
+
26
+ class Object
27
+
28
+ LOGGER = Logger.new( STDERR )
29
+ LOGGER.datetime_format = "%Y-%m-%d %H:%M:%S"
30
+ def logger
31
+ LOGGER
32
+ end
33
+
34
+ end
35
+
36
+ class Logger
37
+
38
+ def set_log_dev( dev )
39
+ @logdev = LogDevice.new( dev )
40
+ end
41
+
42
+ end
43
+
44
+ module Smagacor
45
+
46
+ # The version of this copy of Smagacor
47
+ VERSION = [0, 0, 1]
48
+
49
+ class GameInfo
50
+
51
+ Domain = 'thomasleitner,2004'
52
+ Name = 'gameinfo'
53
+
54
+ attr_reader :name
55
+ attr_reader :icon
56
+ attr_reader :description
57
+ attr_reader :file
58
+ attr_accessor :directory
59
+ attr_reader :classname
60
+ attr_reader :category
61
+
62
+ def get_class_object
63
+ @classname.split( /::/ ).inject( Object ) {|mod, name| mod.const_get( name )}
64
+ end
65
+
66
+ def ==( other )
67
+ @name == other.name && \
68
+ @icon == other.icon && \
69
+ @description == other.description && \
70
+ @file == other.file && \
71
+ @directory == other.directory && \
72
+ @classname == other.classname && \
73
+ @category == other.category
74
+ end
75
+
76
+ alias :to_s :to_yaml
77
+
78
+ def to_yaml_type
79
+ "!#{Domain}/#{Name}"
80
+ end
81
+
82
+ YAML::add_domain_type( Domain, Name ) do |type, val|
83
+ YAML::object_maker( GameInfo, val )
84
+ end
85
+
86
+ end
87
+
88
+
89
+ class Controller
90
+
91
+ attr_reader :gamespath
92
+ attr_reader :games
93
+
94
+ def initialize
95
+ @gamespath = [ File.join( ::Config::CONFIG["datadir"], "smagacor" ), 'data/smagacor' ]
96
+ if defined? Gem::Cache
97
+ gem = Gem::Cache.from_installed_gems.search( "smagacor", "=#{::Smagacor::VERSION.join('.')}" ).last
98
+ @gamespath << File.join( gem.full_gem_path, "data", "smagacor" ) if gem
99
+ end
100
+ begin
101
+ homepath = File.expand_path( '~' )
102
+ rescue
103
+ homepath = ENV['USERPROFILE'] || ENV['HOMEDRIVE']+ENV['HOMEPATH']
104
+ end
105
+ @gamespath.unshift File.join( homepath, '.smagacor' )
106
+ @games = []
107
+ end
108
+
109
+ def get_file( file )
110
+ @gamespath.each do |path|
111
+ name = File.join( path, file )
112
+ return name if File.exists?( name )
113
+ end
114
+ end
115
+
116
+ def load_games
117
+ @games = []
118
+ @gamespath.each do |path|
119
+ Dir[path + '/*/game.info'].each do |file|
120
+ gi = YAML::load( File.open( file ) )
121
+ gi.directory = File.dirname( file )
122
+ @games.push gi
123
+ end
124
+ end
125
+ end
126
+
127
+ end
128
+
129
+ end
@@ -0,0 +1,230 @@
1
+ #
2
+ #--
3
+ #
4
+ # $Id: smagacor-ui.rb 195 2005-02-09 13:16:44Z thomas $
5
+ #
6
+ # smagacor - a collection of small games in ruby
7
+ # Copyright (C) 2004 Thomas Leitner
8
+ #
9
+ # This program is free software; you can redistribute it and/or modify it under the terms of the GNU
10
+ # General Public License as published by the Free Software Foundation; either version 2 of the
11
+ # License, or (at your option) any later version.
12
+ #
13
+ # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
14
+ # even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
+ # General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU General Public License along with this program; if not,
18
+ # write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
+ #
20
+ #++
21
+ #
22
+ require 'logger'
23
+ require 'fox'
24
+ require 'fox/colors'
25
+ require 'smagacor/controller'
26
+
27
+ include Fox
28
+
29
+ module Smagacor
30
+
31
+ # Widget for listing all installed games.
32
+ class GameMenuShutter < FXShutter
33
+
34
+ # Returns a default version of the class.
35
+ def initialize( p )
36
+ super( p, nil, 0, FRAME_SUNKEN|LAYOUT_FILL_X|LAYOUT_FILL_Y )
37
+ @categories = {}
38
+ end
39
+
40
+ # Initializes the list of games. The +switcher+ parameter has to be an object of class
41
+ # GameSwitcher. The method uses the list of games supplied by the +controller+ object.
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
56
+ end
57
+
58
+ end
59
+
60
+
61
+ # Widget for creating category shutter items easily.
62
+ class CategoryShutterItem < FXShutterItem
63
+
64
+ # Create a new category shutter item for category +text+ with +icon+.
65
+ def initialize( p, text, icon=nil, opts=0 )
66
+ super( p, text, icon, opts|LAYOUT_FILL_X|LAYOUT_TOP|LAYOUT_LEFT, 0, 0, 0, 0, 10, 10, 10, 10, 10, 10 )
67
+ button.padTop = 2
68
+ button.padBottom = 2
69
+ self.helpText = text
70
+ self.tipText = text
71
+ end
72
+
73
+ end
74
+
75
+
76
+ # Widget for creating buttons for games easily.
77
+ class GameShutterButton < FXButton
78
+
79
+ # Create a new game button for the game +name+.
80
+ def initialize( p, name )
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)
84
+ end
85
+
86
+ end
87
+
88
+
89
+ # Game switcher widget. Used to display the different games in the space.
90
+ class GameSwitcher < FXSwitcher
91
+
92
+ # Create a new switcher.
93
+ def initializer( p )
94
+ super( p, FRAME_SUNKEN|LAYOUT_FILL_X|LAYOUT_FILL_Y )
95
+ end
96
+
97
+ # Selects the specified +game+ [GameInfo] for playing. If the game has been selected earlier,
98
+ # the widget only displays the game area. Otherwise the information in +game+ is used for
99
+ # loading the necessary game files and for creating the game widget.
100
+ def select_game( game )
101
+ game_index = 0
102
+ children.each_with_index do |child, index|
103
+ game_index = index if child.userData == game
104
+ end
105
+ if game_index == 0
106
+ begin
107
+ require File.join( game.directory, game.file )
108
+ content = game.get_class_object.new( self, game )
109
+ content.create
110
+ content.userData = game
111
+ game_index = children.length - 1
112
+ rescue StandardError => e
113
+ FXMessageBox.new( self, "Error loading game",
114
+ "Could not load the game #{game.name}\nError: #{e.message}\n#{e.backtrace.join("\n")}",
115
+ nil, MBOX_OK ).execute
116
+ end
117
+ end
118
+ self.current = game_index
119
+ end
120
+
121
+ end
122
+
123
+
124
+ # Log window for viewing the log statements (information, error descriptions, etc ).
125
+ class LogWindow < FXDialogBox
126
+
127
+ # Create a LogWindow
128
+ def initialize( p )
129
+ super( p, "Log Window", DECOR_ALL, 0, 0, 600, 400 )
130
+ vertical = FXVerticalFrame.new( self, LAYOUT_SIDE_TOP|LAYOUT_SIDE_LEFT|LAYOUT_FILL_X|LAYOUT_FILL_Y )
131
+ @log = FXText.new( vertical, nil, 0, LAYOUT_FILL_X|LAYOUT_FILL_Y )
132
+ @log.editable = false
133
+ FXButton.new( vertical, "Close", nil, self, ID_ACCEPT, FRAME_RAISED|LAYOUT_FILL_X )
134
+ end
135
+
136
+ # Invoked by the logger library for writing log messages. The +message+ is appended to log.
137
+ def write( message )
138
+ @log.appendText( message )
139
+ @log.makePositionVisible( @log.text.length )
140
+ end
141
+
142
+ # Invoked by the logger library for closing the log device. Does nothing.
143
+ def close() end
144
+
145
+ end
146
+
147
+
148
+ # Main window for Smagacor.
149
+ class SmagacorWindow < FXMainWindow
150
+
151
+ # Small description of Smagacor, for the about view.
152
+ DESCRIPTION = "\n\nSmagacor #{::Smagacor::VERSION.join('.')}
153
+
154
+ Smagacor is a collection of some small games.
155
+ It provides an easy interface for adding new games and has
156
+ a pleasing :-) appearance.
157
+
158
+ Select a game from the menu on the left side!
159
+ And have fun with Smagacor!!!
160
+
161
+ smagacor.rubyforge.org"
162
+
163
+ # Used to load *.png images into FXPNGIcon objects.
164
+ def self.load_image( app, file )
165
+ img = FXPNGIcon.new( app, nil, IMAGE_KEEP|IMAGE_SHMI|IMAGE_SHMP )
166
+ FXFileStream.open( file, FXStreamLoad ) {|str| img.loadPixels(str) }
167
+ img.create
168
+ img
169
+ end
170
+
171
+ # Create the main window, using +app+ [FXApplication] and +controller+ [Controller].
172
+ def initialize( app, controller )
173
+ super( app, "Smagacor Game Collection", nil, nil, DECOR_ALL, 100, 100, 800, 600 )
174
+ @controller = controller
175
+
176
+ @logwindow = LogWindow.new( app )
177
+ logger.set_log_dev( @logwindow )
178
+
179
+ menubar = FXMenubar.new( self, LAYOUT_SIDE_TOP|LAYOUT_FILL_X )
180
+
181
+ filemenu = FXMenuPane.new( self )
182
+ FXMenuCommand.new( filemenu, "Quit\tCtl-Q", nil, getApp(), FXApp::ID_QUIT )
183
+ FXMenuTitle.new( menubar, "&File", nil, filemenu )
184
+
185
+ editmenu = FXMenuPane.new( self )
186
+ FXMenuCommand.new( editmenu, "Undo\tCtl-Z" ).connect( SEL_COMMAND, method( :onUndo ) )
187
+ FXMenuTitle.new( menubar, "&Edit", nil, editmenu )
188
+
189
+ helpmenu = FXMenuPane.new( self )
190
+ FXMenuCommand.new( helpmenu, "Log Window...\tCtl-L" ).connect( SEL_COMMAND ) { @logwindow.show }
191
+ FXMenuCommand.new( helpmenu, "About Smagacor\tCtl-A" ).connect( SEL_COMMAND ) { @switcher.current = 0 }
192
+ FXMenuTitle.new( menubar, "&Help", nil, helpmenu )
193
+
194
+ status = FXStatusbar.new( self, LAYOUT_SIDE_BOTTOM|LAYOUT_FILL_X|STATUSBAR_WITH_DRAGCORNER )
195
+
196
+ splitter = FXSplitter.new( self, LAYOUT_SIDE_TOP|LAYOUT_FILL_X|LAYOUT_FILL_Y|SPLITTER_TRACKING )
197
+
198
+ @shutter = GameMenuShutter.new( splitter )
199
+ @switcher = GameSwitcher.new( splitter )
200
+ @shutter.init_game_list( @switcher, controller )
201
+
202
+ FXLabel.new( @switcher, DESCRIPTION, SmagacorWindow.load_image( getApp(), controller.get_file( 'smagacor.png' ) ), ICON_ABOVE_TEXT )
203
+ end
204
+
205
+ def create
206
+ super
207
+ @shutter.width = 150
208
+ show
209
+ end
210
+
211
+ def onUndo( sender, sel, event )
212
+ end
213
+
214
+ end
215
+
216
+
217
+ # Wraps the creation of the Smagacor Application.
218
+ class SmagacorUI
219
+
220
+ # Builds the application and runs it.
221
+ def start
222
+ app = FXApp.new( "Smagacor Game Collection", "Smagacor Game Collection" )
223
+ window = SmagacorWindow.new( app, Controller.new )
224
+ app.create
225
+ app.run
226
+ end
227
+
228
+ end
229
+
230
+ end