From e8e1f6b51b1ecafff7f6f348d240161d20ab0db6 Mon Sep 17 00:00:00 2001 From: Kevin Chabowski Date: Wed, 14 Aug 2013 16:46:45 +0200 Subject: Added Tools * tool is now Tool and is defined as an interface * toolFill and toolDraw implemented * Updated toolbar --- main.go | 19 ++++++--------- tools.go | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+), 12 deletions(-) create mode 100644 tools.go diff --git a/main.go b/main.go index b300034..9d432db 100644 --- a/main.go +++ b/main.go @@ -7,17 +7,12 @@ import ( "github.com/mattn/go-gtk/gtk" ) -type tool int - -const ( - ToolDraw tool = iota - ToolFill -) - type GUI struct { window *gtk.Window statusbar *gtk.Statusbar showbiomes *gtk.CheckButton + + tool Tool } func (g *GUI) openWorldDlg() { @@ -145,7 +140,7 @@ func (g *GUI) mkToolbox() *gtk.ScrolledWindow { fill := gtk.NewRadioButtonWithLabel(nil, "Fill") fill.SetActive(true) - fill.Connect("toggled", g.mkUpdateToolFx(fill, ToolFill)) + fill.Connect("toggled", g.mkUpdateToolFx(fill, NewFillTool())) draw := gtk.NewRadioButtonWithLabel(fill.GetGroup(), "Draw") drawRadius := gtk.NewSpinButtonWithRange(1, 20, 1) @@ -153,7 +148,7 @@ func (g *GUI) mkToolbox() *gtk.ScrolledWindow { drawHBox.PackStart(draw, true, true, 3) drawHBox.PackStart(gtk.NewLabel("Radius:"), false, false, 3) drawHBox.PackEnd(drawRadius, false, false, 3) - draw.Connect("toggled", g.mkUpdateToolFx(draw, ToolDraw)) + draw.Connect("toggled", g.mkUpdateToolFx(draw, NewDrawTool(func() int { return int(drawRadius.GetValue()) }))) vbox.PackStart(fill, false, false, 3) vbox.PackStart(drawHBox, false, false, 3) @@ -206,7 +201,7 @@ func (g *GUI) Init() { g.window.Connect("destroy", g.exitApp) } -func (g *GUI) mkUpdateToolFx(rb *gtk.RadioButton, t tool) func() { +func (g *GUI) mkUpdateToolFx(rb *gtk.RadioButton, t Tool) func() { return func() { if rb.GetActive() { g.setTool(t) @@ -222,8 +217,8 @@ func (g *GUI) mkUpdateBiomeFx(rb *gtk.RadioButton, bio mcmap.Biome) func() { } } -func (g *GUI) setTool(t tool) { - fmt.Printf("Tool %d\n", t) +func (g *GUI) setTool(t Tool) { + g.tool = t } func (g *GUI) setBiome(bio mcmap.Biome) { diff --git a/tools.go b/tools.go new file mode 100644 index 0000000..ffb763a --- /dev/null +++ b/tools.go @@ -0,0 +1,81 @@ +package main + +import ( + "github.com/kch42/gomcmap/mcmap" +) + +type BiomeGetter interface { + GetBiome(x, z int) (mcmap.Biome, bool) +} + +type XZPos struct { + X, Z int +} + +type Change map[XZPos]mcmap.Biome + +type Tool interface { + SingleClick() bool // Whether only one click should be performed (true) or the action should be repeated, if the mouse is dragged + Do(bio mcmap.Biome, bioget BiomeGetter, x, z int) Change +} + +type drawTool struct { + radGetter func() int +} + +func (d *drawTool) SingleClick() bool { return false } + +func (d *drawTool) Do(bio mcmap.Biome, bioget BiomeGetter, x, z int) Change { + rad := d.radGetter() + if rad <= 0 { + return nil + } + + change := make(Change) + for xp := x - (rad - 1); xp < x+rad; xp++ { + for zp := z - (rad - 1); zp < z+rad; zp++ { + change[XZPos{xp, zp}] = bio + } + } + + return change +} + +func NewDrawTool(radGetter func() int) *drawTool { + return &drawTool{radGetter} +} + +type fillTool struct{} + +func (f *fillTool) SingleClick() bool { return true } + +func (f *fillTool) Do(bio mcmap.Biome, bioget BiomeGetter, x, z int) Change { + oldbio, ok := bioget.GetBiome(x, z) + if !ok { + return nil + } + + change := make(Change) + floodfill(oldbio, bio, bioget, x, z, change) + return change +} + +func floodfill(oldbio, newbio mcmap.Biome, bioget BiomeGetter, x, z int, change Change) { + pos := XZPos{x, z} + if _, ok := change[pos]; ok { + return + } + + if bio, ok := bioget.GetBiome(x, z); ok && (bio == oldbio) { + change[pos] = newbio + + floodfill(oldbio, newbio, bioget, x-1, z, change) + floodfill(oldbio, newbio, bioget, x+1, z, change) + floodfill(oldbio, newbio, bioget, x, z-1, change) + floodfill(oldbio, newbio, bioget, x, z+1, change) + } +} + +func NewFillTool() *fillTool { + return new(fillTool) +} -- cgit v1.2.3-54-g00ecf