Skip to content

Commit

Permalink
support multiple non-modal slave winows.
Browse files Browse the repository at this point in the history
  • Loading branch information
aarzilli committed Sep 28, 2017
1 parent 2cff62e commit a225bb4
Show file tree
Hide file tree
Showing 7 changed files with 340 additions and 275 deletions.
161 changes: 108 additions & 53 deletions _demo/demo.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,63 @@ import (
"golang.org/x/mobile/event/key"
)

var whichdemo int = 4

const dotrace = false
const scaling = 1.8

//var theme nucular.Theme = nucular.WhiteTheme
var theme nstyle.Theme = nstyle.DarkTheme

func id(fn func (*nucular.Window)) func () func(*nucular.Window) {
return func() func(*nucular.Window) {
return fn
}
}

type Demo struct {
Name string
Title string
Flags nucular.WindowFlags
UpdateFn func() func(*nucular.Window)
}

var demos = []Demo{
{ "button", "Button Demo", 0, id(buttonDemo) },
{ "basic", "Basic Demo", 0, func() func(*nucular.Window) {
go func() {
for {
time.Sleep(1 * time.Second)
if Wnd.Closed() {
break
}
Wnd.Changed()
}
}()
return basicDemo
} },
{ "basic2", "Text Editor Demo", 0, textEditorDemo },
{ "calc", "Calculator Demo", 0, func() func(*nucular.Window) {
var cd calcDemo
cd.current = &cd.a
return cd.calculatorDemo
} },
{ "overview", "Overview", 0, func() func(*nucular.Window) {
od := newOverviewDemo()
od.Theme = theme
return od.overviewDemo
} },
{ "editor", "Multiline Text Editor", nucular.WindowNoScrollbar, multilineTextEditorDemo },
{ "split", "Split panel demo", nucular.WindowNoScrollbar, func() func(*nucular.Window) {
pd := &panelDebug{}
pd.Init()
return pd.Update
} },
{ "nestedmenu", "Nested menu demo", 0, id(nestedMenu) },
{ "list", "List", nucular.WindowNoScrollbar, id(listDemo) },
}

var Wnd nucular.MasterWindow

