~ubuntu-branches/ubuntu/saucy/darktable/saucy

« back to all changes in this revision

Viewing changes to src/iop/clipping.c

  • Committer: Package Import Robot
  • Author(s): David Bremner
  • Date: 2011-11-13 10:46:00 UTC
  • mfrom: (8.1.1 sid)
  • Revision ID: package-import@ubuntu.com-20111113104600-56c59agrs615gjim
New upstream version

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
    This file is part of darktable,
3
 
    copyright (c) 2009--2010 johannes hanika.
 
3
    copyright (c) 2009--2011 johannes hanika.
4
4
 
5
5
    darktable is free software: you can redistribute it and/or modify
6
6
    it under the terms of the GNU General Public License as published by
24
24
#include <gtk/gtk.h>
25
25
#include <inttypes.h>
26
26
#include <gdk/gdkkeysyms.h>
27
 
#ifdef HAVE_GEGL
28
 
#include <gegl.h>
29
 
#endif
 
27
#include <assert.h>
 
28
 
30
29
#include "develop/develop.h"
31
30
#include "develop/imageop.h"
32
31
#include "control/control.h"
37
36
#include "dtgtk/resetlabel.h"
38
37
#include "dtgtk/togglebutton.h"
39
38
#include "dtgtk/button.h"
 
39
#include "gui/accelerators.h"
40
40
#include "gui/gtk.h"
41
41
#include "gui/draw.h"
42
42
#include "gui/presets.h"
43
43
 
44
44
DT_MODULE(3)
45
45
 
 
46
// number of gui ratios in combo box
 
47
#define NUM_RATIOS 9
 
48
 
46
49
/** flip H/V, rotate an image, then clip the buffer. */
47
50
typedef enum dt_iop_clipping_flags_t
48
51
{
89
92
typedef struct dt_iop_clipping_gui_data_t
90
93
{
91
94
  GtkDarktableSlider *scale5, *keystone_h,*keystone_v;
 
95
  GtkWidget *swap_button;
92
96
  GtkDarktableToggleButton *hflip,*vflip;
93
97
  GtkComboBoxEntry *aspect_presets;
94
98
  GtkComboBox *guide_lines;
95
99
  GtkLabel *label7;
96
100
  GtkDarktableToggleButton *flipHorGoldenGuide, *flipVerGoldenGuide;
97
101
  GtkCheckButton *goldenSectionBox, *goldenSpiralSectionBox, *goldenSpiralBox, *goldenTriangleBox;
98
 
  GClosure *commit_callback;
99
 
  GClosure *undo_callback;
100
102
 
101
103
  float button_down_zoom_x, button_down_zoom_y, button_down_angle; // position in image where the button has been pressed.
102
104
  float clip_x, clip_y, clip_w, clip_h, handle_x, handle_y;
103
105
  float old_clip_x, old_clip_y, old_clip_w, old_clip_h;
104
 
  int cropping, straightening;
105
 
  float aspect_ratios[9];
 
106
  int cropping, straightening, applied;
 
107
  float aspect_ratios[NUM_RATIOS];
106
108
  float current_aspect;
107
109
}
108
110
dt_iop_clipping_gui_data_t;
163
165
  return IOP_TAG_DISTORT;
164
166
}
165
167
 
 
168
int
 
169
operation_tags_filter ()
 
170
{
 
171
  // switch off watermark, it gets confused.
 
172
  return IOP_TAG_DECORATION;
 
173
}
 
174
 
 
175
 
 
176
static int
 
177
gui_has_focus(struct dt_iop_module_t *self)
 
178
{
 
179
  return self->dev->gui_module == self;
 
180
}
 
181
 
