...
  
  
     1  package cview
     2  
     3  import (
     4  	"sync"
     5  
     6  	"github.com/gdamore/tcell/v2"
     7  )
     8  
     9  
    10  
    11  type Window struct {
    12  	*Box
    13  
    14  	primitive Primitive
    15  
    16  	fullscreen bool
    17  
    18  	normalX, normalY int
    19  	normalW, normalH int
    20  
    21  	dragX, dragY   int
    22  	dragWX, dragWY int
    23  
    24  	sync.RWMutex
    25  }
    26  
    27  
    28  func NewWindow(primitive Primitive) *Window {
    29  	w := &Window{
    30  		Box:       NewBox(),
    31  		primitive: primitive,
    32  		dragWX:    -1,
    33  		dragWY:    -1,
    34  	}
    35  	w.Box.focus = w
    36  	return w
    37  }
    38  
    39  
    40  
    41  func (w *Window) SetFullscreen(fullscreen bool) {
    42  	w.Lock()
    43  	defer w.Unlock()
    44  
    45  	if w.fullscreen == fullscreen {
    46  		return
    47  	}
    48  
    49  	w.fullscreen = fullscreen
    50  	if w.fullscreen {
    51  		w.normalX, w.normalY, w.normalW, w.normalH = w.GetRect()
    52  	} else {
    53  		w.SetRect(w.normalX, w.normalY, w.normalW, w.normalH)
    54  	}
    55  }
    56  
    57  
    58  func (w *Window) Focus(delegate func(p Primitive)) {
    59  	w.Lock()
    60  	defer w.Unlock()
    61  
    62  	w.Box.Focus(delegate)
    63  
    64  	w.primitive.Focus(delegate)
    65  }
    66  
    67  
    68  func (w *Window) Blur() {
    69  	w.Lock()
    70  	defer w.Unlock()
    71  
    72  	w.Box.Blur()
    73  
    74  	w.primitive.Blur()
    75  }
    76  
    77  
    78  func (w *Window) HasFocus() bool {
    79  	w.RLock()
    80  	defer w.RUnlock()
    81  
    82  	focusable := w.primitive.GetFocusable()
    83  	if focusable != nil {
    84  		return focusable.HasFocus()
    85  	}
    86  
    87  	return w.Box.HasFocus()
    88  }
    89  
    90  
    91  func (w *Window) Draw(screen tcell.Screen) {
    92  	if !w.GetVisible() {
    93  		return
    94  	}
    95  
    96  	w.RLock()
    97  	defer w.RUnlock()
    98  
    99  	w.Box.Draw(screen)
   100  
   101  	x, y, width, height := w.GetInnerRect()
   102  	w.primitive.SetRect(x, y, width, height)
   103  	w.primitive.Draw(screen)
   104  }
   105  
   106  
   107  func (w *Window) InputHandler() func(event *tcell.EventKey, setFocus func(p Primitive)) {
   108  	return w.primitive.InputHandler()
   109  }
   110  
   111  
   112  func (w *Window) MouseHandler() func(action MouseAction, event *tcell.EventMouse, setFocus func(p Primitive)) (consumed bool, capture Primitive) {
   113  	return w.WrapMouseHandler(func(action MouseAction, event *tcell.EventMouse, setFocus func(p Primitive)) (consumed bool, capture Primitive) {
   114  		if !w.InRect(event.Position()) {
   115  			return false, nil
   116  		}
   117  
   118  		if action == MouseLeftDown || action == MouseMiddleDown || action == MouseRightDown {
   119  			setFocus(w)
   120  		}
   121  
   122  		if action == MouseLeftDown {
   123  			x, y, width, height := w.GetRect()
   124  			mouseX, mouseY := event.Position()
   125  
   126  			leftEdge := mouseX == x
   127  			rightEdge := mouseX == x+width-1
   128  			bottomEdge := mouseY == y+height-1
   129  			topEdge := mouseY == y
   130  
   131  			if mouseY >= y && mouseY <= y+height-1 {
   132  				if leftEdge {
   133  					w.dragX = -1
   134  				} else if rightEdge {
   135  					w.dragX = 1
   136  				}
   137  			}
   138  
   139  			if mouseX >= x && mouseX <= x+width-1 {
   140  				if bottomEdge {
   141  					w.dragY = -1
   142  				} else if topEdge {
   143  					if leftEdge || rightEdge {
   144  						w.dragY = 1
   145  					} else {
   146  						w.dragWX = mouseX - x
   147  						w.dragWY = mouseY - y
   148  					}
   149  				}
   150  			}
   151  		}
   152  
   153  		_, capture = w.primitive.MouseHandler()(action, event, setFocus)
   154  		return true, capture
   155  	})
   156  }
   157  
View as plain text