Skip to content

Commit

Permalink
Implemented 'always active' mode for menu. Fixes #578
Browse files Browse the repository at this point in the history
  • Loading branch information
kozec committed Sep 26, 2020
1 parent b1913bd commit 1f3b1d8
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 10 deletions.
27 changes: 23 additions & 4 deletions python/scc/gui/ae/menu_action.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from scc.tools import _

from gi.repository import Gtk
from scc.constants import SCButtons, SAME, STICK, DEFAULT
from scc.constants import SCButtons, SAME, STICK, DEFAULT, ALWAYS
from scc.actions import MenuAction, HorizontalMenuAction
from scc.actions import RadialMenuAction, GridMenuAction
from scc.actions import QuickMenuAction, PositionModifier
Expand Down Expand Up @@ -92,12 +92,13 @@ def load_menu_data(self, action):
if self.update_size_display(action):
size = spMenuSize.get_adjustment().set_value(action.size)

cbMenuConfirmWithClick = self.builder.get_object("cbMenuConfirmWithClick")
cbMenuAlwaysActive = self.builder.get_object("cbMenuAlwaysActive")
cbMenuAutoConfirm = self.builder.get_object("cbMenuAutoConfirm")
cbMenuAutoCancel = self.builder.get_object("cbMenuAutoCancel")
cbControlWith = self.builder.get_object("cbControlWith")
cbConfirmWith = self.builder.get_object("cbConfirmWith")
cbCancelWith = self.builder.get_object("cbCancelWith")
cbMenuAutoConfirm = self.builder.get_object("cbMenuAutoConfirm")
cbMenuConfirmWithClick = self.builder.get_object("cbMenuConfirmWithClick")
cbMenuAutoCancel = self.builder.get_object("cbMenuAutoCancel")
if cbControlWith:
self.set_cb(cbControlWith, nameof(action.control_with), 1)