166
182
static void
167
183
backtransform(float *x, float *o, const float *m, const float t_h, const float t_v)
168
184
{
407
423
void commit_params (struct dt_iop_module_t *self, dt_iop_params_t *p1, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
408
424
{
409
425
  dt_iop_clipping_params_t *p = (dt_iop_clipping_params_t *)p1;
410
 
#ifdef HAVE_GEGL
411
 
  // pull in new params to gegl
412
 
#error "clipping needs to be ported to GEGL!"
413
 
#else
414
426
  dt_iop_clipping_data_t *d = (dt_iop_clipping_data_t *)piece->data;
415
427
  // pull in bit from weird p->k => d->keystone = 1
416
428
  d->all_off = 1;
421
433
  if(p->k_v >= -1.0 && p->k_v <= 1.0) d->ki_v = p->k_v;
422
434
  else d->ki_v = 0.0f;
423
435
  d->angle = M_PI/180.0 * p->angle;
424
 
  d->cx = p->cx;
425
 
  d->cy = p->cy;
426
 
  d->cw = fabsf(p->cw);
427
 
  d->ch = fabsf(p->ch);
 
436
  if(gui_has_focus(self))
 
437
  {
 
438
    d->cx = 0.0f;
 
439
    d->cy = 0.0f;
 
440
    d->cw = 1.0f;
 
441
    d->ch = 1.0f;
 
442
  }
 
443
  else
 
444
  {
 
445
    d->cx = p->cx;
 
446
    d->cy = p->cy;
 
447
    d->cw = fabsf(p->cw);
 
448
    d->ch = fabsf(p->ch);
 
449
  }
428
450
  d->flags = (p->ch < 0 ? FLAG_FLIP_VERTICAL : 0) | (p->cw < 0 ? FLAG_FLIP_HORIZONTAL : 0);
429
 
#endif
 
451
}
 
452
 
 
453
void gui_focus (struct dt_iop_module_t *self, gboolean in)
 
454
{
 
455
  dt_iop_clipping_gui_data_t *g = (dt_iop_clipping_gui_data_t *)self->gui_data;
 
456
  dt_iop_clipping_params_t *p = (dt_iop_clipping_params_t *)self->params;
 
457
  if(self->enabled)
 
458
  {
 
459
    if(in)
 
460
    {
 
461
      // got focus. make it redraw in full and grab stuff to gui:
 
462
      // need to get gui stuff for the first time for this image,
 
463
      // and advice the pipe to redraw in full:
 
464
      g->clip_x = p->cx;
 
465
      g->clip_w = p->cw - p->cx;
 
466
      g->clip_y = p->cy;
 
467
      g->clip_h = p->ch - p->cy;
 
468
      // flip one bit to trigger the cache:
 
469
      uint32_t hack = *(uint32_t*)&p->cy;
 
470
      hack ++;
 
471
      p->cy = *(float *)&hack;
 
472
      if(!darktable.gui->reset)
 
473
        dt_dev_add_history_item(darktable.develop, self, TRUE);
 
474
    }
 
475
    else
 
476
    {
 
477
      // lost focus, commit current params:
 
478
      commit_box (self, g, p);
 
479
    }
 
480
  }
430
481
}
431
482
 
432
483
void init_pipe (struct dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
433
484
{
434
 
#ifdef HAVE_GEGL
435
 
#error "clipping needs to be ported to GEGL!"
436
 
#else
437
485
  piece->data = malloc(sizeof(dt_iop_clipping_data_t));
438
486
  self->commit_params(self, self->default_params, pipe, piece);
439
 
#endif
440
487
}
441
488
 
442
489
void cleanup_pipe (struct dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
443
490
{
444
 
#ifdef HAVE_GEGL
445
 
#error "clipping needs to be ported to GEGL!"
446
 
#else
447
491
  free(piece->data);
448
 
#endif
449
492
}
450
493
 
451
494
static void
452
495
apply_box_aspect(dt_iop_module_t *self, int grab)
453
496
{
454
497
  dt_iop_clipping_gui_data_t *g = (dt_iop_clipping_gui_data_t *)self->gui_data;
455
 
  float wd = self->dev->preview_pipe->backbuf_width;
456
 
  float ht = self->dev->preview_pipe->backbuf_height;
 
498
  int iwd, iht;
 
499
  dt_dev_get_processed_size(darktable.develop, &iwd, &iht);
 
500
  float wd = iwd, ht = iht;
457
501
  // enforce aspect ratio.
458
502
  const float aspect = g->current_aspect;
459
503
  // const float aspect = gtk_spin_button_get_value(g->aspect);
539
583
  }
540
584
}
541
585
 
542
 
void init_presets (dt_iop_module_t *self)
 
586
void init_presets (dt_iop_module_so_t *self)
543
587
{
544
588
  dt_iop_clipping_params_t p = (dt_iop_clipping_params_t)
545
589
  {
547
591
  };
548
592
  DT_DEBUG_SQLITE3_EXEC(darktable.db, "begin", NULL, NULL, NULL);
549
593
  p.angle = 90.0f;
550
 
  dt_gui_presets_add_generic(_("rotate by  90"), self->op, &p, sizeof(p), 1);
 
594
  dt_gui_presets_add_generic(_("rotate by  90"), self->op, self->version(), &p, sizeof(p), 1);
551
595
  p.angle = -90.0f;
552
 
  dt_gui_presets_add_generic(_("rotate by -90"), self->op, &p, sizeof(p), 1);
 
596
  dt_gui_presets_add_generic(_("rotate by -90"), self->op, self->version(), &p, sizeof(p), 1);
553
597
  p.angle = 180.0f;
554
 
  dt_gui_presets_add_generic(_("rotate by 180"), self->op, &p, sizeof(p), 1);
 
598
  dt_gui_presets_add_generic(_("rotate by 180"), self->op, self->version(), &p, sizeof(p), 1);
555
599
  DT_DEBUG_SQLITE3_EXEC(darktable.db, "commit", NULL, NULL, NULL);
556
600
}
557
601
 
576
620
}
577
621
 
578
622
static void
 
623
aspect_free_activated (GtkEntry *entry, dt_iop_module_t *self)
 
624
{
 
625
  dt_iop_clipping_gui_data_t *g = (dt_iop_clipping_gui_data_t *)self->gui_data;
 
626
  gchar *text = g_strdup(gtk_entry_get_text(entry));
 
627
  if(text)
 
628
  {
 
629
    gchar *c = text;
 
630
    while(*c != ':' && *c != '/' && c < text + strlen(text)) c++;
 
631
    if(c < text + strlen(text) - 1)
 
632
    {
 
633
      *c = '\0';
 
634
      c++;
 
635
      g->current_aspect = atof(text) / atof(c);
 
636
      apply_box_aspect(self, 5);
 
637
      dt_control_queue_draw_all();
 
638
      dt_iop_request_focus(self);
 
639
    }
 
640
    g_free(text);
 
641
  }
 
642
}
 
643
 
 
644
static void
579
645
aspect_presets_changed (GtkComboBox *combo, dt_iop_module_t *self)
580
646
{
581
647
  dt_iop_clipping_gui_data_t *g = (dt_iop_clipping_gui_data_t *)self->gui_data;
582
648
  int which = gtk_combo_box_get_active(combo);
583
649
  if (which < 0)
584
650
  {
 
651
    // parse config param:
 
652
    if(g->current_aspect == -1.0f)
 
653
    {
 
654
      g->current_aspect = dt_conf_get_float("plugins/darkroom/clipping/custom_aspect");
 
655
      if(g->current_aspect <= 0.0f) g->current_aspect = 1.5f;
 
656
      char text[128];
 
657
      snprintf(text, 128, "%.3f:1", g->current_aspect);
 
658
      gtk_entry_set_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN(combo))), text);
 
659
      apply_box_aspect(self, 5);
 
660
      dt_control_queue_draw_all();
 
661
    }
 
662
    // user is typing, don't overwrite it.
 
663
    g->current_aspect = -2.0f;
585
664
    // reset to free aspect ratio:
586
 
    g->current_aspect = -1.0;
587
665
    dt_conf_set_int("plugins/darkroom/clipping/aspect_preset", -1);
588
 
    gchar *text = gtk_combo_box_get_active_text(combo);
589
 
    if(text)
590
 
    {
591
 
      gchar *c = text;
592
 
      while(*c != ':' && *c != '/' && c < text + strlen(text)) c++;
593
 
      if(c < text + strlen(text) - 1)
594
 
      {
595
 
        *c = '\0';
596
 
        c++;
597
 
        g->current_aspect = atof(text) / atof(c);
598
 
        apply_box_aspect(self, 5);
599
 
        dt_control_queue_draw_all();
600
 
        dt_iop_request_focus(self);
601
 
      }
602
 
      g_free(text);
603
 
    }
604
666
  }
