UX improvement - separate close window icon from other icons
This commit is contained in:
parent
9406044044
commit
4848282327
|
@ -7,7 +7,7 @@ Command Line User Interface (Console UI inspired by TurboVision) with built-in t
|
|||
|
||||
|
||||
## Current version
|
||||
The current version is 1.1.0. Please see details in [changelog](./changelog).
|
||||
The current version is 1.2.0. Please see details in [changelog](./changelog).
|
||||
|
||||
## Applications that uses the library
|
||||
* Terminal FB2 reader(termfb2): https://github.com/VladimirMarkelov/termfb2
|
||||
|
|
10
changelog
10
changelog
|
@ -1,3 +1,13 @@
|
|||
2019-05-10 - version 1.2.0
|
||||
[*] Dual license: MIT or BSD-2-Clause
|
||||
[*] Window icons minimize and maximize are swapped
|
||||
[*] UX improvement: minimize and maximize buttons moved to left side of
|
||||
a window to avoid closing window accidentally after misclicking.
|
||||
Old window title view:
|
||||
╔Demo═══════[^_X]╗
|
||||
New one:
|
||||
╔[_^]═Demo════[X]╗
|
||||
|
||||
2019-05-7 - version 1.2.0
|
||||
[*] Changed default window close icon from "O" to "■"
|
||||
[*] Doc comments clean up
|
||||
|
|
112
window.go
112
window.go
|
@ -57,19 +57,18 @@ func CreateWindow(x, y, w, h int, title string) *Window {
|
|||
return wnd
|
||||
}
|
||||
|
||||
func (wnd *Window) buttonCount() int {
|
||||
cnt := 0
|
||||
func (wnd *Window) buttonCount() (left, right int) {
|
||||
if wnd.buttons&ButtonClose == ButtonClose {
|
||||
cnt += 1
|
||||
right += 1
|
||||
}
|
||||
if wnd.buttons&ButtonMaximize == ButtonMaximize {
|
||||
cnt += 1
|
||||
left += 1
|
||||
}
|
||||
if wnd.buttons&ButtonBottom == ButtonBottom {
|
||||
cnt += 1
|
||||
left += 1
|
||||
}
|
||||
|
||||
return cnt
|
||||
return left, right
|
||||
}
|
||||
|
||||
func (wnd *Window) drawFrame() {
|
||||
|
@ -95,10 +94,19 @@ func (wnd *Window) drawTitle() {
|
|||
PushAttributes()
|
||||
defer PopAttributes()
|
||||
|
||||
btnCount := wnd.buttonCount()
|
||||
maxw := wnd.width - 2 - btnCount
|
||||
if btnCount > 0 {
|
||||
maxw -= 2
|
||||
lb, rb := wnd.buttonCount()
|
||||
maxw := wnd.width - 2
|
||||
xshift := 1
|
||||
if lb > 0 {
|
||||
lbSize := lb + 2 + 1
|
||||
maxw -= lbSize
|
||||
xshift += lbSize
|
||||
}
|
||||
if rb > 0 {
|
||||
maxw -= rb + 2
|
||||
}
|
||||
if maxw < 3 {
|
||||
return
|
||||
}
|
||||
|
||||
fitTitle := wnd.title
|
||||
|
@ -106,13 +114,12 @@ func (wnd *Window) drawTitle() {
|
|||
if xs.Len(rawText) > maxw {
|
||||
fitTitle = SliceColorized(fitTitle, 0, maxw-3) + "..."
|
||||
}
|
||||
|
||||
DrawText(wnd.x+1, wnd.y, fitTitle)
|
||||
DrawText(wnd.x+xshift, wnd.y, fitTitle)
|
||||
}
|
||||
|
||||
func (wnd *Window) drawButtons() {
|
||||
btnCount := wnd.buttonCount()
|
||||
if btnCount == 0 {
|
||||
lb, rb := wnd.buttonCount()
|
||||
if lb+rb == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -122,22 +129,28 @@ func (wnd *Window) drawButtons() {
|
|||
chars := []rune(SysObject(ObjViewButtons))
|
||||
cMax, cBottom, cClose, cOpenB, cCloseB := chars[0], chars[1], chars[2], chars[3], chars[4]
|
||||
|
||||
pos := wnd.x + wnd.width - btnCount - 2
|
||||
putCharUnsafe(pos, wnd.y, cOpenB)
|
||||
pos += 1
|
||||
if wnd.buttons&ButtonBottom == ButtonBottom {
|
||||
putCharUnsafe(pos, wnd.y, cBottom)
|
||||
pos += 1
|
||||
// draw close button (rb can be either 1 or 0)
|
||||
if rb != 0 {
|
||||
pos := wnd.x + wnd.width - rb - 2
|
||||
putCharUnsafe(pos, wnd.y, cOpenB)
|
||||
putCharUnsafe(pos+1, wnd.y, cClose)
|
||||
putCharUnsafe(pos+2, wnd.y, cCloseB)
|
||||
}
|
||||
if wnd.buttons&ButtonMaximize == ButtonMaximize {
|
||||
putCharUnsafe(pos, wnd.y, cMax)
|
||||
|
||||
if lb > 0 {
|
||||
pos := wnd.x + 1
|
||||
putCharUnsafe(pos, wnd.y, cOpenB)
|
||||
pos += 1
|
||||
if wnd.buttons&ButtonBottom == ButtonBottom {
|
||||
putCharUnsafe(pos, wnd.y, cBottom)
|
||||
pos += 1
|
||||
}
|
||||
if wnd.buttons&ButtonMaximize == ButtonMaximize {
|
||||
putCharUnsafe(pos, wnd.y, cMax)
|
||||
pos += 1
|
||||
}
|
||||
putCharUnsafe(pos, wnd.y, cCloseB)
|
||||
}
|
||||
if wnd.buttons&ButtonClose == ButtonClose {
|
||||
putCharUnsafe(pos, wnd.y, cClose)
|
||||
pos += 1
|
||||
}
|
||||
putCharUnsafe(pos, wnd.y, cCloseB)
|
||||
}
|
||||
|
||||
// Draw repaints the control on the screen
|
||||
|
@ -186,27 +199,36 @@ func (c *Window) HitTest(x, y int) HitResult {
|
|||
} else if x == c.x+c.width-1 && y > c.y && y < c.y+c.height-1 {
|
||||
hResult = HitRight
|
||||
} else if y == c.y && x > c.x && x < c.x+c.width-1 {
|
||||
btnCount := c.buttonCount()
|
||||
if x < c.x+c.width-1-btnCount {
|
||||
lb, rb := c.buttonCount()
|
||||
fromL, fromR := lb, rb
|
||||
if lb > 0 {
|
||||
fromL += 2
|
||||
}
|
||||
if rb > 0 {
|
||||
fromR += 2
|
||||
}
|
||||
if x > c.x+fromL && x < c.x+c.width-fromR {
|
||||
hResult = HitTop
|
||||
} else {
|
||||
hitRes := []HitResult{HitTop, HitTop, HitTop}
|
||||
pos := 0
|
||||
|
||||
if c.buttons&ButtonBottom == ButtonBottom {
|
||||
hitRes[pos] = HitButtonBottom
|
||||
pos += 1
|
||||
hResult = HitTop
|
||||
if c.buttons&ButtonClose == ButtonClose && rb != 0 && x == c.x+c.width-2 {
|
||||
hResult = HitButtonClose
|
||||
} else if lb != 0 && x > c.x+1 && x < c.x+2+lb {
|
||||
dx := x - c.x - 2
|
||||
hitRes := []HitResult{HitTop, HitTop}
|
||||
pos := 0
|
||||
if c.buttons&ButtonBottom == ButtonBottom {
|
||||
hitRes[pos] = HitButtonBottom
|
||||
pos += 1
|
||||
}
|
||||
if c.buttons&ButtonMaximize == ButtonMaximize {
|
||||
hitRes[pos] = HitButtonMaximize
|
||||
pos += 1
|
||||
}
|
||||
if dx < len(hitRes) {
|
||||
hResult = hitRes[dx]
|
||||
}
|
||||
}
|
||||
if c.buttons&ButtonMaximize == ButtonMaximize {
|
||||
hitRes[pos] = HitButtonMaximize
|
||||
pos += 1
|
||||
}
|
||||
if c.buttons&ButtonClose == ButtonClose {
|
||||
hitRes[pos] = HitButtonClose
|
||||
pos += 1
|
||||
}
|
||||
|
||||
hResult = hitRes[x-(c.x+c.width-1-btnCount)]
|
||||
}
|
||||
} else if y == c.y+c.height-1 && x > c.x && x < c.x+c.width-1 {
|
||||
hResult = HitBottom
|
||||
|
|
Loading…
Reference in New Issue