gglib 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,206 @@
1
+ module GGLib
2
+
3
+ #The Widget class is an interface between the button class and the window class which allows for user interaction with an area of the screen. This area is referred to as the widget.
4
+ #To make a Widget, simply create a class derived from Widget and override methods as needed:
5
+ #
6
+ # class MyWidget < Widget #all widgets are subclasses of Widget
7
+ # attr_reader :text,:font #most widgets will have text and font attributes
8
+ # def initialize(window,text)
9
+ # super(window,Button::Image,0,400,640,480,"img/gui/mywidget image.png",name="My Widget") #use super to initialize the button
10
+ # @text=text; @font=Gosu::Font.new(window, "arial", 50) #initialize widget specific variables
11
+ # end
12
+ # def draw #the window will call draw every time it executes GameWindow::draw
13
+ # font.draw(text,0,0) #you do not have to draw the image here, Button class does that for you
14
+ # if clicked? #here you do widget specific things like drawing text,
15
+ # setImage(Gosu::Image.new) #changing the picture on mouse over or click, etc
16
+ # end
17
+ # end
18
+ # def onDelete #onDelete is called when the window wants to delete the widget
19
+ # puts "deleted" #execute widget specific code here
20
+ # end #or leave the function alone if there is no widget specific code
21
+ # end
22
+ #
23
+ #See the `Widget Programmer's Handbook` for more info.
24
+
25
+ class Widget < Tile
26
+ attr_reader :window, :name, :sleeping, :defimage, :buttonId, :id, :zfocus
27
+ attr_accessor :theme
28
+ def initialize(name="unnamed",x1=0,y1=0,x2=1,y2=1,theme=Theme::BlankTheme,acceptsticky=true,z=0) #do not modify
29
+ super(x1,y1,x2,y2)
30
+ @id=$window.newWidget(self)
31
+ @theme=theme.newInstance(self)
32
+ @name=name
33
+ @sleeping=false
34
+ @zfocus=z
35
+ @acceptstickyfocus=acceptsticky
36
+ onInitialize
37
+ end
38
+ def hasFocus? #do not modify
39
+ if $window.hasFocus == self
40
+ return true
41
+ else
42
+ return false
43
+ end
44
+ end
45
+ def hasStickyFocus? #do not modify
46
+ if $window.hasStickyFocus == self
47
+ return true
48
+ else
49
+ return false
50
+ end
51
+ end
52
+ def focus #do not modify
53
+ #debugger
54
+ $window.setFocus(@id)
55
+ onMouseOver #focus is triggered by the onMouseOver event, so when the window gives a widget focus, it must preform the mouseover event
56
+ end
57
+ def blur #do not modify
58
+ onMouseOut #blur is triggered by the onMouseOut event, so when the window blurs a widget, it must preform the mouseout event
59
+ end
60
+
61
+ def over?(x,y)
62
+ return iTile(x,y)
63
+ end
64
+ def clicked?(x,y)
65
+ if $window.button_down?(Gosu::Button::MsLeft)
66
+ return xTile(x,y)
67
+ else
68
+ return false
69
+ end
70
+ end
71
+
72
+ def event(type) #do not modify
73
+ if type==WidgetEvent::MsLeft
74
+ if @acceptstickyfocus
75
+ stickFocus
76
+ end
77
+ onClick
78
+ elsif type==WidgetEvent::MsRight
79
+ onRightClick
80
+ else
81
+ onKeyPress(type)
82
+ end
83
+ end
84
+
85
+ def feedText(char)
86
+ end
87
+ def onClick
88
+ end
89
+ def onRightClick
90
+ end
91
+ def onDrag(x1, y1, x2, y2)
92
+ end
93
+ def onRightDrag(x1, y1, x2, y2)
94
+ end
95
+ def onMouseOver
96
+ end
97
+ def onStickyFocus
98
+ end
99
+ def onMouseOut
100
+ end
101
+ def onStickyBlur
102
+ end
103
+ def onInitialize
104
+ end
105
+ def onDelete
106
+ end
107
+ def onKeyPress(key)
108
+ end
109
+
110
+ def stickFocus
111
+ $window.setStickyFocus(self)
112
+ end
113
+ def unstickFocus
114
+ $window.setStickyFocus(nil)
115
+ end
116
+
117
+ def intDraw
118
+ if not @sleeping
119
+ @theme.draw
120
+ draw
121
+ end
122
+ end
123
+
124
+ def draw
125
+ end
126
+
127
+ def sleep
128
+ if not @sleeping
129
+ if hasStickyFocus?
130
+ $window.setStickyFocus(nil)
131
+ end
132
+ @theme.setSleepState
133
+ @sleeping=true
134
+ end
135
+ end
136
+ def sleeping?
137
+ return @sleeping
138
+ end
139
+ def wakeUp
140
+ if @sleeping
141
+ @theme.setWakeState
142
+ @sleeping=false
143
+ end
144
+ end
145
+
146
+ def button
147
+ return Button.getButton(buttonId)
148
+ end
149
+
150
+ def del
151
+ onDelete
152
+ if $window.nil?
153
+ raise "Window assigned to nil" #Very strange bug. Should be dead by now. (This is just in case.)
154
+ return
155
+ end
156
+ $window.deleteWidget(self)
157
+ super
158
+ end
159
+ end
160
+
161
+ class WidgetEvent
162
+ MsLeft=0
163
+ MsRight=1
164
+ KeyUp=2
165
+ KeyDown=3
166
+ KeyLeft=4
167
+ KeyRight=5
168
+ KeyEscape=6
169
+ KeyEnter=7
170
+ KeyAlt=8
171
+ KeyControl=9
172
+ KeyShift=10
173
+ KeySpace=11
174
+ GpEnter=12
175
+ GpCancel=13
176
+ KeyText=14
177
+ KeyDelete=15
178
+ MsLeftDrag=16
179
+ MsRightDrag=17
180
+ end
181
+
182
+ WidgetTextCaps = {
183
+ ","=>"<",
184
+ "."=>">",
185
+ "/"=>"?",
186
+ "'"=>"\"",
187
+ ";"=>":",
188
+ "["=>"{",
189
+ "]"=>"}",
190
+ "\\"=>"|",
191
+ "="=>"+",
192
+ "-"=>"_",
193
+ "0"=>")",
194
+ "9"=>"(",
195
+ "8"=>"*",
196
+ "7"=>"&",
197
+ "6"=>"^",
198
+ "5"=>"%",
199
+ "4"=>"$",
200
+ "3"=>"#",
201
+ "2"=>"@",
202
+ "1"=>"!",
203
+ "`"=>"~"
204
+ }
205
+
206
+ end #module GGLib
@@ -0,0 +1,324 @@
1
+ module GGLib
2
+
3
+ #The GUIWindow class is the central hub of the program. It is utimately responsible for all input and output (exept for logging output).
4
+ #The main game loops can be found in this class.
5
+ class GUIWindow < Gosu::Window
6
+ attr_accessor :cursor, :background_image, :camera, :state
7
+ attr_reader :images, :mapimages
8
+
9
+ BlankState = StateObject.new
10
+
11
+ def initialize(w=640, h=480, fullscreen=true, u=20, stateObj=BlankState)
12
+ super(w, h, fullscreen, u)
13
+ $window=self #pre initialize global var to allow win initialization
14
+ @background_image = Gosu::Image.new(self, File.expand_path(File.dirname(__FILE__))+"/null.png", true)
15
+ @cursor = Cursor.new(File.expand_path(File.dirname(__FILE__))+"/media/cursor.bmp", false)
16
+ @framedrawn=false
17
+ @timer=0
18
+ @camera=Camera.new
19
+ @images = CArray.new
20
+ @mapimages = CArray.new
21
+ @guiWidgets = CArray.new
22
+ @state=stateObj
23
+ @focused=nil
24
+ @stickfocused=nil
25
+ @leftdrag = MouseDragEvent.new
26
+ @rightdrag = MouseDragEvent.new
27
+ @state.start
28
+ $window=self
29
+ $theme_init_hook.call
30
+ end
31
+
32
+ def state=(val)
33
+ @state.end
34
+ @state = val
35
+ @state.start
36
+ end
37
+
38
+ def widgets
39
+ return @widgets
40
+ end
41
+
42
+ def framedrawn
43
+ return @framedrawn
44
+ end
45
+
46
+ def button_down(id)
47
+ @state.button_down(id)
48
+ checkFocus
49
+ widgetDownProc(id)
50
+ end
51
+
52
+ def button_up(id)
53
+ @state.button_up(id)
54
+ checkFocus
55
+ widgetUpProc(id)
56
+ end
57
+
58
+ def timer
59
+ return @timer
60
+ end
61
+
62
+ def widgets
63
+ return @guiWidgets
64
+ end
65
+
66
+ def newImage(x,y,z,src,hardBorders=true,tracer="None")
67
+ img=Image.new(x,y,z,src,hardBorders,tracer,@images.size)
68
+ return @images << img
69
+ end
70
+
71
+ def newTexture(x1,y1,x2,y2,z,src,hardBorders=true,tracer="None")
72
+ img=Texture.new(x1,y1,x2,y2,z,src,hardBorders,tracer,@images.size)
73
+ return @images << img
74
+ end
75
+
76
+ def setImage(index,x,y,z,src,hardBorders=true,tracer="None")
77
+ img=Image.new(x,y,z,src,@images.size,hardBorders,tracer)
78
+ @images[index]=img
79
+ return index
80
+ end
81
+
82
+ def setTexture(index, x1,y1,x2,y2,z,src,hardBorders=true,tracer="None")
83
+ img=Texture.new(x1,y1,x2,y2,z,src,hardBorders,tracer,@images.size)
84
+ @images[index]=img
85
+ return index
86
+ end
87
+
88
+ def deleteImage(no)
89
+ if @images[no]!=nil
90
+ @images[no].del
91
+ end
92
+ @images.delete_at(no)
93
+ end
94
+
95
+ def deleteAllImages
96
+ @images.clear
97
+ end
98
+
99
+ def setBackground(src)
100
+ @background_image = Gosu::Image.new(self,src,true)
101
+ end
102
+
103
+ def setMapBackground(src)
104
+ @map_image = Gosu::Image.new(self,src,true)
105
+ end
106
+
107
+ def newMapImage(x,y,z,src,hardBorders=true,tracer="None")
108
+ img=Image.new(x,y,z,src,hardBorders,tracer,@mapimages.size)
109
+ return @mapimages << img
110
+ end
111
+
112
+ def deleteMapImage(no)
113
+ if @mapimages[no]!=nil
114
+ @mapimages[no].del
115
+ end
116
+ @mapimages.delete_at(no)
117
+ end
118
+
119
+ def deleteAllMapImages
120
+ @mapimages.clear
121
+ end
122
+
123
+ def newWidget(widget)
124
+ return @guiWidgets << widget
125
+ end
126
+
127
+ def deleteWidget(widget)
128
+ id=widget.id
129
+ @guiWidgets.delete_at(id)
130
+ end
131
+
132
+ def deleteAllWidgets
133
+ @guiWidgets.each {|widget| widget.del}
134
+ @guiWidgets.clear
135
+ @focused=nil
136
+ @stickfocused=nil
137
+ self.text_input=nil
138
+ end
139
+
140
+ def createWidgets
141
+ self.text_input=nil
142
+ @focused=nil
143
+ @stickfocused=nil
144
+ end
145
+
146
+ def setTextInput(field)
147
+ self.text_input=field
148
+ end
149
+
150
+ def setFocus(object)
151
+ if @focused!=nil and not @focused.sleeping? #dont blur the object if it is the window or if it is sleeping
152
+ @focused.blur
153
+ end
154
+ if object==nil
155
+ @focused=nil
156
+ else
157
+ @focused=@guiWidgets[object]
158
+ end
159
+ end
160
+
161
+ def setStickyFocus(object)
162
+ if @stickfocused!=nil
163
+ @stickfocused.onStickyBlur
164
+ end
165
+ @stickfocused=object
166
+ if @stickfocused!=nil
167
+ @stickfocused.onStickyFocus
168
+ end
169
+ end
170
+
171
+ def hasFocus
172
+ return @focused
173
+ end
174
+
175
+ def hasStickyFocus
176
+ return @stickfocused
177
+ end
178
+
179
+ def update
180
+ checkFocus
181
+
182
+ if @leftdrag.starting
183
+ if(Gosu::distance(@leftdrag.start_x, @leftdrag.start_y, mouse_x, mouse_y) > 5)
184
+ @leftdrag.confirmStart
185
+ end
186
+ elsif @rightdrag.starting
187
+ if(Gosu::distance(@rightdrag.start_x, @rightdrag.start_y, mouse_x, mouse_y) > 5)
188
+ @rightdrag.confirmStart
189
+ end
190
+ end
191
+
192
+ if @timer>100
193
+ @timer=0
194
+ else
195
+ @timer+=1
196
+ end
197
+
198
+ @state.update
199
+ @framedrawn = false
200
+ end
201
+
202
+ def draw
203
+ @cursor.draw
204
+ @images.each {|img| img.draw}
205
+ @guiWidgets.each {|widget| widget.intDraw}
206
+ @background_image.draw(0, 0, ZOrder::Background)
207
+ @state.draw
208
+ @framedrawn=true
209
+ end
210
+
211
+ private
212
+ def widgetDownProc(id)
213
+ char=button_id_to_char(id)
214
+ setStickyFocus(nil) if (id==Gosu::Button::MsLeft or id==Gosu::Button::MsRight) and @stickfocused!=nil #and not @stickfocused.contains?(mouse_x, mouse_y)
215
+ if @stickfocused!=nil and not @stickfocused.sleeping? #only sticky focused widgets recieve text input
216
+ if id==Gosu::Button::MsLeft
217
+ @leftdrag.start
218
+ elsif id==Gosu::Button::MsRight
219
+ @rightdrag.start
220
+ elsif char!=nil
221
+ if button_down?(Gosu::Button::KbLeftShift) or button_down?(Gosu::Button::KbRightShift)
222
+ if char=~/[A-Z]/i
223
+ char=char.upcase!
224
+ else
225
+ capschar=WidgetTextCaps[char]
226
+ if capschar!=nil
227
+ char=capschar
228
+ end
229
+ end
230
+ end
231
+ @stickfocused.feedText(char)
232
+ end
233
+ end
234
+ end
235
+
236
+ def widgetUpProc(id)
237
+ char=button_id_to_char(id)
238
+ setStickyFocus(nil) if (id==Gosu::Button::MsLeft or id==Gosu::Button::MsRight) and @stickfocused!=nil #and not @stickfocused.contains?(mouse_x, mouse_y)
239
+ if @stickfocused!=nil and not @stickfocused.sleeping? #only sticky focused widgets recieve text input
240
+ if id==Gosu::Button::MsLeft
241
+ if @leftdrag.inprogress
242
+ @leftdrag.end
243
+ @stickfocused.event(WidgetEvent::MsLeftDrag)
244
+ else
245
+ @leftdrag.terminate
246
+ @stickfocused.event(WidgetEvent::MsLeft)
247
+ end
248
+ elsif id==Gosu::Button::MsRight
249
+ if @rightdrag.inprogress
250
+ @rightdrag.end
251
+ @stickfocused.event(WidgetEvent::MsRightDrag)
252
+ else
253
+ @rightdrag.terminate
254
+ @stickfocused.event(WidgetEvent::MsRight)
255
+ end
256
+ elsif id==Gosu::Button::KbUp or id==Gosu::Button::GpUp
257
+ @stickfocused.event(WidgetEvent::KeyUp)
258
+ elsif id==Gosu::Button::KbDown or id==Gosu::Button::GpDown
259
+ @stickfocused.event(WidgetEvent::KeyDown)
260
+ elsif id==Gosu::Button::KbLeft or id==Gosu::Button::GpLeft
261
+ @stickfocused.event(WidgetEvent::KeyLeft)
262
+ elsif id==Gosu::Button::KbRight or id==Gosu::Button::GpRight
263
+ @stickfocused.event(WidgetEvent::KeyRight)
264
+ elsif id==Gosu::Button::KbRight or id==Gosu::Button::GpRight
265
+ @stickfocused.event(WidgetEvent::KeyRight)
266
+ elsif id==Gosu::Button::KbBackspace or id==Gosu::Button::KbDelete
267
+ @stickfocused.event(WidgetEvent::KeyDelete)
268
+ elsif id==Gosu::Button::KbEscape or id==Gosu::Button::GpButton7
269
+ @stickfocused.event(WidgetEvent::KeyEscape)
270
+ elsif id==Gosu::Button::KbEnter or id==Gosu::Button::GpButton2 or id==28 #strange Gosu bug, KbEnter!=Enter code
271
+ @stickfocused.event(WidgetEvent::KeyEnter)
272
+ elsif id==Gosu::Button::KbLeftAlt or id==Gosu::Button::KbRightAlt or id==Gosu::Button::GpButton5
273
+ @stickfocused.event(WidgetEvent::KeyAlt)
274
+ elsif id==Gosu::Button::KbLeftControl or id==Gosu::Button::KbRightControl or id==Gosu::Button::GpButton3
275
+ @stickfocused.event(WidgetEvent::KeyControl)
276
+ elsif id==Gosu::Button::KbLeftShift or id==Gosu::Button::KbRightShift or id==Gosu::Button::GpButton6
277
+ @stickfocused.event(WidgetEvent::KeyShift)
278
+ elsif id==Gosu::Button::KbSpace or id==Gosu::Button::KbSpace or id==Gosu::Button::GpButton4
279
+ @stickfocused.event(WidgetEvent::KeySpace)
280
+ elsif id==Gosu::Button::GpButton0
281
+ @stickfocused.event(WidgetEvent::GpEnter)
282
+ elsif id==Gosu::Button::GpButton1
283
+ @stickfocused.event(WidgetEvent::GpCancel)
284
+ end
285
+ end
286
+ if @focused!=nil and not @focused.sleeping? and (@stickfocused==nil or @focused.id != @stickfocused.id) #normally focused widgets only recieve click input
287
+ if id==Gosu::Button::MsLeft
288
+ @focused.event(WidgetEvent::MsLeft)
289
+ elsif id==Gosu::Button::MsRight
290
+ @focused.event(WidgetEvent::MsRight)
291
+ elsif id==Gosu::Button::GpButton0
292
+ @focused.event(WidgetEvent::GpEnter)
293
+ end
294
+ end
295
+ end
296
+
297
+ def checkFocus
298
+ if @focused==nil
299
+ oldfocus=nil
300
+ else
301
+ oldfocus=@focused.id
302
+ end
303
+ newfocus=nil
304
+ focusFlag=false
305
+ @guiWidgets.each { |widget|
306
+ if (@cursor.visible and widget.over?(mouse_x,mouse_y)) and not widget.sleeping?
307
+ if not focusFlag
308
+ newfocus=widget.id
309
+ focusFlag=true
310
+ elsif widget.zfocus >= @guiWidgets[newfocus].zfocus #give focus to the widget with the highest focus zorder, or in the event of a tie, give focus to the new object
311
+ newfocus=widget.id
312
+ end
313
+ else
314
+ end
315
+ }
316
+ if newfocus!=nil and newfocus!=oldfocus
317
+ @guiWidgets[newfocus].focus
318
+ elsif newfocus==nil and oldfocus!=nil
319
+ setFocus(nil)
320
+ end
321
+ end
322
+ end
323
+
324
+ end #module GGLib