605
 
  else if (which < 9)
 
667
  else if (which < NUM_RATIOS)
606
668
  {
607
669
    dt_conf_set_int("plugins/darkroom/clipping/aspect_preset", which);
608
670
    if(which > 1 && self->dev->image->height > self->dev->image->width)
619
681
angle_callback (GtkDarktableSlider *slider, dt_iop_module_t *self)
620
682
{
621
683
  if(self->dt->gui->reset) return;
 
684
  dt_iop_clipping_gui_data_t *g = (dt_iop_clipping_gui_data_t *)self->gui_data;
622
685
  dt_iop_clipping_params_t *p = (dt_iop_clipping_params_t *)self->params;
623
686
  p->angle = dtgtk_slider_get_value(slider);
624
 
  dt_dev_add_history_item(darktable.develop, self, TRUE);
 
687
  commit_box (self, g, p);
625
688
}
626
689
 
627
690
static void
632
695
  dt_iop_clipping_params_t *p = (dt_iop_clipping_params_t *)self->params;
633
696
  // we need k to be abs(k) < 2, so the second bit will always be zero (except we set it:).
634
697
  p->k_h = fmaxf(-1.9, fminf(1.9, dtgtk_slider_get_value(g->keystone_h)));
635
 
  dt_dev_add_history_item(darktable.develop, self, TRUE);
 
698
  commit_box (self, g, p);
636
699
}
637
700
static void
638
701
keystone_callback_v (GtkWidget *widget, dt_iop_module_t *self)
642
705
  dt_iop_clipping_params_t *p = (dt_iop_clipping_params_t *)self->params;
