Midstream on #8 : Made Tailor::Tileset handle all the size/space/pad attributes, simplified the flow of those attribute changes, renamed things from *_image when they actually use Wx::Bitmap

This commit is contained in:
2014-05-24 09:46:29 -07:00
parent 3c192092d6
commit 1b9c873dca
5 changed files with 122 additions and 87 deletions

View File

@@ -5,23 +5,25 @@ module Tailor
# Ganked from http://rubyforscientificresearch.blogspot.com/2009/05/displaying-images-in-wxruby.html
class ImageDisplay < Wx::ScrolledWindow
class BitmapDisplay < Wx::ScrolledWindow
def initialize(*args)
super(*args)
@image = nil
@bitmap = nil
end
def set_image image
@image = image
set_scrollbars(1, 1, @image.width, @image.height)
def set_bitmap bmp
puts "Setting bitmap to #{bmp}"
@bitmap = bmp
set_scrollbars(1, 1, @bitmap.width, @bitmap.height)
refresh
end
def on_draw dc
puts "Drawing #{@bitmap}"
dc.set_background Wx::WHITE_BRUSH
dc.clear
return if @image == nil
dc.draw_bitmap(@image, 0, 0, true)
return if @bitmap == nil
dc.draw_bitmap(@bitmap, 0, 0, true)
end
end
end

View File

