// 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 }
// 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) }
// Frame adds a simple or expanded frame widget. // func Frame(key *cftype.Key) { if len(key.AuthorizedValues) == 0 { key.SetFrame(nil) key.SetFrameBox(nil) return } value, img := "", "" if key.AuthorizedValues[0] == "" { key.Log().Info("WidgetFrame, need value case 1") // value = g_key_file_get_string(pKeyFile, cGroupName, cKeyName, NULL) // utile ? } else { value = key.AuthorizedValues[0] if len(key.AuthorizedValues) > 1 { img = key.AuthorizedValues[1] } } // Create the frame label with the optional icon. label := newgtk.Label("") // key.SetLabel(label) label.SetMarkup(" " + common.Bold(key.Translate(value)) + " ") var labelContainer gtk.IWidget if img == "" { labelContainer = label } else { box := newgtk.Box(gtk.ORIENTATION_HORIZONTAL, cftype.MarginIcon/2) if icon, e := common.ImageNewFromFile(img, iconSizeFrame); !key.Log().Err(e, "Frame icon") { // TODO: fix size : int(gtk.ICON_SIZE_MENU) box.Add(icon) } box.Add(label) labelContainer = box } // Create the box that will contain next widgets (inside the frame). box := newgtk.Box(gtk.ORIENTATION_VERTICAL, cftype.MarginGUI) key.SetFrameBox(box) frame := newgtk.Frame("") key.SetFrame(frame) frame.SetBorderWidth(cftype.MarginGUI) frame.SetShadowType(gtk.SHADOW_OUT) frame.Add(box) // Set label and create the expander around the frame if needed. switch key.Type { case cftype.KeyFrame: frame.SetLabelWidget(labelContainer) key.BoxPage().PackStart(frame, false, false, 0) case cftype.KeyExpander: expand := newgtk.Expander("") expand.SetExpanded(false) expand.SetLabelWidget(labelContainer) expand.Add(frame) key.BoxPage().PackStart(expand, false, false, 0) } // SAME AS IN builder.go // if (pControlWidgets != NULL) // { // cd_debug ("ctrl\n"); // CDControlWidget *cw = pControlWidgets->data; // if (cw->pControlContainer == key.Box) // { // cd_debug ("ctrl (NbControlled:%d, iFirstSensitiveWidget:%d, iNbSensitiveWidgets:%d)", cw->NbControlled, cw->iFirstSensitiveWidget, cw->iNbSensitiveWidgets); // cw->NbControlled --; // if (cw->iFirstSensitiveWidget > 0) // cw->iFirstSensitiveWidget --; // cw->iNonSensitiveWidget --; // GtkWidget *w = pExternFrame; // if (cw->iFirstSensitiveWidget == 0 && cw->iNbSensitiveWidgets > 0 && cw->iNonSensitiveWidget != 0) // { // cd_debug (" => sensitive\n"); // cw->iNbSensitiveWidgets --; // if (GTK_IS_EXPANDER (w)) // gtk_expander_set_expanded (GTK_EXPANDER (w), TRUE); // } // else // { // cd_debug (" => unsensitive\n"); // if (!GTK_IS_EXPANDER (w)) // gtk_widget_set_sensitive (w, FALSE); // } // if (cw->iFirstSensitiveWidget == 0 && cw->NbControlled == 0) // { // pControlWidgets = g_list_delete_link (pControlWidgets, pControlWidgets); // g_free (cw); // } // } // } }
// Strings adds a string widget. Many options included. // TODO: need password cypher, G_USER_DIRECTORY_PICTURES, play sound. // func Strings(key *cftype.Key) { value := key.Value().String() widget := newgtk.Entry() widget.SetText(value) if key.IsType(cftype.KeyPasswordEntry) { // Hide text and decrypt value. widget.SetVisibility(false) value = key.Source().DecryptString(value) } // Pack the widget before any other (in full size if needed). // So we do it now and fill the callbacks later key.PackKeyWidget(key, nil, nil, widget) var setValue func(interface{}) // Add special buttons to fill the entry box. switch key.Type { case cftype.KeyFileSelector, cftype.KeyFolderSelector, cftype.KeySoundSelector, cftype.KeyImageSelector: // Add a file selector. fileChooser := newgtk.Button() img := newgtk.ImageFromIconName("document-open", gtk.ICON_SIZE_SMALL_TOOLBAR) fileChooser.SetImage(img) fileChooser.Connect("clicked", onFileChooserOpen, fileChooserData{widget, key}) key.PackSubWidget(fileChooser) if key.IsType(cftype.KeySoundSelector) { //Sound Play Button play := newgtk.Button() imgPlay := newgtk.ImageFromIconName("media-playback-start", gtk.ICON_SIZE_SMALL_TOOLBAR) play.SetImage(imgPlay) // play.Connect("clicked", C._cairo_dock_play_a_sound, data) key.PackSubWidget(play) } case cftype.KeyShortkeySelector, cftype.KeyClassSelector: // Add a key/class grabber. grab := newgtk.ButtonWithLabel("Grab") key.PackSubWidget(grab) // gtk_widget_add_events(pMainWindow, GDK_KEY_PRESS_MASK); switch key.Type { case cftype.KeyClassSelector: grab.Connect("clicked", func() { widget.SetSensitive(false) // Block widgets. grab.SetSensitive(false) go func() { class, e := key.Source().GrabWindowClass() // Wait user selection in a routine. glib.IdleAdd(func() { // And resync with the GTK loop to display results. widget.SetSensitive(true) // Reactivate widgets. grab.SetSensitive(true) if !key.Log().Err(e, "ClassSelector", key.Group, key.Name) { setValue(class) // On success. key.Log().Debug("KeyClassSelector window selected", class) } }) }() }) case cftype.KeyShortkeySelector: grab.Connect("clicked", onKeyGrabClicked, &textGrabData{entry: widget, win: key.Source().GetWindow()}) } // for _, sk := range key.Source().ListShortkeys() { // if sk.GetConfFilePath() == key.Storage().FilePath() { // println("found file shortkey") // } // } } // Display a default value when empty. if len(key.AuthorizedValues) > 0 && key.AuthorizedValues[0] != "" { defaultText := key.Translate(key.AuthorizedValues[0]) cbChanged, _ := widget.Connect("changed", onTextDefaultChanged, key) data := textDefaultData{key: key, text: defaultText, cbID: cbChanged} widget.Connect("focus-in-event", onTextDefaultFocusIn, data) widget.Connect("focus-out-event", onTextDefaultFocusOut, data) // TODO: check other use of those fields. // g_object_set_data (G_OBJECT (pEntry), "ignore-value", GINT_TO_POINTER (TRUE)); // g_object_set_data (G_OBJECT (pOneWidget), "default-text", cDefaultText); context, _ := widget.GetStyleContext() context.AddProvider(MainCSS(), gtk.STYLE_PROVIDER_PRIORITY_APPLICATION) setValue = func(uncast interface{}) { // if !key.IsDefault { // not sure why this was here. widget.SetText(uncast.(string)) onTextDefaultFocusOut(widget, nil, data) } setValue(value) // will set IsDefault and button state. } else { setValue = func(uncast interface{}) { widget.SetText(uncast.(string)) } } getValue := func() (text interface{}) { if key.IsDefault { return "" } text, _ = widget.GetText() return text } key.PackKeyWidget(key, getValue, setValue) }