643
706
  // we need k to be abs(k) < 2, so the second bit will always be zero (except we set it:).
644
707
  p->k_v = fmaxf(-1.9, fminf(1.9, dtgtk_slider_get_value(g->keystone_v)));
645
 
  dt_dev_add_history_item(darktable.develop, self, TRUE);
 
708
  commit_box (self, g, p);
646
709
}
647
710
 
648
711
void gui_update(struct dt_iop_module_t *self)
655
718
  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g->hflip), p->cw < 0);
656
719
  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g->vflip), p->ch < 0);
657
720
  int act = dt_conf_get_int("plugins/darkroom/clipping/aspect_preset");
658
 
  if(act < 0 || act > 7) act = 0;
 
721
  if(act < -1 || act >= NUM_RATIOS) act = 0;
659
722
  gtk_combo_box_set_active(GTK_COMBO_BOX(g->aspect_presets), act);
 
723
 
 
724
  // reset gui draw box to what we have in the parameters:
 
725
  g->applied = 1;
 
726
  g->clip_x = p->cx;
 
727
  g->clip_w = p->cw - p->cx;
 
728
  g->clip_y = p->cy;
 
729
  g->clip_h = p->ch - p->cy;
660
730
}
661
731
 
662
732
void init(dt_iop_module_t *module)
695
765
    else                                     p->ch = copysignf(p->ch,  1.0);
696
766
  }
697
767
  if(self->off) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(self->off), 1);
