view src/net/kryshen/charamega/ui.mirah @ 1:fac1b8f35265

Applet.
author Mikhail Kryshen <mikhail@kryshen.net>
date Sat, 14 Jul 2012 06:32:31 +0400
parents 91ecd24948de
children 1e64a109812f
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(20)
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 .setSize(800, 600)
103 .validate
104 .setVisible(true)
105 end
106 end
108 private
110 def create_status
111 ui = self
113 status_panel = JPanel.new
114 layout = GroupLayout.new(status_panel)
115 status_panel.setLayout layout
117 @status = JLabel.new('', SwingConstants.RIGHT)
118 @stop = JButton.new('New game')
119 @stop.addActionListener do |e|
120 ui.update_status
121 ui.stop
122 end
124 gap = 5
126 h_group = layout.createSequentialGroup
127 .addGap(1, gap, gap)
128 .addComponent(@stop)
129 .addGap(1, gap, gap)
130 .addComponent(@status,
131 GroupLayout.DEFAULT_SIZE,
132 GroupLayout.DEFAULT_SIZE,
133 Short.MAX_VALUE)
134 .addGap(1, gap, gap)
136 v_group = layout.createSequentialGroup
137 .addGap(1, gap, gap)
138 .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
139 .addComponent(@stop)
140 .addComponent(@status))
141 .addGap(1, gap, gap)
143 layout.setHorizontalGroup h_group
144 layout.setVerticalGroup v_group
146 status_panel
147 end
149 def create_configurator
150 # Can't use object fields in closures in Mirah 0.11.
151 ui = self
152 game = @game
153 field = @field
155 conf = JPanel.new
156 layout = GroupLayout.new(conf)
157 conf.setLayout layout
158 conf.setBorder BorderFactory.createRaisedBevelBorder
160 layout.setAutoCreateGaps true
161 layout.setAutoCreateContainerGaps true
163 title = JLabel.new(@@title)
164 .setFont(Font.new('serif', Font.BOLD, 26))
166 version = JLabel.new("version #{@@version}")
167 link = HyperlinkLabel.new(@@home)
169 players_label = JLabel.new('Players: ')
170 pairs_label = JLabel.new('Pairs: ')
172 players = SpinnerNumberModel.new(1, 1, 20, 1)
173 pairs = SpinnerNumberModel.new(20, 2, 200, 5)
175 players_spinner = JSpinner.new(players)
176 pairs_spinner = JSpinner.new(pairs)
178 players.addChangeListener do |e|
179 game.players = players.getNumber.intValue
180 field.repaint if game.shuffle
181 ui.update_status
182 end
184 pairs.addChangeListener do |e|
185 game.shuffle pairs.getNumber.intValue
186 field.repaint
187 ui.update_status
188 end
190 @start = JButton.new("Start")
191 @start.addActionListener do |e|
192 ui.start
193 end
195 h_group = layout.createParallelGroup
196 .addGroup(layout.createSequentialGroup
197 .addComponent(title)
198 .addComponent(version))
199 .addGroup(layout.createSequentialGroup
200 .addComponent(link,
201 GroupLayout.DEFAULT_SIZE,
202 GroupLayout.DEFAULT_SIZE,
203 GroupLayout.PREFERRED_SIZE)
204 .addGap(0, 0, Short.MAX_VALUE))
205 .addGroup(layout.createSequentialGroup
206 .addGap(0, 0, Short.MAX_VALUE)
207 .addGroup(layout.createParallelGroup
208 .addComponent(pairs_label)
209 .addComponent(players_label))
210 .addGroup(layout.createParallelGroup
211 .addComponent(pairs_spinner)
212 .addComponent(players_spinner))
213 .addGap(0, 0, Short.MAX_VALUE))
214 .addGroup(layout.createSequentialGroup
215 .addGap(0, 0, Short.MAX_VALUE)
216 .addComponent(@start))
218 v_group = layout.createSequentialGroup
219 .addGroup(layout.createBaselineGroup(false, true)
220 .addComponent(title)
221 .addComponent(version))
222 .addComponent(link)
223 .addGap(25)
224 .addGroup(layout.createBaselineGroup(false, true)
225 .addComponent(pairs_label)
226 .addComponent(pairs_spinner))
227 .addGroup(layout.createBaselineGroup(false, true)
228 .addComponent(players_label)
229 .addComponent(players_spinner))
230 .addGap(15)
231 .addComponent(@start)
233 layout.setHorizontalGroup h_group
234 layout.setVerticalGroup v_group
236 conf
237 end
238 end
240 class HyperlinkLabel < JLabel
242 def initialize(uri:String)
243 initialize URI.new(uri), uri
244 end
246 def initialize(uri:URI)
247 initialize uri, uri.toString
248 end
250 def initialize(uri:URI, text:String)
251 @uri = uri
253 s = text.replace('&', '&amp;')
254 .replace('<', '&lt;')
255 .replace('>', '&gt;')
257 setText "<html><u>#{s}</u></html>"
258 setForeground Color.BLUE.darker
259 setCursor Cursor.new(Cursor.HAND_CURSOR)
261 enableEvents AWTEvent.MOUSE_EVENT_MASK
262 end
264 def processMouseEvent(event)
265 if event.getID == MouseEvent.MOUSE_CLICKED
266 Desktop.getDesktop.browse @uri
267 end
269 super
270 end
271 end
273 class Applet < JApplet
274 def initialize
275 getContentPane.add Ui.new(getRootPane)
276 end
277 end
279 create_frame