292 Тотальный рефакторинг

This commit is contained in:
prospero78su 2019-05-07 12:49:53 +03:00
parent ea13700279
commit 6e4c62e758
17 changed files with 136 additions and 153 deletions

View File

@ -6,6 +6,7 @@ import (
term "github.com/nsf/termbox-go" term "github.com/nsf/termbox-go"
"sync/atomic" "sync/atomic"
мКнст "./пакКонстанты" мКнст "./пакКонстанты"
мИнт "./пакИнтерфейсы"
) )
// BarData is info about one bar in the chart. Every // BarData is info about one bar in the chart. Every
@ -58,7 +59,7 @@ If LegendWidth is greater than half of the chart it is not
displayed. The same is applied to ValueWidth displayed. The same is applied to ValueWidth
*/ */
type BarChart struct { type BarChart struct {
BaseControl *BaseControl
data []BarData data []BarData
autosize bool autosize bool
gap int32 gap int32
@ -77,7 +78,7 @@ w and h - are minimal size of the control.
scale - the way of scaling the control when the parent is resized. Use DoNotScale constant if the scale - the way of scaling the control when the parent is resized. Use DoNotScale constant if the
control should keep its original size. control should keep its original size.
*/ */
func CreateBarChart(parent Control, w, h int, scale int) *BarChart { func CreateBarChart(parent мИнт.ИВиджет, w, h int, scale int) *BarChart {
c := new(BarChart) c := new(BarChart)
c.BaseControl = NewBaseControl() c.BaseControl = NewBaseControl()

View File

@ -5,6 +5,7 @@ import (
term "github.com/nsf/termbox-go" term "github.com/nsf/termbox-go"
"sync" "sync"
"sync/atomic" "sync/atomic"
мИнт "./пакИнтерфейсы"
) )
// BaseControl is a base for all visible controls. // BaseControl is a base for all visible controls.
@ -23,14 +24,14 @@ type BaseControl struct {
tabSkip bool tabSkip bool
disabled bool disabled bool
hidden bool hidden bool
align мКнст.Align align мИнт.Align
parent Control parent мИнт.ИВиджет
inactive bool inactive bool
modal bool modal bool
padX, padY int padX, padY int
gapX, gapY int gapX, gapY int
pack мКнст.PackType pack мИнт.PackType
children []Control children []мИнт.ИВиджет
mtx sync.RWMutex mtx sync.RWMutex
onActive func(active bool) onActive func(active bool)
style string style string
@ -47,8 +48,8 @@ func nextRefId() int64 {
} }
//NewBaseControl -- //NewBaseControl --
func NewBaseControl() BaseControl { func NewBaseControl() *BaseControl {
return BaseControl{refID: nextRefId()} return &BaseControl{refID: nextRefId()}
} }
//SetClipped -- //SetClipped --
@ -238,12 +239,12 @@ func (c *BaseControl) SetVisible(visible bool) {
} }
//Parent -- //Parent --
func (c *BaseControl) Parent() Control { func (c *BaseControl) Parent() мИнт.ИВиджет {
return c.parent return c.parent
} }
//SetParent -- //SetParent --
func (c *BaseControl) SetParent(parent Control) { func (c *BaseControl) SetParent(parent мИнт.ИВиджет) {
if c.parent == nil { if c.parent == nil {
c.parent = parent c.parent = parent
} }
@ -290,12 +291,12 @@ func (c *BaseControl) SetGaps(dx, dy int) {
} }
//Pack -- //Pack --
func (c *BaseControl) Pack() мКнст.PackType { func (c *BaseControl) Pack() мИнт.PackType {
return c.pack return c.pack
} }
//SetPack -- //SetPack --
func (c *BaseControl) SetPack(pack мКнст.PackType) { func (c *BaseControl) SetPack(pack мИнт.PackType) {
c.pack = pack c.pack = pack
} }
@ -312,12 +313,12 @@ func (c *BaseControl) SetScale(scale int) {
} }
//Align -- //Align --
func (c *BaseControl) Align() мКнст.Align { func (c *BaseControl) Align() мИнт.Align {
return c.align return c.align
} }
//SetAlign -- //SetAlign --
func (c *BaseControl) SetAlign(align мКнст.Align) { func (c *BaseControl) SetAlign(align мИнт.Align) {
c.align = align c.align = align
} }
@ -431,9 +432,9 @@ func (c *BaseControl) ResizeChildren() {
} }
//AddChild -- //AddChild --
func (c *BaseControl) AddChild(control Control) { func (c *BaseControl) AddChild(control мИнт.ИВиджет) {
if c.children == nil { if c.children == nil {
c.children = make([]Control, 1) c.children = make([]мИнт.ИВиджет, 1)
c.children[0] = control c.children[0] = control
} else { } else {
if c.ChildExists(control) { if c.ChildExists(control) {
@ -443,8 +444,8 @@ func (c *BaseControl) AddChild(control Control) {
c.children = append(c.children, control) c.children = append(c.children, control)
} }
var ctrl Control var ctrl мИнт.ИВиджет
var mainCtrl Control var mainCtrl мИнт.ИВиджет
ctrl = c ctrl = c
for ctrl != nil { for ctrl != nil {
ww, hh := ctrl.MinimalSize() ww, hh := ctrl.MinimalSize()
@ -476,14 +477,14 @@ func (c *BaseControl) AddChild(control Control) {
} }
//Children -- //Children --
func (c *BaseControl) Children() []Control { func (c *BaseControl) Children() []мИнт.ИВиджет {
child := make([]Control, len(c.children)) child := make([]мИнт.ИВиджет, len(c.children))
copy(child, c.children) copy(child, c.children)
return child return child
} }
//ChildExists -- //ChildExists --
func (c *BaseControl) ChildExists(control Control) bool { func (c *BaseControl) ChildExists(control мИнт.ИВиджет) bool {
if len(c.children) == 0 { if len(c.children) == 0 {
return false return false
} }
@ -576,7 +577,7 @@ func (c *BaseControl) DrawChildren() {
defer PopClip() defer PopClip()
cp := ClippedParent(c) cp := ClippedParent(c)
var cTarget Control var cTarget мВид.ИВиджет
cTarget = c cTarget = c
if cp != nil { if cp != nil {
@ -607,7 +608,7 @@ func (c *BaseControl) setClipper() {
c.clipper = &rect{x: x, y: y, w: w, h: h} c.clipper = &rect{x: x, y: y, w: w, h: h}
} }
//HitTest -- //HitTest --
func (c *BaseControl) HitTest(x, y int) мКнст.HitResult { func (c *BaseControl) HitTest(x, y int) мИнт.HitResult {
if x > c.x && x < c.x+c.width-1 && if x > c.x && x < c.x+c.width-1 &&
y > c.y && y < c.y+c.height-1 { y > c.y && y < c.y+c.height-1 {
return мКнст.HitInside return мКнст.HitInside
@ -627,7 +628,7 @@ func (c *BaseControl) HitTest(x, y int) мКнст.HitResult {
} }
//ProcessEvent -- //ProcessEvent --
func (c *BaseControl) ProcessEvent(ev мКнст.Event) bool { func (c *BaseControl) ProcessEvent(ev мИнт.ИСобытие) bool {
return SendEventToChild(c, ev) return SendEventToChild(c, ev)
} }
@ -671,9 +672,9 @@ func (c *BaseControl) SetActiveTextColor(clr term.Attribute) {
func (c *BaseControl) SetActiveBackColor(clr term.Attribute) { func (c *BaseControl) SetActiveBackColor(clr term.Attribute) {
c.bgActive = clr c.bgActive = clr
} }
//RemoveChild --
func (c *BaseControl) removeChild(control Control) { func (c *BaseControl) RemoveChild(control мИнт.ИВиджет) {
children := []Control{} children := []мИнт.ИВиджет{}
for _, child := range c.children { for _, child := range c.children {
if child.RefID() == control.RefID() { if child.RefID() == control.RefID() {
@ -691,6 +692,6 @@ func (c *BaseControl) removeChild(control Control) {
// Destroy removes an object from its parental chain // Destroy removes an object from its parental chain
func (c *BaseControl) Destroy() { func (c *BaseControl) Destroy() {
c.parent.removeChild(c) c.parent.RemoveChild(c)
c.parent.SetConstraints(0, 0) c.parent.SetConstraints(0, 0)
} }

View File

@ -6,6 +6,7 @@ import (
"sync/atomic" "sync/atomic"
"time" "time"
мКнст "./пакКонстанты" мКнст "./пакКонстанты"
мИнт "./пакИнтерфейсы"
) )
/* /*
@ -14,11 +15,11 @@ emits OnClick event. Event has only one valid field Sender.
Button can be clicked with mouse or using space on keyboard while the Button is active. Button can be clicked with mouse or using space on keyboard while the Button is active.
*/ */
type Button struct { type Button struct {
BaseControl *BaseControl
shadowColor term.Attribute shadowColor term.Attribute
bgActive term.Attribute bgActive term.Attribute
pressed int32 pressed int32
onClick func(мКнст.Event) onClick func(мИнт.ИСобытие)
} }
/* /*
@ -30,7 +31,7 @@ title - button title.
scale - the way of scaling the control when the parent is resized. Use DoNotScale constant if the scale - the way of scaling the control when the parent is resized. Use DoNotScale constant if the
control should keep its original size. control should keep its original size.
*/ */
func CreateButton(parent Control, width, height int, title string, scale int) *Button { func CreateButton(parent мИнт.ИВиджет, width, height int, title string, scale int) *Button {
b := new(Button) b := new(Button)
b.BaseControl = NewBaseControl() b.BaseControl = NewBaseControl()
@ -117,7 +118,7 @@ processes an event it should return true. If the method returns false it means
that the control do not want or cannot process the event and the caller sends that the control do not want or cannot process the event and the caller sends
the event to the control parent the event to the control parent
*/ */
func (b *Button) ProcessEvent(event мКнст.Event) bool { func (b *Button) ProcessEvent(event мИнт.ИСобытие) bool {
if !b.Enabled() { if !b.Enabled() {
return false return false
} }
@ -165,6 +166,6 @@ func (b *Button) ProcessEvent(event мКнст.Event) bool {
// OnClick sets the callback that is called when one clicks button // OnClick sets the callback that is called when one clicks button
// with mouse or pressing space on keyboard while the button is active // with mouse or pressing space on keyboard while the button is active
func (b *Button) OnClick(fn func(мКнст.Event)) { func (b *Button) OnClick(fn func(мИнт.ИСобытие)) {
b.onClick = fn b.onClick = fn
} }

View File

@ -4,6 +4,7 @@ import (
xs "github.com/huandu/xstrings" xs "github.com/huandu/xstrings"
term "github.com/nsf/termbox-go" term "github.com/nsf/termbox-go"
мКнст "./пакКонстанты" мКнст "./пакКонстанты"
мИнт "./пакИнтерфейсы"
) )
/* /*
@ -11,7 +12,7 @@ CheckBox control. It can be two-state one(on and off) - it is default mode - or
State values are 0=off, 1=on, 2=third state State values are 0=off, 1=on, 2=third state
*/ */
type CheckBox struct { type CheckBox struct {
BaseControl *BaseControl
state int state int
allow3state bool allow3state bool
@ -27,7 +28,7 @@ scale - the way of scaling the control when the parent is resized. Use DoNotScal
control should keep its original size. control should keep its original size.
CheckBox state can be changed using mouse or pressing space on keyboard while the control is active CheckBox state can be changed using mouse or pressing space on keyboard while the control is active
*/ */
func CreateCheckBox(parent Control, width int, title string, scale int) *CheckBox { func CreateCheckBox(parent мИнт.ИВиджет, width int, title string, scale int) *CheckBox {
c := new(CheckBox) c := new(CheckBox)
c.BaseControl = NewBaseControl() c.BaseControl = NewBaseControl()
c.parent = parent c.parent = parent
@ -102,7 +103,7 @@ func (c *CheckBox) Draw() {
// processes an event it should return true. If the method returns false it means // processes an event it should return true. If the method returns false it means
// that the control do not want or cannot process the event and the caller sends // that the control do not want or cannot process the event and the caller sends
// the event to the control parent // the event to the control parent
func (c *CheckBox) ProcessEvent(event мКнст.Event) bool { func (c *CheckBox) ProcessEvent(event мИнт.ИСобытие) bool {
if (!c.Active() && event.Type == мКнст.EventKey) || !c.Enabled() { if (!c.Active() && event.Type == мКнст.EventKey) || !c.Enabled() {
return false return false
} }

View File

@ -4,6 +4,7 @@ import (
term "github.com/nsf/termbox-go" term "github.com/nsf/termbox-go"
"sync" "sync"
мКнст "./пакКонстанты" мКнст "./пакКонстанты"
мИнт "./пакИнтерфейсы"
) )
// Composer is a service object that manages Views and console, processes // Composer is a service object that manages Views and console, processes
@ -11,9 +12,9 @@ import (
// one object of this type // one object of this type
type Composer struct { type Composer struct {
// list of visible Views // list of visible Views
windows []Control windows []мИнт.ИВиджет
windowBorder мКнст.BorderStyle windowBorder мКнст.BorderStyle
consumer Control consumer мИнт.ИВиджет
// last pressed key - to make repeatable actions simpler, e.g, at first // last pressed key - to make repeatable actions simpler, e.g, at first
// one presses Ctrl+S and then just repeatedly presses arrow lest to // one presses Ctrl+S and then just repeatedly presses arrow lest to
// resize Window // resize Window
@ -53,7 +54,7 @@ func WindowManager() *Composer {
// this function the control will recieve all mouse and keyboard events even // this function the control will recieve all mouse and keyboard events even
// if it is not active or mouse is outside it. Useful to implement dragging // if it is not active or mouse is outside it. Useful to implement dragging
// or alike stuff // or alike stuff
func GrabEvents(c Control) { func GrabEvents(c мИнт.ИВиджет) {
comp.consumer = c comp.consumer = c
} }
@ -63,7 +64,7 @@ func ReleaseEvents() {
comp.consumer = nil comp.consumer = nil
} }
func termboxEventToLocal(ev term.Event) мКнст.Event { func termboxEventToLocal(ev term.Event) мИнт.ИСобытие {
e := мКнст.Event{Type: мКнст.EventType(ev.Type), Ch: ev.Ch, e := мКнст.Event{Type: мКнст.EventType(ev.Type), Ch: ev.Ch,
Key: ev.Key, Err: ev.Err, X: ev.MouseX, Y: ev.MouseY, Key: ev.Key, Err: ev.Err, X: ev.MouseX, Y: ev.MouseY,
Mod: ev.Mod, Width: ev.Width, Height: ev.Height} Mod: ev.Mod, Width: ev.Width, Height: ev.Height}
@ -146,16 +147,16 @@ func (c *Composer) EndUpdate() {
c.mtx.Unlock() c.mtx.Unlock()
} }
func (c *Composer) getWindowList() []Control { func (c *Composer) getWindowList() []мИнт.ИВиджет {
c.mtx.RLock() c.mtx.RLock()
defer c.mtx.RUnlock() defer c.mtx.RUnlock()
arr_copy := make([]Control, len(c.windows)) arr_copy := make([]мИнт.ИВиджет, len(c.windows))
copy(arr_copy, c.windows) copy(arr_copy, c.windows)
return arr_copy return arr_copy
} }
func (c *Composer) checkWindowUnderMouse(screenX, screenY int) (Control, мКнст.HitResult) { func (c *Composer) checkWindowUnderMouse(screenX, screenY int) (мИнт.ИВиджет, мИнт.HitResult) {
windows := c.getWindowList() windows := c.getWindowList()
if len(windows) == 0 { if len(windows) == 0 {
return nil, мКнст.HitOutside return nil, мКнст.HitOutside
@ -172,7 +173,7 @@ func (c *Composer) checkWindowUnderMouse(screenX, screenY int) (Control, мКн
return nil, мКнст.HitOutside return nil, мКнст.HitOutside
} }
func (c *Composer) activateWindow(window Control) bool { func (c *Composer) activateWindow(window мИнт.ИВиджет) bool {
windows := c.getWindowList() windows := c.getWindowList()
if c.topWindow() == window { if c.topWindow() == window {
for _, v := range windows { for _, v := range windows {
@ -256,7 +257,7 @@ func (c *Composer) moveActiveWindowToBottom() bool {
return true return true
} }
func (c *Composer) sendEventToActiveWindow(ev мКнст.Event) bool { func (c *Composer) sendEventToActiveWindow(ev мИнт.ИВиджет) bool {
view := c.topWindow() view := c.topWindow()
if view != nil { if view != nil {
return view.ProcessEvent(ev) return view.ProcessEvent(ev)
@ -265,7 +266,7 @@ func (c *Composer) sendEventToActiveWindow(ev мКнст.Event) bool {
return false return false
} }
func (c *Composer) topWindow() Control { func (c *Composer) topWindow() мИнт.ИВиджет {
windows := c.getWindowList() windows := c.getWindowList()
if len(windows) == 0 { if len(windows) == 0 {
@ -275,7 +276,7 @@ func (c *Composer) topWindow() Control {
return windows[len(windows)-1] return windows[len(windows)-1]
} }
func (c *Composer) resizeTopWindow(ev мКнст.Event) bool { func (c *Composer) resizeTopWindow(ev мИнт.ИСобытие) bool {
view := c.topWindow() view := c.topWindow()
if view == nil { if view == nil {
return false return false
@ -309,7 +310,7 @@ func (c *Composer) resizeTopWindow(ev мКнст.Event) bool {
return true return true
} }
func (c *Composer) moveTopWindow(ev мКнст.Event) bool { func (c *Composer) moveTopWindow(ev мИнт.ИСобытие) bool {
view := c.topWindow() view := c.topWindow()
if view != nil { if view != nil {
topwindow, ok := view.(*Window) topwindow, ok := view.(*Window)
@ -362,7 +363,7 @@ func (c *Composer) closeTopWindow() {
} }
} }
func (c *Composer) processWindowDrag(ev мКнст.Event) { func (c *Composer) processWindowDrag(ev мИнт.ИСобытие) {
if ev.Mod != term.ModMotion || c.dragType == мКнст.DragNone { if ev.Mod != term.ModMotion || c.dragType == мКнст.DragNone {
return return
} }
@ -491,7 +492,7 @@ func (c *Composer) processWindowDrag(ev мКнст.Event) {
} }
} }
func (c *Composer) processMouse(ev мКнст.Event) { func (c *Composer) processMouse(ev мИнт.ИСобытие) {
if c.consumer != nil { if c.consumer != nil {
tmp := c.consumer tmp := c.consumer
tmp.ProcessEvent(ev) tmp.ProcessEvent(ev)
@ -587,12 +588,12 @@ func Stop() {
} }
// DestroyWindow removes the Window from the list of managed Windows // DestroyWindow removes the Window from the list of managed Windows
func (c *Composer) DestroyWindow(view Control) { func (c *Composer) DestroyWindow(view мИнт.ИВиджет) {
ev := мКнст.Event{Type: мКнст.EventClose} ev := мКнст.Event{Type: мКнст.EventClose}
c.sendEventToActiveWindow(ev) c.sendEventToActiveWindow(ev)
windows := c.getWindowList() windows := c.getWindowList()
var newOrder []Control var newOrder []мИнт.ИВиджет
for i := 0; i < len(windows); i++ { for i := 0; i < len(windows); i++ {
if windows[i] != view { if windows[i] != view {
newOrder = append(newOrder, windows[i]) newOrder = append(newOrder, windows[i])
@ -622,7 +623,7 @@ func IsDeadKey(key term.Key) bool {
return false return false
} }
func (c *Composer) processKey(ev мКнст.Event) { func (c *Composer) processKey(ev мИнт.ИСобытие) {
if ev.Key == term.KeyEsc { if ev.Key == term.KeyEsc {
if IsDeadKey(c.lastKey) { if IsDeadKey(c.lastKey) {
c.lastKey = term.KeyEsc c.lastKey = term.KeyEsc
@ -698,7 +699,7 @@ func (c *Composer) processKey(ev мКнст.Event) {
} }
} }
//ProcessEvent -- //ProcessEvent --
func ProcessEvent(ev мКнст.Event) { func ProcessEvent(ev мИнт.ИСобытие) {
switch ev.Type { switch ev.Type {
case мКнст.EventCloseWindow: case мКнст.EventCloseWindow:
comp.closeTopWindow() comp.closeTopWindow()

View File

@ -2,11 +2,11 @@ package clui
import ( import (
term "github.com/nsf/termbox-go" term "github.com/nsf/termbox-go"
мКнст "./пакКонстанты" мИнт "./пакИнтерфейсы."
) )
// Control is an interface that every visible control should implement // TControl is an interface that every visible control should implement
type Control interface { type TControl interface {
// Title returns the current title or text of the control // Title returns the current title or text of the control
Title() string Title() string
// SetTitle changes control text or title // SetTitle changes control text or title
@ -44,10 +44,10 @@ type Control interface {
SetVisible(enabled bool) SetVisible(enabled bool)
// Parent return control's container or nil if there is no parent container // Parent return control's container or nil if there is no parent container
// that is true for Windows // that is true for Windows
Parent() Control Parent() мИнт.ИВиджет
// The function should not be called manually. It is for internal use by // The function should not be called manually. It is for internal use by
// library // library
SetParent(parent Control) SetParent(parent мИнт.ИВиджет)
// Modal returns if a control is always on top and does not allow to // Modal returns if a control is always on top and does not allow to
// change the current control. Used only by Windows, for other kind of // change the current control. Used only by Windows, for other kind of
// controls it does nothing // controls it does nothing
@ -66,9 +66,9 @@ type Control interface {
SetGaps(dx, dy int) SetGaps(dx, dy int)
// Pack returns direction in which a container packs // Pack returns direction in which a container packs
// its children: horizontal or vertical // its children: horizontal or vertical
Pack() мКнст.PackType Pack() мИнт.PackType
// SetPack changes the direction of children packing // SetPack changes the direction of children packing
SetPack(pack мКнст.PackType) SetPack(pack мИнт.PackType)
// Scale return scale coefficient that is used to calculate // Scale return scale coefficient that is used to calculate
// new control size after its parent resizes. // new control size after its parent resizes.
// Fixed means the controls never changes its size. // Fixed means the controls never changes its size.
@ -85,8 +85,8 @@ type Control interface {
// See Scale method for details // See Scale method for details
SetScale(scale int) SetScale(scale int)
// Align returns alignment of title in control // Align returns alignment of title in control
Align() мКнст.Align Align() мИнт.Align
SetAlign(align мКнст.Align) SetAlign(align мИнт.Align)
TextColor() term.Attribute TextColor() term.Attribute
// SetTextColor changes text color of the control. // SetTextColor changes text color of the control.
@ -110,12 +110,12 @@ type Control interface {
// AddChild adds a new child to a container // AddChild adds a new child to a container
// The method should not be called manually. It is automatically called // The method should not be called manually. It is automatically called
// if parent is not nil in Create* function // if parent is not nil in Create* function
AddChild(control Control) AddChild(control мИнт.ИВиджет)
// Children returns the copy of the list of container child controls // Children returns the copy of the list of container child controls
Children() []Control Children() []мИнт.ИВиджет
// ChildExists returns true if a control has argument as one of its // ChildExists returns true if a control has argument as one of its
// children or child of one of the children // children or child of one of the children
ChildExists(control Control) bool ChildExists(control мИнт.ИВиджет) bool
// MinimalSize returns the minimal size required by a control to show // MinimalSize returns the minimal size required by a control to show
// it and all its children. // it and all its children.
MinimalSize() (w int, h int) MinimalSize() (w int, h int)
@ -142,18 +142,18 @@ type Control interface {
// HitTest returns the area that corresponds to the clicked // HitTest returns the area that corresponds to the clicked
// position X, Y (absolute position in console window): title, // position X, Y (absolute position in console window): title,
// internal view area, title button, border or outside the control // internal view area, title button, border or outside the control
HitTest(x, y int) мКнст.HitResult HitTest(x, y int) мИнт.HitResult
// ProcessEvent processes all events come from the control parent. If a control // ProcessEvent processes all events come from the control parent. If a control
// processes an event it should return true. If the method returns false it means // processes an event it should return true. If the method returns false it means
// that the control do not want or cannot process the event and the caller sends // that the control do not want or cannot process the event and the caller sends
// the event to the control parent // the event to the control parent
ProcessEvent(ev мКнст.Event) bool ProcessEvent(ev мИнт.ИСобытие) bool
// RefID returns the controls internal reference id // RefID returns the controls internal reference id
RefID() int64 RefID() int64
// removeChild removes a child from a container // removeChild removes a child from a container
// It's used to "destroy" controls whenever a control is no longer used // It's used to "destroy" controls whenever a control is no longer used
// by the user // by the user
removeChild(control Control) removeChild(control мИнт.ИВиджет)
// Destroy is the public interface to remove an object from its parental chain // Destroy is the public interface to remove an object from its parental chain
// it implies this control will stop receiving events and will not be drawn nor // it implies this control will stop receiving events and will not be drawn nor
// will impact on other objects position and size calculation // will impact on other objects position and size calculation

View File

@ -3,6 +3,7 @@ package clui
import ( import (
мКнст "./пакКонстанты" мКнст "./пакКонстанты"
term "github.com/nsf/termbox-go" term "github.com/nsf/termbox-go"
мИнт "./пакИнтерфейсы"
) )
// ThumbPosition returns a scrollbar thumb position depending // ThumbPosition returns a scrollbar thumb position depending
@ -58,7 +59,7 @@ func ItemByThumbPosition(position, itemCount, length int) int {
// ChildAt returns the children of parent control that is at absolute // ChildAt returns the children of parent control that is at absolute
// coordinates x, y. Returns nil if x, y are outside parent control and // coordinates x, y. Returns nil if x, y are outside parent control and
// returns parent if no child is at x, y // returns parent if no child is at x, y
func ChildAt(parent Control, x, y int) Control { func ChildAt(parent мИнт.ИВиджет, x, y int) мИнт.ИВиджет {
px, py := parent.Pos() px, py := parent.Pos()
pw, ph := parent.Size() pw, ph := parent.Size()
if px > x || py > y || px+pw <= x || py+ph <= y { if px > x || py > y || px+pw <= x || py+ph <= y {
@ -69,7 +70,7 @@ func ChildAt(parent Control, x, y int) Control {
return parent return parent
} }
var ctrl Control var ctrl мИнт.ИВиджет
ctrl = parent ctrl = parent
for _, child := range parent.Children() { for _, child := range parent.Children() {
if !child.Visible() { if !child.Visible() {
@ -87,7 +88,7 @@ func ChildAt(parent Control, x, y int) Control {
} }
// DeactivateControls makes all children of parent inactive // DeactivateControls makes all children of parent inactive
func DeactivateControls(parent Control) { func DeactivateControls(parent мИнт.ИВиджет) {
for _, ctrl := range parent.Children() { for _, ctrl := range parent.Children() {
if ctrl.Active() { if ctrl.Active() {
ctrl.SetActive(false) ctrl.SetActive(false)
@ -100,7 +101,7 @@ func DeactivateControls(parent Control) {
// ActivateControl makes control active and disables all other children of // ActivateControl makes control active and disables all other children of
// the parent. Returns true if control was found and activated // the parent. Returns true if control was found and activated
func ActivateControl(parent, control Control) bool { func ActivateControl(parent, control мИнт.ИВиджет) bool {
DeactivateControls(parent) DeactivateControls(parent)
res := false res := false
ctrl := FindChild(parent, control) ctrl := FindChild(parent, control)
@ -116,8 +117,8 @@ func ActivateControl(parent, control Control) bool {
} }
// FindChild returns control if it is a child of the parent and nil otherwise // FindChild returns control if it is a child of the parent and nil otherwise
func FindChild(parent, control Control) Control { func FindChild(parent, control мИнт.ИВиджет) мИнт.ИВиджет {
var res Control var res мИнт.ИВиджет
if parent == control { if parent == control {
return parent return parent
@ -139,7 +140,7 @@ func FindChild(parent, control Control) Control {
} }
// IsMouseClickEvent returns if a user action can be treated as mouse click. // IsMouseClickEvent returns if a user action can be treated as mouse click.
func IsMouseClickEvent(ev мКнст.Event) bool { func IsMouseClickEvent(ev мИнт.ИСобытие) bool {
if ev.Type == мКнст.EventClick { if ev.Type == мКнст.EventClick {
return true return true
} }
@ -152,7 +153,7 @@ func IsMouseClickEvent(ev мКнст.Event) bool {
// FindFirstControl returns the first child for that fn returns true. // FindFirstControl returns the first child for that fn returns true.
// The function is used to find active or tab-stop control // The function is used to find active or tab-stop control
func FindFirstControl(parent Control, fn func(Control) bool) Control { func FindFirstControl(parent мИнт.ИВиджет, fn func(мИнт.ИВиджет) bool) мИнт.ИВиджет {
linear := getLinearControlList(parent, fn) linear := getLinearControlList(parent, fn)
if len(linear) == 0 { if len(linear) == 0 {
return nil return nil
@ -164,7 +165,7 @@ func FindFirstControl(parent Control, fn func(Control) bool) Control {
// FindLastControl returns the first child for that fn returns true. // FindLastControl returns the first child for that fn returns true.
// The function is used by TAB processing method if a user goes backwards // The function is used by TAB processing method if a user goes backwards
// with TAB key - not supported now // with TAB key - not supported now
func FindLastControl(parent Control, fn func(Control) bool) Control { func FindLastControl(parent мИнт.ИВиджет, fn func(мИнт.ИВиджет) bool) мИнт.ИВиджет {
linear := getLinearControlList(parent, fn) linear := getLinearControlList(parent, fn)
if len(linear) == 0 { if len(linear) == 0 {
@ -176,7 +177,7 @@ func FindLastControl(parent Control, fn func(Control) bool) Control {
// ActiveControl returns the active child of the parent or nil if no child is // ActiveControl returns the active child of the parent or nil if no child is
// active // active
func ActiveControl(parent Control) Control { func ActiveControl(parent мИнт.ИВиджет) мИнт.ИВиджет {
fnActive := func(c Control) bool { fnActive := func(c Control) bool {
return c.Active() return c.Active()
} }
@ -184,7 +185,7 @@ func ActiveControl(parent Control) Control {
} }
// FindFirstActiveControl returns the first active control of a parent // FindFirstActiveControl returns the first active control of a parent
func FindFirstActiveControl(parent Control) Control { func FindFirstActiveControl(parent мИнт.ИВиджет) мИнт.ИВиджет {
for _, curr := range getLinearControlList(parent, nil) { for _, curr := range getLinearControlList(parent, nil) {
if curr.Active() { if curr.Active() {
return curr return curr
@ -193,8 +194,8 @@ func FindFirstActiveControl(parent Control) Control {
return nil return nil
} }
func getLinearControlList(parent Control, fn func(Control) bool) []Control { func getLinearControlList(parent мИнт.ИВиджет, fn func(мИнт.ИВиджет) bool) []мИнт.ИВиджет {
result := []Control{} result := []мИнт.ИВиджет{}
for _, curr := range parent.Children() { for _, curr := range parent.Children() {
if fn != nil && fn(curr) { if fn != nil && fn(curr) {
@ -216,8 +217,8 @@ func getLinearControlList(parent Control, fn func(Control) bool) []Control {
// NextControl returns the next or previous child (depends on next parameter) // NextControl returns the next or previous child (depends on next parameter)
// that has tab-stop feature on. Used by library when processing TAB key // that has tab-stop feature on. Used by library when processing TAB key
func NextControl(parent Control, curr Control, next bool) Control { func NextControl(parent мИнт.ИВиджет, curr мИнт.ИВиджет, next bool) мИнт.ИВиджет {
fnTab := func(c Control) bool { fnTab := func(c мИнт.ИВиджет) bool {
isVisible := func() bool { isVisible := func() bool {
ctrl := c.Parent() ctrl := c.Parent()
@ -273,8 +274,8 @@ func NextControl(parent Control, curr Control, next bool) Control {
// makes it active, and then sends the event to it. // makes it active, and then sends the event to it.
// If it is not mouse click event then it looks for the first active child and // If it is not mouse click event then it looks for the first active child and
// sends the event to it if it is not nil // sends the event to it if it is not nil
func SendEventToChild(parent Control, ev мКнст.Event) bool { func SendEventToChild(parent мИнт.ИВиджет, ev мИнт.ИСобытие) bool {
var child Control var child мИнт.ИВиджет
if IsMouseClickEvent(ev) { if IsMouseClickEvent(ev) {
child = ChildAt(parent, ev.X, ev.Y) child = ChildAt(parent, ev.X, ev.Y)
if child != nil && !child.Active() { if child != nil && !child.Active() {
@ -300,7 +301,7 @@ func SendEventToChild(parent Control, ev мКнст.Event) bool {
// CalcClipper calculates the clipper size based on the control's size, position // CalcClipper calculates the clipper size based on the control's size, position
// and paddings // and paddings
func CalcClipper(c Control) (int, int, int, int) { func CalcClipper(c мИнт.ИВиджет) (int, int, int, int) {
w, h := c.Size() w, h := c.Size()
x, y := c.Pos() x, y := c.Pos()
px, py := c.Paddings() px, py := c.Paddings()
@ -314,8 +315,8 @@ func CalcClipper(c Control) (int, int, int, int) {
} }
// ClippedParent finds the first c parent with clipped flag // ClippedParent finds the first c parent with clipped flag
func ClippedParent(c Control) Control { func ClippedParent(c мИнт.ИВиджет) мИнт.ИВиджет {
var clipped Control var clipped мИнт.ИВиджет
ctrl := c.Parent() ctrl := c.Parent()
clipped = c clipped = c
@ -333,7 +334,7 @@ func ClippedParent(c Control) Control {
} }
// ControlInRect returns true if c is within a given rect // ControlInRect returns true if c is within a given rect
func ControlInRect(c Control, x int, y int, w int, h int) bool { func ControlInRect(c мИнт.ИВиджет, x int, y int, w int, h int) bool {
xx, yy := c.Pos() xx, yy := c.Pos()
ww, hh := c.Size() ww, hh := c.Size()

View File

@ -5,10 +5,11 @@ import (
term "github.com/nsf/termbox-go" term "github.com/nsf/termbox-go"
"strings" "strings"
мКнст "./пакКонстанты" мКнст "./пакКонстанты"
мИнт "./пакИнтерфейсы"
) )
// OnChange sets the callback that is called when EditField content is changed // OnChange sets the callback that is called when EditField content is changed
func (e *EditField) OnChange(fn func(мКнст.Event)) { func (e *EditField) OnChange(fn func(мИнт.ИСобытие)) {
e.onChange = fn e.onChange = fn
} }

View File

@ -7,6 +7,7 @@ import (
xs "github.com/huandu/xstrings" xs "github.com/huandu/xstrings"
term "github.com/nsf/termbox-go" term "github.com/nsf/termbox-go"
мКнст "./пакКонстанты" мКнст "./пакКонстанты"
мИнт "./пакИнтерфейсы"
) )
/* /*
@ -28,7 +29,7 @@ type EditField struct {
maxWidth int maxWidth int
showStars bool showStars bool
onChange func(мКнст.Event) onChange func(мИнт.ИСобытие)
onKeyPress func(term.Key, rune) bool onKeyPress func(term.Key, rune) bool
} }
@ -39,7 +40,7 @@ type EditField struct {
// text - text to edit. // text - text to edit.
// scale - the way of scaling the control when the parent is resized. Use DoNotScale constant if the // scale - the way of scaling the control when the parent is resized. Use DoNotScale constant if the
// control should keep its original size. // control should keep its original size.
func CreateEditField(parent Control, width int, text string, scale int) *EditField { func CreateEditField(parent мИнт.ИВиджет, width int, text string, scale int) *EditField {
e := new(EditField) e := new(EditField)
e.BaseControl = NewBaseControl() e.BaseControl = NewBaseControl()
e.onChange = nil e.onChange = nil
@ -74,7 +75,7 @@ processes an event it should return true. If the method returns false it means
that the control do not want or cannot process the event and the caller sends that the control do not want or cannot process the event and the caller sends
the event to the control parent the event to the control parent
*/ */
func (e *EditField) ProcessEvent(event мКнст.Event) bool { func (e *EditField) ProcessEvent(event мИнт.ИСобытие) bool {
if !e.Active() || !e.Enabled() { if !e.Active() || !e.Enabled() {
return false return false
} }

View File

@ -4,6 +4,7 @@ import (
xs "github.com/huandu/xstrings" xs "github.com/huandu/xstrings"
"math" "math"
мКнст "./пакКонстанты" мКнст "./пакКонстанты"
мИнт "./пакИнтерфейсы"
) )
/* /*
@ -15,8 +16,8 @@ is required
type Frame struct { type Frame struct {
BaseControl BaseControl
border мКнст.BorderStyle border мКнст.BorderStyle
children []Control children []мИнт.ИВиджет
pack мКнст.PackType pack мИнт.PackType
scrollable bool scrollable bool
lastScrollProp int lastScrollProp int
} }
@ -30,7 +31,7 @@ bs - type of border: no border, single or double.
scale - the way of scaling the control when the parent is resized. Use DoNotScale constant if the scale - the way of scaling the control when the parent is resized. Use DoNotScale constant if the
control should keep its original size. control should keep its original size.
*/ */
func CreateFrame(parent Control, width, height int, bs мКнст.BorderStyle, scale int) *Frame { func CreateFrame(parent мИнт.ИВиджет, width, height int, bs мКнст.BorderStyle, scale int) *Frame {
f := new(Frame) f := new(Frame)
f.BaseControl = NewBaseControl() f.BaseControl = NewBaseControl()
@ -174,7 +175,7 @@ func (f *Frame) ScrollTo(x int, y int) {
f.PlaceChildren() f.PlaceChildren()
} }
//ProcessEvent -- //ProcessEvent --
func (f *Frame) ProcessEvent(ev мКнст.Event) bool { func (f *Frame) ProcessEvent(ev мИнт.ИСобытие) bool {
if ev.Type != мКнст.EventActivateChild || (!f.scrollable || ev.Target == nil) { if ev.Type != мКнст.EventActivateChild || (!f.scrollable || ev.Target == nil) {
return false return false
} }

View File

@ -3,6 +3,7 @@ package clui
import ( import (
xs "github.com/huandu/xstrings" xs "github.com/huandu/xstrings"
мКнст "./пакКонстанты" мКнст "./пакКонстанты"
мИнт "./пакИнтерфейсы"
) )
/* /*
@ -17,7 +18,7 @@ type Label struct {
BaseControl BaseControl
direction мКнст.Direction direction мКнст.Direction
multiline bool multiline bool
textDisplay мКнст.Align textDisplay мИнт.Align
} }
/* /*
@ -29,7 +30,7 @@ title - is Label title.
scale - the way of scaling the control when the parent is resized. Use DoNotScale constant if the scale - the way of scaling the control when the parent is resized. Use DoNotScale constant if the
control should keep its original size. control should keep its original size.
*/ */
func CreateLabel(parent Control, w, h int, title string, scale int) *Label { func CreateLabel(parent мИнт.ИВиджет, w, h int, title string, scale int) *Label {
c := new(Label) c := new(Label)
c.BaseControl = NewBaseControl() c.BaseControl = NewBaseControl()
@ -156,7 +157,7 @@ func (l *Label) SetMultiline(multi bool) {
// - AlignLeft - the head of the title is shown // - AlignLeft - the head of the title is shown
// - AlignRight - the tail of the title is shown // - AlignRight - the tail of the title is shown
// The property is used only by single line Label // The property is used only by single line Label
func (l *Label) TextDisplay() мКнст.Align { func (l *Label) TextDisplay() мИнт.Align {
return l.textDisplay return l.textDisplay
} }
@ -164,7 +165,7 @@ func (l *Label) TextDisplay() мКнст.Align {
// is longer than the lable. Only AlignLeft and AlignRigth are valid values // is longer than the lable. Only AlignLeft and AlignRigth are valid values
// for the property. Any other value does is skipped and does not affect // for the property. Any other value does is skipped and does not affect
// displaying the title // displaying the title
func (l *Label) SetTextDisplay(align мКнст.Align) { func (l *Label) SetTextDisplay(align мИнт.Align) {
if align != мКнст.AlignLeft && align != мКнст.AlignRight { if align != мКнст.AlignLeft && align != мКнст.AlignRight {
return return
} }

View File

@ -4,6 +4,7 @@ import (
term "github.com/nsf/termbox-go" term "github.com/nsf/termbox-go"
"strings" "strings"
мКнст "./пакКонстанты" мКнст "./пакКонстанты"
мИнт "./пакИнтерфейсы"
) )
/* /*
@ -25,7 +26,7 @@ type ListBox struct {
topLine int topLine int
buttonPos int buttonPos int
onSelectItem func(мКнст.Event) onSelectItem func(мИнт.ИСобытие)
onKeyPress func(term.Key) bool onKeyPress func(term.Key) bool
} }
@ -37,7 +38,7 @@ width and heigth - are minimal size of the control.
scale - the way of scaling the control when the parent is resized. Use DoNotScale constant if the scale - the way of scaling the control when the parent is resized. Use DoNotScale constant if the
control should keep its original size. control should keep its original size.
*/ */
func CreateListBox(parent Control, width, height int, scale int) *ListBox { func CreateListBox(parent мИнт.ИВиджет, width, height int, scale int) *ListBox {
l := new(ListBox) l := new(ListBox)
l.BaseControl = NewBaseControl() l.BaseControl = NewBaseControl()
@ -247,7 +248,7 @@ func (l *ListBox) Clear() {
l.topLine = 0 l.topLine = 0
} }
func (l *ListBox) processMouseClick(ev мКнст.Event) bool { func (l *ListBox) processMouseClick(ev мИнт.ИСобытие) bool {
if ev.Key != term.MouseLeft { if ev.Key != term.MouseLeft {
return false return false
} }
@ -310,7 +311,7 @@ processes an event it should return true. If the method returns false it means
that the control do not want or cannot process the event and the caller sends that the control do not want or cannot process the event and the caller sends
the event to the control parent the event to the control parent
*/ */
func (l *ListBox) ProcessEvent(event мКнст.Event) bool { func (l *ListBox) ProcessEvent(event мИнт.ИСобытие) bool {
if !l.Active() || !l.Enabled() { if !l.Active() || !l.Enabled() {
return false return false
} }
@ -456,7 +457,7 @@ func (l *ListBox) RemoveItem(id int) bool {
// OnSelectItem sets a callback that is called every time // OnSelectItem sets a callback that is called every time
// the selected item is changed // the selected item is changed
func (l *ListBox) OnSelectItem(fn func(мКнст.Event)) { func (l *ListBox) OnSelectItem(fn func(мИнт.ИСобытие)) {
l.onSelectItem = fn l.onSelectItem = fn
} }

View File

@ -3,6 +3,7 @@ package clui
import ( import (
term "github.com/nsf/termbox-go" term "github.com/nsf/termbox-go"
мКнст "./пакКонстанты" мКнст "./пакКонстанты"
мИнт "./пакИнтерфейсы"
) )
// Composer is a service object that manages Views and console, processes // Composer is a service object that manages Views and console, processes
@ -10,7 +11,7 @@ import (
// one object of this type // one object of this type
type mainLoop struct { type mainLoop struct {
// a channel to communicate with View(e.g, Views send redraw event to this channel) // a channel to communicate with View(e.g, Views send redraw event to this channel)
channel chan мКнст.Event channel chan мИнт.ИСобытие
} }
var ( var (
@ -19,7 +20,7 @@ var (
func initMainLoop() { func initMainLoop() {
loop = new(mainLoop) loop = new(mainLoop)
loop.channel = make(chan мКнст.Event) loop.channel = make(chan мИнт.ИСобытие)
} }
// MainLoop starts the main application event loop // MainLoop starts the main application event loop
@ -53,12 +54,12 @@ func MainLoop() {
} }
} }
func _putEvent(ev мКнст.Event) { func _putEvent(ev мИнт.ИСобытие) {
loop.channel <- ev loop.channel <- ev
} }
// PutEvent send event to a Composer directly. // PutEvent send event to a Composer directly.
// Used by Views to ask for repainting or for quitting the application // Used by Views to ask for repainting or for quitting the application
func PutEvent(ev мКнст.Event) { func PutEvent(ev мИнт.ИСобытие) {
go _putEvent(ev) go _putEvent(ev)
} }

View File

@ -4,6 +4,7 @@ import (
xs "github.com/huandu/xstrings" xs "github.com/huandu/xstrings"
term "github.com/nsf/termbox-go" term "github.com/nsf/termbox-go"
мКнст "./пакКонстанты" мКнст "./пакКонстанты"
мИнт "./пакИнтерфейсы"
) )
/* /*
@ -104,7 +105,7 @@ that the control do not want or cannot process the event and the caller sends
the event to the control parent. the event to the control parent.
The control processes only space button and mouse clicks to make control selected. Deselecting control is not possible: one has to click another radio of the radio group to deselect this button The control processes only space button and mouse clicks to make control selected. Deselecting control is not possible: one has to click another radio of the radio group to deselect this button
*/ */
func (c *Radio) ProcessEvent(event мКнст.Event) bool { func (c *Radio) ProcessEvent(event мИнт.ИСобытие) bool {
if (!c.Active() && event.Type == мКнст.EventKey) || !c.Enabled() { if (!c.Active() && event.Type == мКнст.EventKey) || !c.Enabled() {
return false return false
} }

View File

@ -4,6 +4,7 @@ import (
"fmt" "fmt"
term "github.com/nsf/termbox-go" term "github.com/nsf/termbox-go"
мКнст "./пакКонстанты" мКнст "./пакКонстанты"
мИнт "./пакИнтерфейсы"
) )
/* /*
@ -78,7 +79,7 @@ type TableView struct {
type Column struct { type Column struct {
Title string Title string
Width int Width int
Alignment мКнст.Align Alignment мИнт.Align
Fg, Bg term.Attribute Fg, Bg term.Attribute
Sort мКнст.SortOrder Sort мКнст.SortOrder
} }

View File

@ -4,6 +4,7 @@ import (
мКнст "./пакКонстанты" мКнст "./пакКонстанты"
xs "github.com/huandu/xstrings" xs "github.com/huandu/xstrings"
term "github.com/nsf/termbox-go" term "github.com/nsf/termbox-go"
мИнт "./пакИнтерфейсы"
) )
// Window is an implemetation of View managed by Composer. // Window is an implemetation of View managed by Composer.
@ -22,15 +23,15 @@ type Window struct {
fixedSize bool fixedSize bool
border мКнст.BorderStyle border мКнст.BorderStyle
onClose func(мКнст.Event) bool onClose func(мИнт.ИСобытие) bool
onScreenResize func(мКнст.Event) onScreenResize func(мИнт.ИСобытие)
onKeyDown *keyDownCb onKeyDown *keyDownCb
} }
type keyDownCb struct { type keyDownCb struct {
data interface{} data interface{}
fn func(evt мКнст.Event, data interface{}) bool fn func(evt мИнт.ИСобытие, data interface{}) bool
} }
//CreateWindow -- //CreateWindow --

View File

@ -2,7 +2,7 @@ package пакКонстанты
import ( import (
term "github.com/nsf/termbox-go" term "github.com/nsf/termbox-go"
мВид "../пакВиджеты" мИнт "../пакИнтерфейсы"
) )
const ( const (
@ -27,19 +27,14 @@ type (
// ViewButton is a set of buttons displayed in a view title // ViewButton is a set of buttons displayed in a view title
ViewButton int ViewButton int
// HitResult is a type of a view area that is under mouse cursor. // HitResult is a type of a view area that is under mouse cursor.
// Used in mouse click events
HitResult int
// Align is text align: left, right and center
Align int
// EventType is a type of event fired by an object // EventType is a type of event fired by an object
EventType int EventType int
// Direction indicates the direction in which a control must draw its // Direction indicates the direction in which a control must draw its
// content. At that moment it can be applied to Label (text output // content. At that moment it can be applied to Label (text output
// direction and to ProgressBar (direction of bar filling) // direction and to ProgressBar (direction of bar filling)
Direction int Direction int
// PackType sets how to pack controls inside its parent. Can be Vertical or
// Horizontal
PackType int
// SelectDialogType sets the way of choosing an item from a list for // SelectDialogType sets the way of choosing an item from a list for
// SelectionDialog control: a list-based selections, or radio group one // SelectionDialog control: a list-based selections, or radio group one
SelectDialogType uint SelectDialogType uint
@ -72,33 +67,6 @@ const (
DragResizeTopRight DragResizeTopRight
) )
// Event is structure used by Views and controls to communicate with Composer
// and vice versa
type Event struct {
// Event type - the first events are mapped to termbox Event and then a few
// own events added to the end
Type EventType
// Mod - is a key modifier. Only Alt modifier is supported
Mod term.Modifier
// Msg is a text part of the event. Used by few events: e.g, ListBox click
// sends a value of clicked item
Msg string
// X and Y are multi-purpose fields: mouse coordinated for click event,
// X is used to indicate on/off for events like Activate
// Y is used for vertical-based events like ListBox item selection - id of the item
X, Y int
// Err is error got from termbox library
Err error
// Key is a pressed key
Key term.Key
// Ch is a printable representation of pressed key combinaton
Ch rune
// For resize event - new terminal size
Width int
Height int
Target мВид.ИВиджет
}
// BorderStyle constants // BorderStyle constants
const ( const (
BorderAuto BorderStyle = iota - 1 BorderAuto BorderStyle = iota - 1
@ -130,7 +98,7 @@ const (
// HitResult constants // HitResult constants
const ( const (
HitOutside HitResult = iota HitOutside мИнт.HitResult = iota
HitInside HitInside
HitBorder HitBorder
HitTop HitTop
@ -160,7 +128,7 @@ const (
// Alignment constants // Alignment constants
const ( const (
AlignLeft Align = iota AlignLeft мИнт.Align = iota
AlignRight AlignRight
AlignCenter AlignCenter
) )