698
 
  dt_dev_add_history_item(darktable.develop, self, TRUE);
 
768
  commit_box (self, g, p);
699
769
}
700
770
 
701
771
static void
724
794
  commit_box(self, g, p);
725
795
}
726
796
 
727
 
static void key_undo_callback(GtkAccelGroup *accel_group,
728
 
                              GObject *acceleratable,
729
 
                              guint keyval, GdkModifierType modifier,
730
 
                              gpointer data)
731
 
{
732
 
  dt_iop_module_t* self = (dt_iop_module_t*)data;
733
 
  dt_iop_clipping_gui_data_t *g = (dt_iop_clipping_gui_data_t *)self->gui_data;
734
 
  dt_iop_clipping_params_t   *p = (dt_iop_clipping_params_t   *)self->params;
735
 
 
736
 
  // reverse cropping to where it was before.
737
 
  p->cx = p->cy = 0.0f;
738
 
  p->cw = p->ch = 1.0f;
739
 
  g->clip_x = g->old_clip_x;
740
 
  g->clip_y = g->old_clip_y;
741
 
  g->clip_w = g->old_clip_w;
742
 
  g->clip_h = g->old_clip_h;
743
 
  dt_dev_add_history_item(darktable.develop, self, TRUE);
744
 
  dt_control_queue_draw_all();
745
 
}
746
 
 
747
797
static void
748
798
aspect_flip(GtkWidget *button, dt_iop_module_t *self)
749
799
{
819
869
  g->old_clip_w = g->old_clip_h = 1.0;
820
870
  g->cropping = 0;
821
871
  g->straightening = 0;
 
872
  g->applied = 1;
822
873
 
823
874
  self->widget = gtk_table_new(10, 6, FALSE);
824
875
  gtk_table_set_row_spacings(GTK_TABLE(self->widget), DT_GUI_IOP_MODULE_CONTROL_SPACING);
844
895
  g_signal_connect (G_OBJECT (g->scale5), "value-changed",
845
896
                    G_CALLBACK (angle_callback), self);
846
897
  g_object_set(G_OBJECT(g->scale5), "tooltip-text", _("right-click and drag a line on the image to drag a straight line"), (char *)NULL);
847
 
  dtgtk_slider_set_accel(g->scale5,darktable.control->accels_darkroom,"<Darktable>/darkroom/plugins/clipping/angle");
848
898
  gtk_table_attach(GTK_TABLE(self->widget), GTK_WIDGET(g->scale5), 0, 6, 1, 2, GTK_EXPAND|GTK_FILL, 0, 0, 0);
849
899
 
850
900
 
853
903
  g_object_set(G_OBJECT(g->keystone_h), "tooltip-text", _("adjust perspective for horizontal keystone distortion"), (char *)NULL);
854
904
  g_signal_connect (G_OBJECT (g->keystone_h), "value-changed",
855
905
                    G_CALLBACK (keystone_callback_h), self);
856
 
  dtgtk_slider_set_accel(g->keystone_h,darktable.control->accels_darkroom,"<Darktable>/darkroom/plugins/clipping/keystone h");
857
906
  gtk_table_attach(GTK_TABLE(self->widget), GTK_WIDGET(g->keystone_h), 0, 6, 2, 3, GTK_EXPAND|GTK_FILL, 0, 0, 0);
858
907
 
859
908
  g->keystone_v = DTGTK_SLIDER(dtgtk_slider_new_with_range(DARKTABLE_SLIDER_BAR, -1.0, 1.0, 0.01, 0.0, 2));
861
910
  g_object_set(G_OBJECT(g->keystone_v), "tooltip-text", _("adjust perspective for vertical keystone distortion"), (char *)NULL);
862
911
  g_signal_connect (G_OBJECT (g->keystone_v), "value-changed",
863
912
                    G_CALLBACK (keystone_callback_v), self);
864
 
  dtgtk_slider_set_accel(g->keystone_v,darktable.control->accels_darkroom,"<Darktable>/darkroom/plugins/clipping/keystone v");
865
913
  gtk_table_attach(GTK_TABLE(self->widget), GTK_WIDGET(g->keystone_v), 0, 6, 3, 4, GTK_EXPAND|GTK_FILL, 0, 0, 0);
866
914
 
867
915
  label = gtk_label_new(_("aspect"));
878
926
  gtk_combo_box_append_text(GTK_COMBO_BOX(g->aspect_presets), _("square"));
879
927
  gtk_combo_box_append_text(GTK_COMBO_BOX(g->aspect_presets), _("DIN"));
880
928
  gtk_combo_box_append_text(GTK_COMBO_BOX(g->aspect_presets), _("16:9"));
881
 
  g->commit_callback = g_cclosure_new(G_CALLBACK(key_commit_callback),
882
 
                                      (gpointer)self, NULL);
883
 
  g->undo_callback = g_cclosure_new(G_CALLBACK(key_undo_callback),
884
 
                                    (gpointer)self, NULL);
885
 
  dt_accel_group_connect_by_path(darktable.control->accels_darkroom,
886
 
                                 "<Darktable>/darkroom/plugins/clipping/commit",
887
 
                                 g->commit_callback);
888
 
  dt_accel_group_connect_by_path(darktable.control->accels_darkroom,
889
 
                                 "<Darktable>/darkroom/plugins/clipping/undo",
890
 
                                 g->undo_callback);
 
929
  dt_gui_key_accel_block_on_focus(gtk_bin_get_child(GTK_BIN(g->aspect_presets)));
891
930
  int act = dt_conf_get_int("plugins/darkroom/clipping/aspect_preset");
892
931
  if(act < 0 || act >= 9) act = 0;
893
932
  gtk_combo_box_set_active(GTK_COMBO_BOX(g->aspect_presets), act);
894
933
  g_signal_connect (G_OBJECT (g->aspect_presets), "changed",
895
934
                    G_CALLBACK (aspect_presets_changed), self);
 
935
  g_signal_connect (G_OBJECT (gtk_bin_get_child(GTK_BIN(g->aspect_presets))), "activate",
 
936
                    G_CALLBACK (aspect_free_activated), self);
896
937
  g_object_set(G_OBJECT(g->aspect_presets), "tooltip-text", _("set the aspect ratio (w:h)\npress ctrl-x to swap sides"), (char *)NULL);
897
938
 
898
939
  GtkBox *hbox = GTK_BOX(gtk_hbox_new(FALSE, 5));
899
940
  gtk_box_pack_start(hbox, GTK_WIDGET(g->aspect_presets), TRUE, TRUE, 0);
900
941
  GtkWidget *button = dtgtk_button_new(dtgtk_cairo_paint_aspectflip, CPF_STYLE_FLAT);
901
 
  dtgtk_button_set_accel(DTGTK_BUTTON(button),darktable.control->accels_darkroom,"<Darktable>/darkroom/plugins/clipping/swap the aspect ratio");
 
942
  g->swap_button = GTK_WIDGET(button);
902
943
  g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (aspect_flip), self);
