Something went wrong. Try again.
small gleam coding and persistent agent daemon with a detachable cli and a canvas ui forked from okami.mom/albedo
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148package uv
import "github.com/charmbracelet/x/ansi"
// Window represents a rectangular area on the screen. It can be a root window// with no parent, or a sub-window with a parent window. A window can have its// own buffer or share the buffer of its parent window (view).type Window struct { *Buffer
method *WidthMethod parent *Window bounds Rectangle}
var ( _ Screen = (*Window)(nil) _ Drawable = (*Window)(nil))
// HasParent returns whether the window has a parent window. This can be used// to determine if the window is a root window or a sub-window.func (w *Window) HasParent() bool { return w.parent != nil}
// Parent returns the parent window of the current window.// If the window does not have a parent, it returns nil.func (w *Window) Parent() *Window { return w.parent}
// MoveTo moves the window to the specified x and y coordinates.func (w *Window) MoveTo(x, y int) { size := w.bounds.Size() w.bounds.Min.X = x w.bounds.Min.Y = y w.bounds.Max.X = x + size.X w.bounds.Max.Y = y + size.Y}
// MoveBy moves the window by the specified delta x and delta y.func (w *Window) MoveBy(dx, dy int) { w.bounds.Min.X += dx w.bounds.Min.Y += dy w.bounds.Max.X += dx w.bounds.Max.Y += dy}
// Clone creates an exact copy of the window, including its buffer and values.// The cloned window will have the same parent and method as the original// window.func (w *Window) Clone() *Window { return w.CloneArea(w.Buffer.Bounds())}
// CloneArea creates an exact copy of the window, including its buffer and// values, but only within the specified area. The cloned window will have the// same parent and method as the original window, but its bounds will be// limited to the specified area.func (w *Window) CloneArea(area Rectangle) *Window { clone := new(Window) clone.Buffer = w.Buffer.CloneArea(area) clone.parent = w.parent clone.method = w.method clone.bounds = area return clone}
// Resize resizes the window to the specified width and height.func (w *Window) Resize(width, height int) { // Only resize the buffer if this window owns its buffer. if w.parent == nil || w.Buffer != w.parent.Buffer { w.Buffer.Resize(width, height) } w.bounds.Max.X = w.bounds.Min.X + width w.bounds.Max.Y = w.bounds.Min.Y + height}
// WidthMethod returns the method used to calculate the width of characters in// the window.func (w *Window) WidthMethod() WidthMethod { return *w.method}
// Bounds returns the bounds of the window as a rectangle.func (w *Window) Bounds() Rectangle { return w.bounds}
// NewWindow creates a new window with its own buffer relative to the parent// window at the specified position and size.//// This will panic if width or height is negative.func (w *Window) NewWindow(x, y, width, height int) *Window { return newWindow(w, x, y, width, height, w.method, false)}
// NewView creates a new view into the parent window at the specified position// and size. Unlike [Window.NewWindow], this view shares the same buffer as the// parent window.func (w *Window) NewView(x, y, width, height int) *Window { return newWindow(w, x, y, width, height, w.method, true)}
// NewWindow creates a new root [Window] with the given size and width method.// If the method is nil, it defaults to [ansi.WcWidth].//// The [WidthMethod] is used to calculate the width of characters in the// window, which is important for correctly rendering text, especially when// dealing with wide characters, combining characters, emojis, and other// Unicode characters that may have varying widths.//// Use [ansi.WcWidth] as the default width method, which is a common// implementation that handles a wide range of Unicode characters according to// the Unicode Standard. Use [ansi.GraphemeWidth] if you know that your// terminal supports grapheme clusters and proper rendering of combining// characters and emojis, and you want to ensure that the width calculations// are based on grapheme clusters rather than individual code points.//// This will panic if width or height is negative.func NewWindow(width, height int, method WidthMethod) *Window { if method == nil { method = ansi.WcWidth } return newWindow(nil, 0, 0, width, height, &method, false)}
// SetWidthMethod sets the width method for the window.func (w *Window) SetWidthMethod(method WidthMethod) { w.method = &method}
// newWindow creates a new [Window] with the specified parent, position,// method, and size.func newWindow(parent *Window, x, y, width, height int, method *WidthMethod, view bool) *Window { w := new(Window) if view { w.Buffer = parent.Buffer } else { w.Buffer = NewBuffer(width, height) } w.parent = parent w.method = method w.bounds = Rect(x, y, width, height) return w}