...

Source file src/github.com/gdamore/tcell/v2/screen.go

Documentation: github.com/gdamore/tcell/v2

     1  // Copyright 2022 The TCell Authors
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use file except in compliance with the License.
     5  // You may obtain a copy of the license at
     6  //
     7  //    http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package tcell
    16  
    17  // Screen represents the physical (or emulated) screen.
    18  // This can be a terminal window or a physical console.  Platforms implement
    19  // this differently.
    20  type Screen interface {
    21  	// Init initializes the screen for use.
    22  	Init() error
    23  
    24  	// Fini finalizes the screen also releasing resources.
    25  	Fini()
    26  
    27  	// Clear logically erases the screen.
    28  	// This is effectively a short-cut for Fill(' ', StyleDefault).
    29  	Clear()
    30  
    31  	// Fill fills the screen with the given character and style.
    32  	// The effect of filling the screen is not visible until Show
    33  	// is called (or Sync).
    34  	Fill(rune, Style)
    35  
    36  	// SetCell is an older API, and will be removed.  Please use
    37  	// SetContent instead; SetCell is implemented in terms of SetContent.
    38  	SetCell(x int, y int, style Style, ch ...rune)
    39  
    40  	// GetContent returns the contents at the given location.  If the
    41  	// coordinates are out of range, then the values will be 0, nil,
    42  	// StyleDefault.  Note that the contents returned are logical contents
    43  	// and may not actually be what is displayed, but rather are what will
    44  	// be displayed if Show() or Sync() is called.  The width is the width
    45  	// in screen cells; most often this will be 1, but some East Asian
    46  	// characters and emoji require two cells.
    47  	GetContent(x, y int) (primary rune, combining []rune, style Style, width int)
    48  
    49  	// SetContent sets the contents of the given cell location.  If
    50  	// the coordinates are out of range, then the operation is ignored.
    51  	//
    52  	// The first rune is the primary non-zero width rune.  The array
    53  	// that follows is a possible list of combining characters to append,
    54  	// and will usually be nil (no combining characters.)
    55  	//
    56  	// The results are not displayed until Show() or Sync() is called.
    57  	//
    58  	// Note that wide (East Asian full width and emoji) runes occupy two cells,
    59  	// and attempts to place character at next cell to the right will have
    60  	// undefined effects.  Wide runes that are printed in the
    61  	// last column will be replaced with a single width space on output.
    62  	SetContent(x int, y int, primary rune, combining []rune, style Style)
    63  
    64  	// SetStyle sets the default style to use when clearing the screen
    65  	// or when StyleDefault is specified.  If it is also StyleDefault,
    66  	// then whatever system/terminal default is relevant will be used.
    67  	SetStyle(style Style)
    68  
    69  	// ShowCursor is used to display the cursor at a given location.
    70  	// If the coordinates -1, -1 are given or are otherwise outside the
    71  	// dimensions of the screen, the cursor will be hidden.
    72  	ShowCursor(x int, y int)
    73  
    74  	// HideCursor is used to hide the cursor.  It's an alias for
    75  	// ShowCursor(-1, -1).sim
    76  	HideCursor()
    77  
    78  	// SetCursorStyle is used to set the cursor style.  If the style
    79  	// is not supported (or cursor styles are not supported at all),
    80  	// then this will have no effect.
    81  	SetCursorStyle(CursorStyle)
    82  
    83  	// Size returns the screen size as width, height.  This changes in
    84  	// response to a call to Clear or Flush.
    85  	Size() (width, height int)
    86  
    87  	// ChannelEvents is an infinite loop that waits for an event and
    88  	// channels it into the user provided channel ch.  Closing the
    89  	// quit channel and calling the Fini method are cancellation
    90  	// signals.  When a cancellation signal is received the method
    91  	// returns after closing ch.
    92  	//
    93  	// This method should be used as a goroutine.
    94  	//
    95  	// NOTE: PollEvent should not be called while this method is running.
    96  	ChannelEvents(ch chan<- Event, quit <-chan struct{})
    97  
    98  	// PollEvent waits for events to arrive.  Main application loops
    99  	// must spin on this to prevent the application from stalling.
   100  	// Furthermore, this will return nil if the Screen is finalized.
   101  	PollEvent() Event
   102  
   103  	// HasPendingEvent returns true if PollEvent would return an event
   104  	// without blocking.  If the screen is stopped and PollEvent would
   105  	// return nil, then the return value from this function is unspecified.
   106  	// The purpose of this function is to allow multiple events to be collected
   107  	// at once, to minimize screen redraws.
   108  	HasPendingEvent() bool
   109  
   110  	// PostEvent tries to post an event into the event stream.  This
   111  	// can fail if the event queue is full.  In that case, the event
   112  	// is dropped, and ErrEventQFull is returned.
   113  	PostEvent(ev Event) error
   114  
   115  	// Deprecated: PostEventWait is unsafe, and will be removed
   116  	// in the future.
   117  	//
   118  	// PostEventWait is like PostEvent, but if the queue is full, it
   119  	// blocks until there is space in the queue, making delivery
   120  	// reliable.  However, it is VERY important that this function
   121  	// never be called from within whatever event loop is polling
   122  	// with PollEvent(), otherwise a deadlock may arise.
   123  	//
   124  	// For this reason, when using this function, the use of a
   125  	// Goroutine is recommended to ensure no deadlock can occur.
   126  	PostEventWait(ev Event)
   127  
   128  	// EnableMouse enables the mouse.  (If your terminal supports it.)
   129  	// If no flags are specified, then all events are reported, if the
   130  	// terminal supports them.
   131  	EnableMouse(...MouseFlags)
   132  
   133  	// DisableMouse disables the mouse.
   134  	DisableMouse()
   135  
   136  	// EnablePaste enables bracketed paste mode, if supported.
   137  	EnablePaste()
   138  
   139  	// DisablePaste disables bracketed paste mode.
   140  	DisablePaste()
   141  
   142  	// HasMouse returns true if the terminal (apparently) supports a
   143  	// mouse.  Note that the return value of true doesn't guarantee that
   144  	// a mouse/pointing device is present; a false return definitely
   145  	// indicates no mouse support is available.
   146  	HasMouse() bool
   147  
   148  	// Colors returns the number of colors.  All colors are assumed to
   149  	// use the ANSI color map.  If a terminal is monochrome, it will
   150  	// return 0.
   151  	Colors() int
   152  
   153  	// Show makes all the content changes made using SetContent() visible
   154  	// on the display.
   155  	//
   156  	// It does so in the most efficient and least visually disruptive
   157  	// manner possible.
   158  	Show()
   159  
   160  	// Sync works like Show(), but it updates every visible cell on the
   161  	// physical display, assuming that it is not synchronized with any
   162  	// internal model.  This may be both expensive and visually jarring,
   163  	// so it should only be used when believed to actually be necessary.
   164  	//
   165  	// Typically, this is called as a result of a user-requested redraw
   166  	// (e.g. to clear up on-screen corruption caused by some other program),
   167  	// or during a resize event.
   168  	Sync()
   169  
   170  	// CharacterSet returns information about the character set.
   171  	// This isn't the full locale, but it does give us the input/output
   172  	// character set.  Note that this is just for diagnostic purposes,
   173  	// we normally translate input/output to/from UTF-8, regardless of
   174  	// what the user's environment is.
   175  	CharacterSet() string
   176  
   177  	// RegisterRuneFallback adds a fallback for runes that are not
   178  	// part of the character set -- for example one could register
   179  	// o as a fallback for ΓΈ.  This should be done cautiously for
   180  	// characters that might be displayed ordinarily in language
   181  	// specific text -- characters that could change the meaning of
   182  	// written text would be dangerous.  The intention here is to
   183  	// facilitate fallback characters in pseudo-graphical applications.
   184  	//
   185  	// If the terminal has fallbacks already in place via an alternate
   186  	// character set, those are used in preference.  Also, standard
   187  	// fallbacks for graphical characters in the alternate character set
   188  	// terminfo string are registered implicitly.
   189  	//
   190  	// The display string should be the same width as original rune.
   191  	// This makes it possible to register two character replacements
   192  	// for full width East Asian characters, for example.
   193  	//
   194  	// It is recommended that replacement strings consist only of
   195  	// 7-bit ASCII, since other characters may not display everywhere.
   196  	RegisterRuneFallback(r rune, subst string)
   197  
   198  	// UnregisterRuneFallback unmaps a replacement.  It will unmap
   199  	// the implicit ASCII replacements for alternate characters as well.
   200  	// When an unmapped char needs to be displayed, but no suitable
   201  	// glyph is available, '?' is emitted instead.  It is not possible
   202  	// to "disable" the use of alternate characters that are supported
   203  	// by your terminal except by changing the terminal database.
   204  	UnregisterRuneFallback(r rune)
   205  
   206  	// CanDisplay returns true if the given rune can be displayed on
   207  	// this screen.  Note that this is a best-guess effort -- whether
   208  	// your fonts support the character or not may be questionable.
   209  	// Mostly this is for folks who work outside of Unicode.
   210  	//
   211  	// If checkFallbacks is true, then if any (possibly imperfect)
   212  	// fallbacks are registered, this will return true.  This will
   213  	// also return true if the terminal can replace the glyph with
   214  	// one that is visually indistinguishable from the one requested.
   215  	CanDisplay(r rune, checkFallbacks bool) bool
   216  
   217  	// Resize does nothing, since it's generally not possible to
   218  	// ask a screen to resize, but it allows the Screen to implement
   219  	// the View interface.
   220  	Resize(int, int, int, int)
   221  
   222  	// HasKey returns true if the keyboard is believed to have the
   223  	// key.  In some cases a keyboard may have keys with this name
   224  	// but no support for them, while in others a key may be reported
   225  	// as supported but not actually be usable (such as some emulators
   226  	// that hijack certain keys).  Its best not to depend to strictly
   227  	// on this function, but it can be used for hinting when building
   228  	// menus, displayed hot-keys, etc.  Note that KeyRune (literal
   229  	// runes) is always true.
   230  	HasKey(Key) bool
   231  
   232  	// Suspend pauses input and output processing.  It also restores the
   233  	// terminal settings to what they were when the application started.
   234  	// This can be used to, for example, run a sub-shell.
   235  	Suspend() error
   236  
   237  	// Resume resumes after Suspend().
   238  	Resume() error
   239  
   240  	// Beep attempts to sound an OS-dependent audible alert and returns an error
   241  	// when unsuccessful.
   242  	Beep() error
   243  
   244  	// SetSize attempts to resize the window.  It also invalidates the cells and
   245  	// calls the resize function.  Note that if the window size is changed, it will
   246  	// not be restored upon application exit.
   247  	//
   248  	// Many terminals cannot support this.  Perversely, the "modern" Windows Terminal
   249  	// does not support application-initiated resizing, whereas the legacy terminal does.
   250  	// Also, some emulators can support this but may have it disabled by default.
   251  	SetSize(int, int)
   252  }
   253  
   254  // NewScreen returns a default Screen suitable for the user's terminal
   255  // environment.
   256  func NewScreen() (Screen, error) {
   257  	// Windows is happier if we try for a console screen first.
   258  	if s, _ := NewConsoleScreen(); s != nil {
   259  		return s, nil
   260  	} else if s, e := NewTerminfoScreen(); s != nil {
   261  		return s, nil
   262  	} else {
   263  		return nil, e
   264  	}
   265  }
   266  
   267  // MouseFlags are options to modify the handling of mouse events.
   268  // Actual events can be ORed together.
   269  type MouseFlags int
   270  
   271  const (
   272  	MouseButtonEvents = MouseFlags(1) // Click events only
   273  	MouseDragEvents   = MouseFlags(2) // Click-drag events (includes button events)
   274  	MouseMotionEvents = MouseFlags(4) // All mouse events (includes click and drag events)
   275  )
   276  
   277  // CursorStyle represents a given cursor style, which can include the shape and
   278  // whether the cursor blinks or is solid.  Support for changing this is not universal.
   279  type CursorStyle int
   280  
   281  const (
   282  	CursorStyleDefault = CursorStyle(iota) // The default
   283  	CursorStyleBlinkingBlock
   284  	CursorStyleSteadyBlock
   285  	CursorStyleBlinkingUnderline
   286  	CursorStyleSteadyUnderline
   287  	CursorStyleBlinkingBar
   288  	CursorStyleSteadyBar
   289  )
   290  

View as plain text