|  | @@ -5,25 +5,13 @@ import (
 | 
	
		
			
				|  |  |  	"log"
 | 
	
		
			
				|  |  |  	"red-green/door"
 | 
	
		
			
				|  |  |  	"runtime/debug"
 | 
	
		
			
				|  |  | -	"strconv"
 | 
	
		
			
				|  |  | -	"strings"
 | 
	
		
			
				|  |  |  	"time"
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |  	// "net/http"
 | 
	
		
			
				|  |  |  	// _ "net/http/pprof"
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	"github.com/mitchellh/go-wordwrap"
 | 
	
		
			
				|  |  |  )
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -//go:generate sh -c "font-util extract -f 'Amazon Cyan,Serpent,Unchained,Asylum,ArmageonRed,BrainDmgBlu,Boner,Descent,Remorse,Dungeon' ../TDFONTS.TDF ../TDFONTS2.TDF ../TDFONTS9.TDF > fonts.go"
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -//go:generate sh -c "font-util extract -f Armageddon -c 7,1 -c 4,2 ../TDFONTS2.TDF > rgfont.go; sed -i 's/Armageddon/RedGreen/g' rgfont.go"
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -func pctUpdate(pct *int64) func() int64 {
 | 
	
		
			
				|  |  | -	return func() int64 {
 | 
	
		
			
				|  |  | -		return *pct
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | +// Max X value we can use before hitting MemStats panel.
 | 
	
		
			
				|  |  | +var MaxX int = 0
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  func press_keys(d *door.Door) {
 | 
	
		
			
				|  |  |  	d.Write(door.Reset + door.CRNL + "Press some keys... <ENTER> to exit.")
 | 
	
	
		
			
				|  | @@ -72,735 +60,6 @@ func press_a_key(d *door.Door) error {
 | 
	
		
			
				|  |  |  	return err
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -func about_test_door(d *door.Door) {
 | 
	
		
			
				|  |  | -	var W int = 60
 | 
	
		
			
				|  |  | -	var center_x int = (door.Width - W) / 2
 | 
	
		
			
				|  |  | -	var center_y int = (door.Height - 16) / 2
 | 
	
		
			
				|  |  | -	var about door.Panel = door.Panel{X: center_x,
 | 
	
		
			
				|  |  | -		Y:           center_y,
 | 
	
		
			
				|  |  | -		Width:       W,
 | 
	
		
			
				|  |  | -		Style:       door.SINGLE_DOUBLE,
 | 
	
		
			
				|  |  | -		BorderColor: door.ColorText("BOLD YELLOW ON BLUE"),
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	about.Lines = append(about.Lines, door.Line{Text: fmt.Sprintf("%*s", -W, "About This Door"),
 | 
	
		
			
				|  |  | -		DefaultColor: door.ColorText("BOLD CYAN ON BLUE")})
 | 
	
		
			
				|  |  | -	about.Lines = append(about.Lines, about.Spacer())
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	about.Lines = append(about.Lines, door.Line{Text: fmt.Sprintf("%*s", -W, "Test Door written in go, using go door.")})
 | 
	
		
			
				|  |  | -	var copyright string = "(C) 2022 Bugz, Red Green Software"
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	if door.Unicode {
 | 
	
		
			
				|  |  | -		copyright = strings.Replace(copyright, "(C)", "\u00a9", -1)
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	about.Lines = append(about.Lines,
 | 
	
		
			
				|  |  | -		door.Line{Text: copyright, Width: W,
 | 
	
		
			
				|  |  | -			DefaultColor: door.ColorText("BOLD WHITE ON BLUE")})
 | 
	
		
			
				|  |  | -	for _, text := range []string{"",
 | 
	
		
			
				|  |  | -		"This door was written by Bugz.",
 | 
	
		
			
				|  |  | -		"",
 | 
	
		
			
				|  |  | -		"It is written in Go, detects CP437/unicode, detects screen",
 | 
	
		
			
				|  |  | -		"size, supports door.sys & door32.sys, supports TheDraw Fonts",
 | 
	
		
			
				|  |  | -		"(the fonts are compiled into the door), has NoMoreSecrets",
 | 
	
		
			
				|  |  | -		"and SpinRite effects, and runs on Linux",
 | 
	
		
			
				|  |  | -		"and sometimes even Windows..."} {
 | 
	
		
			
				|  |  | -		about.Lines = append(about.Lines, door.Line{Text: text, Width: W})
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	var better door.NoMoreSecretsConfig = door.NoMoreSecretsDefault
 | 
	
		
			
				|  |  | -	better.Jumble_Loop_Speed = 75  // 35
 | 
	
		
			
				|  |  | -	better.Reveal_Loop_Speed = 100 // 50
 | 
	
		
			
				|  |  | -	better.Color = door.ColorText("BRI CYAN ON BLUE")
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	door.NoMoreSecrets(about.Output(), d, &better)
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -// Build door.Menu (Main menu)
 | 
	
		
			
				|  |  | -func MainMenu() door.Menu {
 | 
	
		
			
				|  |  | -	// Make the main menu
 | 
	
		
			
				|  |  | -	// Width was 45
 | 
	
		
			
				|  |  | -	var menu door.Menu = door.Menu{Panel: door.Panel{Width: 35,
 | 
	
		
			
				|  |  | -		X:           2,
 | 
	
		
			
				|  |  | -		Y:           5,
 | 
	
		
			
				|  |  | -		Style:       door.DOUBLE,
 | 
	
		
			
				|  |  | -		Title:       "[ Main Menu: ]",
 | 
	
		
			
				|  |  | -		TitleOffset: 3,
 | 
	
		
			
				|  |  | -		BorderColor: door.ColorText("BRI CYAN ON BLA")}}
 | 
	
		
			
				|  |  | -	menu.SelectedR = door.MakeMenuRender(door.ColorText("BOLD CYAN"),
 | 
	
		
			
				|  |  | -		door.ColorText("BOLD BLUE"),
 | 
	
		
			
				|  |  | -		door.ColorText("BOLD WHITE"),
 | 
	
		
			
				|  |  | -		door.ColorText("BOLD CYAN"))
 | 
	
		
			
				|  |  | -	menu.UnselectedR = door.MakeMenuRender(door.ColorText("BOLD YEL ON BLUE"),
 | 
	
		
			
				|  |  | -		door.ColorText("BOLD WHI ON BLUE"),
 | 
	
		
			
				|  |  | -		door.ColorText("BOLD YEL ON BLUE"),
 | 
	
		
			
				|  |  | -		door.ColorText("BOLD CYAN ON BLUE"))
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	menu.AddSelection("A", "ANSI Display")
 | 
	
		
			
				|  |  | -	// m.AddSelection("C", "Crash")
 | 
	
		
			
				|  |  | -	menu.AddSelection("D", "Display Information")
 | 
	
		
			
				|  |  | -	menu.AddSelection("F", "Font Demo")
 | 
	
		
			
				|  |  | -	menu.AddSelection("I", "Input Demo")
 | 
	
		
			
				|  |  | -	menu.AddSelection("M", "Menu Demo")
 | 
	
		
			
				|  |  | -	menu.AddSelection("P", "Progress Bars Demo")
 | 
	
		
			
				|  |  | -	menu.AddSelection("S", "Show Panel")
 | 
	
		
			
				|  |  | -	menu.AddSelection("T", "Test Door About")
 | 
	
		
			
				|  |  | -	menu.AddSelection("W", "Screen Width")
 | 
	
		
			
				|  |  | -	menu.AddSelection("Q", "Quit")
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	var descriptions []string = []string{
 | 
	
		
			
				|  |  | -		// 12345678901234567890123456789012345678901234567890
 | 
	
		
			
				|  |  | -		"Display an ANSI file. It is compiled into the door itself.",
 | 
	
		
			
				|  |  | -		// "Crash go, see a handled error.",  // The error shows up in the logs.
 | 
	
		
			
				|  |  | -		"Display dropfile information.",
 | 
	
		
			
				|  |  | -		"Display TheDraw Fonts. Font information is compiled into the door.",
 | 
	
		
			
				|  |  | -		"Input some values, while updating the time.",
 | 
	
		
			
				|  |  | -		"Isn't this is a menu?",
 | 
	
		
			
				|  |  | -		"Display progress bar styles: half step, display percentage, and gradient.",
 | 
	
		
			
				|  |  | -		"Show multiple panels. Panels can be mouse drag/drop around.",
 | 
	
		
			
				|  |  | -		"Show about the door, using NoMoreSecrets effect.",
 | 
	
		
			
				|  |  | -		"Examples using the full width of the screen.",
 | 
	
		
			
				|  |  | -		"Exit this door.",
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	var widthLeft int = door.Width - (menu.Width + menu.X + 2)
 | 
	
		
			
				|  |  | -	var panelWidth int = widthLeft - (2 + 2)
 | 
	
		
			
				|  |  | -	var maxLines int = 1
 | 
	
		
			
				|  |  | -	var maxLineLength int
 | 
	
		
			
				|  |  | -	// Calculate the max lines needed for each line.
 | 
	
		
			
				|  |  | -	for _, line := range descriptions {
 | 
	
		
			
				|  |  | -		var wrapped string = wordwrap.WrapString(line, uint(panelWidth))
 | 
	
		
			
				|  |  | -		var lines int = len(strings.Split(wrapped, "\n"))
 | 
	
		
			
				|  |  | -		if lines > maxLines {
 | 
	
		
			
				|  |  | -			maxLines = lines
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -		if len(line) > maxLineLength {
 | 
	
		
			
				|  |  | -			maxLineLength = len(line)
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	if maxLines == 1 {
 | 
	
		
			
				|  |  | -		// Ok! Everything fits into one line, SO use max line length as width of panel.
 | 
	
		
			
				|  |  | -		panelWidth = maxLineLength
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	// Position the description panel beside the menu. m.Width + m.X + 2 (1 one to give it a space)
 | 
	
		
			
				|  |  | -	var descPanel door.Panel = door.Panel{X: menu.Width + menu.X + 2 + 1, Y: menu.Y, Width: panelWidth, Style: door.SINGLE, BorderColor: door.ColorText("WHI ON BLU")}
 | 
	
		
			
				|  |  | -	for x := 0; x < maxLines; x++ {
 | 
	
		
			
				|  |  | -		descPanel.Lines = append(descPanel.Lines, door.Line{Text: "", Width: panelWidth})
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	menu.Activated = func(item int, d *door.Door) {
 | 
	
		
			
				|  |  | -		var line string = descriptions[item]
 | 
	
		
			
				|  |  | -		var lines []string = strings.Split(wordwrap.WrapString(line, uint(panelWidth)), "\n")
 | 
	
		
			
				|  |  | -		for idx := range descPanel.Lines {
 | 
	
		
			
				|  |  | -			if idx >= len(lines) {
 | 
	
		
			
				|  |  | -				descPanel.Lines[idx].Text = ""
 | 
	
		
			
				|  |  | -			} else {
 | 
	
		
			
				|  |  | -				descPanel.Lines[idx].Text = lines[idx]
 | 
	
		
			
				|  |  | -			}
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -		d.Write(door.SavePos + descPanel.Output() + door.RestorePos)
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	return menu
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -func display_information(d *door.Door) {
 | 
	
		
			
				|  |  | -	d.Write(door.Clrscr)
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	var headerColor string = door.ColorText("BRI CYAN")
 | 
	
		
			
				|  |  | -	var keyColor string = door.ColorText("BRI GREEN")
 | 
	
		
			
				|  |  | -	var sepColor string = door.ColorText("BRI YEL")
 | 
	
		
			
				|  |  | -	var valColor string = door.ColorText("CYAN")
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	var nice_format func(string, string) string = func(key string, value string) string {
 | 
	
		
			
				|  |  | -		return fmt.Sprintf("%s%-20s %s: %s%s", keyColor, key, sepColor, valColor, value) + door.CRNL
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	var offset string
 | 
	
		
			
				|  |  | -	var header string = "DropFile: "
 | 
	
		
			
				|  |  | -	offset = strings.Repeat(" ", len(header))
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	d.Write(headerColor + header)
 | 
	
		
			
				|  |  | -	d.Write(nice_format("Comm Type", strconv.Itoa(d.Config.Comm_type)))
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	if d.Config.BBSID != "" {
 | 
	
		
			
				|  |  | -		d.Write(offset + nice_format("BBS Software", d.Config.BBSID))
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	d.Write(offset + nice_format("Time Left", strconv.Itoa(d.Config.Time_left)))
 | 
	
		
			
				|  |  | -	d.Write(offset + nice_format("Real Name", d.Config.Real_name))
 | 
	
		
			
				|  |  | -	// d.Write(nice_format("Comm Handle", strconv.Itoa(d.Config.Comm_handle)))
 | 
	
		
			
				|  |  | -	d.Write(offset + nice_format("Handle", d.Config.Handle))
 | 
	
		
			
				|  |  | -	d.Write(offset + nice_format("User #", strconv.Itoa(d.Config.User_number)))
 | 
	
		
			
				|  |  | -	d.Write(offset + nice_format("Security Level", strconv.Itoa(d.Config.Security_level)))
 | 
	
		
			
				|  |  | -	d.Write(offset + nice_format("Node #", strconv.Itoa(d.Config.Node)))
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	header = "Detected: "
 | 
	
		
			
				|  |  | -	offset = strings.Repeat(" ", len(header))
 | 
	
		
			
				|  |  | -	d.Write(door.CRNL + headerColor + header)
 | 
	
		
			
				|  |  | -	d.Write(nice_format("Unicode", strconv.FormatBool(door.Unicode)))
 | 
	
		
			
				|  |  | -	d.Write(offset + nice_format("CP437", strconv.FormatBool(door.CP437)))
 | 
	
		
			
				|  |  | -	d.Write(offset + nice_format("Full CP437", strconv.FormatBool(door.Full_CP437)))
 | 
	
		
			
				|  |  | -	d.Write(offset + nice_format("Screen Size", fmt.Sprintf("%d X %d", door.Width, door.Height)))
 | 
	
		
			
				|  |  | -	var time time.Duration = d.TimeLeft()
 | 
	
		
			
				|  |  | -	d.Write(offset + nice_format("Door Time Left", fmt.Sprintf("%d Hours, %d Minutes, %d Seconds", int(time.Hours()), int(time.Minutes())%60, int(time.Seconds())%60)))
 | 
	
		
			
				|  |  | -	time = d.TimeUsed()
 | 
	
		
			
				|  |  | -	d.Write(offset + nice_format("Door Time Used", fmt.Sprintf("%d Minutes, %d Seconds", int(time.Minutes()), int(time.Seconds())%60)))
 | 
	
		
			
				|  |  | -	press_a_key(d)
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	d.Write(door.Clrscr + door.CRNL + door.CRNL + door.CRNL)
 | 
	
		
			
				|  |  | -	modules := GetModules()
 | 
	
		
			
				|  |  | -	header = "Build:    "
 | 
	
		
			
				|  |  | -	offset = strings.Repeat(" ", len(header))
 | 
	
		
			
				|  |  | -	d.Write(headerColor + header)
 | 
	
		
			
				|  |  | -	gover, gitver, goarch, goos := GetVersion()
 | 
	
		
			
				|  |  | -	d.Write(nice_format("go version", gover))
 | 
	
		
			
				|  |  | -	d.Write(offset + nice_format("git commit", gitver))
 | 
	
		
			
				|  |  | -	d.Write(offset + nice_format("Arch", goarch))
 | 
	
		
			
				|  |  | -	d.Write(offset + nice_format("OS", goos))
 | 
	
		
			
				|  |  | -	for mod, version := range modules {
 | 
	
		
			
				|  |  | -		d.Write(offset + nice_format(mod, version))
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -func display_ansi(d *door.Door) {
 | 
	
		
			
				|  |  | -	var art []string = ANSIGrowl()
 | 
	
		
			
				|  |  | -	d.Write(door.Clrscr)
 | 
	
		
			
				|  |  | -	for _, line := range art {
 | 
	
		
			
				|  |  | -		d.Write(line + door.CRNL)
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -func font_demo(d *door.Door) {
 | 
	
		
			
				|  |  | -	var output []string
 | 
	
		
			
				|  |  | -	var l int
 | 
	
		
			
				|  |  | -	var centering string
 | 
	
		
			
				|  |  | -	var now time.Time = time.Now()
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	// I have checks here (but not all are complete), that verify the font
 | 
	
		
			
				|  |  | -	// output doesn't exceed the size of the screen.
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	d.Write(door.Clrscr + door.CRNL) //  + door.CRNL + door.CRNL)
 | 
	
		
			
				|  |  | -	var fac door.ColorFont = FontAmazonCyan()
 | 
	
		
			
				|  |  | -	output, l = fac.Output(now.Format("Jan Mon"))
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	// Size check:  Is this too big for the screen?
 | 
	
		
			
				|  |  | -	/*
 | 
	
		
			
				|  |  | -		if l > door.Width {
 | 
	
		
			
				|  |  | -			output, l = fac.Output("Jan")
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -	*/
 | 
	
		
			
				|  |  | -	if l < door.Width {
 | 
	
		
			
				|  |  | -		centering = ""
 | 
	
		
			
				|  |  | -		// centering = strings.Repeat(" ", (door.Width-l)/2)
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		for _, o := range output {
 | 
	
		
			
				|  |  | -			d.Write(fmt.Sprintf("%s%s%s", centering, o, door.Reset) + door.CRNL)
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -		d.Write(door.CRNL)
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	var patch door.ColorMap = fac.Scan(6)
 | 
	
		
			
				|  |  | -	// log.Printf("Patch: %#v\n", patch)
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	fac.Modify(4, patch)
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	output, l = fac.Output(now.Format("Monday"))
 | 
	
		
			
				|  |  | -	centering = strings.Repeat(" ", (door.Width-l)/2)
 | 
	
		
			
				|  |  | -	for _, o := range output {
 | 
	
		
			
				|  |  | -		d.Write(fmt.Sprintf("%s%s%s", centering, o, door.Reset) + door.CRNL)
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	d.Write(door.CRNL)
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	fac.Modify(1, patch)
 | 
	
		
			
				|  |  | -	output, l = fac.Output(now.Format("January")) // 3:04:05 PM"))
 | 
	
		
			
				|  |  | -	centering = strings.Repeat(" ", (door.Width-l)/2)
 | 
	
		
			
				|  |  | -	for _, o := range output {
 | 
	
		
			
				|  |  | -		d.Write(fmt.Sprintf("%s%s%s", centering, o, door.Reset) + door.CRNL)
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	d.Write(door.CRNL)
 | 
	
		
			
				|  |  | -	press_a_key(d)
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	// Anarchy Blue - no digits
 | 
	
		
			
				|  |  | -	var fab door.ColorFont = FontSerpent()
 | 
	
		
			
				|  |  | -	output, l = fab.Output("Date/Time:")
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	if l < door.Width {
 | 
	
		
			
				|  |  | -		centering = strings.Repeat(" ", (door.Width-l)/2)
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		for _, o := range output {
 | 
	
		
			
				|  |  | -			d.Write(centering + o + door.Reset + door.CRNL)
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -		d.Write(door.CRNL)
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	var unchain door.ColorFont = FontUnchained()
 | 
	
		
			
				|  |  | -	now = time.Now()
 | 
	
		
			
				|  |  | -	output, l = unchain.Output(now.Format("01/02/2006"))
 | 
	
		
			
				|  |  | -	if l < door.Width {
 | 
	
		
			
				|  |  | -		centering = strings.Repeat(" ", (door.Width-l)/2)
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		for _, o := range output {
 | 
	
		
			
				|  |  | -			d.Write(centering + o + door.Reset + door.CRNL)
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -		d.Write(door.CRNL)
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	output, l = unchain.Output(now.Format("3:04:05 PM"))
 | 
	
		
			
				|  |  | -	if l > door.Width {
 | 
	
		
			
				|  |  | -		output, l = unchain.Output("Meow")
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	if l < door.Width {
 | 
	
		
			
				|  |  | -		centering = strings.Repeat(" ", (door.Width-l)/2)
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		for _, o := range output {
 | 
	
		
			
				|  |  | -			d.Write(centering + o + door.Reset + door.CRNL)
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -		d.Write(door.CRNL)
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	press_a_key(d)
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	var asylum door.ColorFont = FontAsylum()
 | 
	
		
			
				|  |  | -	output, l = asylum.Output("Bugz ROCKS")
 | 
	
		
			
				|  |  | -	if l > door.Width {
 | 
	
		
			
				|  |  | -		output, l = asylum.Output("Aslym")
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	if l < door.Width {
 | 
	
		
			
				|  |  | -		centering = strings.Repeat(" ", (door.Width-l)/2)
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		for _, o := range output {
 | 
	
		
			
				|  |  | -			d.Write(centering + o + door.Reset + door.CRNL)
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -		d.Write(door.CRNL)
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	var brain door.ColorFont = FontBrainDmgBlu()
 | 
	
		
			
				|  |  | -	output, l = brain.Output("I'm so BLUE")
 | 
	
		
			
				|  |  | -	if l > door.Width {
 | 
	
		
			
				|  |  | -		output, l = brain.Output("Blue")
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	if l < door.Width {
 | 
	
		
			
				|  |  | -		centering = strings.Repeat(" ", (door.Width-l)/2)
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		for _, o := range output {
 | 
	
		
			
				|  |  | -			d.Write(centering + o + door.Reset + door.CRNL)
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -		d.Write(door.CRNL)
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	var boner door.ColorFont = FontBoner()
 | 
	
		
			
				|  |  | -	output, l = boner.Output("Welcome!")
 | 
	
		
			
				|  |  | -	if l < door.Width {
 | 
	
		
			
				|  |  | -		centering = strings.Repeat(" ", (door.Width-l)/2)
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		for _, o := range output {
 | 
	
		
			
				|  |  | -			d.Write(centering + o + door.Reset + door.CRNL)
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -		d.Write(door.CRNL)
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	press_a_key(d)
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	var descent door.ColorFont = FontDescent()
 | 
	
		
			
				|  |  | -	output, l = descent.Output("Meanwhile...")
 | 
	
		
			
				|  |  | -	if l > door.Width {
 | 
	
		
			
				|  |  | -		output, l = descent.Output("BUGZ")
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	if l < door.Width {
 | 
	
		
			
				|  |  | -		centering = strings.Repeat(" ", (door.Width-l)/2)
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		for _, o := range output {
 | 
	
		
			
				|  |  | -			d.Write(centering + o + door.Reset + door.CRNL)
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -		d.Write(door.CRNL)
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	var remorse door.ColorFont = FontRemorse()
 | 
	
		
			
				|  |  | -	output, l = remorse.Output("Enjoy the fonts")
 | 
	
		
			
				|  |  | -	if l > door.Width {
 | 
	
		
			
				|  |  | -		output, l = remorse.Output("Amazing")
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	if l < door.Width {
 | 
	
		
			
				|  |  | -		centering = strings.Repeat(" ", (door.Width-l)/2)
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		for _, o := range output {
 | 
	
		
			
				|  |  | -			d.Write(centering + o + door.Reset + door.CRNL)
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -		d.Write(door.CRNL)
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	var dungeon door.ColorFont = FontDungeon()
 | 
	
		
			
				|  |  | -	output, l = dungeon.Output("Until NEXT time")
 | 
	
		
			
				|  |  | -	if l > door.Width {
 | 
	
		
			
				|  |  | -		output, l = dungeon.Output("Beware")
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	if l < door.Width {
 | 
	
		
			
				|  |  | -		centering = strings.Repeat(" ", (door.Width-l)/2)
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		for _, o := range output {
 | 
	
		
			
				|  |  | -			d.Write(centering + o + door.Reset + door.CRNL)
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -		d.Write(door.CRNL)
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	/*
 | 
	
		
			
				|  |  | -		redgreen := FontArmageddon()
 | 
	
		
			
				|  |  | -		white := redgreen.Scan(7)
 | 
	
		
			
				|  |  | -		blue := redgreen.Scan(4)
 | 
	
		
			
				|  |  | -		redgreen.Modify(1, white)
 | 
	
		
			
				|  |  | -		redgreen.Modify(2, blue)
 | 
	
		
			
				|  |  | -	*/
 | 
	
		
			
				|  |  | -	redgreen := FontRedGreen()
 | 
	
		
			
				|  |  | -	output, l = redgreen.Output("Red-Green")
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	if l < door.Width {
 | 
	
		
			
				|  |  | -		press_a_key(d)
 | 
	
		
			
				|  |  | -		centering = strings.Repeat(" ", (door.Width-l)/2)
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		for _, o := range output {
 | 
	
		
			
				|  |  | -			d.Write(centering + o + door.Reset + door.CRNL)
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -		d.Write(door.CRNL)
 | 
	
		
			
				|  |  | -		output, l = redgreen.Output("Software")
 | 
	
		
			
				|  |  | -		centering = strings.Repeat(" ", (door.Width-l)/2)
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		for _, o := range output {
 | 
	
		
			
				|  |  | -			d.Write(centering + o + door.Reset + door.CRNL)
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -		d.Write(door.CRNL)
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -func input_demo(d *door.Door) {
 | 
	
		
			
				|  |  | -	var ticker *time.Ticker = time.NewTicker(time.Second)
 | 
	
		
			
				|  |  | -	var StopIt = make(chan bool)
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	go func() {
 | 
	
		
			
				|  |  | -		for {
 | 
	
		
			
				|  |  | -			select {
 | 
	
		
			
				|  |  | -			case <-StopIt:
 | 
	
		
			
				|  |  | -				return
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -			case t := <-ticker.C:
 | 
	
		
			
				|  |  | -				const tf = "January 2, 2006 03:04:05 PM MST"
 | 
	
		
			
				|  |  | -				output := door.SavePos + door.Goto(5, 2) + door.ColorText("BRI WHI ON CYAN") + t.Format(tf) + door.RestorePos
 | 
	
		
			
				|  |  | -				d.Write(output)
 | 
	
		
			
				|  |  | -			}
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -	}()
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	var inputColor string = door.ColorText("BRI WHI ON BLUE")
 | 
	
		
			
				|  |  | -	var inputColor2 string = door.ColorText("BRI WHI ON GREEN")
 | 
	
		
			
				|  |  | -	var prompt door.Line = door.Line{Text: "What is YOUR Name: "}
 | 
	
		
			
				|  |  | -	prompt.RenderF = door.RenderBlueYellow
 | 
	
		
			
				|  |  | -	d.Write(prompt.Output() + inputColor)
 | 
	
		
			
				|  |  | -	var name string = d.Input(25)
 | 
	
		
			
				|  |  | -	d.Write(door.Reset + door.CRNL)
 | 
	
		
			
				|  |  | -	prompt.Text = "What is Your Quest: "
 | 
	
		
			
				|  |  | -	d.Write(prompt.Output() + inputColor2)
 | 
	
		
			
				|  |  | -	var quest string = d.Input(35)
 | 
	
		
			
				|  |  | -	d.Write(door.Reset + door.CRNL)
 | 
	
		
			
				|  |  | -	prompt.Text = "What is your Favorite CoLoR: "
 | 
	
		
			
				|  |  | -	d.Write(prompt.Output() + inputColor)
 | 
	
		
			
				|  |  | -	var color string = d.Input(15)
 | 
	
		
			
				|  |  | -	d.Write(door.Reset + door.CRNL)
 | 
	
		
			
				|  |  | -	ticker.Stop()
 | 
	
		
			
				|  |  | -	StopIt <- true
 | 
	
		
			
				|  |  | -	d.Write(fmt.Sprintf("You're %s on the %s quest, and fond of %s."+door.CRNL, name, quest, color))
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -func progress_bars(d *door.Door) {
 | 
	
		
			
				|  |  | -	d.Write(door.Clrscr)
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	var bar door.BarLine = door.BarLine{Line: door.Line{DefaultColor: door.ColorText("BOLD YELLOW")}, Width: 20, Style: door.HALF_STEP}
 | 
	
		
			
				|  |  | -	var bar2 door.BarLine = door.BarLine{Width: 30, Style: door.SOLID, PercentStyle: door.PERCENT_SPACE}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	bar2.ColorRange = []door.BarRange{
 | 
	
		
			
				|  |  | -		{Percent: 2500, Color: door.ColorText("RED")},
 | 
	
		
			
				|  |  | -		{Percent: 5000, Color: door.ColorText("BROWN")},
 | 
	
		
			
				|  |  | -		{Percent: 7500, Color: door.ColorText("BOLD YEL")},
 | 
	
		
			
				|  |  | -		{Percent: 9500, Color: door.ColorText("GREEN")},
 | 
	
		
			
				|  |  | -		{Percent: 10100, Color: door.ColorText("BRI GRE")}}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	var bar3 door.BarLine = door.BarLine{Width: 15, Style: door.GRADIENT, Line: door.Line{DefaultColor: door.ColorText("CYAN")}}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	var percentage int64
 | 
	
		
			
				|  |  | -	bar.UpdateP = pctUpdate(&percentage)
 | 
	
		
			
				|  |  | -	bar2.UpdateP = pctUpdate(&percentage)
 | 
	
		
			
				|  |  | -	bar3.UpdateP = pctUpdate(&percentage)
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	update_bars := func() {
 | 
	
		
			
				|  |  | -		bar.Update()
 | 
	
		
			
				|  |  | -		bar2.Update()
 | 
	
		
			
				|  |  | -		bar3.Update()
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	d.Write(door.Goto(3, 12) + "Half-Step")
 | 
	
		
			
				|  |  | -	d.Write(door.Goto(25, 12) + "% with space and Color Range")
 | 
	
		
			
				|  |  | -	d.Write(door.Goto(57, 12) + "Gradient")
 | 
	
		
			
				|  |  | -	d.Write(door.HideCursor)
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	bar_start := door.Goto(3, 15)
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	for f := 0; f <= 100; f++ {
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		d.Write(door.Goto(3, 10) + door.Reset + fmt.Sprintf("Value: %d", f))
 | 
	
		
			
				|  |  | -		percentage = int64(f * 100)
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		update_bars()
 | 
	
		
			
				|  |  | -		d.Write(bar_start + bar.Output() + "  " + door.Reset + bar2.Output() + door.Reset + "  " + bar3.Output())
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		if d.Disconnect() {
 | 
	
		
			
				|  |  | -			// don't continue to sleep if we're disconnected
 | 
	
		
			
				|  |  | -			break
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		time.Sleep(time.Millisecond * 100)
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	d.Write(door.ShowCursor)
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -func width_demo(d *door.Door) {
 | 
	
		
			
				|  |  | -	var w int = door.Width
 | 
	
		
			
				|  |  | -	var panel door.Panel = door.Panel{X: 1, Y: 1, Width: w}
 | 
	
		
			
				|  |  | -	var lineColor string = door.ColorText("WHI")
 | 
	
		
			
				|  |  | -	var line string
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	for y := 1; y <= door.Height; y++ {
 | 
	
		
			
				|  |  | -		if y%10 == 0 {
 | 
	
		
			
				|  |  | -			line = strings.Repeat("1234567890", w/10)
 | 
	
		
			
				|  |  | -			for x := len(line); x < w; x++ {
 | 
	
		
			
				|  |  | -				line += strconv.Itoa((x + 1) % 10)
 | 
	
		
			
				|  |  | -			}
 | 
	
		
			
				|  |  | -		} else {
 | 
	
		
			
				|  |  | -			line = ""
 | 
	
		
			
				|  |  | -			for x := 1; x < w; x++ {
 | 
	
		
			
				|  |  | -				if x%10 == 0 {
 | 
	
		
			
				|  |  | -					line += strconv.Itoa(y % 10)
 | 
	
		
			
				|  |  | -				} else {
 | 
	
		
			
				|  |  | -					line += " "
 | 
	
		
			
				|  |  | -				}
 | 
	
		
			
				|  |  | -			}
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -		var l door.Line = door.Line{Text: line, DefaultColor: lineColor}
 | 
	
		
			
				|  |  | -		panel.Lines = append(panel.Lines, l)
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	var message string = fmt.Sprintf("Screen Size: %d X %d", door.Width, door.Height)
 | 
	
		
			
				|  |  | -	d.Write(panel.Output())
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	// Output alert on top of panel
 | 
	
		
			
				|  |  | -	var cx, cy int
 | 
	
		
			
				|  |  | -	cx = (door.Width - len(message) + 2) / 2
 | 
	
		
			
				|  |  | -	cy = (door.Height - 3) / 2
 | 
	
		
			
				|  |  | -	var alert []string = door.AlertBox(message, 1)
 | 
	
		
			
				|  |  | -	d.Write(door.ColorText("BRI YEL ON BLUE"))
 | 
	
		
			
				|  |  | -	for idx, ab := range alert {
 | 
	
		
			
				|  |  | -		d.Write(door.Goto(cx, cy+idx) + ab)
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	d.Write(door.Reset + panel.GotoEnd())
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	// Pause for key
 | 
	
		
			
				|  |  | -	d.WaitKey(door.Inactivity)
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	panel.Lines = make([]door.Line, 0)
 | 
	
		
			
				|  |  | -	var background string = "BUGZ Test Door in GO "
 | 
	
		
			
				|  |  | -	var bl int = len(background)
 | 
	
		
			
				|  |  | -	for y := 1; y <= door.Height; y++ {
 | 
	
		
			
				|  |  | -		offset := (y - 1) % bl
 | 
	
		
			
				|  |  | -		line = background[offset:]
 | 
	
		
			
				|  |  | -		for len(line) < w {
 | 
	
		
			
				|  |  | -			if len(line)+bl <= w {
 | 
	
		
			
				|  |  | -				line += background
 | 
	
		
			
				|  |  | -			} else {
 | 
	
		
			
				|  |  | -				line += background[0 : w-len(line)]
 | 
	
		
			
				|  |  | -			}
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -		var l door.Line = door.Line{Text: line, RenderF: door.RenderBlueYellow}
 | 
	
		
			
				|  |  | -		panel.Lines = append(panel.Lines, l)
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	d.Write(panel.Output())
 | 
	
		
			
				|  |  | -	d.WaitKey(door.Inactivity)
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -type TrackPanels struct {
 | 
	
		
			
				|  |  | -	Panel  *door.Panel
 | 
	
		
			
				|  |  | -	XPos   int
 | 
	
		
			
				|  |  | -	YPos   int
 | 
	
		
			
				|  |  | -	BColor string
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -// Find the Panel that was mouse clicked.
 | 
	
		
			
				|  |  | -func FindPanel(m door.Mouse, panels []TrackPanels) int {
 | 
	
		
			
				|  |  | -	for idx, p := range panels {
 | 
	
		
			
				|  |  | -		hit, _, _ := p.Panel.Within(int(m.X), int(m.Y))
 | 
	
		
			
				|  |  | -		if hit {
 | 
	
		
			
				|  |  | -			return idx
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	return -1
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -func panel_demo(d *door.Door) {
 | 
	
		
			
				|  |  | -	var width int = 55
 | 
	
		
			
				|  |  | -	var panel door.Panel = door.Panel{X: 5, Y: 5, Width: width, Style: door.DOUBLE, BorderColor: door.ColorText("CYAN ON BLUE"), Title: "[ Panel Demo ]"}
 | 
	
		
			
				|  |  | -	var moveColor string = door.ColorText("CYAN ON BLACK")
 | 
	
		
			
				|  |  | -	var lineColor string = door.ColorText("BRIGHT WHI ON BLUE")
 | 
	
		
			
				|  |  | -	// Add lines to the panel
 | 
	
		
			
				|  |  | -	for _, line := range []string{"The BBS Door Panel Demo", "(C) 2021 Red Green Software, https://red-green.com"} {
 | 
	
		
			
				|  |  | -		if door.Unicode {
 | 
	
		
			
				|  |  | -			line = strings.Replace(line, "(C)", "\u00a9", -1)
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -		var l door.Line = door.Line{Text: line, Width: width, DefaultColor: lineColor}
 | 
	
		
			
				|  |  | -		panel.Lines = append(panel.Lines, l)
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	panel.Lines = append(panel.Lines, panel.Spacer())
 | 
	
		
			
				|  |  | -	panel.Lines = append(panel.Lines, door.Line{Text: "Welcome to golang!", Width: width, DefaultColor: lineColor})
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	width = 10
 | 
	
		
			
				|  |  | -	var single door.Panel = door.Panel{X: 6, Y: 12, Width: width, Style: door.SINGLE, BorderColor: door.ColorText("WHITE ON BLUE"), Title: "< Single >"}
 | 
	
		
			
				|  |  | -	single.Lines = append(single.Lines, door.Line{Text: "Example", Width: width, DefaultColor: door.ColorText("WHI ON BLACK")})
 | 
	
		
			
				|  |  | -	single.Lines = append(single.Lines, single.Spacer())
 | 
	
		
			
				|  |  | -	single.Lines = append(single.Lines, door.Line{Text: "More Text", Width: width, DefaultColor: door.ColorText("BRI GREEN ON BLACK")})
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	width = 15
 | 
	
		
			
				|  |  | -	var double_single door.Panel = door.Panel{X: 26, Y: 12, Width: width, Style: door.DOUBLE_SINGLE, BorderColor: door.ColorText("BRI CYAN ON GREEN"), Title: "Double", TitleOffset: 3}
 | 
	
		
			
				|  |  | -	double_single.Lines = append(double_single.Lines, door.Line{Text: "Double / Single", Width: width, DefaultColor: door.ColorText("BRI WHI ON GREEN")})
 | 
	
		
			
				|  |  | -	double_single.Lines = append(double_single.Lines, double_single.Spacer())
 | 
	
		
			
				|  |  | -	double_single.Lines = append(double_single.Lines, door.Line{Text: "Some Other Text", Width: width, DefaultColor: door.ColorText("BRI CYAN ON GREEN")})
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	var single_double door.Panel = door.Panel{X: 46, Y: 12, Width: width, Style: door.SINGLE_DOUBLE, BorderColor: door.ColorText("BRI YELL ON RED")}
 | 
	
		
			
				|  |  | -	single_double.Lines = append(single_double.Lines, door.Line{Text: "Single / Double", Width: width, DefaultColor: door.ColorText("BRI WHI ON RED")})
 | 
	
		
			
				|  |  | -	single_double.Lines = append(single_double.Lines, single_double.Spacer())
 | 
	
		
			
				|  |  | -	single_double.Lines = append(single_double.Lines, door.Line{Text: "Text Goes Here ", Width: width, DefaultColor: door.ColorText("BRI GREEN ON RED")})
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	d.Write(door.Clrscr)
 | 
	
		
			
				|  |  | -	d.Write(panel.Output())
 | 
	
		
			
				|  |  | -	d.Write(single.Output())
 | 
	
		
			
				|  |  | -	d.Write(double_single.Output())
 | 
	
		
			
				|  |  | -	d.Write(single_double.Output())
 | 
	
		
			
				|  |  | -	d.Write(door.Goto(1, 20) + door.Reset + "Use MOUSE to click/drag panels, Right-Click Exits, R to Reset, Q to quit...")
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	var panels []TrackPanels = []TrackPanels{
 | 
	
		
			
				|  |  | -		{&panel, panel.X, panel.Y, panel.BorderColor},
 | 
	
		
			
				|  |  | -		{&single, single.X, single.Y, single.BorderColor},
 | 
	
		
			
				|  |  | -		{&double_single, double_single.X, double_single.Y, single.BorderColor},
 | 
	
		
			
				|  |  | -		{&single_double, single_double.X, single_double.Y, single_double.BorderColor}}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	var movingPanel *door.Panel
 | 
	
		
			
				|  |  | -	var moveX, moveY int
 | 
	
		
			
				|  |  | -	var panelColor string
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	for {
 | 
	
		
			
				|  |  | -		key, ex, err := d.WaitKey(door.Inactivity)
 | 
	
		
			
				|  |  | -		if err != nil {
 | 
	
		
			
				|  |  | -			return
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -		if ex == door.MOUSE {
 | 
	
		
			
				|  |  | -			m, ok := d.GetMouse()
 | 
	
		
			
				|  |  | -			if ok {
 | 
	
		
			
				|  |  | -				// Process Mouse Event
 | 
	
		
			
				|  |  | -				if m.Button == 3 {
 | 
	
		
			
				|  |  | -					// Exit on right click
 | 
	
		
			
				|  |  | -					return
 | 
	
		
			
				|  |  | -				}
 | 
	
		
			
				|  |  | -				if m.Button == 1 {
 | 
	
		
			
				|  |  | -					idx := FindPanel(m, panels)
 | 
	
		
			
				|  |  | -					if idx != -1 {
 | 
	
		
			
				|  |  | -						movingPanel = panels[idx].Panel
 | 
	
		
			
				|  |  | -						panelColor = movingPanel.BorderColor
 | 
	
		
			
				|  |  | -						moveX = int(m.X)
 | 
	
		
			
				|  |  | -						moveY = int(m.Y)
 | 
	
		
			
				|  |  | -					} else {
 | 
	
		
			
				|  |  | -						continue
 | 
	
		
			
				|  |  | -					}
 | 
	
		
			
				|  |  | -					// Should we do something to the panel?  Yes!
 | 
	
		
			
				|  |  | -					movingPanel.BorderColor = moveColor
 | 
	
		
			
				|  |  | -					d.Update(movingPanel.Output())
 | 
	
		
			
				|  |  | -				} else if m.Button == 4 {
 | 
	
		
			
				|  |  | -					if movingPanel != nil {
 | 
	
		
			
				|  |  | -						PR, PB := movingPanel.RightBottomPos()
 | 
	
		
			
				|  |  | -						log.Printf("Panel (%d,%d) End(%d,%d) W %d, L %d\n", movingPanel.X, movingPanel.Y, PR, PB, movingPanel.Width, movingPanel.Length())
 | 
	
		
			
				|  |  | -						// Ok, panel is move!
 | 
	
		
			
				|  |  | -						d.Update(movingPanel.Clear())
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -						// Restore panel border
 | 
	
		
			
				|  |  | -						movingPanel.BorderColor = panelColor
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -						// move panel
 | 
	
		
			
				|  |  | -						movingPanel.X -= (moveX - int(m.X))
 | 
	
		
			
				|  |  | -						movingPanel.Y -= (moveY - int(m.Y))
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -						// sanity checks
 | 
	
		
			
				|  |  | -						if movingPanel.X < 1 {
 | 
	
		
			
				|  |  | -							movingPanel.X = 1
 | 
	
		
			
				|  |  | -						}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -						// var edgeX bool
 | 
	
		
			
				|  |  | -						if movingPanel.X+movingPanel.Width >= door.Width {
 | 
	
		
			
				|  |  | -							movingPanel.X = door.Width - movingPanel.Width - 1
 | 
	
		
			
				|  |  | -							// edgeX = true
 | 
	
		
			
				|  |  | -						}
 | 
	
		
			
				|  |  | -						if movingPanel.Y < 1 {
 | 
	
		
			
				|  |  | -							movingPanel.Y = 1
 | 
	
		
			
				|  |  | -						}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -						// var edgeY bool
 | 
	
		
			
				|  |  | -						if movingPanel.Y+movingPanel.Length() >= door.Height {
 | 
	
		
			
				|  |  | -							movingPanel.Y = door.Height - movingPanel.Length() - 1
 | 
	
		
			
				|  |  | -							// edgeY = true
 | 
	
		
			
				|  |  | -						}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -						PR, PB = movingPanel.RightBottomPos()
 | 
	
		
			
				|  |  | -						log.Printf("Panel Now (%d,%d) End (%d,%d) %d, %d\n", movingPanel.X, movingPanel.Y, PR, PB, movingPanel.Width, movingPanel.Length()) //, edgeX, edgeY)
 | 
	
		
			
				|  |  | -						// If panel is at the end of the screen -- it scrolls (syncterm)
 | 
	
		
			
				|  |  | -						// This "fixes" it.  (Maybe a better way would be to not use last
 | 
	
		
			
				|  |  | -						// line on the screen?)
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -						// Or another way:
 | 
	
		
			
				|  |  | -						if PR == door.Width && PB == door.Height {
 | 
	
		
			
				|  |  | -							movingPanel.X--
 | 
	
		
			
				|  |  | -						}
 | 
	
		
			
				|  |  | -						/*
 | 
	
		
			
				|  |  | -							if edgeX && edgeY {
 | 
	
		
			
				|  |  | -								movingPanel.X--
 | 
	
		
			
				|  |  | -								log.Printf("Panel adjust X\n")
 | 
	
		
			
				|  |  | -							}
 | 
	
		
			
				|  |  | -						*/
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -						d.Update(movingPanel.Output())
 | 
	
		
			
				|  |  | -					}
 | 
	
		
			
				|  |  | -					movingPanel = nil
 | 
	
		
			
				|  |  | -				}
 | 
	
		
			
				|  |  | -			}
 | 
	
		
			
				|  |  | -		} else {
 | 
	
		
			
				|  |  | -			if (key == 'Q') || (key == 'q') || (key == '\x1b') {
 | 
	
		
			
				|  |  | -				return
 | 
	
		
			
				|  |  | -			}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -			if (key == 'R') || (key == 'r') {
 | 
	
		
			
				|  |  | -				for _, p := range panels {
 | 
	
		
			
				|  |  | -					d.Update(p.Panel.Clear())
 | 
	
		
			
				|  |  | -				}
 | 
	
		
			
				|  |  | -				for _, p := range panels {
 | 
	
		
			
				|  |  | -					p.Panel.X = p.XPos
 | 
	
		
			
				|  |  | -					p.Panel.Y = p.YPos
 | 
	
		
			
				|  |  | -					p.Panel.BorderColor = p.BColor
 | 
	
		
			
				|  |  | -					d.Update(p.Panel.Output())
 | 
	
		
			
				|  |  | -				}
 | 
	
		
			
				|  |  | -			}
 | 
	
		
			
				|  |  | -			if key == '0' {
 | 
	
		
			
				|  |  | -				d.Write(panels[0].Panel.GotoEnd())
 | 
	
		
			
				|  |  | -			}
 | 
	
		
			
				|  |  | -			if key == '1' {
 | 
	
		
			
				|  |  | -				d.Write(panels[1].Panel.GotoEnd())
 | 
	
		
			
				|  |  | -			}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |  func main() {
 | 
	
		
			
				|  |  |  	var message string
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -845,6 +104,7 @@ func main() {
 | 
	
		
			
				|  |  |  	*/
 | 
	
		
			
				|  |  |  	// Add in the GoRoutine Status panel
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +	MaxX = door.Width - 20
 | 
	
		
			
				|  |  |  	var goPanel door.Panel = door.Panel{X: door.Width - 19,
 | 
	
		
			
				|  |  |  		Y:           3,
 | 
	
		
			
				|  |  |  		Width:       16,
 |