2018-05-13 01:17:19 +02:00
|
|
|
#include <gtk/gtk.h>
|
|
|
|
#include <vector>
|
|
|
|
#include <math.h>
|
|
|
|
|
|
|
|
#include "gtk_s9x.h"
|
|
|
|
#include "gtk_display.h"
|
|
|
|
#include "gtk_shader_parameters.h"
|
|
|
|
#include "shaders/glsl.h"
|
|
|
|
|
|
|
|
static inline double snap_to_interval (double value, double interval)
|
|
|
|
{
|
|
|
|
return round (value / interval) * interval;
|
|
|
|
}
|
|
|
|
|
|
|
|
void value_changed (GtkRange *range, gpointer user_data)
|
|
|
|
{
|
|
|
|
GtkAdjustment *adj = gtk_range_get_adjustment (range);
|
|
|
|
double interval = gtk_adjustment_get_step_increment (adj);
|
|
|
|
double value = gtk_range_get_value (range);
|
|
|
|
|
|
|
|
value = snap_to_interval (value, interval);
|
|
|
|
|
|
|
|
gtk_range_set_value (range, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool gtk_shader_parameters_dialog (GtkWindow *parent)
|
|
|
|
{
|
|
|
|
GtkWidget *dialog;
|
|
|
|
std::vector<GLSLParam> *params = (std::vector<GLSLParam> *) S9xDisplayGetDriver()->get_parameters();
|
|
|
|
|
|
|
|
if (!params || params->size() == 0)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
dialog = gtk_dialog_new_with_buttons (_("GLSL Shader Parameters"),
|
|
|
|
parent,
|
|
|
|
GTK_DIALOG_MODAL,
|
|
|
|
"gtk-cancel",
|
|
|
|
GTK_RESPONSE_CANCEL,
|
|
|
|
"gtk-apply",
|
|
|
|
GTK_RESPONSE_APPLY,
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
GtkWidget *scrolled_window;
|
|
|
|
gtk_widget_set_size_request(dialog, 640, 480);
|
|
|
|
|
|
|
|
scrolled_window = gtk_scrolled_window_new (NULL, NULL);
|
2018-05-14 00:18:49 +02:00
|
|
|
gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG(dialog))),
|
|
|
|
scrolled_window);
|
|
|
|
|
|
|
|
#if GTK_MAJOR_VERSION >= 3
|
|
|
|
|
2018-05-13 01:17:19 +02:00
|
|
|
gtk_widget_set_hexpand (scrolled_window, TRUE);
|
|
|
|
gtk_widget_set_vexpand (scrolled_window, TRUE);
|
|
|
|
gtk_widget_set_margin_start (scrolled_window, 5);
|
|
|
|
gtk_widget_set_margin_end (scrolled_window, 5);
|
|
|
|
gtk_widget_set_margin_top (scrolled_window, 5);
|
|
|
|
gtk_widget_set_margin_bottom (scrolled_window, 5);
|
2018-05-14 00:18:49 +02:00
|
|
|
|
2018-05-13 01:17:19 +02:00
|
|
|
GtkWidget *vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
|
|
|
GtkWidget *grid = gtk_grid_new ();
|
|
|
|
gtk_grid_set_row_homogeneous (GTK_GRID (grid), TRUE);
|
2018-05-14 00:18:49 +02:00
|
|
|
gtk_grid_set_column_spacing (GTK_GRID (grid), 12);
|
2018-05-13 01:17:19 +02:00
|
|
|
gtk_container_add (GTK_CONTAINER (vbox), grid);
|
|
|
|
gtk_container_add (GTK_CONTAINER (scrolled_window), vbox);
|
|
|
|
|
|
|
|
GtkWidget **value_holders = new GtkWidget*[params->size()];
|
|
|
|
|
|
|
|
for (unsigned int i = 0; i < params->size(); i++)
|
|
|
|
{
|
|
|
|
GLSLParam *p = &(*params)[i];
|
|
|
|
GtkWidget *label = gtk_label_new (p->name);
|
|
|
|
gtk_label_set_xalign (GTK_LABEL (label), 0.0f);
|
|
|
|
gtk_widget_show (label);
|
|
|
|
|
|
|
|
gtk_grid_attach (GTK_GRID (grid), label, 0, i, 1, 1);
|
|
|
|
|
|
|
|
if (p->min == 0.0 && p->max == 1.0 && p->step == 1.0)
|
|
|
|
{
|
|
|
|
GtkWidget *check = gtk_check_button_new ();
|
|
|
|
gtk_grid_attach (GTK_GRID (grid), check, 1, i, 1, 1);
|
|
|
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), (int) p->val);
|
|
|
|
value_holders[i] = check;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-05-14 00:18:49 +02:00
|
|
|
GtkWidget *scale = gtk_scale_new_with_range (GTK_ORIENTATION_HORIZONTAL, p->min, p->max, p->step);
|
2018-05-13 01:17:19 +02:00
|
|
|
gtk_widget_set_hexpand (scale, TRUE);
|
|
|
|
gtk_grid_attach (GTK_GRID (grid), scale, 1, i, 1, 1);
|
2018-05-14 00:18:49 +02:00
|
|
|
gtk_scale_set_value_pos (GTK_SCALE (scale), GTK_POS_LEFT);
|
|
|
|
gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
|
|
|
|
gtk_scale_set_digits (GTK_SCALE (scale), 3);
|
|
|
|
gtk_range_set_value (GTK_RANGE (scale), p->val);
|
|
|
|
g_signal_connect_data (G_OBJECT (scale),
|
|
|
|
"value-changed",
|
|
|
|
G_CALLBACK (value_changed),
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
(GConnectFlags) 0);
|
|
|
|
|
|
|
|
value_holders[i] = scale;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
GtkWidget *vbox = gtk_vbox_new (FALSE, 5);
|
|
|
|
GtkWidget *table = gtk_table_new (params->size (), 2, FALSE);
|
|
|
|
gtk_table_set_row_spacings (GTK_TABLE (table), 5);
|
|
|
|
gtk_table_set_col_spacings (GTK_TABLE (table), 12);
|
|
|
|
gtk_container_add (GTK_CONTAINER (vbox), table);
|
|
|
|
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (scrolled_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
|
|
|
|
gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_window), vbox);
|
|
|
|
gtk_container_set_border_width (GTK_CONTAINER (scrolled_window), 5);
|
|
|
|
|
|
|
|
GtkWidget **value_holders = new GtkWidget*[params->size()];
|
|
|
|
|
|
|
|
for (unsigned int i = 0; i < params->size(); i++)
|
|
|
|
{
|
|
|
|
GLSLParam *p = &(*params)[i];
|
|
|
|
GtkWidget *label = gtk_label_new (p->name);
|
|
|
|
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
|
|
|
|
gtk_widget_show (label);
|
|
|
|
|
|
|
|
gtk_table_attach (GTK_TABLE (table), label, 0, 1, i, i + 1, GTK_FILL, GTK_FILL, 0, 0);
|
|
|
|
|
|
|
|
if (p->min == 0.0 && p->max == 1.0 && p->step == 1.0)
|
|
|
|
{
|
|
|
|
GtkWidget *check = gtk_check_button_new ();
|
|
|
|
gtk_table_attach (GTK_TABLE (table), check, 1, 2, i, i + 1, GTK_FILL, GTK_FILL, 0, 0);
|
|
|
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), (int) p->val);
|
|
|
|
value_holders[i] = check;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
GtkWidget *scale = gtk_hscale_new_with_range (p->min, p->max, p->step);
|
|
|
|
gtk_table_attach (GTK_TABLE (table), scale, 1, 2, i, i + 1, (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), GTK_FILL, 0, 0);
|
|
|
|
gtk_scale_set_value_pos (GTK_SCALE (scale), GTK_POS_LEFT);
|
2018-05-13 01:17:19 +02:00
|
|
|
gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
|
|
|
|
gtk_scale_set_digits (GTK_SCALE (scale), 3);
|
|
|
|
gtk_range_set_value (GTK_RANGE (scale), p->val);
|
|
|
|
g_signal_connect_data (G_OBJECT (scale),
|
|
|
|
"value-changed",
|
|
|
|
G_CALLBACK (value_changed),
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
(GConnectFlags) 0);
|
|
|
|
|
|
|
|
value_holders[i] = scale;
|
|
|
|
}
|
|
|
|
}
|
2018-05-14 00:18:49 +02:00
|
|
|
#endif
|
2018-05-13 01:17:19 +02:00
|
|
|
|
|
|
|
gtk_widget_show_all (dialog);
|
|
|
|
int response = gtk_dialog_run (GTK_DIALOG(dialog));
|
|
|
|
|
|
|
|
if (response == GTK_RESPONSE_APPLY)
|
|
|
|
{
|
|
|
|
for (unsigned int i = 0; i < params->size(); i++)
|
|
|
|
{
|
|
|
|
GLSLParam *p = &(*params)[i];
|
|
|
|
if (p->min == 0.0 && p->max == 1.0 && p->step == 1.0)
|
|
|
|
{
|
|
|
|
int val = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (value_holders[i]));
|
|
|
|
p->val = (float) val;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
p->val = gtk_range_get_value (GTK_RANGE (value_holders[i]));
|
|
|
|
}
|
|
|
|
|
|
|
|
p->val = snap_to_interval (p->val, p->step);
|
|
|
|
|
|
|
|
p->val = CLAMP (p->val, p->min, p->max);
|
|
|
|
}
|
|
|
|
|
|
|
|
S9xDeinitUpdate (top_level->last_width, top_level->last_height);
|
|
|
|
}
|
|
|
|
|
|
|
|
delete[] value_holders;
|
|
|
|
gtk_widget_destroy (dialog);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|