package main import ( "bytes" "log" "red-green/door" "strings" ) type TrackPanels struct { Panel *door.Panel XPos int YPos int BColor []byte } // 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 = door.ColorText("CYAN ON BLACK") var lineColor = 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: bytes.NewBuffer([]byte(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: bytes.NewBuffer([]byte("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: bytes.NewBuffer([]byte("Example")), Width: width, DefaultColor: door.ColorText("WHI ON BLACK")}) single.Lines = append(single.Lines, single.Spacer()) single.Lines = append(single.Lines, &door.Line{Text: bytes.NewBuffer([]byte("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: bytes.NewBuffer([]byte("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: bytes.NewBuffer([]byte("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: bytes.NewBuffer([]byte("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: bytes.NewBuffer([]byte("Text Goes Here ")), Width: width, DefaultColor: door.ColorText("BRI GREEN ON RED")}) d.WriteA(door.Clrscr, panel.Output(), single.Output(), double_single.Output(), single_double.Output()) d.WriteA(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 []byte 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()) } } } }