903
944
  g_object_set(G_OBJECT(button), "tooltip-text", _("swap the aspect ratio (ctrl-x)"), (char *)NULL);
904
945
  gtk_box_pack_start(hbox, button, TRUE, FALSE, 0);
990
1031
  g->aspect_ratios[6] = 1.0;
991
1032
  g->aspect_ratios[7] = sqrtf(2.0);
992
1033
  g->aspect_ratios[8] = 16.0f/9.0f;
 
1034
  // if adding new presets, make sure to change this as well:
 
1035
  assert(NUM_RATIOS == 9);
993
1036
 
994
1037
  if(act> 0 && self->dev->image->height > self->dev->image->width)
995
1038
    g->current_aspect = 1.0/g->aspect_ratios[act];
999
1042
 
1000
1043
void gui_cleanup(struct dt_iop_module_t *self)
1001
1044
{
1002
 
  dt_accel_group_disconnect(darktable.control->accels_darkroom,
1003
 
                             ((dt_iop_clipping_gui_data_t*)(self->gui_data))->
1004
 
                             commit_callback);
1005
 
  dt_accel_group_disconnect(darktable.control->accels_darkroom,
1006
 
                             ((dt_iop_clipping_gui_data_t*)(self->gui_data))->
1007
 
                             undo_callback);
1008
1045
  free(self->gui_data);
1009
1046
  self->gui_data = NULL;
1010
1047
}
1198
1235
{
1199
1236
  dt_develop_t *dev = self->dev;
1200
1237
  dt_iop_clipping_gui_data_t *g = (dt_iop_clipping_gui_data_t *)self->gui_data;
 
1238
 
1201
1239
  int32_t zoom, closeup;
1202
1240
  float zoom_x, zoom_y;
1203
1241
  float wd = dev->preview_pipe->backbuf_width;
1220
1258
  pzx += 0.5f;
1221
1259
  pzy += 0.5f;
1222
1260
  cairo_set_dash (cr, &dashes, 0, 0);
1223
 
  cairo_set_source_rgba(cr, .3, .3, .3, .8);
 
1261
  if(g->applied)
 
1262
    cairo_set_source_rgba(cr, .2, .2, .2, .8);
 
1263
  else
 
1264
    cairo_set_source_rgba(cr, .3, .3, .3, .5);
1224
1265
  cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD);
