func (o *dataRend) Graph(nbval int, typ cdtype.RendererGraphType) error { if nbval < 1 { addIdle(o.icon.RemoveDataRenderer) return nil } attr := gldi.NewDataRendererAttributeGraph() attr.Type = typ attr.HighColor = make([]float64, nbval*3) attr.LowColor = make([]float64, nbval*3) for i := 0; i < nbval; i++ { attr.HighColor[3*i] = 1 // High Red. attr.LowColor[3*i+1] = 1 // Low Green. } w, _ := o.icon.IconExtent() attr.MemorySize = ternary.Int(w > 1, w, 32) attr.LatencyTime = 500 attr.NbValues = int(nbval) addIdle(func() { o.icon.AddNewDataRenderer(attr) // o.icon.AddDataRendererWithText(attr, o.icon.DataRendererTextPercent) }) return nil }
func cycleNextID(size, id, step int) int { return ternary.Int((id+1)*step < size, id+1, 0) }
// TestValues updates the key data with test values. // func TestValues(key *cftype.Key) { switch key.Type { case cftype.KeyBoolButton, cftype.KeyBoolCtrl: if key.NbElements > 1 { val := key.Value().ListBool() newval := make([]bool, len(val)) for i, v := range val { newval[i] = !v } key.ValueSet(newval) } else { val := key.Value().Bool() newval := !val key.ValueSet(newval) } case cftype.KeyIntSpin, cftype.KeyIntSize, cftype.KeyIntScale: if key.NbElements > 1 { val := key.Value().ListInt() newval := make([]int, len(val)) for i, v := range val { newval[i] = v + 1 + i } key.ValueSet(newval) } else { val := key.Value().Int() newval := val + 1 key.ValueSet(newval) } case cftype.KeyFloatSpin, cftype.KeyFloatScale: if key.NbElements > 1 { val := key.Value().ListFloat() newval := make([]float64, len(val)) for i, v := range val { newval[i] = v + 0.1 + float64(i) // hack +0.1 +i } key.ValueSet(newval) } else { val := key.Value().Float() newval := val + 0.1 key.ValueSet(newval) } case cftype.KeyColorSelectorRGB, cftype.KeyColorSelectorRGBA: val := key.Value().ListFloat() newval := make([]float64, len(val)) for i := range val { newval[i] = val[i] + 0.1 if newval[i] > 1 { newval[i]-- } } if len(newval) == 3 { newval = append(newval, 1) } key.ValueSet(newval) case cftype.KeyLink: val := key.Value().String() list := []string{urlDock, urlGoTour} newval := cycleNextString(list, val, key) key.ValueSet(newval) case cftype.KeyStringEntry, cftype.KeyFileSelector, cftype.KeyFolderSelector, cftype.KeyImageSelector, cftype.KeySoundSelector, cftype.KeyShortkeySelector, cftype.KeyClassSelector, cftype.KeyPasswordEntry, cftype.KeyListEntry: val := key.Value().String() newval := cycleNextString(otherStrings, val, nil) key.ValueSet(newval) case cftype.KeyFontSelector: val := key.Value().String() list := []string{"Arial 8", "Monospace 8"} newval := cycleNextString(list, val, key) key.ValueSet(newval) case cftype.KeyTreeViewSortSimple, cftype.KeyTreeViewSortModify: val := key.Value().ListString() newval := reverseStrings(val) key.ValueSet(newval) case cftype.KeyListNumbered, cftype.KeyListNbCtrlSimple, cftype.KeyListNbCtrlSelect: val := key.Value().Int() step := ternary.Int(key.IsType(cftype.KeyListNbCtrlSelect), 3, 1) newval := cycleNextID(len(key.AuthorizedValues), val, step) key.ValueSet(newval) case cftype.KeyListSimple: val := key.Value().String() newval := cycleNextString(key.AuthorizedValues, val, key) key.ValueSet(newval) case cftype.KeyListDocks: val := key.Value().String() list := []string{datatype.KeyMainDock, datatype.KeyNewDock} newval := cycleNextString(list, val, key) key.ValueSet(newval) case cftype.KeyListThemeApplet: val := key.Value().String() list := []string{"Turbo-night-fuel[0]", "Sound-Mono[0]"} newval := cycleNextString(list, val, key) key.ValueSet(newval) case cftype.KeyHandbook: val := key.Value().String() list := datatype.ListHandbooksKeys(Handbooks) newval := cycleNextString(list, val, key) key.ValueSet(newval) case cftype.KeyListViews: val := key.Value().String() books := key.Source().ListViews() list := datatype.IndexHandbooksKeys(books) newval := cycleNextString(list, val, key) key.ValueSet(newval) case cftype.KeyListIconsMainDock: val := key.Value().String() fields := key.Source().ListIconsMainDock() newval := cycleNextField(fields, val, key) key.ValueSet(newval) case cftype.KeyListThemeDesktopIcon: val := key.Value().String() fields := key.Source().ListThemeDesktopIcon() newval := cycleNextField(fields, val, key) key.ValueSet(newval) } }
// Lists adds a string list widget. // func Lists(key *cftype.Key) { if key.IsType(cftype.KeyListNbCtrlSimple, cftype.KeyListNbCtrlSelect) && len(key.AuthorizedValues) == 0 { key.Log().NewWarn("not enough values", "widget numbered control list:", key.Name) return } // Get full value with ';'. value := key.Value().String() // log.DEV("LIST "+string(key.Type), key.Name, value, key.AuthorizedValues) listIsNumbered := key.IsType(cftype.KeyListNumbered, cftype.KeyListNbCtrlSimple, cftype.KeyListNbCtrlSelect) iSelectedItem := -1 current := "" // Control selective use 3 AuthorizedValues fields for each "value". step := ternary.Int(key.IsType(cftype.KeyListNbCtrlSelect), 3, 1) if key.IsType(cftype.KeyListEntry) { current = value } if listIsNumbered && value != "" { var e error iSelectedItem, e = strconv.Atoi(value) switch { case key.Log().Err(e, "selection problem", "[", value, "]", "[", iSelectedItem, "]", key.Name): case iSelectedItem < 0: case iSelectedItem < len(key.AuthorizedValues): current = key.AuthorizedValues[iSelectedItem*step] default: key.Log().NewWarn("selection out of range", "widget numbered list:", key.Name) } } var list []datatype.Field if len(key.AuthorizedValues) > 0 { // int iOrder1, iOrder2, iExcept; if key.IsType(cftype.KeyListNbCtrlSimple, cftype.KeyListNbCtrlSelect) { key.SetNbControlled(0) } // gchar *cResult = (listIsNumbered ? g_new0 (gchar , 10) : NULL); for k := 0; k < len(key.AuthorizedValues); k += step { // on ajoute toutes les chaines possibles a la combo. if !listIsNumbered && iSelectedItem == -1 && value == key.AuthorizedValues[k] { current = value iSelectedItem = k / step } // if (cResult != NULL) // snprintf (cResult, 9, "%d", k/dk); // dk becomes step // iExcept = 0; // if key.IsType(cftype.KeyListNbCtrlSelect) { // iOrder1 = atoi (key.AuthorizedValues[k+1]); // gchar *str = strchr (key.AuthorizedValues[k+2], ','); // if (str) // Note: this mechanism is an addition to the original {first widget, number of widgets}; it's not very generic nor beautiful, but until we need more, it's well enough (currently, only the Dock background needs it). // { // *str = '\0'; // iExcept = atoi (str+1); // } // iOrder2 = atoi (key.AuthorizedValues[k+2]); // NbControlled = MAX (NbControlled, iOrder1 + iOrder2 - 1); // //g_print ("iSelectedItem:%d ; k/dk:%d\n", iSelectedItem , k/dk); // if (iSelectedItem == (int)k/dk) // { // iFirstSensitiveWidget = iOrder1; // iNbSensitiveWidgets = iOrder2; // iNonSensitiveWidget = iExcept; // if (iNonSensitiveWidget != 0) // NbControlled ++; // } // } else { // iOrder1 = iOrder2 = k; // } // name := "" if key.IsType(cftype.KeyListEntry) { name = key.AuthorizedValues[k] } else { name = key.Translate(key.AuthorizedValues[k]) } list = append(list, datatype.Field{ Key: key.AuthorizedValues[k], Name: name, }) // CAIRO_DOCK_MODEL_ORDER, iOrder1, // CAIRO_DOCK_MODEL_ORDER2, iOrder2, // CAIRO_DOCK_MODEL_STATE, iExcept, -1); } } // Current choice wasn't in the list. Select first. if current == "" && len(list) > 0 { current = list[0].Key iSelectedItem = 0 } // Build the combo widget. widget, _, getValue, setValue := NewComboBox(key, key.IsType(cftype.KeyListEntry), listIsNumbered, current, list) // gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (modele), GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID, GTK_SORT_ASCENDING); // int iNonSensitiveWidget = 0; if len(key.AuthorizedValues) > 0 { if key.IsType(cftype.KeyListNbCtrlSimple, cftype.KeyListNbCtrlSelect) { // _allocate_new_buffer; // data[0] = pKeyBox; // data[1] = (pFrameVBox != NULL ? pFrameVBox : pGroupBox); if key.IsType(cftype.KeyListNbCtrlSimple) { // NbControlled = k; // data[2] = GINT_TO_POINTER (NbControlled); // g_signal_connect (G_OBJECT (pOneWidget), "changed", G_CALLBACK (_cairo_dock_select_one_item_in_control_combo), data); // iFirstSensitiveWidget = iSelectedItem+1; // on decroit jusqu'a 0. // iNbSensitiveWidgets = 1; // //g_print ("CONTROL : %d,%d,%d\n", NbControlled, iFirstSensitiveWidget, iNbSensitiveWidgets); } else { // data[2] = GINT_TO_POINTER (NbControlled); // g_signal_connect (G_OBJECT (pOneWidget), "changed", G_CALLBACK (_cairo_dock_select_one_item_in_control_combo_selective), data); // //g_print ("CONTROL : %d,%d,%d\n", NbControlled, iFirstSensitiveWidget, iNbSensitiveWidgets); } // g_object_set_data (G_OBJECT (pKeyBox), "nb-ctrl-widgets", GINT_TO_POINTER (NbControlled)); // g_object_set_data (G_OBJECT (pKeyBox), "one-widget", pOneWidget); // CDControlWidget *cw = g_new0 (CDControlWidget, 1); // pControlWidgets = g_list_prepend (pControlWidgets, cw); // cw->pControlContainer = (pFrameVBox != NULL ? pFrameVBox : pGroupBox); // cw->NbControlled = NbControlled; // cw->iFirstSensitiveWidget = iFirstSensitiveWidget; // cw->iNbSensitiveWidgets = iNbSensitiveWidgets; // cw->iNonSensitiveWidget = iNonSensitiveWidget; // //g_print (" pControlContainer:%x\n", pControlContainer); } } key.PackKeyWidget(key, getValue, setValue, widget) }
// NewApplet creates a new applet instance. // func NewApplet(base cdtype.AppBase, events *cdtype.Events) cdtype.AppInstance { app := &Applet{AppBase: base} app.SetConfig(&app.conf, app.actions()...) // Events. events.OnClick = func() { // Left click: open and manage the gui window. if app.Window().IsOpened() { // Window opened. app.Window().ToggleVisibility() } else { app.createGui(true, true) } } events.OnMiddleClick = func() { app.Action().Launch(app.Action().ID(app.conf.ActionClickMiddle)) } events.OnScroll = func(scrollUp bool) { var key int switch app.conf.ActionMouseWheel { case "Change volume": key = ternary.Int(scrollUp, int(upnptype.ActionVolumeUp), int(upnptype.ActionVolumeDown)) case "Seek in track": key = ternary.Int(scrollUp, int(upnptype.ActionSeekForward), int(upnptype.ActionSeekBackward)) } app.Action().Launch(key) } events.OnBuildMenu = app.Action().CallbackMenu(dockMenu) events.End = func() { if app.win != nil { glib.IdleAdd(app.win.Destroy) } } // Create the UPnP device manager. var e error app.cp, e = gupnp.New(&logger{app.Log()}) app.Log().Err(e, "temp Dir") // Connect local tests. hook := app.cp.SubscribeHook("applet") hook.OnRendererFound = app.onMediaRendererFound hook.OnServerFound = app.onMediaServerFound hook.OnRendererLost = app.onMediaRendererLost hook.OnServerLost = app.onMediaServerLost // hook.OnRendererSelected = gui.SetRenderer // hook.OnServerSelected = gui.SetServer // hook.OnTransportState = func(r upnptype.Renderer, state upnptype.PlaybackState) { gui.SetPlaybackState(state) } // hook.OnCurrentTrackDuration = func(r upnptype.Renderer, dur int) { gui.SetDuration(mediacp.TimeToString(dur)) } // hook.OnCurrentTrackMetaData = func(r upnptype.Renderer, item upnptype.Item) { gui.SetTitle(item.Title) } // hook.OnMute = func(r upnptype.Renderer, muted bool) { gui.SetMuted(muted) } // hook.OnVolume = func(r upnptype.Renderer, vol uint) { gui.SetVolume(int(vol)) } // hook.OnCurrentTime = func(r upnptype.Renderer, secs int, f float64) { gui.SetCurrentTime(secs, f*100) } // hook.OnSetVolumeDelta = func(delta int) { gui.SetVolumeDelta(delta) } // } // Connect an UPnP backend to the manager. // mgr := backendsonos.NewManager(&logger{app.Log()}) // mgr.SetEvents(app.cp.DefineEvents()) // go mgr.Start(true) cp := backendgupnp.NewControlPoint() cp.SetEvents(app.cp.DefineEvents()) return app }
// Start starts the edit applet console GUI. // func Start(log cdtype.Logger, packs packages.AppletPackages) error { e := termui.Init() if e != nil { return e } defer termui.Close() // Applet info. ed := New(log, packs) selected := fieldVersion appID := 0 ed.SetField(selected) ed.SetPack(appID) // calculate layout and render. ed.resize() termui.Handle("/sys/wnd/resize", func(termui.Event) { ed.resize() }) termui.Handle("/sys/kbd", func(evt termui.Event) { key := evt.Data.(termui.EvtKbd).KeyStr switch key { case "<f10>", "C-c", "C-q": termui.StopLoop() case "<f7>": e := ed.save(appID) if e == nil { // Refresh data to clear updated color. ed.SetPack(appID) termui.Render(ed.appinfo, ed.locked, ed.desc) } else { ed.locked.Text = "SAVE FAILED: " + e.Error() } case "<up>", "<down>": delta := ternary.Int(key == "<down>", 1, -1) selected = ed.SetField(selected + delta) termui.Render(ed.fields, ed.locked, ed.desc) case "<previous>", "<next>": ed.edits = nil delta := ternary.Int(key == "<next>", 1, -1) appID = ed.SetPack(appID + delta) termui.Render(ed.applets, ed.appinfo, ed.locked, ed.desc, ed.title) case "<left>", "<right>": delta := ternary.Int(key == "<right>", 1, -1) ed.editValue(appID, selected, delta) termui.Render(ed.applets, ed.appinfo, ed.locked, ed.desc, ed.title) // default: // ed.title.BorderLabel = key // termui.Render(ed.title) } }) termui.Loop() return nil }