frame

package
v0.0.0-...-7126e5d Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 29, 2021 License: BSD-3-Clause, MIT Imports: 7 Imported by: 0

Documentation

Overview

Package frame supports frames of editable text.

This is a port of Plan9's libframe to Go. It supports displaying a frame of editable text in a single font on raster displays, such as would be found in sam(1) and 9term(1). Frames may hold any character except NUL (0). Long lines are folded and tabs are at fixed intervals.

Index

Constants

View Source
const (
	ColBack = iota
	ColHigh
	ColBord
	ColText
	ColHText
	NumColours
)

TODO(rjk): Make this into a struct of colours?

Variables

View Source
var (
	TMPSIZE = 256
)

Functions

func Rpt

func Rpt(min, max image.Point) image.Rectangle

Types

type Frame

type Frame interface {
	SelectScrollUpdater

	// Maxtab sets the maximum size of a tab in pixels.
	Maxtab(m int)

	// GetMaxtab returns the current maximum size of a tab in pixels.
	GetMaxtab() int

	// Init prepares the Frame for the display of text in rectangle r.
	// Frame f will reuse previously set font, colours, tab width and
	// destination image for drawing unless these are overridden with
	// one or more instances of the OptColors, OptBackground
	// OptFont or OptMaxTab option settings.
	//
	// The background (OptBackground setter) may be null to allow
	// calling the other routines to maintain the model in, for example,
	// an obscured window.
	//
	// Changing the background or font will force the tick to be
	// recreated.
	Init(image.Rectangle, ...OptionClosure)

	// Clear frees the internal structures associated with f, permitting
	// another Init or SetRects on the Frame. It does not clear the
	// associated display. If f is to be deallocated, the associated Font and
	// Image must be freed separately. The resize argument should be non-zero
	// if the frame is to be redrawn with a different font; otherwise the
	// frame will maintain some data structures associated with the font.
	//
	// /To resize a Frame, use Clear and Init and then Insert to recreate the
	// /display. If a Frame is being moved but not resized, that is, if the
	// /shape of its containing rectangle is unchanged, it is sufficient to
	// /use Draw to copy the containing rectangle from the old to the new
	// /location and then call SetRects to establish the new geometry.
	Clear(bool)

	// Ptofchar returns the location of the upper left corner of the p'th
	// rune, starting from 0, in the receiver Frame. If the Frame holds
	// fewer than p runes, Ptofchar returns the location of the upper right
	// corner of the last character in the Frame
	Ptofchar(int) image.Point

	// Redraw redraws the background of the Frame where the Frame is inside
	// enclosing. Frame is responsible for drawing all of the pixels inside
	// enclosing though may fill less than enclosing with text. (In particular,
	// a margin may be added and the rectangle occupied by text is always
	// a multiple of the fixed line height.)
	// TODO(rjk): Modify this function to redraw the text as well and stop having
	// the drawing of text strings be a side-effect of Insert, Delete, etc.
	// TODO(rjk): Draw text to the bottom of enclosing as opposed to filling the
	// bottom partial text row with blank.
	//
	// Note: this function is not part of the documented libframe entrypoints and
	// was not invoked from Edwood code. Consequently, I am repurposing the name.
	// Future changes will have this function able to clear the Frame and draw the
	// entire box model.
	Redraw(enclosing image.Rectangle)

	// GetSelectionExtent returns the rune offsets of the selection maintained by
	// the Frame.
	GetSelectionExtent() (int, int)

	// Select takes ownership of the mouse channel to update the selection
	// so long as a button is down in downevent. Selection stops when the
	// staring point buttondown is altered. getmorelines is a callback provided
	// by the caller to provide n additional lines on demand to the specified frame.
	// The implementation of the callback must use the Frame instance provided
	// in place of the one that Select is invoked on.
	//
	// Select returns the selection range in the Frame.
	Select(*draw.Mousectl, *draw.Mouse, func(SelectScrollUpdater, int)) (int, int)

	// SelectOpt makes a selection in the same fashion as Select but does it in a
	// temporary way with the specified text colours fg, bg.
	SelectOpt(*draw.Mousectl, *draw.Mouse, func(SelectScrollUpdater, int), draw.Image, draw.Image) (int, int)

	// DrawSel repaints a section of the frame, delimited by rune
	// positions p0 and p1, either with plain background or entirely
	// highlighted, according to the flag highlighted, managing the tick
	// appropriately. The point pt0 is the geometrical location of p0 on the
	// screen; like all of the selection-helper routines' Point arguments, it
	// must be a value generated by Ptofchar.
	//
	// Clarification of semantics: the point of this routine is to redraw the
	// state of the Frame with selection p0, p1. In particular, this requires
	// updating f.p0 and f.p1 so that other entry points (e.g. Insert) can (transparently) remove
	// a pre-existing selection.
	//
	// Note that the original C code does not remove the pre-existing selection where
	// this code does draw the selection to the p0, p1. I (rjk) believe that this is a better
	// API.
	//
	// DrawSel does the minimum work needed to clear a highlight and (in particular)
	// multiple calls to DrawSel with highlighted false will be cheap.
	// TODO(rjk): DrawSel does more drawing work than necessary.
	DrawSel(image.Point, int, int, bool)
}