1225
1266
  cairo_rectangle (cr, -1, -1, wd+2, ht+2);
1226
1267
  cairo_rectangle (cr, g->clip_x*wd, g->clip_y*ht, g->clip_w*wd, g->clip_h*ht);
1388
1429
  }
1389
1430
  else if(darktable.control->button_down && darktable.control->button_down_which == 1)
1390
1431
  {
 
1432
    // draw a light gray frame, to show it's not stored yet:
 
1433
    g->applied = 0;
1391
1434
    // first mouse button, adjust cropping frame, but what do we do?
1392
1435
    float bzx = g->button_down_zoom_x + .5f, bzy = g->button_down_zoom_y + .5f;
1393
1436
    if(!g->cropping && !g->straightening)
1470
1513
static void
1471
1514
commit_box (dt_iop_module_t *self, dt_iop_clipping_gui_data_t *g, dt_iop_clipping_params_t *p)
1472
1515
{
 
1516
  if(darktable.gui->reset) return;
1473
1517
  g->old_clip_x = g->clip_x;
1474
1518
  g->old_clip_y = g->clip_y;
1475
1519
  g->old_clip_w = g->clip_w;
1481
1525
    p->cx = p->cy = 0.0f;
1482
1526
    p->cw = p->ch = 1.0f;
1483
1527
  }
1484
 
  const float cx = p->cx, cy = p->cy;
1485
 
  const float cw = fabsf(p->cw), ch = fabsf(p->ch);
1486
 
  p->cx += g->clip_x*(cw-cx);
1487
 
  p->cy += g->clip_y*(ch-cy);
1488
 
  p->cw = copysignf(p->cx + (cw - cx)*g->clip_w, p->cw);
1489
 
  p->ch = copysignf(p->cy + (ch - cy)*g->clip_h, p->ch);
1490
 
  g->clip_x = g->clip_y = 0.0f;
1491
 
  g->clip_w = g->clip_h = 1.0;
1492
 
  darktable.gui->reset = 1;
1493
 
  self->gui_update(self);
1494
 
  darktable.gui->reset = 0;
 
1528
  p->cx = g->clip_x;
 
1529
  p->cy = g->clip_y;
 
1530
  p->cw = copysignf(p->cx + g->clip_w, p->cw);
 
1531
  p->ch = copysignf(p->cy + g->clip_h, p->ch);
1495
1532
  if(self->off) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(self->off), 1);
 
