[WIP] Allow building with GTK+ 3.16+.
Set CMake option `ENABLE_GTK3` to `ON` to build with GTK+ 3.0. In GTK3 mode: - Use `GtkGrid` instead of `GtkTable` - Don't use `GtkMisc` to set `GtkLabel`'s alignments - `PianoKeyboard`'s draw() code still needs to be refactored (doesn't show key presses). - Grab keyboard functionality still needs to be ported (doesn't work yet).
This commit is contained in:
parent
44980fc2f5
commit
2f5b69c021
@ -27,6 +27,9 @@
|
|||||||
#
|
#
|
||||||
cmake_minimum_required(VERSION 2.8)
|
cmake_minimum_required(VERSION 2.8)
|
||||||
|
|
||||||
|
option(ENABLE_GTK2 "Enable GTK2 Version" ON)
|
||||||
|
option(ENABLE_GTK3 "Enable GTK3 Version" OFF)
|
||||||
|
|
||||||
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/")
|
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/")
|
||||||
set(VERSION "2.7.2")
|
set(VERSION "2.7.2")
|
||||||
|
|
||||||
@ -38,9 +41,20 @@ project(jack-keyboard)
|
|||||||
|
|
||||||
add_executable(jack-keyboard src/jack-keyboard src/pianokeyboard)
|
add_executable(jack-keyboard src/jack-keyboard src/pianokeyboard)
|
||||||
|
|
||||||
find_package(GTK2 2.20 REQUIRED gtk)
|
find_package(PkgConfig REQUIRED)
|
||||||
|
|
||||||
|
if(ENABLE_GTK3)
|
||||||
|
set(ENABLE_GTK2 OFF)
|
||||||
|
PKG_CHECK_MODULES(GTK3 "gtk+-3.0 >= 3.16" REQUIRED)
|
||||||
|
include_directories(${GTK3_INCLUDE_DIRS})
|
||||||
|
target_link_libraries(jack-keyboard ${GTK3_LIBRARIES})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(ENABLE_GTK2)
|
||||||
|
PKG_CHECK_MODULES(GTK2 "gtk+-2.0 >= 2.20" REQUIRED)
|
||||||
include_directories(${GTK2_INCLUDE_DIRS})
|
include_directories(${GTK2_INCLUDE_DIRS})
|
||||||
target_link_libraries(jack-keyboard ${GTK2_LIBRARIES})
|
target_link_libraries(jack-keyboard ${GTK2_LIBRARIES})
|
||||||
|
endif()
|
||||||
|
|
||||||
# In preparation for GTK+3:
|
# In preparation for GTK+3:
|
||||||
# Set GDK/GTK+ flags to report deprecated includes and symbols.
|
# Set GDK/GTK+ flags to report deprecated includes and symbols.
|
||||||
|
@ -1039,6 +1039,7 @@ int grab_x_error_handler(Display *dpy, XErrorEvent *notused)
|
|||||||
GdkFilterReturn
|
GdkFilterReturn
|
||||||
keyboard_grab_filter(GdkXEvent *xevent, GdkEvent *event, gpointer notused)
|
keyboard_grab_filter(GdkXEvent *xevent, GdkEvent *event, gpointer notused)
|
||||||
{
|
{
|
||||||
|
#if !GTK_CHECK_VERSION(3,0,0)
|
||||||
XEvent *xe;
|
XEvent *xe;
|
||||||
XKeyEvent *xke;
|
XKeyEvent *xke;
|
||||||
|
|
||||||
@ -1051,14 +1052,16 @@ keyboard_grab_filter(GdkXEvent *xevent, GdkEvent *event, gpointer notused)
|
|||||||
|
|
||||||
/* Lie to GDK, pretending we are the proper recipient of this XEvent. Without it,
|
/* Lie to GDK, pretending we are the proper recipient of this XEvent. Without it,
|
||||||
GDK would discard it. */
|
GDK would discard it. */
|
||||||
xke->window = GDK_WINDOW_XWINDOW(gtk_widget_get_window(window));
|
xke->window = GDK_WINDOW_XID(gtk_widget_get_window(window));
|
||||||
|
|
||||||
|
#endif /* GTK_CHECK_VERSION */
|
||||||
return (GDK_FILTER_CONTINUE);
|
return (GDK_FILTER_CONTINUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ungrab_keyboard(void)
|
ungrab_keyboard(void)
|
||||||
{
|
{
|
||||||
|
#if !GTK_CHECK_VERSION(3,0,0)
|
||||||
static int (*standard_x_error_handler)(Display *dpy, XErrorEvent *notused);
|
static int (*standard_x_error_handler)(Display *dpy, XErrorEvent *notused);
|
||||||
|
|
||||||
standard_x_error_handler = XSetErrorHandler(grab_x_error_handler);
|
standard_x_error_handler = XSetErrorHandler(grab_x_error_handler);
|
||||||
@ -1069,11 +1072,13 @@ ungrab_keyboard(void)
|
|||||||
XSetErrorHandler(standard_x_error_handler);
|
XSetErrorHandler(standard_x_error_handler);
|
||||||
|
|
||||||
keyboard_grabbed = 0;
|
keyboard_grabbed = 0;
|
||||||
|
#endif /* GTK_CHECK_VERSION */
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
grab_keyboard(void)
|
grab_keyboard(void)
|
||||||
{
|
{
|
||||||
|
#if !GTK_CHECK_VERSION(3,0,0)
|
||||||
int i;
|
int i;
|
||||||
static int (*standard_x_error_handler)(Display *dpy, XErrorEvent *notused);
|
static int (*standard_x_error_handler)(Display *dpy, XErrorEvent *notused);
|
||||||
|
|
||||||
@ -1129,6 +1134,7 @@ grab_keyboard(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
gdk_window_add_filter(NULL, keyboard_grab_filter, NULL);
|
gdk_window_add_filter(NULL, keyboard_grab_filter, NULL);
|
||||||
|
#endif /* GTK_CHECK_VERSION */
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* ! HAVE_X11 */
|
#else /* ! HAVE_X11 */
|
||||||
@ -1550,49 +1556,102 @@ init_gtk_1(int *argc, char ***argv)
|
|||||||
void
|
void
|
||||||
init_gtk_2(void)
|
init_gtk_2(void)
|
||||||
{
|
{
|
||||||
|
#if GTK_CHECK_VERSION(3,0,0)
|
||||||
|
GtkWidget *grid;
|
||||||
|
#else
|
||||||
GtkTable *table;
|
GtkTable *table;
|
||||||
|
#endif
|
||||||
GtkWidget *label;
|
GtkWidget *label;
|
||||||
GtkCellRenderer *renderer;
|
GtkCellRenderer *renderer;
|
||||||
|
|
||||||
|
#if GTK_CHECK_VERSION(3,0,0)
|
||||||
|
grid = gtk_grid_new();
|
||||||
|
gtk_grid_set_row_spacing(GTK_GRID(grid), 5);
|
||||||
|
gtk_grid_set_column_spacing(GTK_GRID(grid), 5);
|
||||||
|
#else
|
||||||
/* Table. */
|
/* Table. */
|
||||||
table = GTK_TABLE(gtk_table_new(4, 8, FALSE));
|
table = GTK_TABLE(gtk_table_new(4, 8, FALSE));
|
||||||
gtk_table_set_row_spacings(table, 5);
|
gtk_table_set_row_spacings(table, 5);
|
||||||
gtk_table_set_col_spacings(table, 5);
|
gtk_table_set_col_spacings(table, 5);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (enable_gui)
|
if (enable_gui)
|
||||||
|
#if GTK_CHECK_VERSION(3,0,0)
|
||||||
|
gtk_container_add(GTK_CONTAINER(window), grid);
|
||||||
|
#else
|
||||||
gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(table));
|
gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(table));
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Channel label and spin. */
|
/* Channel label and spin. */
|
||||||
label = gtk_label_new("Channel:");
|
label = gtk_label_new("Channel:");
|
||||||
|
#if GTK_CHECK_VERSION(3,0,0)
|
||||||
|
gtk_widget_set_hexpand(label, TRUE);
|
||||||
|
gtk_label_set_xalign(GTK_LABEL(label), 1);
|
||||||
|
gtk_container_add(GTK_CONTAINER(grid), label);
|
||||||
|
#else
|
||||||
gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
|
gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
|
||||||
gtk_table_attach(table, label, 0, 1, 0, 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
|
gtk_table_attach(table, label, 0, 1, 0, 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
|
||||||
|
#endif
|
||||||
channel_spin = gtk_spin_button_new_with_range(1, CHANNEL_MAX, 1);
|
channel_spin = gtk_spin_button_new_with_range(1, CHANNEL_MAX, 1);
|
||||||
gtk_widget_set_can_focus(channel_spin, FALSE);
|
gtk_widget_set_can_focus(channel_spin, FALSE);
|
||||||
|
#if GTK_CHECK_VERSION(3,0,0)
|
||||||
|
gtk_widget_set_hexpand(channel_spin, TRUE);
|
||||||
|
gtk_grid_attach_next_to(GTK_GRID(grid), channel_spin, label, GTK_POS_RIGHT, 1, 1);
|
||||||
|
#else
|
||||||
gtk_table_attach(table, channel_spin, 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
|
gtk_table_attach(table, channel_spin, 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
|
||||||
|
#endif
|
||||||
g_signal_connect(G_OBJECT(channel_spin), "value-changed", G_CALLBACK(channel_event_handler), NULL);
|
g_signal_connect(G_OBJECT(channel_spin), "value-changed", G_CALLBACK(channel_event_handler), NULL);
|
||||||
|
|
||||||
/* Bank label and spin. */
|
/* Bank label and spin. */
|
||||||
label = gtk_label_new("Bank:");
|
label = gtk_label_new("Bank:");
|
||||||
|
#if GTK_CHECK_VERSION(3,0,0)
|
||||||
|
gtk_widget_set_hexpand(label, TRUE);
|
||||||
|
gtk_label_set_xalign(GTK_LABEL(label), 1);
|
||||||
|
gtk_grid_attach_next_to(GTK_GRID(grid), label, channel_spin, GTK_POS_RIGHT, 1, 1);
|
||||||
|
#else
|
||||||
gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
|
gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
|
||||||
gtk_table_attach(table, label, 2, 3, 0, 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
|
gtk_table_attach(table, label, 2, 3, 0, 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
|
||||||
|
#endif
|
||||||
bank_spin = gtk_spin_button_new_with_range(0, BANK_MAX, 1);
|
bank_spin = gtk_spin_button_new_with_range(0, BANK_MAX, 1);
|
||||||
gtk_widget_set_can_focus(bank_spin, FALSE);
|
gtk_widget_set_can_focus(bank_spin, FALSE);
|
||||||
|
#if GTK_CHECK_VERSION(3,0,0)
|
||||||
|
gtk_widget_set_hexpand(bank_spin, TRUE);
|
||||||
|
gtk_grid_attach_next_to(GTK_GRID(grid), bank_spin, label, GTK_POS_RIGHT, 1, 1);
|
||||||
|
#else
|
||||||
gtk_table_attach(table, bank_spin, 3, 4, 0, 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
|
gtk_table_attach(table, bank_spin, 3, 4, 0, 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
|
||||||
|
#endif
|
||||||
g_signal_connect(G_OBJECT(bank_spin), "value-changed", G_CALLBACK(bank_event_handler), NULL);
|
g_signal_connect(G_OBJECT(bank_spin), "value-changed", G_CALLBACK(bank_event_handler), NULL);
|
||||||
|
|
||||||
/* Program label and spin. */
|
/* Program label and spin. */
|
||||||
label = gtk_label_new("Program:");
|
label = gtk_label_new("Program:");
|
||||||
|
#if GTK_CHECK_VERSION(3,0,0)
|
||||||
|
gtk_widget_set_hexpand(label, TRUE);
|
||||||
|
gtk_label_set_xalign(GTK_LABEL(label), 1);
|
||||||
|
gtk_grid_attach_next_to(GTK_GRID(grid), label, bank_spin, GTK_POS_RIGHT, 1, 1);
|
||||||
|
#else
|
||||||
gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
|
gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
|
||||||
gtk_table_attach(table, label, 4, 5, 0, 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
|
gtk_table_attach(table, label, 4, 5, 0, 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
|
||||||
|
#endif
|
||||||
program_spin = gtk_spin_button_new_with_range(0, PROGRAM_MAX, 1);
|
program_spin = gtk_spin_button_new_with_range(0, PROGRAM_MAX, 1);
|
||||||
gtk_widget_set_can_focus(program_spin, FALSE);
|
gtk_widget_set_can_focus(program_spin, FALSE);
|
||||||
|
#if GTK_CHECK_VERSION(3,0,0)
|
||||||
|
gtk_widget_set_hexpand(program_spin, TRUE);
|
||||||
|
gtk_grid_attach_next_to(GTK_GRID(grid), program_spin, label, GTK_POS_RIGHT, 1, 1);
|
||||||
|
#else
|
||||||
gtk_table_attach(table, program_spin, 5, 6, 0, 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
|
gtk_table_attach(table, program_spin, 5, 6, 0, 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
|
||||||
|
#endif
|
||||||
g_signal_connect(G_OBJECT(program_spin), "value-changed", G_CALLBACK(program_event_handler), NULL);
|
g_signal_connect(G_OBJECT(program_spin), "value-changed", G_CALLBACK(program_event_handler), NULL);
|
||||||
|
|
||||||
/* "Connected to" label and combo box. */
|
/* "Connected to" label and combo box. */
|
||||||
label = gtk_label_new("Connected to:");
|
label = gtk_label_new("Connected to:");
|
||||||
|
#if GTK_CHECK_VERSION(3,0,0)
|
||||||
|
gtk_widget_set_hexpand(label, TRUE);
|
||||||
|
gtk_label_set_xalign(GTK_LABEL(label), 1);
|
||||||
|
gtk_grid_attach_next_to(GTK_GRID(grid), label, program_spin, GTK_POS_RIGHT, 1, 1);
|
||||||
|
#else
|
||||||
gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
|
gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
|
||||||
gtk_table_attach(table, label, 6, 7, 0, 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
|
gtk_table_attach(table, label, 6, 7, 0, 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
connected_to_store = gtk_list_store_new(1, G_TYPE_STRING);
|
connected_to_store = gtk_list_store_new(1, G_TYPE_STRING);
|
||||||
connected_to_combo = gtk_combo_box_new_with_model(GTK_TREE_MODEL(connected_to_store));
|
connected_to_combo = gtk_combo_box_new_with_model(GTK_TREE_MODEL(connected_to_store));
|
||||||
@ -1602,54 +1661,109 @@ init_gtk_2(void)
|
|||||||
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT(connected_to_combo), renderer, "text", 0, NULL);
|
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT(connected_to_combo), renderer, "text", 0, NULL);
|
||||||
|
|
||||||
gtk_widget_set_can_focus(connected_to_combo, FALSE);
|
gtk_widget_set_can_focus(connected_to_combo, FALSE);
|
||||||
|
#if GTK_CHECK_VERSION(3,0,0)
|
||||||
|
gtk_widget_set_focus_on_click(connected_to_combo, FALSE);
|
||||||
|
gtk_widget_set_hexpand(connected_to_combo, TRUE);
|
||||||
|
gtk_grid_attach_next_to(GTK_GRID(grid), connected_to_combo, label, GTK_POS_RIGHT, 1, 1);
|
||||||
|
#else
|
||||||
gtk_combo_box_set_focus_on_click(GTK_COMBO_BOX(connected_to_combo), FALSE);
|
gtk_combo_box_set_focus_on_click(GTK_COMBO_BOX(connected_to_combo), FALSE);
|
||||||
gtk_table_attach(table, connected_to_combo, 7, 8, 0, 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
|
gtk_table_attach(table, connected_to_combo, 7, 8, 0, 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
|
||||||
|
#endif
|
||||||
gtk_widget_set_size_request(GTK_WIDGET(connected_to_combo), 200, -1);
|
gtk_widget_set_size_request(GTK_WIDGET(connected_to_combo), 200, -1);
|
||||||
g_signal_connect(G_OBJECT(connected_to_combo), "changed", G_CALLBACK(connected_to_event_handler), NULL);
|
g_signal_connect(G_OBJECT(connected_to_combo), "changed", G_CALLBACK(connected_to_event_handler), NULL);
|
||||||
|
|
||||||
/* Octave label and spin. */
|
/* Octave label and spin. */
|
||||||
label = gtk_label_new("Octave:");
|
label = gtk_label_new("Octave:");
|
||||||
|
#if GTK_CHECK_VERSION(3,0,0)
|
||||||
|
gtk_widget_set_hexpand(label, TRUE);
|
||||||
|
gtk_label_set_xalign(GTK_LABEL(label), 1);
|
||||||
|
gtk_grid_attach(GTK_GRID(grid), label, 0, 1, 1, 1);
|
||||||
|
#else
|
||||||
gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
|
gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
|
||||||
gtk_table_attach(table, label, 0, 1, 1, 2, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
|
gtk_table_attach(table, label, 0, 1, 1, 2, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
|
||||||
|
#endif
|
||||||
octave_spin = gtk_spin_button_new_with_range(OCTAVE_MIN, OCTAVE_MAX, 1);
|
octave_spin = gtk_spin_button_new_with_range(OCTAVE_MIN, OCTAVE_MAX, 1);
|
||||||
gtk_widget_set_can_focus(octave_spin, FALSE);
|
gtk_widget_set_can_focus(octave_spin, FALSE);
|
||||||
gtk_spin_button_set_value(GTK_SPIN_BUTTON(octave_spin), octave);
|
gtk_spin_button_set_value(GTK_SPIN_BUTTON(octave_spin), octave);
|
||||||
|
#if GTK_CHECK_VERSION(3,0,0)
|
||||||
|
gtk_widget_set_hexpand(octave_spin, TRUE);
|
||||||
|
gtk_grid_attach_next_to(GTK_GRID(grid), octave_spin, label, GTK_POS_RIGHT, 1, 1);
|
||||||
|
#else
|
||||||
gtk_table_attach(table, octave_spin, 1, 2, 1, 2, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
|
gtk_table_attach(table, octave_spin, 1, 2, 1, 2, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
|
||||||
|
#endif
|
||||||
g_signal_connect(G_OBJECT(octave_spin), "value-changed", G_CALLBACK(octave_event_handler), NULL);
|
g_signal_connect(G_OBJECT(octave_spin), "value-changed", G_CALLBACK(octave_event_handler), NULL);
|
||||||
|
|
||||||
/* "Grab keyboard" label and checkbutton. */
|
/* "Grab keyboard" label and checkbutton. */
|
||||||
label = gtk_label_new("Grab keyboard:");
|
label = gtk_label_new("Grab keyboard:");
|
||||||
|
#if GTK_CHECK_VERSION(3,0,0)
|
||||||
|
gtk_widget_set_hexpand(label, TRUE);
|
||||||
|
gtk_label_set_xalign(GTK_LABEL(label), 1);
|
||||||
|
gtk_grid_attach(GTK_GRID(grid), label, 4, 1, 1, 1);
|
||||||
|
#else
|
||||||
gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
|
gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
|
||||||
gtk_table_attach(table, label, 4, 5, 1, 2, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
|
gtk_table_attach(table, label, 4, 5, 1, 2, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
|
||||||
|
#endif
|
||||||
grab_keyboard_checkbutton = gtk_check_button_new();
|
grab_keyboard_checkbutton = gtk_check_button_new();
|
||||||
gtk_widget_set_can_focus(grab_keyboard_checkbutton, FALSE);
|
gtk_widget_set_can_focus(grab_keyboard_checkbutton, FALSE);
|
||||||
g_signal_connect(G_OBJECT(grab_keyboard_checkbutton), "toggled", G_CALLBACK(grab_keyboard_handler), NULL);
|
g_signal_connect(G_OBJECT(grab_keyboard_checkbutton), "toggled", G_CALLBACK(grab_keyboard_handler), NULL);
|
||||||
|
#if GTK_CHECK_VERSION(3,0,0)
|
||||||
|
gtk_widget_set_hexpand(grab_keyboard_checkbutton, TRUE);
|
||||||
|
gtk_grid_attach_next_to(GTK_GRID(grid), grab_keyboard_checkbutton, label, GTK_POS_RIGHT, 1, 1);
|
||||||
|
#else
|
||||||
gtk_table_attach(table, grab_keyboard_checkbutton, 5, 6, 1, 2, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
|
gtk_table_attach(table, grab_keyboard_checkbutton, 5, 6, 1, 2, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Velocity label and hscale */
|
/* Velocity label and hscale */
|
||||||
label = gtk_label_new("Velocity:");
|
label = gtk_label_new("Velocity:");
|
||||||
|
#if GTK_CHECK_VERSION(3,0,0)
|
||||||
|
gtk_widget_set_hexpand(label, TRUE);
|
||||||
|
gtk_label_set_xalign(GTK_LABEL(label), 1);
|
||||||
|
gtk_grid_attach_next_to(GTK_GRID(grid), label, grab_keyboard_checkbutton, GTK_POS_RIGHT, 1, 1);
|
||||||
|
|
||||||
|
velocity_hscale = gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL, VELOCITY_MIN, VELOCITY_MAX, 1);
|
||||||
|
#else
|
||||||
gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
|
gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
|
||||||
gtk_table_attach(table, label, 6, 7, 1, 2, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
|
gtk_table_attach(table, label, 6, 7, 1, 2, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
|
||||||
|
|
||||||
velocity_hscale = gtk_hscale_new_with_range(VELOCITY_MIN, VELOCITY_MAX, 1);
|
velocity_hscale = gtk_hscale_new_with_range(VELOCITY_MIN, VELOCITY_MAX, 1);
|
||||||
|
#endif
|
||||||
gtk_scale_set_draw_value(GTK_SCALE(velocity_hscale), FALSE);
|
gtk_scale_set_draw_value(GTK_SCALE(velocity_hscale), FALSE);
|
||||||
gtk_widget_set_can_focus(velocity_hscale, FALSE);
|
gtk_widget_set_can_focus(velocity_hscale, FALSE);
|
||||||
g_signal_connect(G_OBJECT(velocity_hscale), "value-changed", G_CALLBACK(velocity_event_handler), NULL);
|
g_signal_connect(G_OBJECT(velocity_hscale), "value-changed", G_CALLBACK(velocity_event_handler), NULL);
|
||||||
gtk_range_set_value(GTK_RANGE(velocity_hscale), VELOCITY_NORMAL);
|
gtk_range_set_value(GTK_RANGE(velocity_hscale), VELOCITY_NORMAL);
|
||||||
|
#if GTK_CHECK_VERSION(3,0,0)
|
||||||
|
gtk_widget_set_hexpand(velocity_hscale, TRUE);
|
||||||
|
gtk_grid_attach_next_to(GTK_GRID(grid), velocity_hscale, label, GTK_POS_RIGHT, 1, 1);
|
||||||
|
#else
|
||||||
gtk_table_attach(table, velocity_hscale, 7, 8, 1, 2, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
|
gtk_table_attach(table, velocity_hscale, 7, 8, 1, 2, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
|
||||||
|
#endif
|
||||||
gtk_widget_set_size_request(GTK_WIDGET(velocity_hscale), 200, -1);
|
gtk_widget_set_size_request(GTK_WIDGET(velocity_hscale), 200, -1);
|
||||||
|
|
||||||
/* Sustain. It's a toggle button, not an ordinary one, because we want gtk_whatever_set_active() to work.*/
|
/* Sustain. It's a toggle button, not an ordinary one, because we want gtk_whatever_set_active() to work.*/
|
||||||
sustain_button = gtk_toggle_button_new_with_label("Sustain");
|
sustain_button = gtk_toggle_button_new_with_label("Sustain");
|
||||||
|
#if GTK_CHECK_VERSION(3,0,0)
|
||||||
|
gtk_widget_set_focus_on_click(sustain_button, FALSE);
|
||||||
|
gtk_widget_set_hexpand(sustain_button, TRUE);
|
||||||
|
gtk_grid_attach(GTK_GRID(grid), sustain_button, 0, 2, 8, 1);
|
||||||
|
#else
|
||||||
gtk_button_set_focus_on_click(GTK_BUTTON(sustain_button), FALSE);
|
gtk_button_set_focus_on_click(GTK_BUTTON(sustain_button), FALSE);
|
||||||
gtk_table_attach(table, sustain_button, 0, 8, 2, 3, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
|
gtk_table_attach(table, sustain_button, 0, 8, 2, 3, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
|
||||||
|
#endif
|
||||||
g_signal_connect(G_OBJECT(sustain_button), "toggled", G_CALLBACK(sustain_event_handler), NULL);
|
g_signal_connect(G_OBJECT(sustain_button), "toggled", G_CALLBACK(sustain_event_handler), NULL);
|
||||||
|
|
||||||
/* PianoKeyboard widget. */
|
/* PianoKeyboard widget. */
|
||||||
keyboard = PIANO_KEYBOARD(piano_keyboard_new());
|
keyboard = PIANO_KEYBOARD(piano_keyboard_new());
|
||||||
|
|
||||||
if (enable_gui)
|
if (enable_gui)
|
||||||
|
#if GTK_CHECK_VERSION(3,0,0)
|
||||||
|
{
|
||||||
|
gtk_widget_set_hexpand(GTK_WIDGET(keyboard), TRUE);
|
||||||
|
gtk_widget_set_vexpand(GTK_WIDGET(keyboard), TRUE);
|
||||||
|
gtk_grid_attach(GTK_GRID(grid), GTK_WIDGET(keyboard), 0, 3, 8, 1);
|
||||||
|
}
|
||||||
|
#else
|
||||||
gtk_table_attach_defaults(table, GTK_WIDGET(keyboard), 0, 8, 3, 4);
|
gtk_table_attach_defaults(table, GTK_WIDGET(keyboard), 0, 8, 3, 4);
|
||||||
|
#endif
|
||||||
else
|
else
|
||||||
gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(keyboard));
|
gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(keyboard));
|
||||||
|
|
||||||
|
@ -75,7 +75,11 @@ draw_keyboard_cue(PianoKeyboard *pk)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
#if GTK_CHECK_VERSION(3,0,0)
|
||||||
|
draw_note(PianoKeyboard *pk, cairo_t *cr, int note)
|
||||||
|
#else
|
||||||
draw_note(PianoKeyboard *pk, int note)
|
draw_note(PianoKeyboard *pk, int note)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
if (note < pk->min_note)
|
if (note < pk->min_note)
|
||||||
return;
|
return;
|
||||||
@ -83,6 +87,13 @@ draw_note(PianoKeyboard *pk, int note)
|
|||||||
return;
|
return;
|
||||||
int is_white, x, w, h;
|
int is_white, x, w, h;
|
||||||
|
|
||||||
|
#if GTK_CHECK_VERSION(3,0,0)
|
||||||
|
if (!cr)
|
||||||
|
cr = gdk_cairo_create(gtk_widget_get_window(GTK_WIDGET(pk)));
|
||||||
|
|
||||||
|
GdkRGBA black = { .red = 0.0, .green = 0.0, .blue = 0.0, .alpha = 1.0};
|
||||||
|
GdkRGBA white = { .red = 1.0, .green = 1.0, .blue = 1.0, .alpha = 1.0};
|
||||||
|
#else
|
||||||
cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(GTK_WIDGET(pk)));
|
cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(GTK_WIDGET(pk)));
|
||||||
|
|
||||||
GdkColor black = {0, 0, 0, 0};
|
GdkColor black = {0, 0, 0, 0};
|
||||||
@ -90,6 +101,7 @@ draw_note(PianoKeyboard *pk, int note)
|
|||||||
|
|
||||||
GtkWidget *widget;
|
GtkWidget *widget;
|
||||||
GtkAllocation allocation;
|
GtkAllocation allocation;
|
||||||
|
#endif
|
||||||
|
|
||||||
is_white = pk->notes[note].white;
|
is_white = pk->notes[note].white;
|
||||||
|
|
||||||
@ -101,26 +113,47 @@ draw_note(PianoKeyboard *pk, int note)
|
|||||||
is_white = !is_white;
|
is_white = !is_white;
|
||||||
|
|
||||||
if (is_white)
|
if (is_white)
|
||||||
|
#if GTK_CHECK_VERSION(3,0,0)
|
||||||
|
gdk_cairo_set_source_rgba(cr, &white);
|
||||||
|
#else
|
||||||
gdk_cairo_set_source_color(cr, &white);
|
gdk_cairo_set_source_color(cr, &white);
|
||||||
|
#endif
|
||||||
else
|
else
|
||||||
|
#if GTK_CHECK_VERSION(3,0,0)
|
||||||
|
gdk_cairo_set_source_rgba(cr, &black);
|
||||||
|
#else
|
||||||
gdk_cairo_set_source_color(cr, &black);
|
gdk_cairo_set_source_color(cr, &black);
|
||||||
|
#endif
|
||||||
|
|
||||||
cairo_rectangle(cr, x, 0, w, h);
|
cairo_rectangle(cr, x, 0, w, h);
|
||||||
cairo_fill(cr);
|
cairo_fill(cr);
|
||||||
|
#if GTK_CHECK_VERSION(3,0,0)
|
||||||
|
gdk_cairo_set_source_rgba(cr, &black);
|
||||||
|
#else
|
||||||
gdk_cairo_set_source_color(cr, &black);
|
gdk_cairo_set_source_color(cr, &black);
|
||||||
|
#endif
|
||||||
cairo_rectangle(cr, x, 0, w, h);
|
cairo_rectangle(cr, x, 0, w, h);
|
||||||
cairo_stroke(cr);
|
cairo_stroke(cr);
|
||||||
|
|
||||||
|
#if !GTK_CHECK_VERSION(3,0,0)
|
||||||
cairo_destroy(cr);
|
cairo_destroy(cr);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (pk->enable_keyboard_cue)
|
if (pk->enable_keyboard_cue)
|
||||||
draw_keyboard_cue(pk);
|
draw_keyboard_cue(pk);
|
||||||
|
|
||||||
/* We need to redraw black keys that partially obscure the white one. */
|
/* We need to redraw black keys that partially obscure the white one. */
|
||||||
if (note < NNOTES - 2 && !pk->notes[note + 1].white)
|
if (note < NNOTES - 2 && !pk->notes[note + 1].white)
|
||||||
|
#if GTK_CHECK_VERSION(3,0,0)
|
||||||
|
draw_note(pk, cr, note + 1);
|
||||||
|
#else
|
||||||
draw_note(pk, note + 1);
|
draw_note(pk, note + 1);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (note > 0 && !pk->notes[note - 1].white)
|
if (note > 0 && !pk->notes[note - 1].white)
|
||||||
|
#if GTK_CHECK_VERSION(3,0,0)
|
||||||
|
draw_note(pk, cr, note - 1);
|
||||||
|
#else
|
||||||
draw_note(pk, note - 1);
|
draw_note(pk, note - 1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -134,6 +167,7 @@ draw_note(PianoKeyboard *pk, int note)
|
|||||||
gtk_paint_shadow(gtk_widget_get_style(widget), gtk_widget_get_window(widget), GTK_STATE_NORMAL, GTK_SHADOW_IN, NULL,
|
gtk_paint_shadow(gtk_widget_get_style(widget), gtk_widget_get_window(widget), GTK_STATE_NORMAL, GTK_SHADOW_IN, NULL,
|
||||||
widget, NULL, pk->widget_margin, 0, allocation.width - pk->widget_margin * 2 + 1,
|
widget, NULL, pk->widget_margin, 0, allocation.width - pk->widget_margin * 2 + 1,
|
||||||
allocation.height);
|
allocation.height);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -156,7 +190,11 @@ press_key(PianoKeyboard *pk, int key)
|
|||||||
pk->notes[key].pressed = 1;
|
pk->notes[key].pressed = 1;
|
||||||
|
|
||||||
g_signal_emit_by_name(GTK_WIDGET(pk), "note-on", key);
|
g_signal_emit_by_name(GTK_WIDGET(pk), "note-on", key);
|
||||||
|
#if GTK_CHECK_VERSION(3,0,0)
|
||||||
|
draw_note(pk, NULL, key);
|
||||||
|
#else
|
||||||
draw_note(pk, key);
|
draw_note(pk, key);
|
||||||
|
#endif
|
||||||
|
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
@ -181,7 +219,11 @@ release_key(PianoKeyboard *pk, int key)
|
|||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
g_signal_emit_by_name(GTK_WIDGET(pk), "note-off", key);
|
g_signal_emit_by_name(GTK_WIDGET(pk), "note-off", key);
|
||||||
|
#if GTK_CHECK_VERSION(3,0,0)
|
||||||
|
draw_note(pk, NULL, key);
|
||||||
|
#else
|
||||||
draw_note(pk, key);
|
draw_note(pk, key);
|
||||||
|
#endif
|
||||||
|
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
@ -195,7 +237,11 @@ stop_unsustained_notes(PianoKeyboard *pk)
|
|||||||
if (pk->notes[i].pressed && !pk->notes[i].sustained) {
|
if (pk->notes[i].pressed && !pk->notes[i].sustained) {
|
||||||
pk->notes[i].pressed = 0;
|
pk->notes[i].pressed = 0;
|
||||||
g_signal_emit_by_name(GTK_WIDGET(pk), "note-off", i);
|
g_signal_emit_by_name(GTK_WIDGET(pk), "note-off", i);
|
||||||
|
#if GTK_CHECK_VERSION(3,0,0)
|
||||||
|
draw_note(pk, NULL, i);
|
||||||
|
#else
|
||||||
draw_note(pk, i);
|
draw_note(pk, i);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -210,7 +256,11 @@ stop_sustained_notes(PianoKeyboard *pk)
|
|||||||
pk->notes[i].pressed = 0;
|
pk->notes[i].pressed = 0;
|
||||||
pk->notes[i].sustained = 0;
|
pk->notes[i].sustained = 0;
|
||||||
g_signal_emit_by_name(GTK_WIDGET(pk), "note-off", i);
|
g_signal_emit_by_name(GTK_WIDGET(pk), "note-off", i);
|
||||||
|
#if GTK_CHECK_VERSION(3,0,0)
|
||||||
|
draw_note(pk, NULL, i);
|
||||||
|
#else
|
||||||
draw_note(pk, i);
|
draw_note(pk, i);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -420,23 +470,45 @@ mouse_motion_event_handler(PianoKeyboard *pk, GdkEventMotion *event, gpointer no
|
|||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
#if GTK_CHECK_VERSION(3,0,0)
|
||||||
|
piano_keyboard_draw(GtkWidget *widget, cairo_t *cr)
|
||||||
|
#else
|
||||||
piano_keyboard_expose(GtkWidget *widget, GdkEventExpose *event)
|
piano_keyboard_expose(GtkWidget *widget, GdkEventExpose *event)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
PianoKeyboard *pk = PIANO_KEYBOARD(widget);
|
PianoKeyboard *pk = PIANO_KEYBOARD(widget);
|
||||||
|
|
||||||
for (i = 0; i < NNOTES; i++)
|
for (i = 0; i < NNOTES; i++)
|
||||||
|
#if GTK_CHECK_VERSION(3,0,0)
|
||||||
|
draw_note(pk, NULL, i);
|
||||||
|
#else
|
||||||
draw_note(pk, i);
|
draw_note(pk, i);
|
||||||
|
#endif
|
||||||
|
|
||||||
return (TRUE);
|
return (TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if GTK_CHECK_VERSION(3,0,0)
|
||||||
|
static void
|
||||||
|
piano_keyboard_get_preferred_width(GtkWidget *widget, gint *minimal_width, gint *natural_width)
|
||||||
|
{
|
||||||
|
*minimal_width = *natural_width = PIANO_KEYBOARD_DEFAULT_WIDTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
piano_keyboard_get_preferred_height(GtkWidget *widget, gint *minimal_height, gint *natural_height)
|
||||||
|
{
|
||||||
|
*minimal_height = *natural_height = PIANO_KEYBOARD_DEFAULT_HEIGHT;
|
||||||
|
}
|
||||||
|
#else
|
||||||
static void
|
static void
|
||||||
piano_keyboard_size_request(GtkWidget *widget, GtkRequisition *requisition)
|
piano_keyboard_size_request(GtkWidget *widget, GtkRequisition *requisition)
|
||||||
{
|
{
|
||||||
requisition->width = PIANO_KEYBOARD_DEFAULT_WIDTH;
|
requisition->width = PIANO_KEYBOARD_DEFAULT_WIDTH;
|
||||||
requisition->height = PIANO_KEYBOARD_DEFAULT_HEIGHT;
|
requisition->height = PIANO_KEYBOARD_DEFAULT_HEIGHT;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static int is_black(int key)
|
static int is_black(int key)
|
||||||
{
|
{
|
||||||
@ -544,8 +616,14 @@ piano_keyboard_class_init(PianoKeyboardClass *klass)
|
|||||||
|
|
||||||
widget_klass = (GtkWidgetClass*)klass;
|
widget_klass = (GtkWidgetClass*)klass;
|
||||||
|
|
||||||
|
#if GTK_CHECK_VERSION(3,0,0)
|
||||||
|
widget_klass->draw = piano_keyboard_draw;
|
||||||
|
widget_klass->get_preferred_width = piano_keyboard_get_preferred_width;
|
||||||
|
widget_klass->get_preferred_height = piano_keyboard_get_preferred_height;
|
||||||
|
#else
|
||||||
widget_klass->expose_event = piano_keyboard_expose;
|
widget_klass->expose_event = piano_keyboard_expose;
|
||||||
widget_klass->size_request = piano_keyboard_size_request;
|
widget_klass->size_request = piano_keyboard_size_request;
|
||||||
|
#endif
|
||||||
widget_klass->size_allocate = piano_keyboard_size_allocate;
|
widget_klass->size_allocate = piano_keyboard_size_allocate;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -638,7 +716,11 @@ piano_keyboard_set_note_on(PianoKeyboard *pk, int note)
|
|||||||
{
|
{
|
||||||
if (pk->notes[note].pressed == 0) {
|
if (pk->notes[note].pressed == 0) {
|
||||||
pk->notes[note].pressed = 1;
|
pk->notes[note].pressed = 1;
|
||||||
|
#if GTK_CHECK_VERSION(3,0,0)
|
||||||
|
draw_note(pk, NULL, note);
|
||||||
|
#else
|
||||||
draw_note(pk, note);
|
draw_note(pk, note);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -648,7 +730,11 @@ piano_keyboard_set_note_off(PianoKeyboard *pk, int note)
|
|||||||
if (pk->notes[note].pressed || pk->notes[note].sustained) {
|
if (pk->notes[note].pressed || pk->notes[note].sustained) {
|
||||||
pk->notes[note].pressed = 0;
|
pk->notes[note].pressed = 0;
|
||||||
pk->notes[note].sustained = 0;
|
pk->notes[note].sustained = 0;
|
||||||
|
#if GTK_CHECK_VERSION(3,0,0)
|
||||||
|
draw_note(pk, NULL, note);
|
||||||
|
#else
|
||||||
draw_note(pk, note);
|
draw_note(pk, note);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user