@@ -1,5 +1,5 @@
require 'wx'
require 'Tailor/GUI/ImageDisplay'
require 'Tailor/GUI/BitmapDisplay'
module Tailor
module GUI
@@ -19,80 +19,85 @@ module Tailor
end
class GridDisplay < Tailor::GUI::ImageDisplay
class GridDisplay < Tailor::GUI::BitmapDisplay
attr_accessor :tileset
def initialize(*args)
super(*args)
@imageGrid = nil
self.tileset = nil
@bitmapGrid = nil
@darkenCell = nil
@pristineImage = nil
@darken_x = 0
@darken_y = 0
@rectlist = []
@selected = nil
evt_left_up() { |event| on_gridClicked(event) }
end
def set_image(image)
@pristineImage = image
set_grid(0, 0, 0, 0, 32, 32)
self.tileset.image = image
@bitmap = image.convert_to_bitmap
refresh_grid
end
def set_grid(padX, padY, pitchX, pitchY, gridX, gridY)
def refresh_grid
@rectlist = []
@selected = nil
@imageGrid = Wx::Bitmap.new(@pristineImage.get_width(),
@pristineImage.get_height(),
@pristineImage.get_depth()
@bitmapGrid = Wx::Bitmap.new(@bitmap.get_width(),
@bitmap.get_height(),
@bitmap.get_depth()
)
tmpImage = Wx::Image.new(gridX, gridY)
tmpImage = Wx::Image.new(self.tileset.tile_x, self.tileset.tile_y)
tmpImage.init_alpha
(0..gridX).each do |x|
(0..gridY).each do |y|
(0..self.tileset.tile_x).each do |x|
(0..self.tileset.tile_y).each do |y|
tmpImage.set_rgb(x, y, 0, 0, 0)
tmpImage.set_alpha(x, y, 150)
end
end
@darkenCell = tmpImage.to_bitmap
@darken_x = -(gridX)
@darken_y = -(gridY)
@darken_x = -(self.tileset.tile_x)
@darken_y = -(self.tileset.tile_y)
evt_left_up() { |event| on_gridClicked(event) }
@imageGrid.draw() { |dc|
dc.clear
dc.draw_bitmap(@pristineImage, 0, 0, true)
stepx = gridX + pitchX
stepx = self.tileset.tile_x + self.tileset.space_x
stepx = 1 unless stepx != 0
stepy = gridY + pitchY
stepy = self.tileset.tile_y + self.tileset.space_y
stepy = 1 unless stepy != 0
rows = ( (@pristineImage.height - padY) / stepy )
columns = ( (@pristineImage.width - padX) / stepx )
curX = padX
curY = padY
rows = ( (@bitmap.height - self.tileset.pad_y) / stepy )
columns = ( (@bitmap.width - self.tileset.pad_x) / stepx )
curX = self.tileset.pad_x
curY = self.tileset.pad_y
@bitmapGrid.draw() { |dc|
dc.clear
dc.draw_bitmap(@bitmap, 0, 0, true)
dc.set_brush(Wx::TRANSPARENT_BRUSH)
dc.set_pen(Wx::RED_PEN)
for row in 0..rows
for column in 0..columns
next if ((curX + stepx + padX) > @imageGrid.get_width)
next if ((curY + stepy + padY) > @imageGrid.get_height)
dc.draw_rectangle(curX, curY, gridX, gridY)
@rectlist << Wx::Rect.new(curX, curY, gridX, gridY)
next if ((curX + stepx + self.tileset.pad_x) > @bitmapGrid.get_width)
next if ((curY + stepy + self.tileset.pad_y) > @bitmapGrid.get_height)
dc.draw_rectangle(curX, curY, self.tileset.tile_x, self.tileset.tile_y)
@rectlist << Wx::Rect.new(curX, curY, self.tileset.tile_x, self.tileset.tile_y)
curX += stepx
end
curX = padX
curX = self.tileset.pad_x
curY += stepy
end
}
_super.set_image(@imageGrid)
refresh
end
def on_draw(dc)
dc.set_background Wx::WHITE_BRUSH
dc.clear
return if @imageGrid == nil
dc.draw_bitmap(@imageGrid, 0, 0, true)
return if @bitmapGrid == nil
dc.draw_bitmap(@bitmapGrid, 0, 0, true)
return if @darkenCell == nil
dc.draw_bitmap(@darkenCell, @darken_x, @darken_y, true)
end
@@ -113,21 +118,21 @@ module Tailor
@rectlist.length
end
def get_image
@pristineImage
def get_bitmap
@bitmap
end
def get_tiles
def get_tile_bitmaps
ret = []
@rectlist.each do |rect|
img = @pristineImage.sub_bitmap(rect)
img = @bitmap.sub_bitmap(rect)
ret << img
end
ret
end
def get_selected_tile
@pristineImage.get_sub_bitmap(@selected)
@bitmap.get_sub_bitmap(@selected)
end
def get_selected_index

View File

@@ -54,6 +54,8 @@ module Tailor
Wx::ID_ANY,
"Tileset Name")
tmpversizer.add(@tilesetNameCtrl, 0, flag = Wx::EXPAND|Wx::ALIGN_TOP)
evt_text(@tilesetNameCtrl) { |event| on_tilesetNameChanged(event) }
@tileNameCtrl = Wx::TextCtrl.new(@panel,
Wx::ID_ANY,
"Tile Name")
@@ -66,6 +68,7 @@ module Tailor
Wx::DEFAULT_POSITION,
Wx::DEFAULT_SIZE,
Wx::TE_MULTILINE|Wx::TE_WORDWRAP)
evt_text(@tilesetNotesCtrl) { |event| on_tilesetNotesChanged(event) }
@tilesetNotesCtrl.set_min_size(Wx::Size.new(200,120))
tmpversizer.add(@tilesetNotesCtrl, 1, flag = Wx::EXPAND|Wx::ALL)
@tilesetLicenseCtrl = Wx::TextCtrl.new(@panel,
@@ -74,6 +77,7 @@ module Tailor
Wx::DEFAULT_POSITION,
Wx::DEFAULT_SIZE,
Wx::TE_MULTILINE|Wx::TE_WORDWRAP)
evt_text(@tilesetLicenseCtrl) { |event| on_tilesetLicenseChanged(event) }
@tilesetLicenseCtrl.set_min_size(Wx::Size.new(200,120))
tmpversizer.add(@tilesetLicenseCtrl, 1, flag = Wx::EXPAND|Wx::ALL)
@@ -92,6 +96,8 @@ module Tailor
def on_ImportClicked(event)
@tileset = Tailor::Tileset.new
@tilesetSlicer.tileset = @tileset
@tilesetProperties.set_tileset(@tileset)
wildcards = "*.png;*.bmp;*.tiff;*.gif"
fd = Wx::FileDialog.new(self, "Select tileset to import",
:wildcard => wildcards,
@@ -121,7 +127,7 @@ module Tailor
self,
style = Wx::PD_CAN_ABORT | Wx::PD_SMOOTH | Wx::PD_AUTO_HIDE)
dirname = dirfinder.get_path
tiles = @tilesetSlicer.get_tiles
tiles = @tilesetSlicer.get_tile_bitmaps
(0..(tiles.size-1)).each do |i|
tile = tiles[i]
tileName = @tilesetNames[i]
@@ -148,23 +154,13 @@ module Tailor
:wildcard => wildcards)
if fd.show_modal == Wx::ID_OK
filename = fd.get_path
@tileset.tileset_name = @tilesetNameCtrl.get_value
@tileset.license = @tilesetLicenseCtrl.get_value
@tileset.notes = @tilesetNotesCtrl.get_value
@tileset.tile_x = @tilesetProperties.TileX
@tileset.tile_y = @tilesetProperties.TileY
@tileset.space_x = @tilesetProperties.SpaceX
@tileset.space_y = @tilesetProperties.SpaceY
@tileset.pad_x = @tilesetProperties.PadX
@tileset.pad_y = @tilesetProperties.PadY
@tileset.image = @tilesetSlicer.get_image
progdialog = Wx::ProgressDialog.new("Saving...",
"Saving...",
@tilesetSlicer.get_size - 1,
self,
style = Wx::PD_SMOOTH | Wx::PD_AUTO_HIDE)
tiles = @tilesetSlicer.get_tiles
tiles = @tilesetSlicer.get_tile_bitmaps
(0..(tiles.size-1)).each do |i|
@tileset.add_tile(@tilesetNames[i], tiles[i])
end
@@ -191,14 +187,19 @@ module Tailor
@tileNameCtrl.set_value("")
end
puts "Tileset properties changed : #{event.inspect} #{event.client_data}"
@tilesetSlicer.set_grid(event.client_data['padX'],
event.client_data['padY'],
event.client_data['pitchX'],
event.client_data['pitchY'],
event.client_data['gridX'],
event.client_data['gridY']
)
@tilesetSlicer.refresh_grid
end
def on_tilesetNameChanged(event)
@tileset.tileset_name = @tilesetNameCtrl.get_value
end
def on_tilesetLicenseChanged(event)
@tileset.license = @tilesetLicenseCtrl.get_value
end
def on_tilesetNotesChanged(event)
@tileset.notes = @tilesetNotesCtrl.get_value
end
def on_tileNameChanged(event)
@@ -207,7 +208,7 @@ module Tailor
def refresh_image
begin
@tilesetImage = Wx::Bitmap.new(@tilesetFilename)
@tilesetImage = Wx::Image.new(@tilesetFilename)
if @tilesetImage.is_ok
@tilesetSlicer.set_image @tilesetImage
# The + 20 here is a hack to make scroll bars go away where we don't want them