1533
  g->applied = 1;
1496
1534
  dt_dev_add_history_item(darktable.develop, self, TRUE);
1497
 
  // loose focus, continue with other plugins?
1498
 
  darktable.develop->gui_module = NULL;
1499
1535
}
1500
1536
 
1501
1537
int button_released(struct dt_iop_module_t *self, double x, double y, int which, uint32_t state)
1544
1580
  else return 0;
1545
1581
}
1546
1582
 
1547
 
void init_key_accels()
1548
 
{
1549
 
  gtk_accel_map_add_entry("<Darktable>/darkroom/plugins/clipping/commit",
1550
 
                          GDK_Return, 0);
1551
 
  gtk_accel_map_add_entry("<Darktable>/darkroom/plugins/clipping/undo",
1552
 
                          GDK_z, GDK_CONTROL_MASK);
1553
 
 
1554
 
  // Making sure these get into the accelerator lists as well
1555
 
  dt_accel_group_connect_by_path(darktable.control->accels_darkroom,
1556
 
                                 "<Darktable>/darkroom/plugins/clipping/commit",
1557
 
                                 NULL);
1558
 
  dt_accel_group_connect_by_path(darktable.control->accels_darkroom,
1559
 
                                 "<Darktable>/darkroom/plugins/clipping/undo",
1560
 
                                 NULL);
1561
 
  dtgtk_slider_init_accel(darktable.control->accels_darkroom,"<Darktable>/darkroom/plugins/clipping/angle");
1562
 
  dtgtk_slider_init_accel(darktable.control->accels_darkroom,"<Darktable>/darkroom/plugins/clipping/keystone h");
1563
 
  dtgtk_slider_init_accel(darktable.control->accels_darkroom,"<Darktable>/darkroom/plugins/clipping/keystone v");
1564
 
  dtgtk_button_init_accel(darktable.control->accels_darkroom,"<Darktable>/darkroom/plugins/clipping/swap the aspect ratio");
 
1583
void init_key_accels(dt_iop_module_so_t *self)
 
1584
{
 
1585
  dt_accel_register_iop(self, TRUE, NC_("accel", "commit"),
 
1586
                        GDK_Return, 0);
 
1587
  dt_accel_register_iop(self, TRUE, NC_("accel", "swap the aspect ratio"),
 
1588
                        GDK_x, 0);
 
1589
  dt_accel_register_slider_iop(self, FALSE, NC_("accel", "angle"));
 
1590
  dt_accel_register_slider_iop(self, FALSE, NC_("accel", "keystone h"));
 
1591
  dt_accel_register_slider_iop(self, FALSE, NC_("accel", "keystone v"));
 
1592
}
 
1593
 
 
1594
void connect_key_accels(dt_iop_module_t *self)
 
1595
{
 
1596
  dt_iop_clipping_gui_data_t *g = (dt_iop_clipping_gui_data_t*)self->gui_data;
 
1597
  GClosure *closure;
 
1598
 
 
1599
  closure = g_cclosure_new(G_CALLBACK(key_commit_callback),
 
1600
                           (gpointer)self, NULL);
 
1601
  dt_accel_connect_iop(self, "commit", closure);
 
1602
 
 
1603
  dt_accel_connect_button_iop(self, "swap the aspect ratio", g->swap_button);
 
1604
  dt_accel_connect_slider_iop(self, "angle", GTK_WIDGET(g->scale5));
 
1605
  dt_accel_connect_slider_iop(self, "keystone h", GTK_WIDGET(g->keystone_h));
 
1606
  dt_accel_connect_slider_iop(self, "keystone v", GTK_WIDGET(g->keystone_v));
1565
1607
}
1566
1608
 
1567
1609
#undef PHI
1573
1615
#undef GUIDE_TRIANGL
1574
1616
#undef GUIDE_GOLDEN
1575
1617
 
 
1618
#undef NUM_RATIOS
 
1619
 
1576
1620
// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-space on;