int button_pressed(struct dt_iop_module_t *self, double x, double y, double pressure, int which, int type, uint32_t state) { dt_iop_graduatednd_gui_data_t *g = (dt_iop_graduatednd_gui_data_t *)self->gui_data; float pzx, pzy; dt_dev_get_pointer_zoom_pos(self->dev, x, y, &pzx, &pzy); pzx += 0.5f; pzy += 0.5f; if(which == 3) { g->dragging = 2; g->xa = pzx; g->ya = pzy; g->xb = pzx; g->yb = pzy; g->oldx = pzx; g->oldy = pzy; return 1; } else if(g->selected > 0 && which == 1) { g->dragging = g->selected; g->oldx = pzx; g->oldy = pzy; return 1; } g->dragging = 0; return 0; }
int button_released(struct dt_iop_module_t *self, double x, double y, int which, uint32_t state) { dt_iop_graduatednd_gui_data_t *g = (dt_iop_graduatednd_gui_data_t *)self->gui_data; dt_iop_graduatednd_params_t *p = (dt_iop_graduatednd_params_t *)self->params; if (g->dragging > 0) { //dt_iop_graduatednd_params_t *p = (dt_iop_graduatednd_params_t *)self->params; //float wd = self->dev->preview_pipe->backbuf_width; //float ht = self->dev->preview_pipe->backbuf_height; float pzx, pzy; dt_dev_get_pointer_zoom_pos(self->dev, x, y, &pzx, &pzy); pzx += 0.5f; pzy += 0.5f; float r=0.0,o=0.0; //float pts[4]; //dt_dev_distort_backtransform(self->dev,pts,2); set_grad_from_points(self,g->xa,g->ya,g->xb,g->yb,&r, &o); //if this is a "line dragging, we reset extremities, to be sure they are not outside the image if (g->dragging == 3) set_points_from_grad(self,&g->xa,&g->ya,&g->xb,&g->yb,r,o); self->dt->gui->reset = 1; dt_bauhaus_slider_set(g->scale3,r); //dt_bauhaus_slider_set(g->scale4,o); self->dt->gui->reset = 0; p->rotation = r; p->offset = o; g->dragging = 0; dt_dev_add_history_item(darktable.develop, self, TRUE); } g->dragging = 0; return 0; }
int mouse_moved(struct dt_iop_module_t *self, double x, double y, double pressure, int which) { dt_iop_graduatednd_gui_data_t *g = (dt_iop_graduatednd_gui_data_t *)self->gui_data; int32_t zoom, closeup; DT_CTL_GET_GLOBAL(zoom, dev_zoom); DT_CTL_GET_GLOBAL(closeup, dev_closeup); float zoom_scale = dt_dev_get_zoom_scale(self->dev, zoom, closeup ? 2 : 1, 1); float pzx, pzy; dt_dev_get_pointer_zoom_pos(self->dev, x, y, &pzx, &pzy); pzx += 0.5f; pzy += 0.5f; //are we dragging something ? if (g->dragging > 0) { if (g->dragging == 1) { //we are dragging xa,ya g->xa = pzx; g->ya = pzy; } else if (g->dragging == 2) { //we are dragging xb,yb g->xb = pzx; g->yb = pzy; } else if (g->dragging == 3) { //we are dragging the entire line g->xa += pzx-g->oldx; g->xb += pzx-g->oldx; g->ya += pzy-g->oldy; g->yb += pzy-g->oldy; g->oldx = pzx; g->oldy = pzy; } } else { g->selected = 0; const float ext = 0.02f / zoom_scale; //are we near extermity ? if (pzy>g->ya-ext && pzy<g->ya+ext && pzx>g->xa-ext && pzx<g->xa+ext) { g->selected = 1; } else if (pzy>g->yb-ext && pzy<g->yb+ext && pzx>g->xb-ext && pzx<g->xb+ext) { g->selected = 2; } else if (dist_seg(g->xa,g->ya,g->xb,g->yb,pzx,pzy) < ext*ext*0.5) g->selected = 3; } dt_control_queue_redraw_center(); return 0; }
void gui_post_expose(struct dt_iop_module_t *self, cairo_t *cr, int32_t width, int32_t height, int32_t pointerx, int32_t pointery) { dt_develop_t *dev = self->dev; // dt_iop_graduatednd_gui_data_t *g = (dt_iop_graduatednd_gui_data_t *)self->gui_data; // dt_iop_graduatednd_params_t *p = (dt_iop_graduatednd_params_t *)self->params; // general house keeping. int32_t zoom, closeup; float zoom_x, zoom_y; float wd = dev->preview_pipe->backbuf_width; float ht = dev->preview_pipe->backbuf_height; // Commented out to allow this stub to be compilable with some versions of gcc ... // float bigger_side, smaller_side; // if(wd >= ht) // { // bigger_side = wd; // smaller_side = ht; // } // else // { // bigger_side = ht; // smaller_side = wd; // } DT_CTL_GET_GLOBAL(zoom_y, dev_zoom_y); DT_CTL_GET_GLOBAL(zoom_x, dev_zoom_x); DT_CTL_GET_GLOBAL(zoom, dev_zoom); DT_CTL_GET_GLOBAL(closeup, dev_closeup); float zoom_scale = dt_dev_get_zoom_scale(dev, zoom, closeup ? 2 : 1, 1); float pzx, pzy; dt_dev_get_pointer_zoom_pos(dev, pointerx, pointery, &pzx, &pzy); pzx += 0.5f; pzy += 0.5f; cairo_translate(cr, width/2.0, height/2.0); cairo_scale(cr, zoom_scale, zoom_scale); cairo_translate(cr, -.5f*wd-zoom_x*wd, -.5f*ht-zoom_y*ht); // now top-left is (0,0) and bottom-right is (wd,ht) //TODO calculate values for and execute cairo_translate() and cairo_rotate(). // of course the results can also be passed to draw_overlay() if it's easier to use them there instead. // finally draw the guides. if rotation and translation is done correctly it can be drawn statically in draw_overlay(). // int grab = get_grab(pzx*wd*0.5, pzy*ht*0.5, zoom_scale); //FIXME use the calculated offsets in the 1st and 2nd paramter to get correct mouse positions cairo_set_line_cap(cr,CAIRO_LINE_CAP_ROUND); cairo_set_line_width(cr, 3.0/zoom_scale); cairo_set_source_rgba(cr, .3, .3, .3, .8); // draw_overlay(cr, wd, ht, grab, zoom_scale); //FIXME removed to not annoy users as long as this is just a demo. cairo_set_line_width(cr, 1.0/zoom_scale); cairo_set_source_rgba(cr, .8, .8, .8, .8); // draw_overlay(cr, wd, ht, grab, zoom_scale); //FIXME removed to not annoy users as long as this is just a demo. }
int mouse_moved(dt_iop_module_t *self, double x, double y, int which) { dt_iop_spots_params_t *p = (dt_iop_spots_params_t *)self->params; dt_iop_spots_gui_data_t *g = (dt_iop_spots_gui_data_t *)self->gui_data; // draw line (call post expose) // highlight selected point, if any float pzx, pzy; dt_dev_get_pointer_zoom_pos(self->dev, x, y, &pzx, &pzy); pzx += 0.5f; pzy += 0.5f; float mind = FLT_MAX; int selected = -1; const int old_sel = g->selected; gboolean hoover_c = g->hoover_c; g->selected = -1; if(g->dragging < 0) for(int i=0; i<p->num_spots; i++) { float dist = (pzx - p->spot[i].x)*(pzx - p->spot[i].x) + (pzy - p->spot[i].y)*(pzy - p->spot[i].y); if(dist < mind) { mind = dist; selected = i; hoover_c = FALSE; } dist = (pzx - p->spot[i].xc)*(pzx - p->spot[i].xc) + (pzy - p->spot[i].yc)*(pzy - p->spot[i].yc); if(dist < mind) { mind = dist; selected = i; hoover_c = TRUE; } } else { if(g->hoover_c) { p->spot[g->dragging].xc = pzx; p->spot[g->dragging].yc = pzy; } else { p->spot[g->dragging].x = pzx; p->spot[g->dragging].y = pzy; } } if(selected >= 0 && mind < p->spot[selected].radius * p->spot[selected].radius) { g->selected = selected; g->hoover_c = hoover_c; } if(g->dragging >= 0 || g->selected != old_sel) dt_control_queue_redraw_center(); return 1; }
void gui_post_expose(dt_iop_module_t *self, cairo_t *cr, int32_t width, int32_t height, int32_t pointerx, int32_t pointery) { dt_develop_t *dev = self->dev; dt_iop_spots_params_t *p = (dt_iop_spots_params_t *)self->params; dt_iop_spots_gui_data_t *g = (dt_iop_spots_gui_data_t *)self->gui_data; float wd = dev->preview_pipe->backbuf_width; float ht = dev->preview_pipe->backbuf_height; float pzx, pzy; dt_dev_get_pointer_zoom_pos(dev, pointerx, pointery, &pzx, &pzy); pzx += 0.5f; pzy += 0.5f; float zoom_x, zoom_y; int32_t zoom, closeup; DT_CTL_GET_GLOBAL(zoom_y, dev_zoom_y); DT_CTL_GET_GLOBAL(zoom_x, dev_zoom_x); DT_CTL_GET_GLOBAL(zoom, dev_zoom); DT_CTL_GET_GLOBAL(closeup, dev_closeup); float zoom_scale = dt_dev_get_zoom_scale(dev, zoom, closeup ? 2 : 1, 1); cairo_set_source_rgb(cr, .3, .3, .3); cairo_translate(cr, width/2.0, height/2.0f); cairo_scale(cr, zoom_scale, zoom_scale); cairo_translate(cr, -.5f*wd-zoom_x*wd, -.5f*ht-zoom_y*ht); for(int i=0; i<p->num_spots; i++) { const float rad = MIN(wd, ht)*p->spot[i].radius; const float dx = p->spot[i].xc - p->spot[i].x; float dy = p->spot[i].yc - p->spot[i].y; if(dx == 0.0 && dy == 0.0) dy = EPSILON; // otherwise we'll have ol = 1.0/0.0 ==> xr = yr = -nan const float ol = 1.0f/sqrtf(dx*dx*wd*wd + dy*dy*ht*ht); const float d = rad * ol; const float x = p->spot[i].x*wd, y = p->spot[i].y*ht; const float xc = p->spot[i].xc*wd, yc = p->spot[i].yc*ht; const float xr = (p->spot[i].x + d*dx)*wd, yr = (p->spot[i].y + d*dy)*ht; cairo_set_line_cap(cr,CAIRO_LINE_CAP_ROUND); if(i == g->selected || i == g->dragging) cairo_set_line_width(cr, 5.0/zoom_scale); else cairo_set_line_width(cr, 3.0/zoom_scale); cairo_set_source_rgba(cr, .3, .3, .3, .8); draw_overlay(cr, rad, x, y, xc, yc, xr, yr); if(i == g->selected || i == g->dragging) cairo_set_line_width(cr, 2.0/zoom_scale); else cairo_set_line_width(cr, 1.0/zoom_scale); cairo_set_source_rgba(cr, .8, .8, .8, .8); draw_overlay(cr, rad, x, y, xc, yc, xr, yr); } }
int button_released(struct dt_iop_module_t *self, double x, double y, int which, uint32_t state) { // end point, stop drag dt_iop_spots_params_t *p = (dt_iop_spots_params_t *)self->params; dt_iop_spots_gui_data_t *g = (dt_iop_spots_gui_data_t *)self->gui_data; if(which == 1 && g->dragging >= 0) { float pzx, pzy; dt_dev_get_pointer_zoom_pos(self->dev, x, y, &pzx, &pzy); pzx += 0.5f; pzy += 0.5f; const int i = g->dragging; if(g->hoover_c) { p->spot[i].xc = pzx; p->spot[i].yc = pzy; } else { p->spot[i].x = pzx; p->spot[i].y = pzy; } g->selected = -1; dt_dev_add_history_item(darktable.develop, self, TRUE); g->dragging = -1; char str[3]; snprintf(str,3,"%d",p->num_spots); gtk_label_set_text(g->label, str); return 1; } else if(which == 3 && g->selected >= 0) { // remove brush stroke const int i = --(p->num_spots); if(i > 0) memcpy(p->spot + g->selected, p->spot + i, sizeof(spot_t)); dt_dev_add_history_item(darktable.develop, self, TRUE); g->selected = -1; char str[3]; snprintf(str,3,"%d",p->num_spots); gtk_label_set_text(g->label, str); } return 0; }
int button_pressed(dt_iop_module_t *self, double x, double y, int which, int type, uint32_t state) { // set new point, select it, start drag if(self->off) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(self->off), 1); dt_iop_spots_params_t *p = (dt_iop_spots_params_t *)self->params; dt_iop_spots_gui_data_t *g = (dt_iop_spots_gui_data_t *)self->gui_data; if(which == 1) { if(g->selected < 0) { if(p->num_spots == 32) { dt_control_log(_("spot removal only supports up to 32 spots")); return 1; } float pzx, pzy; dt_dev_get_pointer_zoom_pos(self->dev, x, y, &pzx, &pzy); pzx += 0.5f; pzy += 0.5f; const int i = p->num_spots++; g->dragging = i; // on *wd|*ht scale, radius on *min(wd, ht). p->spot[i].x = p->spot[i].xc = pzx; p->spot[i].y = p->spot[i].yc = pzy; p->spot[i].radius = 0.01f; g->selected = i; g->hoover_c = TRUE; } else { g->dragging = g->selected; } return 1; } return 0; }
int button_pressed(dt_view_t *self, double x, double y, int which, int type, uint32_t state) { const int32_t capwd = darktable.thumbnail_width; const int32_t capht = darktable.thumbnail_height; dt_develop_t *dev = (dt_develop_t *)self->data; const int32_t width_i = self->width; const int32_t height_i = self->height; if(width_i > capwd) x += (capwd-width_i) *.5f; if(height_i > capht) y += (capht-height_i)*.5f; int handled = 0; if(dev->gui_module && dev->gui_module->request_color_pick && which == 1) { float zoom_x, zoom_y; dt_dev_get_pointer_zoom_pos(dev, x, y, &zoom_x, &zoom_y); if(darktable.lib->proxy.colorpicker.size) { dev->gui_module->color_picker_box[0] = .5f+zoom_x; dev->gui_module->color_picker_box[1] = .5f+zoom_y; dev->gui_module->color_picker_box[2] = .5f+zoom_x; dev->gui_module->color_picker_box[3] = .5f+zoom_y; } else { dev->gui_module->color_picker_point[0] = .5f+zoom_x; dev->gui_module->color_picker_point[1] = .5f+zoom_y; dev->preview_pipe->changed |= DT_DEV_PIPE_SYNCH; dt_dev_invalidate_all(dev); } dt_control_queue_redraw(); return 1; } if(dev->gui_module && dev->gui_module->button_pressed) handled = dev->gui_module->button_pressed(dev->gui_module, x, y, which, type, state); if(handled) return handled; if(which == 1 && type == GDK_2BUTTON_PRESS) return 0; if(which == 1) { dt_control_change_cursor(GDK_HAND1); return 1; } if(which == 2) { // zoom to 1:1 2:1 and back dt_dev_zoom_t zoom; int closeup, procw, proch; float zoom_x, zoom_y; DT_CTL_GET_GLOBAL(zoom, dev_zoom); DT_CTL_GET_GLOBAL(closeup, dev_closeup); DT_CTL_GET_GLOBAL(zoom_x, dev_zoom_x); DT_CTL_GET_GLOBAL(zoom_y, dev_zoom_y); dt_dev_get_processed_size(dev, &procw, &proch); const float scale = dt_dev_get_zoom_scale(dev, zoom, closeup ? 2 : 1, 0); zoom_x += (1.0/scale)*(x - .5f*dev->width )/procw; zoom_y += (1.0/scale)*(y - .5f*dev->height)/proch; if(zoom == DT_ZOOM_1) { if(!closeup) closeup = 1; else { zoom = DT_ZOOM_FIT; zoom_x = zoom_y = 0.0f; closeup = 0; } } else zoom = DT_ZOOM_1; dt_dev_check_zoom_bounds(dev, &zoom_x, &zoom_y, zoom, closeup, NULL, NULL); DT_CTL_SET_GLOBAL(dev_zoom, zoom); DT_CTL_SET_GLOBAL(dev_closeup, closeup); DT_CTL_SET_GLOBAL(dev_zoom_x, zoom_x); DT_CTL_SET_GLOBAL(dev_zoom_y, zoom_y); dt_dev_invalidate(dev); return 1; } return 0; }
void mouse_moved(dt_view_t *self, double x, double y, int which) { const int32_t capwd = darktable.thumbnail_width; const int32_t capht = darktable.thumbnail_height; dt_develop_t *dev = (dt_develop_t *)self->data; // if we are not hovering over a thumbnail in the filmstrip -> show metadata of opened image. int32_t mouse_over_id = -1; DT_CTL_GET_GLOBAL(mouse_over_id, lib_image_mouse_over_id); if(mouse_over_id == -1) { mouse_over_id = dev->image_storage.id; DT_CTL_SET_GLOBAL(lib_image_mouse_over_id, mouse_over_id); } dt_control_t *ctl = darktable.control; const int32_t width_i = self->width; const int32_t height_i = self->height; int32_t offx = 0.0f, offy = 0.0f; if(width_i > capwd) offx = (capwd-width_i) *.5f; if(height_i > capht) offy = (capht-height_i)*.5f; int handled = 0; x += offx; y += offy; if(dev->gui_module && dev->gui_module->request_color_pick && ctl->button_down && ctl->button_down_which == 1) { // module requested a color box float zoom_x, zoom_y, bzoom_x, bzoom_y; dt_dev_get_pointer_zoom_pos(dev, x, y, &zoom_x, &zoom_y); dt_dev_get_pointer_zoom_pos(dev, ctl->button_x + offx, ctl->button_y + offy, &bzoom_x, &bzoom_y); if(darktable.lib->proxy.colorpicker.size) { dev->gui_module->color_picker_box[0] = fmaxf(0.0, fminf(.5f+bzoom_x, .5f+zoom_x)); dev->gui_module->color_picker_box[1] = fmaxf(0.0, fminf(.5f+bzoom_y, .5f+zoom_y)); dev->gui_module->color_picker_box[2] = fminf(1.0, fmaxf(.5f+bzoom_x, .5f+zoom_x)); dev->gui_module->color_picker_box[3] = fminf(1.0, fmaxf(.5f+bzoom_y, .5f+zoom_y)); } else { dev->gui_module->color_picker_point[0] = .5f + zoom_x; dev->gui_module->color_picker_point[1] = .5f + zoom_y; } dev->preview_pipe->changed |= DT_DEV_PIPE_SYNCH; dt_dev_invalidate_all(dev); dt_control_queue_redraw(); return; } if(dev->gui_module && dev->gui_module->mouse_moved) handled = dev->gui_module->mouse_moved(dev->gui_module, x, y, which); if(handled) return; if(darktable.control->button_down && darktable.control->button_down_which == 1) { // depending on dev_zoom, adjust dev_zoom_x/y. dt_dev_zoom_t zoom; int closeup; DT_CTL_GET_GLOBAL(zoom, dev_zoom); DT_CTL_GET_GLOBAL(closeup, dev_closeup); int procw, proch; dt_dev_get_processed_size(dev, &procw, &proch); const float scale = dt_dev_get_zoom_scale(dev, zoom, closeup ? 2 : 1, 0); float old_zoom_x, old_zoom_y; DT_CTL_GET_GLOBAL(old_zoom_x, dev_zoom_x); DT_CTL_GET_GLOBAL(old_zoom_y, dev_zoom_y); float zx = old_zoom_x - (1.0/scale)*(x - ctl->button_x - offx)/procw; float zy = old_zoom_y - (1.0/scale)*(y - ctl->button_y - offy)/proch; dt_dev_check_zoom_bounds(dev, &zx, &zy, zoom, closeup, NULL, NULL); DT_CTL_SET_GLOBAL(dev_zoom_x, zx); DT_CTL_SET_GLOBAL(dev_zoom_y, zy); ctl->button_x = x - offx; ctl->button_y = y - offy; dt_dev_invalidate(dev); dt_control_queue_redraw(); } }