Пример #1
0
// New creates the config menu with add or save buttons.
//
func New(control Controller) *MenuBar {
	wmb := &MenuBar{
		Box:     *newgtk.Box(gtk.ORIENTATION_HORIZONTAL, 0),
		Save:    newgtk.ButtonWithMnemonic("_Save"),
		control: control,
	}

	wmb.Save.Set("no-show-all", true)

	sep := newgtk.Box(gtk.ORIENTATION_HORIZONTAL, 0)

	/// Actions
	wmb.Save.Connect("clicked", wmb.control.ClickedSave)

	mainBtn, _ := gtk.MenuButtonNew()

	img := newgtk.ImageFromIconName("preferences-system", IconSize)
	mainBtn.SetImage(img)

	mainBtn.SetPopup(menus.NewMenu(
		menus.NewItem(tran.Slate("Help"), func() { control.Select("Config", "Help") }),
		menus.NewItem(tran.Slate("About"), func() { about.New() }),
		nil,
		menus.NewItem(tran.Slate("Close"), wmb.control.ClickedQuit),
	))

	/// Packing: End list = reversed.

	wmb.PackEnd(mainBtn, false, false, 0)
	wmb.PackEnd(sep, false, false, 3) // separator add 3x2px.
	wmb.PackEnd(wmb.Save, false, false, 0)
	return wmb
}
Пример #2
0
// AddPage connects a page to a new button.
//
func (widget *Switcher) AddPage(page *Page) {
	if page.Icon != "" {
		img := newgtk.ImageFromIconName(page.Icon, gtk.ICON_SIZE_SMALL_TOOLBAR)
		if img != nil {
			page.btn = newgtk.ToggleButton()
			page.btn.SetTooltipText(page.Name)
			page.btn.SetImage(img)
		}
	}

	if page.btn == nil {
		page.btn = newgtk.ToggleButtonWithLabel(page.Name)
	}

	context, _ := page.btn.GetStyleContext()
	context.RemoveClass("text-button")

	widget.PackStart(page.btn, false, false, 0)
	page.handler, _ = page.btn.Connect("clicked", func() { widget.clickedBtn(page.Key) })

	widget.pages[page.Key] = page
	page.btn.Show()
}
Пример #3
0
// 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);
	// 			}
	// 		}
	// 	}
	// }
}
Пример #4
0
// IntegerSize adds an integer selector widget.
//
func IntegerSize(key *cftype.Key) {
	if key.NbElements > 1 { // TODO: remove temp test
		key.Log().Info("IntegerSize multi", key.NbElements, key.Type.String())
	}

	toggle := newgtk.ToggleButton()
	img := newgtk.ImageFromIconName("media-playback-pause", gtk.ICON_SIZE_MENU) // get better image.
	toggle.SetImage(img)

	values := key.Value().ListInt()
	minValue, maxValue := minMaxValues(key)

	var valuers []WidgetValuer

	key.NbElements *= 2 // Two widgets to add.

	// Value pair data.
	var firstValue int
	var firstWidget *gtk.SpinButton
	var cbBlock func() func()

	for k := 0; k < key.NbElements; k++ {
		var value int
		if k < len(values) {
			value = values[k]
		}

		w := newgtk.SpinButtonWithRange(minValue, maxValue, 1)
		w.SetValue(float64(value))
		key.PackSubWidget(w)
		valuers = append(valuers, w)

		if k&1 == 0 { // first value, separator
			label := newgtk.Label("x")
			key.PackSubWidget(label)

			firstWidget = w
			firstValue = value

		} else { // second value. connect both spin values.
			if firstValue == value {
				toggle.SetActive(true)
			}

			cb0, e := firstWidget.Connect("value-changed", onValuePairChanged, &valuePair{
				linked: w,
				toggle: toggle})
			key.Log().Err(e, "IntegerSize connect value-changed 1")
			cb1, e := w.Connect("value-changed", onValuePairChanged, &valuePair{
				linked: firstWidget,
				toggle: toggle})
			key.Log().Err(e, "IntegerSize connect value-changed 2")

			cbBlock = func() func() {
				firstWidget.HandlerBlock(cb0)
				w.HandlerBlock(cb1)
				return func() {
					firstWidget.HandlerUnblock(cb0)
					w.HandlerUnblock(cb1)
				}
			}
		}
	}

	setValue := func(uncast interface{}) {
		if cbBlock == nil {
			key.Log().NewErr("no valuePair callbacks", "IntegerSize", key.Name)
		} else {
			defer cbBlock()() // This disables now and reenables during defer.
		}
		values := uncast.([]int)
		if len(values) < 2 {
			key.Log().NewErr("not enough values provided", "IntegerSize set value", key.Name, values)
			values = []int{0, 0}
		}

		listValuerSet(valuers, cast.IntsToFloats(values))
		toggle.SetActive(values[0] == values[1])
	}

	key.PackKeyWidget(key,
		func() interface{} { return cast.FloatsToInts(listValuerGet(valuers)) },
		setValue,
		toggle,
	)

	oldval, e := key.Storage().Default(key.Group, key.Name)
	key.Log().Err(e, "IntegerSize original value")
	if e == nil {
		PackReset(key, oldval.ListInt())
	}
}
Пример #5
0
// 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)
}