From 40fb1bce22c1deb2802cd63e5062c94b85a2fc99 Mon Sep 17 00:00:00 2001 From: "Carsten Haitzler (Rasterman)" Date: Fri, 3 Jan 2020 22:03:57 +0000 Subject: [PATCH] shot - add delay button in shot dialog to try again with a delay also adds an action you can bind with an explicitly provided delay time for customization in bindings if you always use the same timeout. @feature --- TODO | 1 - src/modules/shot/e_mod_delay.c | 98 ++++++++++++++++++++++++ src/modules/shot/e_mod_edit.c | 10 +-- src/modules/shot/e_mod_main.c | 125 +++++++++++++++++++++++++++++-- src/modules/shot/e_mod_main.h | 5 ++ src/modules/shot/e_mod_preview.c | 26 +++++-- src/modules/shot/e_mod_share.c | 1 - src/modules/shot/meson.build | 3 +- 8 files changed, 249 insertions(+), 20 deletions(-) create mode 100644 src/modules/shot/e_mod_delay.c diff --git a/TODO b/TODO index ce6e85324..980333257 100644 --- a/TODO +++ b/TODO @@ -151,7 +151,6 @@ TODO: * provide fuller status per line (reception and other info?) * massively flesh out connman vpn support in the gui * vpnmanager + create method support -* shot: add customizable timeout version of shot action * shot: create special save dir for shots (~/.e/...) and keep last N * shot: use efm and offer save dir to dnd from * bz5: add icon set for actions/states per bt device (pair.unpair, etc.) diff --git a/src/modules/shot/e_mod_delay.c b/src/modules/shot/e_mod_delay.c new file mode 100644 index 000000000..337d7aa42 --- /dev/null +++ b/src/modules/shot/e_mod_delay.c @@ -0,0 +1,98 @@ +#include "e_mod_main.h" + +static Evas_Object *delay_win = NULL; +static double delay = 5.0; + +static void +_cb_delay(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED) +{ + delay = elm_slider_value_get(obj); +} + +static void +_win_delete_cb(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *info EINA_UNUSED) +{ +// E_FREE_FUNC(delay_win, evas_object_del); + delay_win = NULL; +} + +static void +_cb_ok(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *info EINA_UNUSED) +{ + E_Action *a = e_action_find("shot_delay"); + E_FREE_FUNC(delay_win, evas_object_del); + if (a) + { + char buf[128]; + + snprintf(buf, sizeof(buf), "%i", (int)(delay * 1000.0)); + a->func.go(NULL, buf); + } +} + +static void +_cb_cancel(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *info EINA_UNUSED) +{ + E_FREE_FUNC(delay_win, evas_object_del); +} + +void +win_delay(void) +{ + Evas_Object *o, *o_bg, *o_bx, *o_sl; + + if (delay_win) return; + + delay_win = o = elm_win_add(NULL, NULL, ELM_WIN_DIALOG_BASIC); + elm_win_title_set(o, _("Select action to take with screenshot")); + evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _win_delete_cb, NULL); + ecore_evas_name_class_set(e_win_ee_get(o), "E", "_shot_dialog"); + + o_bg = o = elm_layout_add(delay_win); + evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_win_resize_object_add(delay_win, o); + e_theme_edje_object_set(o, "base/theme/dialog", "e/widgets/dialog/main"); + evas_object_show(o); + + o_sl = o = elm_slider_add(delay_win); + elm_slider_span_size_set(o, 240); + elm_object_text_set(o, _("Delay")); + elm_slider_indicator_show_set(o, EINA_FALSE); + elm_slider_unit_format_set(o, "%1.1f sec"); + elm_slider_min_max_set(o, 1, 60); + evas_object_size_hint_align_set(o, EVAS_HINT_FILL, 1.0); + evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_object_part_content_set(o_bg, "e.swallow.content", o); + evas_object_show(o); + evas_object_smart_callback_add(o, "delay,changed", _cb_delay, NULL); + + elm_slider_value_set(o_sl, delay); + + o_bx = o = elm_box_add(delay_win); + elm_box_horizontal_set(o, EINA_TRUE); + elm_box_homogeneous_set(o, EINA_TRUE); + elm_object_part_content_set(o_bg, "e.swallow.buttons", o); + evas_object_show(o); + + o = elm_button_add(delay_win); + evas_object_size_hint_align_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL); + elm_object_text_set(o, _("OK")); + elm_box_pack_end(o_bx, o); + evas_object_show(o); + evas_object_smart_callback_add(o, "clicked", _cb_ok, NULL); + + o = elm_button_add(delay_win); + evas_object_size_hint_align_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL); + elm_object_text_set(o, _("Cancel")); + elm_box_pack_end(o_bx, o); + evas_object_show(o); + evas_object_smart_callback_add(o, "clicked", _cb_cancel, NULL); + + evas_object_show(delay_win); +} + +void +delay_abort(void) +{ + E_FREE_FUNC(delay_win, evas_object_del); +} diff --git a/src/modules/shot/e_mod_edit.c b/src/modules/shot/e_mod_edit.c index f92c0a9f9..baa2c9273 100644 --- a/src/modules/shot/e_mod_edit.c +++ b/src/modules/shot/e_mod_edit.c @@ -2,7 +2,7 @@ ////////////////////////////////////////////////////////////////////////////// // globals -static Evas_Object *win, *o_img, *o_rend, *win2, *o_events, *o_scroll; +static Evas_Object *o_img, *o_rend, *win2, *o_events, *o_scroll; static Evas_Object *o_col1, *o_col2; static int img_w, img_h, edit_w, edit_h; @@ -1361,10 +1361,10 @@ try_win: if (point_in_area(x, y, crop_window_areas[i])) { crop_area = crop_window_areas[i]; - crop_area.x -= window_pad; - crop_area.y -= window_pad; - crop_area.w += window_pad * 2; - crop_area.h += window_pad * 2; + crop_area.x -= ELM_SCALE_SIZE(window_pad); + crop_area.y -= ELM_SCALE_SIZE(window_pad); + crop_area.w += ELM_SCALE_SIZE(window_pad) * 2; + crop_area.h += ELM_SCALE_SIZE(window_pad) * 2; E_RECTS_CLIP_TO_RECT(crop_area.x, crop_area.y, crop_area.w, crop_area.h, 0, 0, img_w, img_h); diff --git a/src/modules/shot/e_mod_main.c b/src/modules/shot/e_mod_main.c index a630a964d..3842d7947 100644 --- a/src/modules/shot/e_mod_main.c +++ b/src/modules/shot/e_mod_main.c @@ -12,16 +12,51 @@ E_Module *shot_module = NULL; -static E_Action *border_act = NULL, *act = NULL; +static E_Action *border_act = NULL, *delay_act = NULL, *act = NULL; static E_Int_Menu_Augmentation *maug = NULL; -static Ecore_Timer *timer, *border_timer = NULL; +static Ecore_Timer *timer = NULL, *border_timer = NULL; static Evas_Object *snap = NULL; static E_Client_Menu_Hook *border_hook = NULL; +static E_Object_Delfn *delfn_client = NULL; +static E_Object_Delfn *delfn_zone = NULL; static E_Client *shot_ec = NULL; static E_Zone *shot_zone = NULL; static char *shot_params; +static void +_cb_client_del(void *data EINA_UNUSED, void *obj EINA_UNUSED) +{ + if (delfn_client) + { + e_object_delfn_del(E_OBJECT(shot_ec), delfn_client); + delfn_client = NULL; + } + if (delfn_zone) + { + e_object_delfn_del(E_OBJECT(shot_zone), delfn_zone); + delfn_zone = NULL; + } + if (timer) + { + ecore_timer_del(timer); + timer = NULL; + } + if (border_timer) + { + ecore_timer_del(border_timer); + border_timer = NULL; + } + E_FREE_FUNC(snap, evas_object_del); + E_FREE(shot_params); +} + +static void +_cb_zone_del(void *data, void *obj) +{ + _cb_client_del(data, obj); +} + static void _shot_post(void *buffer EINA_UNUSED, Evas *e EINA_UNUSED, void *event EINA_UNUSED) { @@ -32,6 +67,16 @@ _shot_post(void *buffer EINA_UNUSED, Evas *e EINA_UNUSED, void *event EINA_UNUSE (void *)evas_object_image_data_get(snap, 0), x, y, w, h); E_FREE_FUNC(snap, evas_object_del); + if (delfn_client) + { + e_object_delfn_del(E_OBJECT(shot_ec), delfn_client); + delfn_client = NULL; + } + if (delfn_zone) + { + e_object_delfn_del(E_OBJECT(shot_zone), delfn_zone); + delfn_zone = NULL; + } shot_ec = NULL; shot_zone = NULL; E_FREE(shot_params); @@ -77,6 +122,16 @@ _shot_now(E_Zone *zone, E_Client *ec, const char *params) preview_dialog_show(zone, ec, params, (void *)ecore_evas_buffer_pixels_get(e_comp->ee), x, y, w, h); + if (delfn_client) + { + e_object_delfn_del(E_OBJECT(ec), delfn_client); + delfn_client = NULL; + } + if (delfn_zone) + { + e_object_delfn_del(E_OBJECT(zone), delfn_zone); + delfn_zone = NULL; + } return; } shot_ec = ec; @@ -99,7 +154,6 @@ _shot_delay(void *data) { timer = NULL; _shot_now(data, NULL, NULL); - return EINA_FALSE; } /* @@ -118,9 +172,8 @@ _shot_delay_border_padded(void *data) char buf[128]; border_timer = NULL; - snprintf(buf, sizeof(buf), "pad %i", (int)(64 * e_scale)); + snprintf(buf, sizeof(buf), "pad %i", (int)(ELM_SCALE_SIZE(64))); _shot_now(NULL, data, buf); - return EINA_FALSE; } /* @@ -136,6 +189,7 @@ _shot_border_padded(E_Client *ec) { if (border_timer) ecore_timer_del(border_timer); border_timer = ecore_timer_loop_add(1.0, _shot_delay_border_padded, ec); + delfn_client = e_object_delfn_add(E_OBJECT(ec), _cb_client_del, NULL); } static void @@ -143,6 +197,7 @@ _shot(E_Zone *zone) { if (timer) ecore_timer_del(timer); timer = ecore_timer_loop_add(1.0, _shot_delay, zone); + delfn_zone = e_object_delfn_add(E_OBJECT(zone), _cb_zone_del, NULL); } /* static void @@ -195,6 +250,40 @@ _delayed_shot(void *data) free(ds); } +static void +_delayed_shot_timer(void *data) +{ + timer = NULL; + _delayed_shot(data); + return EINA_FALSE; +} + +static void +_e_mod_action_delay_cb(E_Object *obj, const char *params) +{ + E_Zone *zone = NULL; + Delayed_Shot *ds; + double delay = 0.0; + + if (obj) + { + if (obj->type == E_COMP_TYPE) zone = e_zone_current_get(); + else if (obj->type == E_ZONE_TYPE) zone = ((void *)obj); + else zone = e_zone_current_get(); + } + if (!zone) zone = e_zone_current_get(); + if (!zone) return; + E_FREE_FUNC(timer, ecore_timer_del); + ds = E_NEW(Delayed_Shot, 1); + e_object_ref(E_OBJECT(zone)); + ds->zone = zone; + ds->params = params ? strdup(params) : NULL; + if (params) delay = (double)atoi(params) / 1000.0; + if (timer) ecore_timer_del(timer); + timer = ecore_timer_loop_add(delay, _delayed_shot_timer, ds); + delfn_zone = e_object_delfn_add(E_OBJECT(zone), _cb_zone_del, NULL); +} + static void _e_mod_action_cb(E_Object *obj, const char *params) { @@ -283,6 +372,14 @@ e_modapi_init(E_Module *m) "shot", NULL, "syntax: [share|save [perfect|high|medium|low|QUALITY current|all|SCREEN-NUM]", 1); } + delay_act = e_action_add("shot_delay"); + if (delay_act) + { + delay_act->func.go = _e_mod_action_delay_cb; + e_action_predef_name_set(N_("Screen"), N_("Take Screenshot with Delay"), + "shot_delay", NULL, + "syntax: delay_ms (e.g. 3000)", 1); + } border_act = e_action_add("border_shot"); if (border_act) { @@ -304,11 +401,29 @@ e_modapi_shutdown(E_Module *m EINA_UNUSED) share_abort(); save_abort(); preview_abort(); + delay_abort(); + if (delfn_client) + { + e_object_delfn_del(E_OBJECT(shot_ec), delfn_client); + delfn_client = NULL; + } + if (delfn_zone) + { + e_object_delfn_del(E_OBJECT(shot_zone), delfn_zone); + delfn_zone = NULL; + } if (timer) { ecore_timer_del(timer); timer = NULL; } + if (border_timer) + { + ecore_timer_del(border_timer); + border_timer = NULL; + } + E_FREE_FUNC(snap, evas_object_del); + E_FREE(shot_params); if (maug) { e_int_menus_menu_augmentation_del("main/2", maug); diff --git a/src/modules/shot/e_mod_main.h b/src/modules/shot/e_mod_main.h index e4c02ecc1..9158c6e60 100644 --- a/src/modules/shot/e_mod_main.h +++ b/src/modules/shot/e_mod_main.h @@ -33,5 +33,10 @@ Evas_Object *ui_edit(Evas_Object *window, Evas_Object *o_bg, E_Zone *zone, void ui_edit_prepare(void); void ui_edit_crop_screen_set(int x, int y, int w, int h); +void win_delay(void); +void delay_abort(void); + + +extern Evas_Object *win; extern int quality; extern Eina_Rectangle crop; diff --git a/src/modules/shot/e_mod_preview.c b/src/modules/shot/e_mod_preview.c index 66c94d796..37b65d32e 100644 --- a/src/modules/shot/e_mod_preview.c +++ b/src/modules/shot/e_mod_preview.c @@ -1,7 +1,8 @@ #include "e_mod_main.h" -static Evas_Object *win = NULL; static Evas_Object *o_img = NULL; + +Evas_Object *win = NULL; int quality = 90; Eina_Rectangle crop = { 0, 0, 0, 0 }; @@ -17,6 +18,13 @@ _win_share_cb(void *d EINA_UNUSED, void *d2 EINA_UNUSED) share_confirm(); } +static void +_win_delay_cb(void *d EINA_UNUSED, void *d2 EINA_UNUSED) +{ + E_FREE_FUNC(win, evas_object_del); + win_delay(); +} + static void _win_cancel_cb(void *data EINA_UNUSED, void *data2 EINA_UNUSED) { @@ -45,12 +53,11 @@ preview_dialog_show(E_Zone *zone, E_Client *ec, const char *params, void *dst, int w, h; char smode[128], squal[128], sscreen[128]; - win = elm_win_add(NULL, NULL, ELM_WIN_BASIC); - - evas = evas_object_evas_get(win); - elm_win_title_set(win, _("Select action to take with screenshot")); - evas_object_event_callback_add(win, EVAS_CALLBACK_DEL, _win_delete_cb, NULL); - ecore_evas_name_class_set(e_win_ee_get(win), "E", "_shot_dialog"); + win = o = elm_win_add(NULL, NULL, ELM_WIN_BASIC); + evas = evas_object_evas_get(o); + elm_win_title_set(o, _("Select action to take with screenshot")); + evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _win_delete_cb, NULL); + ecore_evas_name_class_set(e_win_ee_get(o), "E", "_shot_dialog"); o_bg = o = elm_layout_add(e_win_evas_win_get(evas)); evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); @@ -81,6 +88,11 @@ preview_dialog_show(E_Zone *zone, E_Client *ec, const char *params, void *dst, e_widget_list_object_append(o_box, o, 1, 0, 0.5); o = e_widget_button_add(evas, _("Share"), NULL, _win_share_cb, win, NULL); e_widget_list_object_append(o_box, o, 1, 0, 0.5); + if (!ec) + { + o = e_widget_button_add(evas, _("Delay"), NULL, _win_delay_cb, win, NULL); + e_widget_list_object_append(o_box, o, 1, 0, 0.5); + } o = e_widget_button_add(evas, _("Cancel"), NULL, _win_cancel_cb, win, NULL); e_widget_list_object_append(o_box, o, 1, 0, 0.5); diff --git a/src/modules/shot/e_mod_share.c b/src/modules/shot/e_mod_share.c index 2024f7fc9..c814ab94a 100644 --- a/src/modules/shot/e_mod_share.c +++ b/src/modules/shot/e_mod_share.c @@ -1,6 +1,5 @@ #include "e_mod_main.h" -static Evas_Object *win = NULL; static E_Confirm_Dialog *cd = NULL; static Ecore_Exe *img_write_exe = NULL; static Evas_Object *o_label = NULL; diff --git a/src/modules/shot/meson.build b/src/modules/shot/meson.build index b503ed0e3..fde7c1475 100644 --- a/src/modules/shot/meson.build +++ b/src/modules/shot/meson.build @@ -4,7 +4,8 @@ src = files( 'e_mod_preview.c', 'e_mod_edit.c', 'e_mod_save.c', - 'e_mod_share.c' + 'e_mod_share.c', + 'e_mod_delay.c' ) if get_option(m) == true