// Separator adds a simple horizontal separator. // func Separator(key *cftype.Key) { // GtkWidget *pAlign = gtk_alignment_new (.5, .5, 0.8, 1.); // g_object_set (pAlign, "height-request", 12, NULL); widget := newgtk.Separator(gtk.ORIENTATION_HORIZONTAL) // gtk_container_add (GTK_CONTAINER (pAlign), pOneWidget); key.PackWidget(widget, false, false, 0) }
// ListThemeDesktopIcon adds a desktop icon-themes list widget. // func ListThemeDesktopIcon(key *cftype.Key) { getList := fieldsPrepend(key.Source().ListThemeDesktopIcon(), datatype.Field{}, datatype.Field{Key: "_Custom Icons_", Name: tran.Slate("_Custom Icons_")}, ) PackComboBoxWithListField(key, false, false, getList) }
func (lf *lineFeed) addTest(key *cftype.Key) { def, e := key.Storage().Default(key.Group, key.Name) if e != nil { println("default: ", e.Error()) return } valStatus := key.ValueState(def) if !valStatus.IsChanged() { return } lf.countChanged++ lf.valuePrint = func(key *cftype.Key, line tablist.Liner) { for i, st := range valStatus { curline := lf.testNewLine(line, i) switch { // case cftype.StateUnchanged: // curline.Set(RowOld, st.Old) case st.State == cftype.StateEdited && st.New != "": curline.Set(RowOld, st.New) case st.State == cftype.StateAdded: curline.Colored(RowOld, color.FgYellow, st.New) case st.State == cftype.StateEdited, st.State == cftype.StateRemoved: curline.Colored(RowOld, color.FgMagenta, "**EMPTY**") } } } lf.Add(key) }
// ColorSelector adds a color selector widget. // func ColorSelector(key *cftype.Key) { values := key.Value().ListFloat() if len(values) == 3 { values = append(values, 1) // no transparency. } gdkColor := gdk.NewRGBA(values...) widget := newgtk.ColorButtonWithRGBA(gdkColor) var getValue func() interface{} switch key.Type { case cftype.KeyColorSelectorRGB: key.NbElements = 3 getValue = func() interface{} { return widget.GetRGBA().Floats()[:3] } // Need to trunk ? case cftype.KeyColorSelectorRGBA: key.NbElements = 4 getValue = func() interface{} { return widget.GetRGBA().Floats() } } widget.Set("use-alpha", key.IsType(cftype.KeyColorSelectorRGBA)) key.PackKeyWidget(key, getValue, func(uncast interface{}) { widget.SetRGBA(gdk.NewRGBA(uncast.([]float64)...)) }, widget, ) oldval, e := key.Storage().Default(key.Group, key.Name) if e == nil { PackReset(key, oldval.ListFloat()) } }
// PackKeyWidget packs a key widget to the page with its getValue call // // (was _pack_subwidget). func (build *builder) PackKeyWidget(key *cftype.Key, getValue func() interface{}, setValue func(interface{}), childs ...gtk.IWidget) { for _, w := range childs { build.pWidgetBox.PackStart(w, key.IsAlignedVertical, key.IsAlignedVertical, 0) } // key.SetValue = setValue key.SetWidSetValue(setValue) key.SetWidGetValue(getValue) }
// PackValuerAsInt packs a valuer widget with its reset button (to given value). // Values are get and set as int. // func PackValuerAsInt(key *cftype.Key, w gtk.IWidget, valuer WidgetValuer, value int) { key.PackKeyWidget(key, func() interface{} { return int(valuer.GetValue()) }, func(uncast interface{}) { valuer.SetValue(float64(uncast.(int))) }, w) oldval, e := key.Storage().Default(key.Group, key.Name) if e == nil { PackReset(key, oldval.Int()) } }
// PackComboBoxWithListField creates a combo box filled with the getList call. // func PackComboBoxWithListField(key *cftype.Key, withEntry, numbered bool, getList func() []datatype.Field) *gtk.ComboBox { var list []datatype.Field if getList != nil { list = getList() } current, _ := key.Storage().String(key.Group, key.Name) widget, _, getValue, setValue := NewComboBox(key, withEntry, numbered, current, list) key.PackKeyWidget(key, getValue, setValue, widget) return widget }
func findID(list []string, current string, key *cftype.Key) int { for i, str := range list { if current == str { return i } } if key != nil { key.Log().NewErr("not found", "list findID", current, list) } return 0 }
// IntegerSpin adds an integer scale widget. // func IntegerSpin(key *cftype.Key) { if key.NbElements > 1 { // TODO: remove temp test key.Log().Info("integer multi ffs", key.Type.String()) } value := key.Value().Int() minValue, maxValue := minMaxValues(key) w := newgtk.SpinButtonWithRange(minValue, maxValue, 1) w.SetValue(float64(value)) PackValuerAsInt(key, w, w, value) }
// FontSelector adds a font selector widget. // func FontSelector(key *cftype.Key) { value := key.Value().String() widget := newgtk.FontButtonWithFont(value) widget.Set("show-style", true) widget.Set("show-size", true) widget.Set("use-size", true) widget.Set("use-font", true) key.PackKeyWidget(key, func() interface{} { return widget.GetFontName() }, func(val interface{}) { widget.SetFontName(val.(string)) }, widget) }
// ListScreens adds a screen selection widget. // func ListScreens(key *cftype.Key) { list := key.Source().ListScreens() combo := PackComboBoxWithListField(key, false, false, fieldsPrepend(list)) if len(list) <= 1 { combo.SetSensitive(false) } // gldi_object_register_notification (&myDesktopMgr, // NOTIFICATION_DESKTOP_GEOMETRY_CHANGED, // (GldiNotificationFunc) _on_screen_modified, // GLDI_RUN_AFTER, pScreensListStore); // g_signal_connect (pOneWidget, "destroy", G_CALLBACK (_on_list_destroyed), NULL); }
func (lf *lineFeed) valueDefault(key *cftype.Key, line tablist.Liner) { flag := false def, e := key.Storage().Default(key.Group, key.Name) if e != nil { println("default: ", e.Error()) } valStatus := key.ValueState(def) for i, st := range valStatus { curline := lf.testNewLine(line, i) switch st.State { case cftype.StateBothEmpty: line.Set(RowOld, "**EMPTY**") case cftype.StateUnchanged: curline.Set(RowOld, st.Old) case cftype.StateEdited: curline.Set(RowOld, st.Old) if st.New == "" { curline.Colored(RowNew, color.FgMagenta, "**EMPTY**") } else { curline.Colored(RowNew, color.FgGreen, st.New) } flag = true case cftype.StateAdded: curline.Set(RowOld, "**EMPTY**") curline.Colored(RowNew, color.FgYellow, st.New) flag = true case cftype.StateRemoved: curline.Set(RowOld, st.Old) curline.Colored(RowNew, color.FgMagenta, "**EMPTY**") flag = true } } if flag { lf.countChanged++ } }
// IntegerScale adds an integer scale widget. // func IntegerScale(key *cftype.Key) { if key.NbElements > 1 { // TODO: remove temp test key.Log().Info("IntegerScale multi", key.NbElements, key.Type.String()) } value := key.Value().Int() minValue, maxValue := minMaxValues(key) step := (maxValue - minValue) / 20 if step < 1 { step = 1 } adjustment := newgtk.Adjustment(float64(value), minValue, maxValue, 1, step, 0) w := newgtk.Scale(gtk.ORIENTATION_HORIZONTAL, adjustment) w.Set("digits", 0) PackValuerAsInt(key, WrapKeyScale(key, w), w, value) }
// modelAddField adds one field to the model and can save reference of fields+iter. // func modelAddField(key *cftype.Key, model *gtk.ListStore, field datatype.Field, ro indexiter.ByString) *gtk.TreeIter { iter := model.Append() model.SetCols(iter, gtk.Cols{ RowKey: field.Key, RowName: field.Name, RowDesc: "none", }) if field.Icon != "" { pix, e := common.PixbufNewFromFile(field.Icon, iconSizeCombo) if !key.Log().Err(e, "Load icon") { model.SetValue(iter, RowIcon, pix) } } if ro != nil { ro.Append(iter, field.Key) } return iter }
// WrapKeyScale wraps a key scale with its information labels if needed (enough values). // // (was _pack_hscale). func WrapKeyScale(key *cftype.Key, child *gtk.Scale) gtk.IWidget { child.Set("width-request", 150) if len(key.AuthorizedValues) >= 4 { child.Set("value-pos", gtk.POS_TOP) // log.DEV("MISSING SubScale options", string(key.Type), key.AuthorizedValues) box := newgtk.Box(gtk.ORIENTATION_HORIZONTAL, 0) // GtkWidget * pAlign = gtk_alignment_new(1., 1., 0., 0.) labelLeft := newgtk.Label(key.Translate(key.AuthorizedValues[2])) // pAlign = gtk_alignment_new(1., 1., 0., 0.) labelRight := newgtk.Label(key.Translate(key.AuthorizedValues[3])) box.PackStart(labelLeft, false, false, 0) box.PackStart(child, false, false, 0) box.PackStart(labelRight, false, false, 0) return box } child.Set("value-pos", gtk.POS_LEFT) return child }
// Link adds a link widget. // func Link(key *cftype.Key) { var text, link string if len(key.AuthorizedValues) > 0 { text = key.AuthorizedValues[0] } else { text = tran.Slate("link") } if len(key.AuthorizedValues) > 1 { // Custom keys have to use this input way. link = key.AuthorizedValues[1] } else { link = key.Value().String() } widget := newgtk.LinkButtonWithLabel(link, text) key.PackKeyWidget(key, func() interface{} { return widget.GetUri() }, func(val interface{}) { widget.SetUri(val.(string)) }, widget) }
// ListThemeApplet adds an theme list widget. // func ListThemeApplet(key *cftype.Key) { var index map[string]datatype.Handbooker if len(key.AuthorizedValues) > 2 { if key.AuthorizedValues[1] == "gauges" { index = key.Source().ListThemeXML(key.AuthorizedValues[0], key.AuthorizedValues[1], key.AuthorizedValues[2]) } else { index = key.Source().ListThemeINI(key.AuthorizedValues[0], key.AuthorizedValues[1], key.AuthorizedValues[2]) } } PackComboBoxWithIndexHandbooker(key, index) // // list local packages first. // _allocate_new_buffer; // data[0] = pOneWidget; // data[1] = pMainWindow; // data[2] = g_key_file_get_string (pKeyFile, cGroupName, cKeyName, NULL); // freed in the callback '_got_themes_combo_list'. // data[3] = g_strdup (cHint); // idem // GHashTable *pThemeTable = cairo_dock_list_packages (cShareThemesDir, cUserThemesDir, NULL, NULL); // _got_themes_combo_list (pThemeTable, (gpointer*)data); // // list distant packages asynchronously. // if (cDistantThemesDir != NULL) // { // cairo_dock_set_status_message_printf (pMainWindow, _("Listing themes in '%s' ..."), cDistantThemesDir); // data[2] = g_key_file_get_string (pKeyFile, cGroupName, cKeyName, NULL); // freed in the callback '_got_themes_combo_list'. // data[3] = g_strdup (cHint); // CairoDockTask *pTask = cairo_dock_list_packages_async (NULL, NULL, cDistantThemesDir, (CairoDockGetPackagesFunc) _got_themes_combo_list, data, pThemeTable); // the table will be freed along with the task. // g_object_set_data (G_OBJECT (pOneWidget), "cd-task", pTask); // g_signal_connect (G_OBJECT (pOneWidget), "destroy", G_CALLBACK (on_delete_async_widget), NULL); // } // else // { // g_hash_table_destroy (pThemeTable); // } // g_free (cUserThemesDir); // g_free (cShareThemesDir); }
// NewComboBox creates a combo box. // func NewComboBox(key *cftype.Key, withEntry, numbered bool, current string, list []datatype.Field) ( widget *gtk.ComboBox, model *gtk.ListStore, getValue func() interface{}, setValue func(interface{})) { model = newModelSimple() // gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(modele), CAIRO_DOCK_MODEL_NAME, GTK_SORT_ASCENDING) widget = newgtk.ComboBoxWithModel(model) renderer := newgtk.CellRendererText() widget.PackStart(renderer, true) widget.AddAttribute(renderer, "text", RowName) // Fill and set current. iter := fillModelWithFields(key, model, list, current, nil) widget.SetActiveIter(iter) switch { case withEntry: // get and set the entry content string. entry := newgtk.Entry() // Add entry manually so we don't have to recast a GetChild entry.SetText(current) widget.Add(entry) widget.Set("id-column", RowName) widget.Connect("changed", func() { entry.SetText(widget.GetActiveID()) }) getValue = func() interface{} { v, _ := entry.GetText(); return v } setValue = func(uncast interface{}) { entry.SetText(uncast.(string)) } case numbered: // get and set selected as position int getValue = func() interface{} { return widget.GetActive() } setValue = func(uncast interface{}) { widget.SetActive(uncast.(int)) } default: // get and set selected as content string widget.Set("id-column", RowKey) getValue = func() interface{} { return widget.GetActiveID() } setValue = func(uncast interface{}) { newID := datatype.ListFieldsIDByName(list, uncast.(string), key.Log()) widget.SetActive(newID) } } return }
// ListDeskletDecoration adds a desklet decoration list widget. // func ListDeskletDecoration(key *cftype.Key) { current := key.Value().String() getList := key.Source().ListDeskletDecorations if key.IsType(cftype.KeyListDeskletDecoDefault) { getList = fieldsPrepend(getList(), datatype.Field{Key: "default", Name: tran.Slate("default")}, ) } PackComboBoxWithListField(key, false, false, getList) // gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (pListStore), CAIRO_DOCK_MODEL_NAME, GTK_SORT_ASCENDING); // _allocate_new_buffer; // data[0] = pKeyBox; // data[1] = (pFrameVBox != NULL ? pFrameVBox : pGroupBox); // NbControlled = 9; // data[2] = GINT_TO_POINTER (NbControlled); // NbControlled --; // car dans cette fonction, on ne compte pas le separateur. // g_signal_connect (G_OBJECT (pOneWidget), "changed", G_CALLBACK (_cairo_dock_select_custom_item_in_combo), data); if current == "personnal" { // Disable the next widgets. // CDControlWidget *cw = g_new0 (CDControlWidget, 1); // pControlWidgets = g_list_prepend (pControlWidgets, cw); // cw->NbControlled = NbControlled; // cw->iNbSensitiveWidgets = 0; // cw->iFirstSensitiveWidget = 1; // cw->pControlContainer = (pFrameVBox != NULL ? pFrameVBox : pGroupBox); } }
func (lf *lineFeed) valueUpdated(key *cftype.Key, line tablist.Liner) { flag := false older := key.Storage().Valuer(key.Group, key.Name) valStatus := key.ValueState(older) for i, st := range valStatus { curline := lf.testNewLine(line, i) switch st.State { case cftype.StateBothEmpty: line.Colored(RowOld, color.FgMagenta, "**EMPTY**") line.Colored(RowNew, color.BgRed, " == ") case cftype.StateUnchanged: curline.Set(RowOld, st.Old) curline.Colored(RowNew, color.BgRed, " == ") case cftype.StateEdited: curline.Set(RowOld, st.Old) st.New = ternary.String(st.New == "", "**EMPTY**", st.New) curline.Colored(RowNew, color.FgGreen, st.New) flag = true case cftype.StateAdded: curline.Set(RowOld, "**EMPTY**") curline.Colored(RowNew, color.FgGreen, st.New) flag = true case cftype.StateRemoved: curline.Set(RowOld, st.Old) curline.Colored(RowNew, color.FgGreen, "**EMPTY**") flag = true } } if flag { lf.countChanged++ } }
// PackReset adds a reset value button. // func PackReset(key *cftype.Key, value interface{}) *gtk.Button { fileDefault := key.Storage().FileDefault() if fileDefault == "" { return nil } back := newgtk.ButtonFromIconName("edit-clear", gtk.ICON_SIZE_MENU) back.Connect("clicked", func() { key.ValueSet(value) }) key.PackSubWidget(back) return back }
// Add adds a key to the printer. // func (lf *lineFeed) Add(key *cftype.Key) { if key.Group != lf.lastGroup { lf.AddGroup(RowName, key.Group) lf.lastGroup = key.Group lf.hasFrame = false } var line tablist.Liner var title string switch { case key.IsType(cftype.KeyFrame, cftype.KeyExpander): line = lf.AddEmptyFilled() lf.hasFrame = true line.Set(RowType, key.Type.String()) if len(key.AuthorizedValues) == 0 { title = "[*FRAME NO TITLE*]" } else { title = key.AuthorizedValues[0] } case key.IsType(cftype.KeySeparator): line = lf.AddEmptyFilled() line.Set(RowType, key.Type.String()) title = lf.indent() + "---------" case key.IsType(cftype.KeyTextLabel, cftype.KeyLaunchCmdSimple): line = lf.AddEmptyFilled() line.Set(RowType, key.Type.String()) title = lf.indent() + key.Name default: line = lf.AddLine() lf.valuePrint(key, line) line.Colored(RowType, color.FgGreen, key.Type.String()) title = lf.indent() + key.Name lf.countChangeable++ } line.Set(RowName, title) }
func cycleNextField(fields []datatype.Field, current string, key *cftype.Key) string { newID := datatype.ListFieldsIDByName(fields, current, key.Log()) return fields[cycleNextID(len(fields), newID, 1)].Key }
// 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) } }
// TreeView adds a treeview widget. // func TreeView(key *cftype.Key) { values := key.Value().ListString() // Build treeview. model := newgtk.ListStore( glib.TYPE_STRING, /* RowKey*/ glib.TYPE_STRING, /* RowName*/ glib.TYPE_STRING, /* RowIcon*/ glib.TYPE_STRING, /* RowDesc*/ glib.TYPE_BOOLEAN, // active glib.TYPE_INT) // order widget := newgtk.TreeViewWithModel(model) widget.Set("headers-visible", false) getValue := func() interface{} { // Grab data from all iters. var list []string iter, ok := model.GetIterFirst() for ; ok; ok = model.IterNext(iter) { str, e := gunvalue.New(model.GetValue(iter, RowName)).String() if !key.Log().Err(e, "WidgetTreeView GetValue "+key.Name) { list = append(list, str) } } return list } // Add control buttons. if key.IsType(cftype.KeyTreeViewMultiChoice) { renderer := newgtk.CellRendererToggle() col := newgtk.TreeViewColumnWithAttribute("", renderer, "active", 4) widget.AppendColumn(col) // g_signal_connect (G_OBJECT (rend), "toggled", (GCallback) _cairo_dock_activate_one_element, modele); renderer.Set("active", 4) } renderer := newgtk.CellRendererText() col := newgtk.TreeViewColumnWithAttribute("", renderer, "text", RowName) widget.AppendColumn(col) // cValueList = g_key_file_get_string_list (pKeyFile, cGroupName, cKeyName, &length, NULL); model.SetSortColumnId(5, gtk.SORT_ASCENDING) scroll := newgtk.ScrolledWindow(nil, nil) // // if len(key.AuthorizedValues) > 0 { // key.Log().Info("WidgetTreeView AuthorizedValues", key.AuthorizedValues) // } // if (key.AuthorizedValues != NULL && key.AuthorizedValues[0] != NULL) // for (k = 0; key.AuthorizedValues[k] != NULL; k++); // else // k = 1; scroll.Set("height-request", 100) // key.IsType(cftype.KeyTreeViewSortModify) ? 100 : MIN (100, k * 25) scroll.Set("width-request", 250) scroll.SetPolicy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC) scroll.Add(widget) vboxItems := newgtk.Box(gtk.ORIENTATION_VERTICAL, cftype.MarginGUI) grid := newgtk.Grid() grid.Attach(vboxItems, 0, 0, 1, 1) grid.Attach(scroll, 1, 0, 1, 1) if key.IsType(cftype.KeyTreeViewSortSimple, cftype.KeyTreeViewSortModify) { buttonUp := newgtk.Button() buttonDn := newgtk.Button() imgUp := newgtk.ImageFromIconName("go-up", gtk.ICON_SIZE_SMALL_TOOLBAR) imgDn := newgtk.ImageFromIconName("go-down", gtk.ICON_SIZE_SMALL_TOOLBAR) buttonUp.SetImage(imgUp) buttonDn.SetImage(imgDn) data := treeViewData{key.Log(), model, widget, nil} buttonUp.Connect("clicked", onTreeviewMoveUp, data) // Move selection up and down callbacks. buttonDn.Connect("clicked", onTreeviewMoveDown, data) vboxItems.PackStart(buttonUp, false, false, 0) vboxItems.PackStart(buttonDn, false, false, 0) if key.IsType(cftype.KeyTreeViewSortModify) { buttonAdd := newgtk.Button() entry := newgtk.Entry() buttonRm := newgtk.Button() imgAdd := newgtk.ImageFromIconName("list-add", gtk.ICON_SIZE_SMALL_TOOLBAR) imgRm := newgtk.ImageFromIconName("list-remove", gtk.ICON_SIZE_SMALL_TOOLBAR) buttonAdd.SetImage(imgAdd) buttonRm.SetImage(imgRm) vboxItems.PackStart(buttonRm, false, false, 0) grid.Attach(newgtk.Separator(gtk.ORIENTATION_HORIZONTAL), 0, 1, 2, 1) grid.Attach(buttonAdd, 0, 2, 1, 1) grid.Attach(entry, 1, 2, 1, 1) data.entry = entry buttonAdd.Connect("clicked", onTreeviewAddText, data) // Add new iter to model with the value of the entry widget. Clear entry widget. buttonRm.Connect("clicked", onTreeviewRemoveText, data) // Remove selected iter from model. Set its value to the entry widget. } } setValues := func(newvalues []string) { for i, val := range newvalues { iter := model.Append() model.SetValue(iter, RowKey, val) model.SetValue(iter, RowName, val) model.SetValue(iter, 4, true) // active model.SetValue(iter, 5, i) // order } } // Fill model with values. switch key.Type { case cftype.KeyTreeViewSortModify, // add saved values. cftype.KeyTreeViewSortSimple: // TODO: TEMP to improve and maybe regroup this case as was with multichoice and not modify. setValues(values) key.PackKeyWidget(key, getValue, func(uncast interface{}) { model.Clear(); setValues(uncast.([]string)) }, grid) case cftype.KeyTreeViewMultiChoice: if len(key.AuthorizedValues) > 0 { // var NbMax, order int } // else if (pAuthorizedValuesList != NULL) // on liste les choix possibles dans l'ordre choisi. Pour CAIRO_DOCK_WidgetTreeViewMultiChoice, on complete avec ceux n'ayant pas ete selectionnes. // { // gint iNbPossibleValues = 0, iOrder = 0; // while (pAuthorizedValuesList[iNbPossibleValues] != NULL) // iNbPossibleValues ++; // guint l; // for (l = 0; l < length; l ++) // { // cValue = cValueList[l]; // if (! g_ascii_isdigit (*cValue)) // ancien format. // { // cd_debug ("old format\n"); // int k; // for (k = 0; k < iNbPossibleValues; k ++) // on cherche la correspondance. // { // if (strcmp (cValue, pAuthorizedValuesList[k]) == 0) // { // cd_debug (" correspondance %s <-> %d", cValue, k); // g_free (cValueList[l]); // cValueList[l] = g_strdup_printf ("%d", k); // cValue = cValueList[l]; // break ; // } // } // if (k < iNbPossibleValues) // iValue = k; // else // continue; // } // else // iValue = atoi (cValue); // if (iValue < iNbPossibleValues) // { // memset (&iter, 0, sizeof (GtkTreeIter)); // gtk_list_store_append (modele, &iter); // gtk_list_store_set (modele, &iter, // CAIRO_DOCK_MODEL_ACTIVE, TRUE, // CAIRO_DOCK_MODEL_NAME, dgettext (cGettextDomain, pAuthorizedValuesList[iValue]), // CAIRO_DOCK_MODEL_RESULT, cValue, // CAIRO_DOCK_MODEL_ORDER, iOrder ++, -1); // } } // if (iOrder < iNbPossibleValues) // il reste des valeurs a inserer (ce peut etre de nouvelles valeurs apparues lors d'une maj du fichier de conf, donc CAIRO_DOCK_WidgetTreeViewSortSimple est concerne aussi). // { // gchar cResult[10]; // for (k = 0; pAuthorizedValuesList[k] != NULL; k ++) // { // cValue = pAuthorizedValuesList[k]; // for (l = 0; l < length; l ++) // { // iValue = atoi (cValueList[l]); // if (iValue == (int)k) // a deja ete inseree. // break; // } // if (l == length) // elle n'a pas encore ete inseree. // { // snprintf (cResult, 9, "%d", k); // memset (&iter, 0, sizeof (GtkTreeIter)); // gtk_list_store_append (modele, &iter); // gtk_list_store_set (modele, &iter, // CAIRO_DOCK_MODEL_ACTIVE, (iElementType == CAIRO_DOCK_WidgetTreeViewSortSimple), // CAIRO_DOCK_MODEL_NAME, dgettext (cGettextDomain, cValue), // CAIRO_DOCK_MODEL_RESULT, cResult, // CAIRO_DOCK_MODEL_ORDER, iOrder ++, -1); // } // } // } // } }
// 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) }
// LaunchCommand adds a launch command widget. // HELP ONLY // func LaunchCommand(key *cftype.Key) { if len(key.AuthorizedValues) == 0 || key.AuthorizedValues[0] == "" { key.Log().NewErrf("command missing", "widget LaunchCommand: %s", key.Name) return } // log.Info(key.Name, key.AuthorizedValues) if key.IsType(cftype.KeyLaunchCmdIf) { if len(key.AuthorizedValues) < 2 { key.Label().SetSensitive(false) return } key.Log().Info("KeyLaunchCmdIf : disabled for now") return // key.Log().Info("test", key.AuthorizedValues[1]) // key.Log().Err(key.Log().ExecShow(key.AuthorizedValues[1]), "exec test") // gchar *cSecondCommand = pAuthorizedValuesList[1]; // gchar *cResult = cairo_dock_launch_command_sync (cSecondCommand); // cd_debug ("%s: %s => %s", __func__, cSecondCommand, cResult); // if (cResult == NULL || *cResult == '0' || *cResult == '\0') // result is 'fail' // { // gtk_widget_set_sensitive (pLabel, FALSE); // g_free (cResult); // break ; // } // g_free (cResult); } spinner := newgtk.Spinner() spinner.SetNoShowAll(true) key.PackSubWidget(spinner) btn := newgtk.ButtonFromIconName("go-jump", gtk.ICON_SIZE_BUTTON) key.PackSubWidget(btn) btn.Connect("clicked", func() { cmd, e := key.Log().ExecShlex(key.AuthorizedValues[0]) if key.Log().Err(e, "widget LaunchCommand parse command", key.Name, ":", key.AuthorizedValues[0]) { return } e = cmd.Start() if key.Log().Err(e, "widget LaunchCommand exec", key.AuthorizedValues[0]) { return } btn.Hide() spinner.Show() spinner.Start() // Wait the external program in a go routine. // When finished, restore buttons state in the gtk idle loop. go func() { cmd.Wait() glib.IdleAdd(func() { btn.Show() spinner.Hide() spinner.Stop() }) }() }) // G_CALLBACK (_cairo_dock_widget_launch_command), }
// ListIconsMainDock adds an icon list widget. // func ListIconsMainDock(key *cftype.Key) { // { // if (g_pMainDock == NULL) // maintenance mode... no dock, no icons // { // cValue = g_key_file_get_string (pKeyFile, cGroupName, cKeyName, NULL); // pOneWidget = gtk_entry_new (); // gtk_entry_set_text (GTK_ENTRY (pOneWidget), cValue); // if there is a problem, we can edit it. // _pack_subwidget (pOneWidget); // g_free (cValue); // break; // } // // current := key.Value().String() model := newModelSimple() widget := newgtk.ComboBoxWithModel(model) rp := newgtk.CellRendererPixbuf() widget.PackStart(rp, false) widget.AddAttribute(rp, "pixbuf", RowIcon) renderer := newgtk.CellRendererText() widget.PackStart(renderer, true) widget.AddAttribute(renderer, "text", RowName) list := key.Source().ListIconsMainDock() saved := indexiter.NewByString(widget, key.Log()) iter := fillModelWithFields(key, model, list, current, saved) widget.SetActiveIter(iter) // // // build the modele and combo // modele = _cairo_dock_gui_allocate_new_model (); // pOneWidget = gtk_combo_box_new_with_model (GTK_TREE_MODEL (modele)); // rend = gtk_cell_renderer_pixbuf_new (); // gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (pOneWidget), rend, FALSE); // gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (pOneWidget), rend, "pixbuf", CAIRO_DOCK_MODEL_ICON, NULL); // rend = gtk_cell_renderer_text_new (); // gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (pOneWidget), rend, FALSE); // gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (pOneWidget), rend, "text", CAIRO_DOCK_MODEL_NAME, NULL); // _pack_subwidget (pOneWidget); // // get the dock // CairoDock *pDock = NULL; // if (pAuthorizedValuesList != NULL && pAuthorizedValuesList[0] != NULL) // pDock = gldi_dock_get (pAuthorizedValuesList[0]); // if (!pDock) // pDock = g_pMainDock; // // insert each icon // cValue = g_key_file_get_string (pKeyFile, cGroupName, cKeyName, NULL); // gint iDesiredIconSize = cairo_dock_search_icon_size (GTK_ICON_SIZE_LARGE_TOOLBAR); // 24 by default // GtkTreeIter iter; // Icon *pIcon; // gchar *cImagePath, *cID; // const gchar *cName; // GdkPixbuf *pixbuf; // GList *ic; // for (ic = pDock->icons; ic != NULL; ic = ic->next) // { // pIcon = ic->data; // if (pIcon->cDesktopFileName != NULL // || pIcon->pModuleInstance != NULL) // { // pixbuf = NULL; // cImagePath = NULL; // cName = NULL; // // get the ID // if (pIcon->cDesktopFileName != NULL) // cID = pIcon->cDesktopFileName; // else // cID = pIcon->pModuleInstance->cConfFilePath; // // get the image // if (pIcon->cFileName != NULL) // { // cImagePath = cairo_dock_search_icon_s_path (pIcon->cFileName, iDesiredIconSize); // } // if (cImagePath == NULL || ! g_file_test (cImagePath, G_FILE_TEST_EXISTS)) // { // g_free (cImagePath); // if (GLDI_OBJECT_IS_SEPARATOR_ICON (pIcon)) // { // if (myIconsParam.cSeparatorImage) // cImagePath = cairo_dock_search_image_s_path (myIconsParam.cSeparatorImage); // } // else if (CAIRO_DOCK_IS_APPLET (pIcon)) // { // cImagePath = g_strdup (pIcon->pModuleInstance->pModule->pVisitCard->cIconFilePath); // } // else // { // cImagePath = cairo_dock_search_image_s_path (CAIRO_DOCK_DEFAULT_ICON_NAME); // if (cImagePath == NULL || ! g_file_test (cImagePath, G_FILE_TEST_EXISTS)) // { // g_free (cImagePath); // cImagePath = g_strdup (GLDI_SHARE_DATA_DIR"/icons/"CAIRO_DOCK_DEFAULT_ICON_NAME); // } // } // } // //g_print (" + %s\n", cImagePath); // if (cImagePath != NULL) // { // pixbuf = gdk_pixbuf_new_from_file_at_size (cImagePath, iDesiredIconSize, iDesiredIconSize, NULL); // } // //g_print (" -> %p\n", pixbuf); // // get the name // if (CAIRO_DOCK_IS_USER_SEPARATOR (pIcon)) // separator // cName = "---------"; // else if (CAIRO_DOCK_IS_APPLET (pIcon)) // applet // cName = pIcon->pModuleInstance->pModule->pVisitCard->cTitle; // else // launcher // cName = (pIcon->cInitialName ? pIcon->cInitialName : pIcon->cName); // // store the icon // memset (&iter, 0, sizeof (GtkTreeIter)); // gtk_list_store_append (GTK_LIST_STORE (modele), &iter); // gtk_list_store_set (GTK_LIST_STORE (modele), &iter, // CAIRO_DOCK_MODEL_NAME, cName, // CAIRO_DOCK_MODEL_RESULT, cID, // CAIRO_DOCK_MODEL_ICON, pixbuf, -1); // g_free (cImagePath); // if (pixbuf) // g_object_unref (pixbuf); // if (cValue && strcmp (cValue, cID) == 0) // gtk_combo_box_set_active_iter (GTK_COMBO_BOX (pOneWidget), &iter); // } // } // g_free (cValue); // } key.PackKeyWidget(key, getValueListCombo(widget, model, key.Log()), func(uncast interface{}) { saved.SetActive(uncast.(string)) }, widget) }
// ListDock adds a dock list widget. // func ListDock(key *cftype.Key) { // Get current Icon name if its a Subdock. iIconType, _ := key.Storage().Int(key.Group, "Icon Type") SubdockName := "" if iIconType == cftype.UserIconStack { // it's a stack-icon SubdockName, _ = key.Storage().String(key.Group, "Name") // It's a subdock, get its name to remove the selection of a recursive position (inside itself). } list := key.Source().ListDocks("", SubdockName) // Get the list of available docks. Keep parent, but remove itself from the list. list = append(list, datatype.Field{ Key: datatype.KeyNewDock, Name: tran.Slate("New main dock")}, ) model := newModelSimple() current := key.Value().String() if current == "" { current = datatype.KeyMainDock } model.SetSortColumnId(RowName, gtk.SORT_ASCENDING) widget := newgtk.ComboBoxWithModel(model) renderer := newgtk.CellRendererText() widget.PackStart(renderer, false) widget.AddAttribute(renderer, "text", RowName) saved := indexiter.NewByString(widget, key.Log()) iter := fillModelWithFields(key, model, list, current, saved) widget.SetActiveIter(iter) key.PackKeyWidget(key, getValueListCombo(widget, model, key.Log()), func(uncast interface{}) { saved.SetActive(uncast.(string)) }, widget) }
// ListDialogDecorator adds an dialog decorator list widget. // func ListDialogDecorator(key *cftype.Key) { PackComboBoxWithListField(key, false, false, key.Source().ListDialogDecorator) }