func main() {
var wnd nucular.MasterWindow

if dotrace {
fh, _ := os.Create("demo.trace.out")
Expand All @@ -42,48 +89,35 @@ func main() {
defer pprof.StopCPUProfile()
}
}


whichdemo := ""
if len(os.Args) > 1 {
whichdemo = os.Args[1]
}

switch whichdemo {
case 0:
wnd = nucular.NewMasterWindow(0, "Button Demo", buttonDemo)
case 1:
wnd = nucular.NewMasterWindow(0, "Basic Demo", basicDemo)
go func() {
for {
time.Sleep(1 * time.Second)
if wnd.Closed() {
break
}
wnd.Changed()
case "multi", "":
Wnd = nucular.NewMasterWindow(0, "Multiwindow Demo", func(w *nucular.Window) {})
Wnd.PopupOpen("Multiwindow Demo", nucular.WindowTitle|nucular.WindowBorder | nucular.WindowMovable | nucular.WindowScalable|nucular.WindowNonmodal, rect.Rect{ 0, 0, 400, 300 }, true, multiDemo)
default:
for i := range demos {
if demos[i].Name == whichdemo {
Wnd = nucular.NewMasterWindow(demos[i].Flags, demos[i].Title, demos[i].UpdateFn())
break
}
}()
case 2:
textEditorEditor.Flags = nucular.EditSelectable
textEditorEditor.Buffer = []rune("prova")
wnd = nucular.NewMasterWindow(0, "Text Editor Demo", textEditorDemo)
case 3:
var cd calcDemo
cd.current = &cd.a
wnd = nucular.NewMasterWindow(0, "Calculator Demo", cd.calculatorDemo)
case 4:
od := newOverviewDemo()
od.Theme = theme
wnd = nucular.NewMasterWindow(0, "Overview", od.overviewDemo)
case 7:
bs, _ := ioutil.ReadFile("overview.go")
multilineTextEditor.Buffer = []rune(string(bs))
wnd = nucular.NewMasterWindow(nucular.WindowNoScrollbar, "Multiline Text Editor", multilineTextEditorDemo)
case 8:
pd := &panelDebug{}
pd.Init()
wnd = nucular.NewMasterWindow(nucular.WindowNoScrollbar, "Split panel demo", pd.Update)
case 9:
wnd = nucular.NewMasterWindow(nucular.WindowNoScrollbar, "Nested menu demo", nestedMenu)
case 10:
wnd = nucular.NewMasterWindow(nucular.WindowNoScrollbar, "List", listDemo)
}
}
if Wnd == nil {
fmt.Fprintf(os.Stderr, "unknown demo %q\n", whichdemo)
fmt.Fprintf(os.Stderr, "known demos:\n")
for i := range demos {
fmt.Fprintf(os.Stderr, "\t%s\n", demos[i].Name)
}
os.Exit(1)
}
wnd.SetStyle(nstyle.FromTheme(theme, scaling))
wnd.Main()

Wnd.SetStyle(nstyle.FromTheme(theme, scaling))
Wnd.Main()
if dotrace {
fh, _ := os.Create("demo.heap.pprof")
if fh != nil {
Expand Down Expand Up @@ -132,20 +166,27 @@ func basicDemo(w *nucular.Window) {
w.PropertyInt("Compression:", 0, &compression, 100, 10, 1)
}

var textEditorEditor nucular.TextEditor

func textEditorDemo(w *nucular.Window) {
w.Row(30).Dynamic(1)
textEditorEditor.Maxlen = 30
textEditorEditor.Edit(w)
func textEditorDemo() func(w *nucular.Window) {
var textEditorEditor nucular.TextEditor
textEditorEditor.Flags = nucular.EditSelectable
textEditorEditor.Buffer = []rune("prova")
return func (w *nucular.Window) {
w.Row(30).Dynamic(1)
textEditorEditor.Maxlen = 30
textEditorEditor.Edit(w)
}
}

var multilineTextEditor nucular.TextEditor

func multilineTextEditorDemo(w *nucular.Window) {
w.Row(0).Dynamic(1)
multilineTextEditor.Flags = nucular.EditMultiline | nucular.EditSelectable | nucular.EditClipboard
multilineTextEditor.Edit(w)
func multilineTextEditorDemo() func(w *nucular.Window) {
var multilineTextEditor nucular.TextEditor
bs, _ := ioutil.ReadFile("overview.go")
multilineTextEditor.Buffer = []rune(string(bs))
return func(w *nucular.Window) {
w.Row(0).Dynamic(1)
multilineTextEditor.Flags = nucular.EditMultiline | nucular.EditSelectable | nucular.EditClipboard
multilineTextEditor.Edit(w)
}
}

type panelDebug struct {
Expand Down Expand Up @@ -286,3 +327,17 @@ func listDemo(w *nucular.Window) {
}
}
}

func multiDemo(w *nucular.Window) {
w.Row(20).Dynamic(1)
w.Label("Welcome to the multi-window demo.", "LC")
w.Label("Open any demo window by clicking on the buttons.", "LC")
w.Label("To run a demo as a stand-alone window use:", "LC")
w.Label(" \"./demo <demo-name>\"", "LC")
w.Row(30).Static(100, 100, 100)
for i := range demos {
if w.ButtonText(demos[i].Name) {
w.Master().PopupOpen(demos[i].Title, nucular.WindowDefaultFlags|nucular.WindowNonmodal | demos[i].Flags, rect.Rect{0, 0, 200, 200}, true, demos[i].UpdateFn())
}
}
}
5 changes: 0 additions & 5 deletions _demo/overview.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,6 @@ func newOverviewDemo() (od *overviewDemo) {
od.Resize = true
od.Movable = true
od.NoScrollbar = false
od.Minimizable = true
od.Close = true
od.HeaderAlign = nstyle.HeaderRight
od.Mprog = 60
Expand Down Expand Up @@ -232,7 +231,6 @@ func (od *overviewDemo) overviewDemo(w *nucular.Window) {
w.CheckboxText("Resizable", &od.Resize)
w.CheckboxText("Movable", &od.Movable)
w.CheckboxText("No Scrollbars", &od.NoScrollbar)
w.CheckboxText("Minimizable", &od.Minimizable)
w.CheckboxText("Closable", &od.Close)
w.TreePop()
}
Expand Down Expand Up @@ -1055,9 +1053,6 @@ func (od *overviewDemo) showAppAbout(mw nucular.MasterWindow) {
if od.NoScrollbar {
wf |= nucular.WindowNoScrollbar
}
if od.Minimizable {
wf |= nucular.WindowMinimizable
}
if od.Close {
wf |= nucular.WindowClosable
}
Expand Down
52 changes: 52 additions & 0 deletions context.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ type context struct {
activateEditor *TextEditor
cmds []command.Command
trashFrame bool
autopos image.Point
}

func contextAllCommands(ctx *context) {
Expand All @@ -52,6 +53,7 @@ func (ctx *context) Update() {
for i := 0; i < len(ctx.Windows); i++ {
ctx.Windows[i].began = false
}
ctx.Restack()
for i := 0; i < len(ctx.Windows); i++ { // this must not use range or tooltips won't work
win := ctx.Windows[i]
if win.updateFn != nil {
Expand Down Expand Up @@ -125,6 +127,56 @@ func (ctx *context) Reset() {
in.Keyboard.Keys = in.Keyboard.Keys[0:0]
}

func (ctx *context) Restack() {
nonmodalToplevel := false
var toplevelIdx int
for i := len(ctx.Windows) - 1; i >= 0; i-- {
if ctx.Windows[i].flags&windowTooltip == 0 {
toplevelIdx = i
nonmodalToplevel = ctx.Windows[i].flags&WindowNonmodal != 0
break
}
}
if !nonmodalToplevel {
return
}
// toplevel window is non-modal, proceed to change the stacking order if
// the user clicked outside of it
restacked := false
for i := len(ctx.Windows) - 1; i > 0; i-- {
if ctx.Windows[i].flags&windowTooltip != 0 {
continue
}
if ctx.restackClick(i) {
if toplevelIdx != i {
newToplevel := ctx.Windows[i]
copy(ctx.Windows[i:toplevelIdx], ctx.Windows[i+1:toplevelIdx+1])
ctx.Windows[toplevelIdx] = newToplevel
restacked = true
}
break
}
}
if restacked {
for i := range ctx.Windows {
ctx.Windows[i].idx = i
}
}
}

func (ctx *context) restackClick(i int) bool {
if !ctx.Input.Mouse.valid {
return false
}
for _, b := range []mouse.Button{mouse.ButtonLeft, mouse.ButtonRight, mouse.ButtonMiddle} {
btn := ctx.Input.Mouse.Buttons[b]
if btn.Clicked && btn.Down && ctx.Windows[i].Bounds.Contains(btn.ClickedPos) {
return true
}
}
return false
}

var cnt = 0
var ln, frect, brrect, frrect, ftri, circ, fcirc, txt int

Expand Down
6 changes: 1 addition & 5 deletions drawing.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ type drawableWindowHeader struct {
Hovered bool
Title string

Minimized bool
Dynamic bool
HeaderActive bool
Bounds rect.Rect
Expand All @@ -86,10 +85,7 @@ type drawableWindowHeader struct {

func (dwh *drawableWindowHeader) Draw(z *nstyle.Style, out *command.Buffer) {
style := dwh.Style
if dwh.Minimized {
/* draw window background if minimized */
out.FillRect(rect.Rect{dwh.Bounds.X, dwh.Bounds.Y, dwh.Bounds.W, dwh.RowHeight}, 0, style.Background)
} else if !dwh.Dynamic {
if !dwh.Dynamic {
/* draw fixed window body */
body := dwh.Bounds
if dwh.HeaderActive {
Expand Down
Loading

0 comments on commit a225bb4

Please sign in to comment.