Class: Rubydraw::Window

Inherits:
Object show all
Defined in:
lib/rubydraw/window.rb

Overview

Instances of Rubydraw::Window can draw themselves on the screen after you open them. Note: there can only be one window on the screen at a time; it is a limit of SDL. One important things about instances of Rubydraw::Window: its main loop (which starts when Rubydraw::Window#open is called) is not forked! It will break when Rubydraw::Window#close is called.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(dimensions, flags = [], bkg_color = Color::Black, persistent = false) ⇒ Window

Create a new window.



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/rubydraw/window.rb', line 11

def initialize(dimensions, flags=[], bkg_color=Color::Black, persistent=false)
  width, height = dimensions.to_ary
  @fullscreen, @persistent = flags.include?(Rubydraw::Flags::Fullscreen), persistent
  if width < 0
    raise SDLError, "New window width cannot be less than zero"
  end
  if height < 0
    raise SDLError, "New window height cannot be less than zero"
  end
  unless flags.include?(Flags::Fullscreen)
    if height == 0
      # Compensate for the height of the window bar itself, the menu bar at the top
      # of the screen, and a space of around 4px at the bottom of the screen. Not
      # sure what the numbers would be for anything other than Mac OSX; more info
      # would be appreciated.
      height = Rubydraw::screen_height - 48
    end
  end
  @width, @height, @flags, @bkg_color = width, height, Flags.collapse(flags), bkg_color
  @open = false

  @event_queue = EventQueue.new

  @registered_actions = {}
end

Instance Attribute Details

#bkg_colorObject

Returns the value of attribute bkg_color.



8
9
10
# File 'lib/rubydraw/window.rb', line 8

def bkg_color
  @bkg_color
end

Instance Method Details

#clearObject

Clear the window’s contents by filling it with black. A bit of a cheat; I don’t know if there is a better way to do this.



89
90
91
# File 'lib/rubydraw/window.rb', line 89

def clear
  fill_with(@bkg_color)
end

#closeObject Also known as: quit

Call this method to tell SDL to quit drawing. The loop (started in Rubydraw::Window#open) would continue if close only stopped drawing, so break the loop too.



111
112
113
114
# File 'lib/rubydraw/window.rb', line 111

def close
  break_main_loop
  SDL.QuitSubSystem(SDL::INIT_VIDEO)
end

#convert(color) ⇒ Object

Convert color to the display format.



100
101
102
103
104
105
106
# File 'lib/rubydraw/window.rb', line 100

def convert(color)
  if @fullscreen
    return color.to_i(:display_fullscreen)
  else
    return color.to_i(:display)
  end
end

#draw_circle(center, radius, color, mode = :fill) ⇒ Object

Draw a circle.



250
251
252
# File 'lib/rubydraw/window.rb', line 250

def draw_circle(center, radius, color, mode=:fill)
  draw_ellipse(center, Point[radius, radius], color, mode)
end

#draw_ellipse(center, dimensions, color, mode = :fill) ⇒ Object

Draw an ellipse. Similar to Rubydraw::Window#draw_circle, except not all ellipses are circles.

center:         The center of the ellipse, should be a Rubydraw::Point object.
dimensions:     Determines the width and the height of the ellipse to be drawn; should be a Rubydraw::Point.
color:          The color to use when drawing; should be an instance of Rubydraw::Color.
mode:           Can be one of three modes; +:fill+, +:outline+, or +:aa+. When set to +:fill+, it will draw a *solid* ellipse. When it is +:outline+, it renders without filling. When set to +:aa+ (anti-aliasing), it will draw without filling and smooth the border.

Raises:

  • (ArgumentError)


226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
# File 'lib/rubydraw/window.rb', line 226

def draw_ellipse(center, dimensions, color, mode=:fill)
  x, y = center.to_a
  width, height = (dimensions / 2).to_a
  r, g, b, a = color.to_a
  args = [@screen, x, y, width, height, r, g, b, a]

  if mode == :fill
    SDL::Gfx.filledEllipseRGBA(*args)
    return self
  end
  if mode == :outline
    SDL::Gfx.ellipseRGBA(*args)
    return self
  end
  if mode == :aa
    SDL::Gfx.aaellipseRGBA(*args)
    return self
  end

  # Only reaches this when +mode+ is not recognized.
  raise ArgumentError, "Unknown mode '#{mode}'"
end

#draw_line(start, finish, color, anti_aliasing = true) ⇒ Object

Draw a line from start to finish. Both should be an instance of Rubydraw::Point.

start:   The point on one side of the line.
finish:  The point on the other end of the line.
color:   An instance of Rubydraw::Color; defines the color of the line.
mode:    Should be either +:aa+ or +:default+. When +:aa+, anti-aliasing is enabled, otherwise, it's not.


187
188
189
190
191
192
193
194
195
196
197
# File 'lib/rubydraw/window.rb', line 187

def draw_line(start, finish, color, anti_aliasing=true)
  r, g, b, a = color.to_a
  args = [@screen, start.x, start.y, finish.x, finish.y, r, g, b, a]
  if not anti_aliasing
    SDL::Gfx.lineRGBA(*args)
  end
  if anti_aliasing
    SDL::Gfx.aalineRGBA(*args)
  end
  self
end

#draw_rectangle(area, color, fill = true) ⇒ Object Also known as: draw_rect

Draw a rectangle over area.

area:   The area which the new rectangle will cover. Should be an instance of Rubydraw::Rectangle.
color:  Specifies what color to use when drawing the rectangle. If +fill+ is enabled, it will fill the new rect with this color. If not, it will only affect the border.
fill:   A boolean determining whether to fill it in or not. (anti-aliasing is not needed because all the lines are perfectly straigt)


204
205
206
207
208
209
210
211
212
213
214
215
216
# File 'lib/rubydraw/window.rb', line 204

def draw_rectangle(area, color, fill=true)
  tl = area.top_left
  br = area.bottom_right
  r, g, b, a = color.to_a
  args = [@screen, tl.x, tl.y, br.x, br.y, r, g, b, a]
  if fill
    SDL::Gfx.boxRGBA(*args)
  end
  if not fill
    SDL::Gfx.rectangleRGBA(*args)
  end
  self
end

#fill_with(color) ⇒ Object

Fill the entire window with a Rubydraw::Color. Do this by feeding SDL the numeric verion of the color; see Rubydraw::Color#to_i



95
96
97
# File 'lib/rubydraw/window.rb', line 95

def fill_with(color)
  SDL::FillRect(@screen, nil, convert(color))
end

#handle_eventsObject

Collect and handle new events by executing blocks in @regestered_events. See Object#whenever on how to use it.



135
136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/rubydraw/window.rb', line 135

def handle_events
  events = @event_queue.get_events
  events.each {|event|
    # +blocks+ is a hashmap; the value being the object that registered it. This
    # property is only used in Object#unregister_action.
    events = @registered_actions
    blocks = events[event.class]
    unless blocks.nil?
      blocks.each {|obj, b|
        b.call(event) unless b.nil?
      }
    end
  }
end

#heightObject



49
50
51
52
53
54
55
56
57
58
59
# File 'lib/rubydraw/window.rb', line 49

def height
  begin
    return @screen.h
  rescue NameError
    if @height == 0
      return Rubydraw.screen_height
    else
      return @height
    end
  end
end

#icon=(new) ⇒ Object

Sets the window’s icon to new.



129
130
131
# File 'lib/rubydraw/window.rb', line 129

def icon=(new)
  SDL.WM_SetIcon(new.to_sdl, nil)
end

#open?Boolean

Returns if this window is open.

Returns:

  • (Boolean)


158
159
160
# File 'lib/rubydraw/window.rb', line 158

def open?
  @open
end

#registered_actionsObject



177
178
179
# File 'lib/rubydraw/window.rb', line 177

def registered_actions
  @registered_actions
end

#sdl_surfaceObject Also known as: to_sdl

Return the SDL surface object. Only used in Rubydraw::Image#draw for blitting to this window.



164
165
166
# File 'lib/rubydraw/window.rb', line 164

def sdl_surface
  @screen
end

#showObject

Call this method to start updating and drawing.



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/rubydraw/window.rb', line 66

def show
  @open = true
  # Behold, the main loop. Drumroll!
  @screen = SDL::SetVideoMode(@width, @height, 0, @flags)
  loop do
    handle_events
    if @open
      unless @persistent
        # Clear the contents of the window
        clear
      end
      tick
      # Update the screen to show any changes.
      SDL::UpdateRect(@screen, 0, 0, 0, 0)
    else
      # This is where the loop is broken after Rubydraw::Window#close is called.
      break
    end
  end
end

#sizeObject



61
62
63
# File 'lib/rubydraw/window.rb', line 61

def size
  Point[width, height]
end

#tickObject

Redefine Rubydraw::Window#tick with any code you want to be executed every frame, like drawing functions.

Does nothing by default.



174
175
# File 'lib/rubydraw/window.rb', line 174

def tick
end

#titleObject

Returns the window’s current title.



119
120
121
# File 'lib/rubydraw/window.rb', line 119

def title
  SDL.WM_GetCaption
end

#title=(new) ⇒ Object

Sets the window title to new.



124
125
126
# File 'lib/rubydraw/window.rb', line 124

def title=(new)
  SDL.WM_SetCaption(new, new)
end

#widthObject



37
38
39
40
41
42
43
44
45
46
47
# File 'lib/rubydraw/window.rb', line 37

def width
  begin
    return @screen.w
  rescue NameError
    if @width == 0
      return Rubydraw.screen_width
    else
      return @width
    end
  end
end