func (t *tbfe) qmlChanged(value, field interface{}) { if !batching_enabled { qml.Changed(value, field) } else { t.qmlDispatch <- qmlDispatch{value, field} } }
func (fv *frontendView) formatLine(line int) { prof := util.Prof.Enter("frontendView.formatLine") defer prof.Exit() buf := bytes.NewBuffer(nil) vr := fv.bv.Buffer().Line(fv.bv.Buffer().TextPoint(line, 0)) for line >= len(fv.FormattedLine) { fv.FormattedLine = append(fv.FormattedLine, &lineStruct{Text: ""}) fv.Len = len(fv.FormattedLine) qml.Changed(fv, &fv.Len) } if vr.Size() == 0 { // TODO: draw cursor if here if fv.FormattedLine[line].Text != "" { fv.FormattedLine[line].Text = "" qml.Changed(fv.FormattedLine[line], fv.FormattedLine[line]) } return } recipie := fv.bv.Transform(scheme, vr).Transcribe() highlight_line := false if b, ok := fv.bv.Settings().Get("highlight_line", highlight_line).(bool); ok { highlight_line = b } lastEnd := vr.Begin() for _, reg := range recipie { if lastEnd != reg.Region.Begin() { fmt.Fprintf(buf, "<span>%s</span>", fv.bv.Buffer().Substr(Region{lastEnd, reg.Region.Begin()})) } fmt.Fprintf(buf, "<span style=\"white-space:pre; color:#%s; background:#%s\">%s</span>", htmlcol(reg.Flavour.Foreground), htmlcol(reg.Flavour.Background), fv.bv.Buffer().Substr(reg.Region)) lastEnd = reg.Region.End() } if lastEnd != vr.End() { io.WriteString(buf, fv.bv.Buffer().Substr(Region{lastEnd, vr.End()})) } str := buf.String() if fv.FormattedLine[line].Text != str { fv.FormattedLine[line].Text = str qml.Changed(fv.FormattedLine[line], fv.FormattedLine[line]) } }
func (ctrl *Control) TextReleased(text *qml.Object) { x := text.Int("x") y := text.Int("y") width := text.Int("width") height := text.Int("height") ctrl.Emit(x+15, y+height/2) ctrl.Emit(x+width/2, 1.0*y+height/2) ctrl.Emit(x+width-15, 1.0*y+height/2) go func() { time.Sleep(500 * time.Millisecond) messages := []string{"Hello", "Hello", "Hacks"} ctrl.Message = messages[rand.Intn(len(messages))] + " from Go!" qml.Changed(ctrl, &ctrl.Message) }() }
// Apparently calling qml.Changed also triggers a re-draw, meaning that typed text is at the // mercy of how quick Qt happens to be rendering. // Try setting batching_enabled = false to see the effects of non-batching func (t *tbfe) qmlBatchLoop() { queue := make(map[qmlDispatch]bool) t.qmlDispatch = make(chan qmlDispatch, 1000) for { if len(queue) > 0 { select { case <-time.After(time.Millisecond * 20): // Nothing happened for 20 milliseconds, so dispatch all queued changes for k := range queue { qml.Changed(k.value, k.field) } queue = make(map[qmlDispatch]bool) case d := <-t.qmlDispatch: queue[d] = true } } else { queue[<-t.qmlDispatch] = true } } }
func (t *tbfe) loop() { qml.Init(nil) engine := qml.NewEngine() engine.Context().SetVar("lines", t) engine.Context().SetVar("frontend", t) engine.Context().SetVar("editor", backend.GetEditor()) backend.OnNew.Add(func(v *backend.View) { fv := &frontendView{bv: v} v.Buffer().AddCallback(fv.bufferChanged) v.Settings().AddOnChange("blah", func(name string) { if name == "lime.syntax.updated" { // force redraw, as the syntax regions might have changed... for i := range fv.FormattedLine { fv.formatLine(i) } } }) t.views[v] = fv t.Len = len(t.views) qml.Changed(t, &t.Len) }) ed := backend.GetEditor() ed.SetFrontend(t) ed.LogInput(false) ed.LogCommands(false) c := ed.Console() t.Console = &frontendView{bv: c} c.Buffer().AddCallback(t.Console.bufferChanged) if sc, err := textmate.LoadTheme("../../3rdparty/bundles/TextMate-Themes/GlitterBomb.tmTheme"); err != nil { log4go.Error(err) } else { scheme = sc } defer func() { fmt.Println(util.Prof) }() w := ed.NewWindow() v := w.OpenFile("main.go", 0) v.Settings().Set("trace", true) v.Settings().Set("syntax", "../../3rdparty/bundles/go.tmbundle/Syntaxes/Go.tmLanguage") c.Buffer().AddCallback(t.scroll) sel := v.Sel() sel.Clear() sel.Add(Region{0, 0}) { w, h := 800, 600 t.lock.Lock() t.layout[v] = layout{0, 0, w, h - console_height - 1, Region{}, 0} t.layout[c] = layout{0, h - console_height + 1, w, console_height - 5, Region{}, 0} t.lock.Unlock() t.Show(v, Region{1, 1}) } t.Show(v, Region{100, 100}) t.Show(v, Region{1, 1}) // t.Len, _ = v.Buffer().RowCol(v.Buffer().Size()) ed.Init() sublime.Init() component, err := engine.LoadFile("main.qml") if err != nil { log4go.Exit(err) } window := component.CreateWindow(nil) window.Show() log4go.Debug("Done") window.Wait() }
func (ts *GoType) NotifyStringChanged() { qml.Changed(ts, &ts.StringValue) }
Done: func(c *TestData) { c.Assert(c.createdValue, HasLen, 1) c.Assert(c.createdValue[0].StringValue, Equals, "<newest>") }, }, { Summary: "Singleton type registration", QML: `Item { Component.onCompleted: console.log("String is", GoSingleton.stringValue) }`, QMLLog: "String is <initial>", }, { Summary: "qml.Changed on unknown value is okay", Value: GoType{StringValue: "<old>"}, Init: func(c *TestData) { value := &GoType{} qml.Changed(&value, &value.StringValue) }, QML: `Item{}`, }, { Summary: "qml.Changed triggers a QML slot", QML: ` GoType { stringValue: "<old>" onStringValueChanged: console.log("String is", stringValue) } `, QMLLog: "!String is", Done: func(c *TestData) { c.Assert(c.createdValue, HasLen, 1) value := c.createdValue[0]
QMLLog: "String is <content>", }, { Summary: "qml.Changed triggers a QML slot", Value: TestType{StringValue: "<old>"}, QML: ` import GoTest 4.2 GoType { onStringValueChanged: console.log("String is", stringValue) } `, QMLLog: "!String is", QMLValue: TestType{StringValue: "<old>"}, Done: func(d *TestData) { d.value.StringValue = "<new>" qml.Changed(d.value, &d.value.StringValue) }, DoneLog: "String is <new>", DoneValue: TestType{StringValue: "<new>"}, }, { Summary: "qml.Changed must not trigger on the wrong field", Value: TestType{StringValue: "<old>"}, QML: ` import GoTest 4.2 GoType { onStringValueChanged: console.log("String is", stringValue) } `, Done: func(d *TestData) { d.value.StringValue = "<new>" qml.Changed(d.value, &d.value.IntValue) },
func (t *tbfe) loop() { qml.Init(nil) engine := qml.NewEngine() engine.Context().SetVar("lines", t) engine.Context().SetVar("frontend", t) engine.Context().SetVar("editor", backend.GetEditor()) backend.OnNew.Add(func(v *backend.View) { v.Settings().AddOnChange("lime.frontend.html.render", func(name string) { t.dirty = true }) }) backend.OnModified.Add(func(v *backend.View) { t.dirty = true }) backend.OnSelectionModified.Add(func(v *backend.View) { t.dirty = true }) ed := backend.GetEditor() ed.SetFrontend(t) ed.LogInput(false) ed.LogCommands(false) c := ed.Console() if sc, err := textmate.LoadTheme("../../3rdparty/bundles/TextMate-Themes/GlitterBomb.tmTheme"); err != nil { log4go.Error(err) } else { scheme = sc } defer func() { fmt.Println(util.Prof) }() w := ed.NewWindow() v := w.OpenFile("main.go", 0) v.Settings().Set("trace", true) v.Settings().Set("syntax", "../../3rdparty/bundles/go.tmbundle/Syntaxes/Go.tmLanguage") c.Buffer().AddCallback(t.scroll) sel := v.Sel() sel.Clear() sel.Add(Region{0, 0}) { w, h := 800, 600 t.lock.Lock() t.layout[v] = layout{0, 0, w, h - console_height - 1, Region{}, 0} t.layout[c] = layout{0, h - console_height + 1, w, console_height - 5, Region{}, 0} t.lock.Unlock() t.Show(v, Region{1, 1}) } t.Show(v, Region{100, 100}) t.Show(v, Region{1, 1}) t.Len, _ = v.Buffer().RowCol(v.Buffer().Size()) ed.Init() sublime.Init() component, err := engine.LoadFile("main.qml") if err != nil { log4go.Exit(err) } window := component.CreateWindow(nil) window.Show() qml.Changed(t, &t.Len) log4go.Debug("Done") window.Wait() }
func (colors *Colors) Add(c color.RGBA) { colors.list = append(colors.list, c) colors.Len = len(colors.list) qml.Changed(colors, &colors.Len) }