1
/***************************************************************************
2
DIA_threshold.cpp - configuration dialog for
5
Chris MacGregor, September 2007
6
chris-avidemux@bouncingdog.com
7
***************************************************************************/
9
/***************************************************************************
11
* This program is free software; you can redistribute it and/or modify *
12
* it under the terms of the GNU General Public License as published by *
13
* the Free Software Foundation; either version 2 of the License, or *
14
* (at your option) any later version. *
16
***************************************************************************/
29
#include "ADM_editor/ADM_edit.hxx"
30
#include "ADM_video/ADM_genvideo.hxx"
31
#include "ADM_videoFilter/ADM_vidThreshold.h"
32
#include "ADM_toolkit/toolkit.hxx"
33
#include "ADM_toolkit_gtk/ADM_gladeSupport.h"
34
#include "ADM_toolkit_gtk/toolkit_gtk.h"
35
#include "ADM_toolkit_gtk/toolkit_gtk_include.h"
36
#include "ADM_assert.h"
37
#include "DIA_flyDialog.h"
38
#include "DIA_flyThreshold.h"
40
/********************************************************************/
41
static GtkWidget *create_threshold_dialog (void);
42
static GtkWidget *dialog = 0;
44
static gboolean gui_draw (GtkWidget * widget,
45
GdkEventExpose * event, gpointer user_data);
46
static void gui_update (GtkButton * button, gpointer user_data);
47
static void frame_changed (void);
49
static volatile int lock = 0;
50
static flyThreshold * myDialog = 0;
52
/********************************************************************/
54
static gboolean previewButtonEvent (GtkWidget * widget,
55
GdkEventButton * event,
58
if (event->type != GDK_BUTTON_PRESS)
61
uint32_t x = static_cast <uint32_t> (event->x);
62
uint32_t y = static_cast <uint32_t> (event->y);
64
flyThreshold * myFly = static_cast <flyThreshold *> (data);
65
ADMImage * image = event->button == 1
66
? myFly->getInputImage() : myFly->getOutputImage();
68
uint32_t width = image->_width;
69
uint32_t height = image->_height;
71
if (x >= width || y >= height)
75
if (event->state & GDK_SHIFT_MASK)
77
if (event->state & GDK_CONTROL_MASK)
79
if (event->state & GDK_MOD1_MASK)
82
uint8_t halfrange = range / 2;
84
uint32_t xmin = (x > halfrange) ? x - halfrange : 0;
85
uint32_t ymin = (y > halfrange) ? y - halfrange : 0;
87
uint32_t xmax = x + halfrange;
88
uint32_t ymax = y + halfrange;
95
uint8_t * imagepix = YPLANE (image);
98
for (x = xmin; x <= xmax; x++)
101
for (x = xmin; x <= xmax; x++)
105
for (y = ymin; y <= ymax; y++)
107
uint8_t * pixp = imagepix + (y * width) + xmin;
109
for (x = xmin; x <= xmax; x++)
110
printf (" %3d", *pixp++);
117
/********************************************************************/
119
uint8_t DIA_threshold (AVDMGenericVideoStream *in, THRESHOLD_PARAM * param)
121
// Allocate space for preview video
122
uint32_t width = in->getInfo()->width;
123
uint32_t height = in->getInfo()->height;
125
dialog = create_threshold_dialog();
126
gtk_register_dialog(dialog);
127
gtk_window_set_title (GTK_WINDOW (dialog),
128
QT_TR_NOOP("Threshold Configuration"));
129
gtk_widget_show(dialog);
131
myDialog = new flyThreshold (width, height, in,
132
WID(previewVideo), WID(previewSlider),
135
myDialog->sliderChanged();
137
// update things when settings are changed
138
#define CNX(_widg,_signame) \
139
g_signal_connect(GTK_OBJECT(WID(_widg)), _signame, \
140
GTK_SIGNAL_FUNC(gui_update), (void *) (1));
142
// CNX (minValueSlider, "drag_data_received");
143
CNX (minValueSpinner, "value_changed");
145
// CNX (maxValueSlider, "drag_data_received");
146
CNX (maxValueSpinner, "value_changed");
148
CNX (outputValuesMenu, "changed");
150
g_signal_connect(GTK_OBJECT(WID(previewSlider)), "value_changed",
151
GTK_SIGNAL_FUNC(frame_changed), 0);
152
g_signal_connect(GTK_OBJECT(WID(previewVideo)), "expose_event",
153
GTK_SIGNAL_FUNC(gui_draw), 0);
155
g_signal_connect(GTK_OBJECT(WID(previewVideo)), "button_press_event",
156
GTK_SIGNAL_FUNC(previewButtonEvent),
159
g_signal_connect(GTK_OBJECT(WID(previewVideo)), "motion_notify_event",
160
GTK_SIGNAL_FUNC(previewMotionEvent),
165
int response = gtk_dialog_run(GTK_DIALOG(dialog));
167
if (response == GTK_RESPONSE_OK)
169
myDialog->download();
170
myDialog->getParam (param);
174
gtk_unregister_dialog(dialog);
175
gtk_widget_destroy(dialog);
182
void frame_changed (void)
184
myDialog->sliderChanged();
187
void gui_update (GtkButton * button, gpointer user_data)
195
gboolean gui_draw (GtkWidget * widget, GdkEventExpose * event, gpointer user_data)
201
/**************************************/
203
uint8_t flyThreshold::upload (void)
207
gtk_spin_button_set_value (GTK_SPIN_BUTTON(WID(minValueSpinner)), param.min);
208
gtk_spin_button_set_value (GTK_SPIN_BUTTON(WID(maxValueSpinner)), param.max);
209
gtk_spin_button_set_value (GTK_SPIN_BUTTON(WID(debugSpinButton)), param.debug);
210
gtk_combo_box_set_active (GTK_COMBO_BOX(WID(outputValuesMenu)),
211
param.in_range_is_white);
217
uint8_t flyThreshold::download (void)
219
param.min = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (WID(minValueSpinner)));
220
param.max = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (WID(maxValueSpinner)));
221
param.debug = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (WID(debugSpinButton)));
222
param.in_range_is_white
223
= gtk_combo_box_get_active (GTK_COMBO_BOX(WID(outputValuesMenu)));
228
// The following was generated by glade once upon a time. It has since been
229
// tweaked by hand (to share the GtkAdjustment objects between the spinbutton
230
// and hscale, for instance), so beware...
233
create_threshold_dialog (void)
235
GtkWidget *threshold_dialog;
236
GtkWidget *dialogVbox;
237
GtkWidget *allButButtonsVbox;
238
GtkWidget *settingsOuterHbox;
239
GtkWidget *settingsOuterVbox;
240
GtkWidget *minValueVbox;
241
GtkWidget *minValueLabel;
242
GtkWidget *minValueHbox;
243
GtkWidget *minValueSlider;
244
GtkObject *minValueSpinner_adj;
245
GtkWidget *minValueSpinner;
246
GtkWidget *maxValueVbox;
247
GtkWidget *maxValueLabel;
248
GtkWidget *maxValueHbox;
249
GtkWidget *maxValueSlider;
250
GtkObject *maxValueSpinner_adj;
251
GtkWidget *maxValueSpinner;
252
GtkWidget *outputValuesHbox;
253
GtkWidget *outputValuesLabel;
254
GtkWidget *outputValuesMenu;
255
GtkWidget *debugHbox;
256
GtkWidget *debugLabel;
257
GtkObject *debugSpinButton_adj;
258
GtkWidget *debugSpinButton;
259
GtkWidget *previewFrame;
260
GtkWidget *previewAlignment;
261
GtkWidget *previewVbox;
262
GtkWidget *previewControlHbox;
263
GtkWidget *previewOutputMenu;
264
GtkWidget *previewSlider;
265
GtkWidget *previewVideo;
266
GtkWidget *previewLabel;
267
GtkWidget *dialogButtonBox;
268
GtkWidget *cancelButton;
271
threshold_dialog = gtk_dialog_new ();
272
gtk_window_set_title (GTK_WINDOW (threshold_dialog), QT_TR_NOOP("Threshold"));
273
gtk_window_set_type_hint (GTK_WINDOW (threshold_dialog), GDK_WINDOW_TYPE_HINT_DIALOG);
275
dialogVbox = GTK_DIALOG (threshold_dialog)->vbox;
276
gtk_widget_show (dialogVbox);
278
allButButtonsVbox = gtk_vbox_new (FALSE, 12);
279
gtk_widget_show (allButButtonsVbox);
280
gtk_box_pack_start (GTK_BOX (dialogVbox), allButButtonsVbox, TRUE, TRUE, 0);
282
settingsOuterHbox = gtk_hbox_new (FALSE, 0);
283
gtk_widget_show (settingsOuterHbox);
284
gtk_box_pack_start (GTK_BOX (allButButtonsVbox), settingsOuterHbox, FALSE, TRUE, 0);
286
settingsOuterVbox = gtk_vbox_new (FALSE, 12);
287
gtk_widget_show (settingsOuterVbox);
288
gtk_box_pack_start (GTK_BOX (settingsOuterHbox), settingsOuterVbox, TRUE, TRUE, 0);
290
minValueVbox = gtk_vbox_new (FALSE, 0);
291
gtk_widget_show (minValueVbox);
292
gtk_box_pack_start (GTK_BOX (settingsOuterVbox), minValueVbox, FALSE, FALSE, 0);
294
minValueLabel = gtk_label_new (QT_TR_NOOP("Minimum value to be in-range:"));
295
gtk_widget_show (minValueLabel);
296
gtk_box_pack_start (GTK_BOX (minValueVbox), minValueLabel, FALSE, FALSE, 0);
297
gtk_misc_set_alignment (GTK_MISC (minValueLabel), 0.5, 1);
298
gtk_misc_set_padding (GTK_MISC (minValueLabel), 0, 8);
300
minValueHbox = gtk_hbox_new (FALSE, 5);
301
gtk_widget_show (minValueHbox);
302
gtk_box_pack_start (GTK_BOX (minValueVbox), minValueHbox, TRUE, TRUE, 0);
304
#ifdef ORIGINAL_CODE_GENERATED_BY_GLADE
305
minValueSlider = gtk_hscale_new (GTK_ADJUSTMENT (gtk_adjustment_new (0, 0, 255, 1, 1, 0)));
307
minValueSpinner_adj = gtk_adjustment_new (0, 0, 255, 1, 1, 0);
308
minValueSlider = gtk_hscale_new (GTK_ADJUSTMENT (minValueSpinner_adj));
310
gtk_widget_show (minValueSlider);
311
gtk_box_pack_start (GTK_BOX (minValueHbox), minValueSlider, TRUE, TRUE, 0);
312
gtk_scale_set_draw_value (GTK_SCALE (minValueSlider), FALSE);
313
gtk_scale_set_value_pos (GTK_SCALE (minValueSlider), GTK_POS_LEFT);
314
gtk_scale_set_digits (GTK_SCALE (minValueSlider), 0);
316
#ifdef ORIGINAL_CODE_GENERATED_BY_GLADE
317
minValueSpinner_adj = gtk_adjustment_new (0, 0, 255, 1, 10, 10);
319
minValueSpinner = gtk_spin_button_new (GTK_ADJUSTMENT (minValueSpinner_adj), 1, 0);
320
gtk_widget_show (minValueSpinner);
321
gtk_box_pack_start (GTK_BOX (minValueHbox), minValueSpinner, FALSE, TRUE, 0);
323
maxValueVbox = gtk_vbox_new (FALSE, 0);
324
gtk_widget_show (maxValueVbox);
325
gtk_box_pack_start (GTK_BOX (settingsOuterVbox), maxValueVbox, FALSE, FALSE, 0);
327
maxValueLabel = gtk_label_new (QT_TR_NOOP("Maximum value to be in-range:"));
328
gtk_widget_show (maxValueLabel);
329
gtk_box_pack_start (GTK_BOX (maxValueVbox), maxValueLabel, FALSE, FALSE, 0);
331
maxValueHbox = gtk_hbox_new (FALSE, 5);
332
gtk_widget_show (maxValueHbox);
333
gtk_box_pack_start (GTK_BOX (maxValueVbox), maxValueHbox, TRUE, TRUE, 0);
335
#ifdef ORIGINAL_CODE_GENERATED_BY_GLADE
336
maxValueSlider = gtk_hscale_new (GTK_ADJUSTMENT (gtk_adjustment_new (255, 0, 255, 1, 1, 0)));
338
maxValueSpinner_adj = gtk_adjustment_new (255, 0, 255, 1, 1, 0);
339
maxValueSlider = gtk_hscale_new (GTK_ADJUSTMENT (maxValueSpinner_adj));
341
gtk_widget_show (maxValueSlider);
342
gtk_box_pack_start (GTK_BOX (maxValueHbox), maxValueSlider, TRUE, TRUE, 0);
343
gtk_scale_set_draw_value (GTK_SCALE (maxValueSlider), FALSE);
344
gtk_scale_set_value_pos (GTK_SCALE (maxValueSlider), GTK_POS_LEFT);
345
gtk_scale_set_digits (GTK_SCALE (maxValueSlider), 0);
347
#ifdef ORIGINAL_CODE_GENERATED_BY_GLADE
348
maxValueSpinner_adj = gtk_adjustment_new (255, 0, 255, 1, 10, 10);
350
maxValueSpinner = gtk_spin_button_new (GTK_ADJUSTMENT (maxValueSpinner_adj), 1, 0);
351
gtk_widget_show (maxValueSpinner);
352
gtk_box_pack_start (GTK_BOX (maxValueHbox), maxValueSpinner, FALSE, TRUE, 0);
354
outputValuesHbox = gtk_hbox_new (FALSE, 0);
355
gtk_widget_show (outputValuesHbox);
356
gtk_box_pack_start (GTK_BOX (settingsOuterVbox), outputValuesHbox, TRUE, TRUE, 0);
358
outputValuesLabel = gtk_label_new (QT_TR_NOOP("Output values: "));
359
gtk_widget_show (outputValuesLabel);
360
gtk_box_pack_start (GTK_BOX (outputValuesHbox), outputValuesLabel, FALSE, FALSE, 0);
362
outputValuesMenu = gtk_combo_box_new_text ();
363
gtk_widget_show (outputValuesMenu);
364
gtk_box_pack_start (GTK_BOX (outputValuesHbox), outputValuesMenu, TRUE, TRUE, 0);
365
gtk_combo_box_append_text (GTK_COMBO_BOX (outputValuesMenu), QT_TR_NOOP("In-range values go black, out-of-range values go white"));
366
gtk_combo_box_append_text (GTK_COMBO_BOX (outputValuesMenu), QT_TR_NOOP("In-range values go white, out-of-range values go black"));
368
debugHbox = gtk_hbox_new (FALSE, 0);
369
gtk_widget_show (debugHbox);
370
gtk_box_pack_start (GTK_BOX (settingsOuterVbox), debugHbox, TRUE, TRUE, 0);
372
debugLabel = gtk_label_new (QT_TR_NOOP("Debugging settings (bits): "));
373
gtk_widget_show (debugLabel);
374
gtk_box_pack_start (GTK_BOX (debugHbox), debugLabel, FALSE, FALSE, 0);
376
debugSpinButton_adj = gtk_adjustment_new (0, 0, 16777215, 1, 10, 10);
377
debugSpinButton = gtk_spin_button_new (GTK_ADJUSTMENT (debugSpinButton_adj), 1, 0);
378
gtk_widget_show (debugSpinButton);
379
gtk_box_pack_start (GTK_BOX (debugHbox), debugSpinButton, TRUE, TRUE, 0);
381
previewFrame = gtk_frame_new (NULL);
382
gtk_widget_show (previewFrame);
383
gtk_box_pack_start (GTK_BOX (allButButtonsVbox), previewFrame, TRUE, TRUE, 0);
385
previewAlignment = gtk_alignment_new (0.5, 0.5, 1, 1);
386
gtk_widget_show (previewAlignment);
387
gtk_container_add (GTK_CONTAINER (previewFrame), previewAlignment);
388
gtk_alignment_set_padding (GTK_ALIGNMENT (previewAlignment), 0, 8, 6, 8);
390
previewVbox = gtk_vbox_new (FALSE, 5);
391
gtk_widget_show (previewVbox);
392
gtk_container_add (GTK_CONTAINER (previewAlignment), previewVbox);
394
previewControlHbox = gtk_hbox_new (FALSE, 5);
395
gtk_widget_show (previewControlHbox);
396
gtk_box_pack_start (GTK_BOX (previewVbox), previewControlHbox, TRUE, TRUE, 0);
398
previewOutputMenu = gtk_combo_box_new_text ();
399
#ifdef ORIGINAL_CODE_GENERATED_BY_GLADE
400
// temporarily (?) disable this until it's actually implemented
401
gtk_widget_show (previewOutputMenu);
403
gtk_box_pack_start (GTK_BOX (previewControlHbox), previewOutputMenu, FALSE, TRUE, 0);
404
gtk_combo_box_append_text (GTK_COMBO_BOX (previewOutputMenu), QT_TR_NOOP("Threshold output"));
405
gtk_combo_box_append_text (GTK_COMBO_BOX (previewOutputMenu), QT_TR_NOOP("Final output"));
407
previewSlider = gtk_hscale_new (GTK_ADJUSTMENT (gtk_adjustment_new (0, 0, 99, 1, 1, 1)));
408
gtk_widget_show (previewSlider);
409
gtk_box_pack_start (GTK_BOX (previewControlHbox), previewSlider, TRUE, TRUE, 0);
410
gtk_scale_set_digits (GTK_SCALE (previewSlider), 0);
412
previewVideo = gtk_drawing_area_new ();
413
gtk_widget_show (previewVideo);
414
gtk_box_pack_start (GTK_BOX (previewVbox), previewVideo, TRUE, TRUE, 0);
415
gtk_widget_set_size_request (previewVideo, -1, 300);
416
gtk_widget_set_events (previewVideo, GDK_BUTTON1_MOTION_MASK | GDK_BUTTON_PRESS_MASK);
418
previewLabel = gtk_label_new (QT_TR_NOOP("Preview"));
419
gtk_widget_show (previewLabel);
420
gtk_frame_set_label_widget (GTK_FRAME (previewFrame), previewLabel);
422
dialogButtonBox = GTK_DIALOG (threshold_dialog)->action_area;
423
gtk_widget_show (dialogButtonBox);
424
gtk_button_box_set_layout (GTK_BUTTON_BOX (dialogButtonBox), GTK_BUTTONBOX_END);
426
cancelButton = gtk_button_new_from_stock ("gtk-cancel");
427
gtk_widget_show (cancelButton);
428
gtk_dialog_add_action_widget (GTK_DIALOG (threshold_dialog), cancelButton, GTK_RESPONSE_CANCEL);
429
GTK_WIDGET_SET_FLAGS (cancelButton, GTK_CAN_DEFAULT);
431
okButton = gtk_button_new_from_stock ("gtk-ok");
432
gtk_widget_show (okButton);
433
gtk_dialog_add_action_widget (GTK_DIALOG (threshold_dialog), okButton, GTK_RESPONSE_OK);
434
GTK_WIDGET_SET_FLAGS (okButton, GTK_CAN_DEFAULT);
436
/* Store pointers to all widgets, for use by lookup_widget(). */
437
GLADE_HOOKUP_OBJECT_NO_REF (threshold_dialog, threshold_dialog, "threshold_dialog");
438
GLADE_HOOKUP_OBJECT_NO_REF (threshold_dialog, dialogVbox, "dialogVbox");
439
GLADE_HOOKUP_OBJECT (threshold_dialog, allButButtonsVbox, "allButButtonsVbox");
440
GLADE_HOOKUP_OBJECT (threshold_dialog, settingsOuterHbox, "settingsOuterHbox");
441
GLADE_HOOKUP_OBJECT (threshold_dialog, settingsOuterVbox, "settingsOuterVbox");
442
GLADE_HOOKUP_OBJECT (threshold_dialog, minValueVbox, "minValueVbox");
443
GLADE_HOOKUP_OBJECT (threshold_dialog, minValueLabel, "minValueLabel");
444
GLADE_HOOKUP_OBJECT (threshold_dialog, minValueHbox, "minValueHbox");
445
GLADE_HOOKUP_OBJECT (threshold_dialog, minValueSlider, "minValueSlider");
446
GLADE_HOOKUP_OBJECT (threshold_dialog, minValueSpinner, "minValueSpinner");
447
GLADE_HOOKUP_OBJECT (threshold_dialog, maxValueVbox, "maxValueVbox");
448
GLADE_HOOKUP_OBJECT (threshold_dialog, maxValueLabel, "maxValueLabel");
449
GLADE_HOOKUP_OBJECT (threshold_dialog, maxValueHbox, "maxValueHbox");
450
GLADE_HOOKUP_OBJECT (threshold_dialog, maxValueSlider, "maxValueSlider");
451
GLADE_HOOKUP_OBJECT (threshold_dialog, maxValueSpinner, "maxValueSpinner");
452
GLADE_HOOKUP_OBJECT (threshold_dialog, outputValuesHbox, "outputValuesHbox");
453
GLADE_HOOKUP_OBJECT (threshold_dialog, outputValuesLabel, "outputValuesLabel");
454
GLADE_HOOKUP_OBJECT (threshold_dialog, outputValuesMenu, "outputValuesMenu");
455
GLADE_HOOKUP_OBJECT (threshold_dialog, debugHbox, "debugHbox");
456
GLADE_HOOKUP_OBJECT (threshold_dialog, debugLabel, "debugLabel");
457
GLADE_HOOKUP_OBJECT (threshold_dialog, debugSpinButton, "debugSpinButton");
458
GLADE_HOOKUP_OBJECT (threshold_dialog, previewFrame, "previewFrame");
459
GLADE_HOOKUP_OBJECT (threshold_dialog, previewAlignment, "previewAlignment");
460
GLADE_HOOKUP_OBJECT (threshold_dialog, previewVbox, "previewVbox");
461
GLADE_HOOKUP_OBJECT (threshold_dialog, previewControlHbox, "previewControlHbox");
462
GLADE_HOOKUP_OBJECT (threshold_dialog, previewOutputMenu, "previewOutputMenu");
463
GLADE_HOOKUP_OBJECT (threshold_dialog, previewSlider, "previewSlider");
464
GLADE_HOOKUP_OBJECT (threshold_dialog, previewVideo, "previewVideo");
465
GLADE_HOOKUP_OBJECT (threshold_dialog, previewLabel, "previewLabel");
466
GLADE_HOOKUP_OBJECT_NO_REF (threshold_dialog, dialogButtonBox, "dialogButtonBox");
467
GLADE_HOOKUP_OBJECT (threshold_dialog, cancelButton, "cancelButton");
468
GLADE_HOOKUP_OBJECT (threshold_dialog, okButton, "okButton");
470
return threshold_dialog;