view src/net/kryshen/charamega/ui.mirah @ 6:9d940c7ee4c0

Adjusted defaults and limits.
author Mikhail Kryshen <mikhail@kryshen.net>
date Mon, 16 Jul 2012 06:30:28 +0400
parents 1e64a109812f
children 64334b3d9236
line source
1 #
2 # Copyright 2012 Mikhail Kryshen <mikhail@kryshen.net>
3 #
4 # This file is part of Charamega.
5 #
6 # Charamega is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation, either version 3 of the License, or
9 # (at your option) any later version.
10 #
11 # Charamega is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with Charamega. If not, see <http://www.gnu.org/licenses/>.
18 #
20 package net.kryshen.charamega
22 import java.awt.*
23 import java.awt.event.*
24 import javax.swing.*
25 import java.net.URI
27 class Ui < JPanel
29 def self.initialize:void
30 @@title = 'Charamega'
31 @@version = '0.9'
32 @@home = 'http://kryshen.net/games/'
33 end
35 def initialize(root_pane:JRootPane)
36 super LayoutManager(BorderLayout.new)
38 @game = Game.new.shuffle(30)
39 @field = Field.new(@game)
40 @field.setBorder BorderFactory.createEmptyBorder(5, 5, 5, 5)
42 add @field, BorderLayout.CENTER
43 add create_status, BorderLayout.SOUTH
45 ui = self
46 @timer = Timer.new(250) { |e| ui.update }
48 @conf = create_configurator
49 root_pane.getLayeredPane.add @conf, JLayeredPane.MODAL_LAYER
50 root_pane.setDefaultButton @start
52 stop
53 update_status
54 end
56 def doLayout
57 @conf.setSize @conf.getPreferredSize
58 @conf.setLocation int(getWidth * 0.05), int(getHeight * 0.05)
59 super
60 end
62 def update
63 @field.repaint if @game.update
64 stop if @game.finished?
65 update_status
66 end
68 def update_status
69 @status.setText(@game.status)
70 end
72 def start
73 @conf.setVisible false
74 @field.setEnabled true
75 @start.setEnabled false
76 @stop.setEnabled true
77 @game.start
78 @timer.start
79 @field.repaint
80 end
82 def stop
83 @timer.stop
84 @game.stop
85 @stop.setEnabled false
86 @start.setEnabled true
87 @field.setEnabled false
88 @conf.setVisible true
89 @field.repaint
90 end
92 def self.create_frame
93 title = @@title
94 SwingUtilities.invokeLater do
95 # UIManager.setLookAndFeel UIManager.getSystemLookAndFeelClassName
97 frame = JFrame.new title
98 ui = Ui.new(frame.getRootPane)
100 frame.getContentPane.add ui
101 frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE)
102 .pack
103 .setVisible(true)
104 end
105 end
107 private
109 def create_status
110 ui = self
112 status_panel = JPanel.new
113 layout = GroupLayout.new(status_panel)
114 status_panel.setLayout layout
116 @status = JLabel.new('', SwingConstants.RIGHT)
117 @stop = JButton.new('New game')
118 @stop.addActionListener do |e|
119 ui.update_status
120 ui.stop
121 end
123 gap = 5
125 h_group = layout.createSequentialGroup
126 .addGap(1, gap, gap)
127 .addComponent(@stop)
128 .addGap(1, gap, gap)
129 .addComponent(@status,
130 GroupLayout.DEFAULT_SIZE,
131 GroupLayout.DEFAULT_SIZE,
132 Short.MAX_VALUE)
133 .addGap(1, gap, gap)
135 v_group = layout.createSequentialGroup
136 .addGap(1, gap, gap)
137 .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
138 .addComponent(@stop)
139 .addComponent(@status))
140 .addGap(1, gap, gap)
142 layout.setHorizontalGroup h_group
143 layout.setVerticalGroup v_group
145 status_panel
146 end
148 def create_configurator
149 # Can't use object fields in closures in Mirah 0.11.
150 ui = self
151 game = @game
152 field = @field
154 conf = JPanel.new
155 layout = GroupLayout.new(conf)
156 conf.setLayout layout
157 conf.setBorder BorderFactory.createRaisedBevelBorder
159 layout.setAutoCreateGaps true
160 layout.setAutoCreateContainerGaps true
162 title = JLabel.new(@@title)
163 .setFont(Font.new('serif', Font.BOLD, 26))
165 version = JLabel.new("version #{@@version}")
166 link = HyperlinkLabel.new(@@home)
168 players_label = JLabel.new('Players: ')
169 pairs_label = JLabel.new('Pairs: ')
171 players = SpinnerNumberModel.new(1, 1, 20, 1)
172 pairs = SpinnerNumberModel.new(@game.cards.size / 2, 2, 200, 10)
174 players_spinner = JSpinner.new(players)
175 pairs_spinner = JSpinner.new(pairs)
177 players.addChangeListener do |e|
178 game.players = players.getNumber.intValue
179 field.repaint if game.shuffle
180 ui.update_status
181 end
183 pairs.addChangeListener do |e|
184 game.shuffle pairs.getNumber.intValue
185 field.repaint
186 ui.update_status
187 end
189 @start = JButton.new("Start")
190 @start.addActionListener do |e|
191 ui.start
192 end
194 h_group = layout.createParallelGroup
195 .addGroup(layout.createSequentialGroup
196 .addComponent(title)
197 .addComponent(version))
198 .addGroup(layout.createSequentialGroup
199 .addComponent(link,
200 GroupLayout.DEFAULT_SIZE,
201 GroupLayout.DEFAULT_SIZE,
202 GroupLayout.PREFERRED_SIZE)
203 .addGap(0, 0, Short.MAX_VALUE))
204 .addGroup(layout.createSequentialGroup
205 .addGap(0, 0, Short.MAX_VALUE)
206 .addGroup(layout.createParallelGroup
207 .addComponent(pairs_label)
208 .addComponent(players_label))
209 .addGroup(layout.createParallelGroup
210 .addComponent(pairs_spinner)
211 .addComponent(players_spinner))
212 .addGap(0, 0, Short.MAX_VALUE))
213 .addGroup(layout.createSequentialGroup
214 .addGap(0, 0, Short.MAX_VALUE)
215 .addComponent(@start))
217 v_group = layout.createSequentialGroup
218 .addGroup(layout.createBaselineGroup(false, true)
219 .addComponent(title)
220 .addComponent(version))
221 .addComponent(link)
222 .addGap(25)
223 .addGroup(layout.createBaselineGroup(false, true)
224 .addComponent(pairs_label)
225 .addComponent(pairs_spinner))
226 .addGroup(layout.createBaselineGroup(false, true)
227 .addComponent(players_label)
228 .addComponent(players_spinner))
229 .addGap(15)
230 .addComponent(@start)
232 layout.setHorizontalGroup h_group
233 layout.setVerticalGroup v_group
235 conf
236 end
237 end
239 class HyperlinkLabel < JLabel
241 def initialize(uri:String)
242 initialize URI.new(uri), uri
243 end
245 def initialize(uri:URI)
246 initialize uri, uri.toString
247 end
249 def initialize(uri:URI, text:String)
250 @uri = uri
252 s = text.replace('&', '&amp;')
253 .replace('<', '&lt;')
254 .replace('>', '&gt;')
256 setText "<html><u>#{s}</u></html>"
257 setForeground Color.BLUE.darker
258 setCursor Cursor.new(Cursor.HAND_CURSOR)
260 enableEvents AWTEvent.MOUSE_EVENT_MASK
261 end
263 def processMouseEvent(event)
264 if event.getID == MouseEvent.MOUSE_CLICKED
265 Desktop.getDesktop.browse @uri
266 end
268 super
269 end
270 end
272 class Applet < JApplet
273 def initialize
274 getContentPane.add Ui.new(getRootPane)
275 end
276 end
278 create_frame