Expand All @@ -111,6 +112,9 @@ def load_menu_data(self, action):
elif cbMenuConfirmWithClick and cow == self.get_default_confirm():
cbMenuConfirmWithClick.set_active(True)
cbConfirmWith.set_sensitive(False)
if cow == ALWAYS and cbMenuAlwaysActive:
cbMenuAlwaysActive.set_active(True)
cbConfirmWith.set_sensitive(False)
else:
if cbMenuAutoConfirm:
cbMenuAutoConfirm.set_active(False)
Expand Down Expand Up @@ -277,26 +281,37 @@ def prevent_confirm_cancel_nonsense(self, widget, *a):
being checked in nonsensical way.
"""
cbMenuConfirmWithClick = self.builder.get_object("cbMenuConfirmWithClick")
cbMenuAlwaysActive = self.builder.get_object("cbMenuAlwaysActive")
cbMenuAutoConfirm = self.builder.get_object("cbMenuAutoConfirm")
cbMenuAutoCancel = self.builder.get_object("cbMenuAutoCancel")
if widget.get_active():
if widget == cbMenuConfirmWithClick:
if cbMenuAutoConfirm:
cbMenuAutoConfirm.set_active(False)
if cbMenuAlwaysActive:
cbMenuAlwaysActive.set_active(False)
elif widget == cbMenuAutoConfirm:
if cbMenuConfirmWithClick:
cbMenuConfirmWithClick.set_active(False)
if cbMenuAutoCancel:
cbMenuAutoCancel.set_active(False)
if cbMenuAlwaysActive:
cbMenuAlwaysActive.set_active(False)
elif widget == cbMenuAutoCancel:
if cbMenuAutoConfirm:
cbMenuAutoConfirm.set_active(False)
elif widget == cbMenuAlwaysActive:
if cbMenuConfirmWithClick:
cbMenuConfirmWithClick.set_active(False)
if cbMenuAutoConfirm:
cbMenuAutoConfirm.set_active(False)


def on_cbMenus_changed(self, *a):
""" Called when user changes any menu settings """
if self._recursing : return
cbMenuConfirmWithClick = self.builder.get_object("cbMenuConfirmWithClick")
cbMenuAlwaysActive = self.builder.get_object("cbMenuAlwaysActive")
cbMenuAutoConfirm = self.builder.get_object("cbMenuAutoConfirm")
cbMenuAutoCancel = self.builder.get_object("cbMenuAutoCancel")
lblControlWith = self.builder.get_object("lblControlWith")
Expand All @@ -322,6 +337,8 @@ def on_cbMenus_changed(self, *a):
sensitive = False
if cbMenuConfirmWithClick and cbMenuConfirmWithClick.get_active():
sensitive = False
if cbMenuAlwaysActive and cbMenuAlwaysActive.get_active():
sensitive = False
if menu_type == "quickmenu":
sensitive = False
lblConfirmWith.set_sensitive(sensitive)
Expand Down Expand Up @@ -355,6 +372,8 @@ def on_cbMenus_changed(self, *a):
cow = SAME
elif cbMenuConfirmWithClick and cbMenuConfirmWithClick.get_active():
cow = DEFAULT
elif cbMenuAlwaysActive and cbMenuAlwaysActive.get_active():
cow = ALWAYS
elif cbConfirmWith:
cow = cbConfirmWith.get_model().get_value(cbConfirmWith.get_active_iter(), 1)
if cow != DEFAULT:
Expand Down
24 changes: 24 additions & 0 deletions share/glade/ae/dpad.glade
Original file line number Diff line number Diff line change
Expand Up @@ -952,6 +952,30 @@
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="cbMenuAlwaysActive">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="margin_top">5</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="on_cbMenus_changed" swapped="no"/>
<signal name="toggled" handler="prevent_confirm_cancel_nonsense" swapped="no"/>
<child>
<object class="GtkLabel" id="lblMenuAlwaysActive">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Selection is always active</property>
<property name="xalign">0</property>
</object>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">5</property>
<property name="width">2</property>
</packing>
</child>
</object>
</child>
</object>
Expand Down
4 changes: 3 additions & 1 deletion src/actions/param_checker/check.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@ bool check_axis_name(const char* value) {
}

static bool check_plus(const char* value) {
return (0 == strcmp(value, "DEFAULT")) || (0 == strcmp(value, "SAME"));
return (0 == strcmp(value, "DEFAULT"))
|| (0 == strcmp(value, "ALWAYS"))
|| (0 == strcmp(value, "SAME"));
}

bool check_button_name_plus(const char* value) {
Expand Down
3 changes: 2 additions & 1 deletion src/actions/sa_menu.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ static void whole(Action* a, Mapper* m, AxisValue x, AxisValue y, PadStickTrigge
break;
}
sa->data.triggered_by = what;
LOG("WHOOOLE %i %i", x, y);
if ((m->special_action == NULL) || !m->special_action(m, SAT_MENU, &sa->data))
DWARN("Mapper lacks support for 'menu'");
}
Expand All @@ -93,6 +92,8 @@ static Parameter* get_property(Action* a, const char* name) {

SCButton string_to_confirm_cancel(const char* s) {
// TODO: Magic strings here
if (0 == strcmp("ALWAYS", s))
return SCC_ALWAYS;
if (0 == strcmp("DEFAULT", s))
return SCC_DEFAULT;
if (0 == strcmp("SAME", s))
Expand Down
56 changes: 52 additions & 4 deletions src/osd/menus/menu.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ struct _OSDMenuPrivate {
G_DEFINE_TYPE_WITH_CODE(OSDMenu, osd_menu, OSD_WINDOW_TYPE, G_ADD_PRIVATE(OSDMenu));


static void osd_menu_exit(OSDMenu* mnu, int code);
static void osd_menu_finalize(GObject* mnu);

static void osd_menu_class_init(OSDMenuClass *klass) {
Expand Down Expand Up @@ -128,7 +129,7 @@ static gboolean osd_menu_on_data_ready(GIOChannel* source, GIOCondition conditio
const char* message = sccc_recieve(priv->client);
if (message != NULL) {
if (message[0] == 0) {
osd_window_exit(OSD_WINDOW(mnu), 1);
osd_menu_exit(mnu, 1);
return false;
}
}
Expand All @@ -148,16 +149,18 @@ void osd_menu_lock_inputs(OSDMenu* mnu) {
LERROR("There is no controller connected");
else
LERROR("Requested controller '%s' not connected", priv->settings.controller_id);
osd_window_exit(OSD_WINDOW(mnu), 4);
osd_menu_exit(mnu, 4);
return;
}

const char* control_with = scc_what_to_string(priv->settings.control_with);
const char* confirm_with = scc_button_to_string(priv->settings.confirm_with);
const char* cancel_with = scc_button_to_string(priv->settings.cancel_with);
if (priv->settings.confirm_with == SCC_ALWAYS)
confirm_with = control_with;
if (!sccc_lock(priv->client, handle, control_with, confirm_with, cancel_with)) {
LERROR("Failed to lock controller");
osd_window_exit(OSD_WINDOW(mnu), 3);
osd_menu_exit(mnu, 3);
return;
}

Expand Down Expand Up @@ -211,7 +214,7 @@ void osd_menu_parse_event(OSDMenu* mnu, SCCClient* c, uint32_t handle,
else if ((button == priv->settings.confirm_with) && (!values[0]))
osd_menu_confirm(mnu);
else if ((button == priv->settings.cancel_with) && (!values[0]))
osd_window_exit(OSD_WINDOW(mnu), -1);
osd_menu_exit(mnu, -1);
}


Expand All @@ -233,6 +236,39 @@ static void _osd_menu_handle_stick(int dx, int dy, void* _mnu) {
priv->handle_stick_cb(mnu, dx, dy);
}

/**
* Activates (calls 'pressed' handler) or deactivates (calls 'released hanlder')
* specific menu item.
* Doesn't works with submenus & etc.
*/
static void osd_menu_set_action_active(OSDMenu* mnu, MenuItem* i, bool active) {
if (i == NULL) return;
OSDMenuPrivate* priv = get_private(mnu);
Action* a = NULL;

switch (i->type) {
case MI_ACTION:
a = i->action;
scc_action_compress(&a);
if (active)
a->button_press(a, priv->slave_mapper);
else
a->button_release(a, priv->slave_mapper);
break;
default:
break;
}
}

static void osd_menu_exit(OSDMenu* mnu, int code) {
OSDMenuPrivate* priv = get_private(mnu);
if ((priv->settings.confirm_with == SCC_ALWAYS) && (priv->selected != NULL)) {
MenuItem* i = g_object_get_data(G_OBJECT(priv->selected), "scc-menu-item-data");
osd_menu_set_action_active(mnu, i, false);
}
osd_window_exit(OSD_WINDOW(mnu), 2);
}


bool osd_menu_select_index(OSDMenu* mnu, size_t index) {
OSDMenuPrivate* priv = get_private(mnu);
Expand All @@ -255,6 +291,10 @@ bool osd_menu_select(OSDMenu* mnu, MenuItem* i) {
gtk_widget_set_name(GTK_WIDGET(priv->selected), name);
}
free(name);
if (priv->settings.confirm_with == SCC_ALWAYS) {
MenuItem* i = g_object_get_data(G_OBJECT(priv->selected), "scc-menu-item-data");
osd_menu_set_action_active(mnu, i, false);
}
priv->selected = NULL;
}

Expand All @@ -278,6 +318,10 @@ bool osd_menu_select(OSDMenu* mnu, MenuItem* i) {
strbuilder_free(sb);
// GLib.timeout_add(2, self._check_on_screen_position)
}
if (priv->settings.confirm_with == SCC_ALWAYS) {
MenuItem* i = g_object_get_data(G_OBJECT(priv->selected), "scc-menu-item-data");
osd_menu_set_action_active(mnu, i, true);
}
return true;
}

Expand Down Expand Up @@ -385,6 +429,7 @@ void osd_menu_connect(OSDMenu* mnu) {
g_source_set_callback(src, (GSourceFunc)osd_menu_on_data_ready, mnu, NULL);
}


struct osd_menu_release_data {
Action* action;
OSDMenu* mnu;
Expand All @@ -393,6 +438,7 @@ struct osd_menu_release_data {
static gboolean osd_menu_dummy(gpointer ptr) {
return FALSE;
}

static void osd_menu_release(gpointer ptr) {
struct osd_menu_release_data* data = ptr;

Expand Down Expand Up @@ -577,6 +623,8 @@ bool osd_menu_parse_args(int argc, char** argv, const char** usage, OSDMenuSetti
settings->confirm_with = B_A;
} else if (strcmp(confirm_with, "SAME") == 0) {
settings->confirm_with = scc_what_to_touch_button(settings->control_with);
} else if (strcmp(confirm_with, "ALWAYS") == 0) {
settings->confirm_with = SCC_ALWAYS;
} else if (settings->confirm_with == 0) {
LERROR("Invalid value for '--confirm-with' option: '%s'", confirm_with);
return false;
Expand Down
1 change: 1 addition & 0 deletions src/tools/constants.c
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ const char* scc_button_to_string(SCButton b) {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wswitch"
case SCC_DEFAULT: return "DEFAULT";
case SCC_ALWAYS: return "ALWAYS";
case SCC_SAME: return "SAME";
#pragma GCC diagnostic pop
default:
Expand Down

0 comments on commit 1f3b1d8

Please sign in to comment.