View File

@@ -8,10 +8,9 @@ module Tailor
nil,
"evt_tileprops_changed",
1)
def initialize(source, grid)
def initialize(source)
super(EVT_TILEPROPS_CHANGED)
self.id = source.get_id
self.client_data = grid
end
end
@@ -21,11 +20,23 @@ module Tailor
self.class.send( :define_method, name, &block )
end
def set_tileset(tileset)
@tileset = tileset
self.tile_x = @tileset.tile_x
self.tile_y = @tileset.tile_y
self.pad_x = @tileset.pad_x
self.pad_y = @tileset.pad_y
self.space_x = @tileset.space_x
self.space_y = @tileset.space_y
refresh
end
def initialize(*args)
super(*args)
@tileset = nil
values = {
"Tile X" => 32,
"Tile Y" => 32,
"Tile X" => 0,
"Tile Y" => 0,
"Pad X" => 0,
"Pad Y" => 0,
"Space X" => 0,
@@ -46,9 +57,13 @@ module Tailor
evt_text_enter(elemCtrl) { |event| on_textChanged(event) }
tmpsizer.add(elemCtrl, flag = Wx::EXPAND|Wx::ALIGN_RIGHT)
rubyname = elem.gsub(/ /, '')
create_method( "@#{rubyname}=".to_sym ) { |val|
rubyname = elem.gsub(/ /, '_').downcase
create_method( "#{rubyname}=".to_sym ) { |val|
if val.instance_of?(Integer) or val.instance_of?(Fixnum)
elemCtrl.set_value(val.to_s)
else
elemCtrl.set_value(val)
end
}
create_method( "#{rubyname}".to_sym ) {
elemCtrl.get_value.to_i
@@ -59,13 +74,15 @@ module Tailor
end
def on_textChanged(event)
grid = { 'gridX' => self.TileX,
'gridY' => self.TileY,
'pitchX' => self.SpaceX,
'pitchY' => self.SpaceY,
'padX' => self.PadX,
'padY' => self.PadY }
evt = TilesetPropertiesChangedEvent.new(self, grid)
return if @tileset.nil?
@tileset.tile_x = self.tile_x
@tileset.tile_y = self.tile_y
@tileset.space_x = self.space_x
@tileset.space_y = self.space_y
@tileset.pad_x = self.pad_x
@tileset.pad_y = self.pad_y
evt = TilesetPropertiesChangedEvent.new(self)
event_handler.process_event(evt)
end
end

View File

@@ -21,8 +21,8 @@ module Tailor
self.license = ''
self.notes = ''
self.tileset_name = ''
self.tile_x = 0
self.tile_y = 0
self.tile_x = 32
self.tile_y = 32
self.space_x = 0
self.space_y = 0
self.pad_x = 0
@@ -31,6 +31,12 @@ module Tailor
end
def add_tile(name, image)
if image.instance_of?(Wx::Bitmap)
image = Wx::Image.from_bitmap(image)
elsif not image.instance_of?(Wx::Image)
throw TypeError("Tailor::Tileset::add_tile only accepts Wx::Image or Wx::Bitmap")
return
end
@tiles << {"name" => name, "image" => image}
end
@@ -72,10 +78,14 @@ module Tailor
}
StringIO.open do |iostream|
Wx::Image.from_bitmap(self.image).write(iostream, Wx::BITMAP_TYPE_PNG)
if self.image.nil?
obj['image']=nil
else
self.image.write(iostream, Wx::BITMAP_TYPE_PNG)
iostream.rewind
obj['image'] = Base64.encode64(iostream.read)
end
end
idx = 0
@tiles.each do |tile|
@@ -83,7 +93,7 @@ module Tailor
if not callback.nil?
callback.call("Converting to base64", tile['image'], tile['name'], idx)
end
Wx::Image.from_bitmap(tile['image']).write(iostream, Wx::BITMAP_TYPE_PNG)
tile['image'].write(iostream, Wx::BITMAP_TYPE_PNG)
iostream.rewind
data = {
"name" => tile['name'],