From 1b9c873dca797e850b4dfab79a7a8768ea17f5be Mon Sep 17 00:00:00 2001 From: Andrew Kesterson Date: Sat, 24 May 2014 09:46:29 -0700 Subject: [PATCH] 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 --- .../GUI/{ImageDisplay.rb => BitmapDisplay.rb} | 16 ++-- lib/tailor/GUI/GridDisplay.rb | 83 ++++++++++--------- lib/tailor/GUI/TilesetEditor.rb | 43 +++++----- lib/tailor/GUI/TilesetProperties.rb | 45 ++++++---- lib/tailor/Tileset.rb | 22 +++-- 5 files changed, 122 insertions(+), 87 deletions(-) rename lib/tailor/GUI/{ImageDisplay.rb => BitmapDisplay.rb} (51%) diff --git a/lib/tailor/GUI/ImageDisplay.rb b/lib/tailor/GUI/BitmapDisplay.rb similarity index 51% rename from lib/tailor/GUI/ImageDisplay.rb rename to lib/tailor/GUI/BitmapDisplay.rb index 362d503..35f0066 100644 --- a/lib/tailor/GUI/ImageDisplay.rb +++ b/lib/tailor/GUI/BitmapDisplay.rb @@ -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 diff --git a/lib/tailor/GUI/GridDisplay.rb b/lib/tailor/GUI/GridDisplay.rb index f3839db..137efd4 100644 --- a/lib/tailor/GUI/GridDisplay.rb +++ b/lib/tailor/GUI/GridDisplay.rb @@ -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| + stepx = self.tileset.tile_x + self.tileset.space_x + 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.draw_bitmap(@pristineImage, 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.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 diff --git a/lib/tailor/GUI/TilesetEditor.rb b/lib/tailor/GUI/TilesetEditor.rb index c3362cd..5b9883d 100644 --- a/lib/tailor/GUI/TilesetEditor.rb +++ b/lib/tailor/GUI/TilesetEditor.rb @@ -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,23 +187,28 @@ 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) @tilesetNames[@tilesetSlicer.get_selected_index] = @tileNameCtrl.get_value end 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 diff --git a/lib/tailor/GUI/TilesetProperties.rb b/lib/tailor/GUI/TilesetProperties.rb index ddd8a19..b848b87 100644 --- a/lib/tailor/GUI/TilesetProperties.rb +++ b/lib/tailor/GUI/TilesetProperties.rb @@ -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| - elemCtrl.set_value(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 diff --git a/lib/tailor/Tileset.rb b/lib/tailor/Tileset.rb index 3e00da8..59630d5 100644 --- a/lib/tailor/Tileset.rb +++ b/lib/tailor/Tileset.rb @@ -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,9 +78,13 @@ module Tailor } StringIO.open do |iostream| - Wx::Image.from_bitmap(self.image).write(iostream, Wx::BITMAP_TYPE_PNG) - iostream.rewind - obj['image'] = Base64.encode64(iostream.read) + 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 @@ -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'],