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

View File

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

View File

@@ -54,6 +54,8 @@ module Tailor
Wx::ID_ANY, Wx::ID_ANY,
"Tileset Name") "Tileset Name")
tmpversizer.add(@tilesetNameCtrl, 0, flag = Wx::EXPAND|Wx::ALIGN_TOP) tmpversizer.add(@tilesetNameCtrl, 0, flag = Wx::EXPAND|Wx::ALIGN_TOP)
evt_text(@tilesetNameCtrl) { |event| on_tilesetNameChanged(event) }
@tileNameCtrl = Wx::TextCtrl.new(@panel, @tileNameCtrl = Wx::TextCtrl.new(@panel,
Wx::ID_ANY, Wx::ID_ANY,
"Tile Name") "Tile Name")
@@ -66,6 +68,7 @@ module Tailor
Wx::DEFAULT_POSITION, Wx::DEFAULT_POSITION,
Wx::DEFAULT_SIZE, Wx::DEFAULT_SIZE,
Wx::TE_MULTILINE|Wx::TE_WORDWRAP) Wx::TE_MULTILINE|Wx::TE_WORDWRAP)
evt_text(@tilesetNotesCtrl) { |event| on_tilesetNotesChanged(event) }
@tilesetNotesCtrl.set_min_size(Wx::Size.new(200,120)) @tilesetNotesCtrl.set_min_size(Wx::Size.new(200,120))
tmpversizer.add(@tilesetNotesCtrl, 1, flag = Wx::EXPAND|Wx::ALL) tmpversizer.add(@tilesetNotesCtrl, 1, flag = Wx::EXPAND|Wx::ALL)
@tilesetLicenseCtrl = Wx::TextCtrl.new(@panel, @tilesetLicenseCtrl = Wx::TextCtrl.new(@panel,
@@ -74,6 +77,7 @@ module Tailor
Wx::DEFAULT_POSITION, Wx::DEFAULT_POSITION,
Wx::DEFAULT_SIZE, Wx::DEFAULT_SIZE,
Wx::TE_MULTILINE|Wx::TE_WORDWRAP) Wx::TE_MULTILINE|Wx::TE_WORDWRAP)
evt_text(@tilesetLicenseCtrl) { |event| on_tilesetLicenseChanged(event) }
@tilesetLicenseCtrl.set_min_size(Wx::Size.new(200,120)) @tilesetLicenseCtrl.set_min_size(Wx::Size.new(200,120))
tmpversizer.add(@tilesetLicenseCtrl, 1, flag = Wx::EXPAND|Wx::ALL) tmpversizer.add(@tilesetLicenseCtrl, 1, flag = Wx::EXPAND|Wx::ALL)
@@ -92,6 +96,8 @@ module Tailor
def on_ImportClicked(event) def on_ImportClicked(event)
@tileset = Tailor::Tileset.new @tileset = Tailor::Tileset.new
@tilesetSlicer.tileset = @tileset
@tilesetProperties.set_tileset(@tileset)
wildcards = "*.png;*.bmp;*.tiff;*.gif" wildcards = "*.png;*.bmp;*.tiff;*.gif"
fd = Wx::FileDialog.new(self, "Select tileset to import", fd = Wx::FileDialog.new(self, "Select tileset to import",
:wildcard => wildcards, :wildcard => wildcards,
@@ -121,7 +127,7 @@ module Tailor
self, self,
style = Wx::PD_CAN_ABORT | Wx::PD_SMOOTH | Wx::PD_AUTO_HIDE) style = Wx::PD_CAN_ABORT | Wx::PD_SMOOTH | Wx::PD_AUTO_HIDE)
dirname = dirfinder.get_path dirname = dirfinder.get_path
tiles = @tilesetSlicer.get_tiles tiles = @tilesetSlicer.get_tile_bitmaps
(0..(tiles.size-1)).each do |i| (0..(tiles.size-1)).each do |i|
tile = tiles[i] tile = tiles[i]
tileName = @tilesetNames[i] tileName = @tilesetNames[i]
@@ -148,23 +154,13 @@ module Tailor
:wildcard => wildcards) :wildcard => wildcards)
if fd.show_modal == Wx::ID_OK if fd.show_modal == Wx::ID_OK
filename = fd.get_path 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...", progdialog = Wx::ProgressDialog.new("Saving...",
"Saving...", "Saving...",
@tilesetSlicer.get_size - 1, @tilesetSlicer.get_size - 1,
self, self,
style = Wx::PD_SMOOTH | Wx::PD_AUTO_HIDE) style = Wx::PD_SMOOTH | Wx::PD_AUTO_HIDE)
tiles = @tilesetSlicer.get_tiles tiles = @tilesetSlicer.get_tile_bitmaps
(0..(tiles.size-1)).each do |i| (0..(tiles.size-1)).each do |i|
@tileset.add_tile(@tilesetNames[i], tiles[i]) @tileset.add_tile(@tilesetNames[i], tiles[i])
end end
@@ -191,23 +187,28 @@ module Tailor
@tileNameCtrl.set_value("") @tileNameCtrl.set_value("")
end end
puts "Tileset properties changed : #{event.inspect} #{event.client_data}" @tilesetSlicer.refresh_grid
@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']
)
end 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) def on_tileNameChanged(event)
@tilesetNames[@tilesetSlicer.get_selected_index] = @tileNameCtrl.get_value @tilesetNames[@tilesetSlicer.get_selected_index] = @tileNameCtrl.get_value
end end
def refresh_image def refresh_image
begin begin
@tilesetImage = Wx::Bitmap.new(@tilesetFilename) @tilesetImage = Wx::Image.new(@tilesetFilename)
if @tilesetImage.is_ok if @tilesetImage.is_ok
@tilesetSlicer.set_image @tilesetImage @tilesetSlicer.set_image @tilesetImage
# The + 20 here is a hack to make scroll bars go away where we don't want them # 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, nil,
"evt_tileprops_changed", "evt_tileprops_changed",
1) 1)
def initialize(source, grid) def initialize(source)
super(EVT_TILEPROPS_CHANGED) super(EVT_TILEPROPS_CHANGED)
self.id = source.get_id self.id = source.get_id
self.client_data = grid
end end
end end
@@ -21,11 +20,23 @@ module Tailor
self.class.send( :define_method, name, &block ) self.class.send( :define_method, name, &block )
end 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) def initialize(*args)
super(*args) super(*args)
@tileset = nil
values = { values = {
"Tile X" => 32, "Tile X" => 0,
"Tile Y" => 32, "Tile Y" => 0,
"Pad X" => 0, "Pad X" => 0,
"Pad Y" => 0, "Pad Y" => 0,
"Space X" => 0, "Space X" => 0,
@@ -46,9 +57,13 @@ module Tailor
evt_text_enter(elemCtrl) { |event| on_textChanged(event) } evt_text_enter(elemCtrl) { |event| on_textChanged(event) }
tmpsizer.add(elemCtrl, flag = Wx::EXPAND|Wx::ALIGN_RIGHT) tmpsizer.add(elemCtrl, flag = Wx::EXPAND|Wx::ALIGN_RIGHT)
rubyname = elem.gsub(/ /, '') rubyname = elem.gsub(/ /, '_').downcase
create_method( "@#{rubyname}=".to_sym ) { |val| create_method( "#{rubyname}=".to_sym ) { |val|
elemCtrl.set_value(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 ) { create_method( "#{rubyname}".to_sym ) {
elemCtrl.get_value.to_i elemCtrl.get_value.to_i
@@ -59,13 +74,15 @@ module Tailor
end end
def on_textChanged(event) def on_textChanged(event)
grid = { 'gridX' => self.TileX, return if @tileset.nil?
'gridY' => self.TileY, @tileset.tile_x = self.tile_x
'pitchX' => self.SpaceX, @tileset.tile_y = self.tile_y
'pitchY' => self.SpaceY, @tileset.space_x = self.space_x
'padX' => self.PadX, @tileset.space_y = self.space_y
'padY' => self.PadY } @tileset.pad_x = self.pad_x
evt = TilesetPropertiesChangedEvent.new(self, grid) @tileset.pad_y = self.pad_y
evt = TilesetPropertiesChangedEvent.new(self)
event_handler.process_event(evt) event_handler.process_event(evt)
end end
end end

View File

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