...

Source file src/github.com/gdamore/tcell/v2/views/textbar.go

Documentation: github.com/gdamore/tcell/v2/views

     1  // Copyright 2015 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 views
    16  
    17  import (
    18  	"sync"
    19  
    20  	"github.com/gdamore/tcell/v2"
    21  )
    22  
    23  // TextBar is a Widget that provides a single line of text, but with
    24  // distinct left, center, and right areas.  Each of the areas can be styled
    25  // differently, and they align to the left, center, and right respectively.
    26  // This is basically a convenience type on top Text and BoxLayout.
    27  type TextBar struct {
    28  	changed bool
    29  	style   tcell.Style
    30  	left    Text
    31  	right   Text
    32  	center  Text
    33  	view    View
    34  	lview   ViewPort
    35  	rview   ViewPort
    36  	cview   ViewPort
    37  	once    sync.Once
    38  
    39  	WidgetWatchers
    40  }
    41  
    42  // SetCenter sets the center text for the textbar.  The text is
    43  // always center aligned.
    44  func (t *TextBar) SetCenter(s string, style tcell.Style) {
    45  	t.initialize()
    46  	if style == tcell.StyleDefault {
    47  		style = t.style
    48  	}
    49  	t.center.SetText(s)
    50  	t.center.SetStyle(style)
    51  }
    52  
    53  // SetLeft sets the left text for the textbar.  It is always left-aligned.
    54  func (t *TextBar) SetLeft(s string, style tcell.Style) {
    55  	t.initialize()
    56  	if style == tcell.StyleDefault {
    57  		style = t.style
    58  	}
    59  	t.left.SetText(s)
    60  	t.left.SetStyle(style)
    61  }
    62  
    63  // SetRight sets the right text for the textbar.  It is always right-aligned.
    64  func (t *TextBar) SetRight(s string, style tcell.Style) {
    65  	t.initialize()
    66  	if style == tcell.StyleDefault {
    67  		style = t.style
    68  	}
    69  	t.right.SetText(s)
    70  	t.right.SetStyle(style)
    71  }
    72  
    73  // SetStyle is used to set a default style to use for the textbar, including
    74  // areas where no text is present.  Note that this will not change the text
    75  // already displayed, so call this before changing or setting text.
    76  func (t *TextBar) SetStyle(style tcell.Style) {
    77  	t.initialize()
    78  	t.style = style
    79  }
    80  
    81  func (t *TextBar) initialize() {
    82  	t.once.Do(func() {
    83  		t.center.SetView(&t.cview)
    84  		t.left.SetView(&t.lview)
    85  		t.right.SetView(&t.rview)
    86  		t.center.SetAlignment(VAlignTop | HAlignCenter)
    87  		t.left.SetAlignment(VAlignTop | HAlignLeft)
    88  		t.right.SetAlignment(VAlignTop | HAlignRight)
    89  		t.center.Watch(t)
    90  		t.left.Watch(t)
    91  		t.right.Watch(t)
    92  	})
    93  }
    94  
    95  func (t *TextBar) layout() {
    96  	w, _ := t.view.Size()
    97  	ww, wh := t.left.Size()
    98  	t.lview.Resize(0, 0, ww, wh)
    99  
   100  	ww, wh = t.center.Size()
   101  	t.cview.Resize((w-ww)/2, 0, ww, wh)
   102  
   103  	ww, wh = t.right.Size()
   104  	t.rview.Resize(w-ww, 0, ww, wh)
   105  
   106  	t.changed = false
   107  }
   108  
   109  // SetView sets the View drawing context for this TextBar.
   110  func (t *TextBar) SetView(view View) {
   111  	t.initialize()
   112  	t.view = view
   113  	t.lview.SetView(view)
   114  	t.rview.SetView(view)
   115  	t.cview.SetView(view)
   116  	t.changed = true
   117  }
   118  
   119  // Draw draws the TextBar into its View context.
   120  func (t *TextBar) Draw() {
   121  
   122  	t.initialize()
   123  	if t.changed {
   124  		t.layout()
   125  	}
   126  	w, h := t.view.Size()
   127  	for y := 0; y < h; y++ {
   128  		for x := 0; x < w; x++ {
   129  			t.view.SetContent(x, y, ' ', nil, t.style)
   130  		}
   131  	}
   132  
   133  	// Draw in reverse order -- if we clip, we will clip at the
   134  	// right side.
   135  	t.right.Draw()
   136  	t.center.Draw()
   137  	t.left.Draw()
   138  }
   139  
   140  // Resize is called when the TextBar's View changes size, and
   141  // updates the layout.
   142  func (t *TextBar) Resize() {
   143  	t.initialize()
   144  	t.layout()
   145  
   146  	t.left.Resize()
   147  	t.center.Resize()
   148  	t.right.Resize()
   149  
   150  	t.PostEventWidgetResize(t)
   151  }
   152  
   153  // Size implements the Size method for Widget, returning the width
   154  // and height in character cells.
   155  func (t *TextBar) Size() (int, int) {
   156  	w, h := 0, 0
   157  
   158  	ww, wh := t.left.Size()
   159  	w += ww
   160  	if wh > h {
   161  		h = wh
   162  	}
   163  	ww, wh = t.center.Size()
   164  	w += ww
   165  	if wh > h {
   166  		h = wh
   167  	}
   168  	ww, wh = t.right.Size()
   169  	w += ww
   170  	if wh > h {
   171  		h = wh
   172  	}
   173  	return w, h
   174  }
   175  
   176  // HandleEvent handles incoming events.  The only events handled are
   177  // those for the Text objects; when those change, the TextBar adjusts
   178  // the layout to accommodate.
   179  func (t *TextBar) HandleEvent(ev tcell.Event) bool {
   180  	switch ev.(type) {
   181  	case *EventWidgetContent:
   182  		t.changed = true
   183  		return true
   184  	}
   185  	return false
   186  }
   187  
   188  // NewTextBar creates an empty, initialized TextBar.
   189  func NewTextBar() *TextBar {
   190  	t := &TextBar{}
   191  	t.initialize()
   192  	return t
   193  }
   194  

View as plain text