Frame is the public interface to a frame of text. Unlike the C implementation, new Frame instances should be created with NewFrame.

func NewFrame

func NewFrame(r image.Rectangle, ft draw.Font, b draw.Image, cols [NumColours]draw.Image) Frame

NewFrame creates a new Frame with Font ft, background image b, colours cols, and of the size r

type FrameFillStatus

type FrameFillStatus struct {
	Nchars         int
	Nlines         int
	Maxlines       int
	MaxPixelHeight int
}

FrameFillStatus is a snapshot of the capacity of the Frame.

type OptionClosure

type OptionClosure func(*frameimpl, *optioncontext)

Option handling per https://commandcenter.blogspot.ca/2014/01/self-referential-functions-and-design.html

Returns true if the option requires resetting the tick. TODO(rjk): It is possible to generalize this as needed with a more complex state object. One might imagine a set of updater functions?

func OptBackground

func OptBackground(b draw.Image) OptionClosure

OptBackground sets the background screen image.

func OptColors

func OptColors(cols [NumColours]draw.Image) OptionClosure

OptColors sets the default colours.

func OptFont

func OptFont(ft draw.Font) OptionClosure

OptFont sets the default font.

func OptMaxTab

func OptMaxTab(maxtabchars int) OptionClosure

OptMaxTab sets the default tabwidth in `0` characters.

type SelectScrollUpdater

type SelectScrollUpdater interface {
	// GetFrameFillStatus returns a snapshot of the capacity of the frame.
	GetFrameFillStatus() FrameFillStatus

	// Charofpt returns the index of the closest rune whose image's upper
	// left corner is up and to the left of pt.
	Charofpt(pt image.Point) int

	// DefaultFontHeight returns the height of the Frame's default font.
	// TODO(rjk): Reconsider this for Frames containing many styles.
	DefaultFontHeight() int

	// Delete deletes from the Frame the text between p0 and p1; p1 points at
	// the first rune beyond the deletion.
	//
	// Delete will clear a selection or tick if present but not put it back.
	Delete(int, int) int

	// Insert inserts r into Frame f starting at index p0.
	// If a NUL (0) character is inserted, chaos will ensue. Tabs
	// and newlines are handled by the library, but all other characters,
	// including control characters, are just displayed. For example,
	// backspaces are printed; to erase a character, use Delete.
	//
	// Insert will remove the selection or tick  if present but update selection offsets.
	Insert([]rune, int) bool

	IsLastLineFull() bool
	Rect() image.Rectangle

	// TextOccupiedHeight returns the height of the region in the frame
	// occupied by boxes (which in the future could be of varying height)
	// that is closest to the height of rectangle r such that only unclipped
	// boxes fit in the returned height. If r.Dy() exeeds the total height of
	// the current boxes, then returns the height of current set of boxes.
	TextOccupiedHeight(r image.Rectangle) int
}

SelectScrollUpdater are those frame.Frame methods offered to frame.Select callbacks.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL