smagacor 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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