From f5bef8a0ed6beb23e81dec5be1a5ee240eb4687f Mon Sep 17 00:00:00 2001 From: Carsten Haitzler Date: Wed, 4 Jul 2012 14:44:43 +0000 Subject: [PATCH] incoming sexiness... links, file paths, email addresses found in text on mousover. highlight with a subtley animated underline and on click.. do something sensible. the inline handler is the sexiest of all. try local file pahts for now (full paths). as they work best. remote urls for video files SHOULd work if they have http:// etc. before them - no adjusting of loose ones. u may want to look at the helpers config panel. internal handling of remote urls for media doesnt download currently. still needs to be done. anyway. enjoy! SVN revision: 73288 --- data/themes/default.edc | 426 ++++++++++++++++++++++++++++++ data/themes/images/Makefile.am | 8 +- data/themes/images/lk_bottom.png | Bin 0 -> 257 bytes data/themes/images/lk_left.png | Bin 0 -> 364 bytes data/themes/images/lk_right.png | Bin 0 -> 338 bytes data/themes/images/pm_fill.png | Bin 0 -> 254 bytes data/themes/images/pm_overlay.png | Bin 0 -> 8673 bytes data/themes/images/pm_shadow.png | Bin 0 -> 4010 bytes src/bin/Makefile.am | 1 + src/bin/config.c | 24 ++ src/bin/config.h | 9 + src/bin/main.c | 44 ++- src/bin/media.c | 97 +++++-- src/bin/media.h | 11 +- src/bin/options.c | 10 + src/bin/options_helpers.c | 373 ++++++++++++++++++++++++++ src/bin/options_helpers.h | 1 + src/bin/termio.c | 387 +++++++++++++++++++++++++-- src/bin/termio.h | 3 +- 19 files changed, 1353 insertions(+), 41 deletions(-) create mode 100644 data/themes/images/lk_bottom.png create mode 100644 data/themes/images/lk_left.png create mode 100644 data/themes/images/lk_right.png create mode 100644 data/themes/images/pm_fill.png create mode 100644 data/themes/images/pm_overlay.png create mode 100644 data/themes/images/pm_shadow.png create mode 100644 src/bin/options_helpers.c create mode 100644 src/bin/options_helpers.h diff --git a/data/themes/default.edc b/data/themes/default.edc index 9221890f..c9d4c9a6 100644 --- a/data/themes/default.edc +++ b/data/themes/default.edc @@ -12,6 +12,9 @@ collections { image: "bg_led_base.png" COMP; image: "bg_led.png" COMP; image: "bg_led_strobe.png" COMP; + image: "pm_shadow.png" COMP; + image: "pm_overlay.png" COMP; + image: "pm_fill.png" COMP; } parts { // other signals sent not handled here @@ -320,6 +323,317 @@ collections { target: "bell_strobe"; } + //////////////////////////////////////////////////////////////////// + // popup media over the terminal (until dismissed) + part { name: "popmedia_clip"; type: RECT; + mouse_events: 1; + description { state: "default" 0.0; + fixed: 1 1; + visible: 0; + color: 255 255 255 0; + } + description { state: "visible" 0.0; + inherit: "default" 0.0; + visible: 1; + color: 255 255 255 255; + } + } + part { name: "popmedia_shadow"; + mouse_events: 0; + description { state: "default" 0.0; + fixed: 1 1; + rel1 { + to: "terminology.popmedia"; + } + rel2 { + to: "terminology.popmedia"; + } + image.normal: "pm_shadow.png"; + image.border: 64 64 64 64; + image.border_scale_by: 0.1; + fill.smooth: 0; + visible: 0; + } + description { state: "visible" 0.0; + inherit: "default" 0.0; + rel1.offset: -32 -32; + rel2.offset: 31 31; + image.border_scale_by: 1.0; + visible: 1; + } + } + part { name: "popmedia_fill"; + mouse_events: 0; + description { state: "default" 0.0; + fixed: 1 1; + rel1.to: "terminology.popmedia"; + rel2.to: "terminology.popmedia"; + image.normal: "pm_fill.png"; + fill { + size.relative: 0.0 0.0; + size.offset: 64 64; + } + } + } + part { name: "terminology.popmedia"; type: SWALLOW; + clip_to: "popmedia_clip"; + description { state: "default" 0.0; + fixed: 1 1; + rel1.relative: 0.5 0.5; + rel2.relative: 0.5 0.5; + visible: 0; + } + description { state: "image" 0.0; + inherit: "default" 0.0; + rel1.relative: 0.1 0.1; + rel2.relative: 0.9 0.9; + visible: 1; + } + description { state: "scale" 0.0; + inherit: "default" 0.0; + rel1.relative: 0.1 0.1; + rel2.relative: 0.9 0.9; + visible: 1; + } + description { state: "edje" 0.0; + inherit: "default" 0.0; + rel1.relative: 0.1 0.1; + rel2.relative: 0.9 0.9; + visible: 1; + } + description { state: "movie" 0.0; + inherit: "default" 0.0; + rel1.relative: 0.1 0.1; + rel2.relative: 0.9 0.9; + visible: 1; + } + } + part { name: "popmedia_overlay"; + mouse_events: 0; + description { state: "default" 0.0; + fixed: 1 1; + rel1.to: "terminology.popmedia"; + rel2.to: "terminology.popmedia"; + image.normal: "pm_overlay.png"; + fill.smooth: 0; + visible: 0; + } + description { state: "visible" 0.0; + inherit: "default" 0.0; + visible: 1; + } + } + part { name: "popmedia_bevel"; + mouse_events: 0; + description { state: "default" 0.0; + fixed: 1 1; + rel1.to: "terminology.popmedia"; + rel2.to: "terminology.popmedia"; + image.normal: "bg_bevel.png"; + image.border: 3 3 5 3; + image.middle: 0; + fill.smooth: 0; + visible: 0; + } + description { state: "visible" 0.0; + inherit: "default" 0.0; + visible: 1; + } + } + part { name: "popmedia_glintclip"; type: RECT; + mouse_events: 0; + description { state: "default" 0.0; + fixed: 1 1; + visible: 0; + } + description { state: "visible" 0.0; + inherit: "default" 0.0; + visible: 1; + } + } + part { name: "popmedia_glint"; + mouse_events: 0; + clip_to: "popmedia_glintclip"; + description { state: "default" 0.0; + fixed: 1 1; + min: 79 5; + max: 79 5; + rel1 { + to: "terminology.popmedia"; + relative: 0.0 0.0; + offset: 0 0; + } + rel2 { + to: "terminology.popmedia"; + relative: 1.0 0.0; + offset: -1 0; + } + image.normal: "bg_glint.png"; + visible: 0; + } + description { state: "visible" 0.0; + inherit: "default" 0.0; + visible: 1; + } + } + part { name: "popmedia_shine"; + mouse_events: 0; + description { state: "default" 0.0; + fixed: 1 1; + rel1.to: "terminology.popmedia"; + rel2.to: "terminology.popmedia"; + image.normal: "bg_shine.png"; + fill.smooth: 0; + align: 0.5 0.0; + aspect: (255/120) (255/120); + aspect_preference: HORIZONTAL; + visible: 0; + } + description { state: "visible" 0.0; + inherit: "default" 0.0; + visible: 1; + } + } + part { name: "popmedia_dismiss"; type: RECT; + mouse_events: 1; + description { state: "default" 0.0; + fixed: 1 1; + color: 0 0 0 0; + visible: 0; + rel1.to: "terminology.popmedia"; + rel2.to: "terminology.popmedia"; + } + description { state: "visible" 0.0; + inherit: "default" 0.0; + visible: 1; + } + } + program { name: "popmedia_dismiss"; + signal: "mouse,clicked,*"; + source: "popmedia_dismiss"; + action: STATE_SET "default" 0.0; + transition: DECELERATE 0.5; + target: "terminology.popmedia"; + target: "popmedia_clip"; + target: "popmedia_dismiss"; + target: "popmedia_shadow"; + target: "popmedia_fill"; + target: "popmedia_overlay"; + target: "popmedia_bevel"; + target: "popmedia_glint"; + target: "popmedia_glintclip"; + target: "popmedia_shine"; + after: "popmedia_dismiss2"; + } + program { name: "popmedia_dismiss2"; + action: SIGNAL_EMIT "popmedia,done" "terminology"; + } + program { name: "popmedia_off"; + signal: "popmedia,off"; + source: "terminology"; + action: STATE_SET "default" 0.0; + transition: DECELERATE 0.2; + target: "terminology.popmedia"; + target: "popmedia_clip"; + target: "popmedia_dismiss"; + target: "popmedia_shadow"; + target: "popmedia_fill"; + target: "popmedia_overlay"; + target: "popmedia_bevel"; + target: "popmedia_glint"; + target: "popmedia_glintclip"; + target: "popmedia_shine"; + after: "popmedia_dismiss2"; + } + program { name: "popmedia_img"; + signal: "popmedia,image"; + source: "terminology"; + action: STATE_SET "image" 0.0; + transition: DECELERATE 0.2; + target: "terminology.popmedia"; + } + program { name: "popmedia_scale"; + signal: "popmedia,scale"; + source: "terminology"; + action: STATE_SET "scale" 0.0; + transition: DECELERATE 0.2; + target: "terminology.popmedia"; + } + program { name: "popmedia_edje"; + signal: "popmedia,edje"; + source: "terminology"; + action: STATE_SET "edje" 0.0; + transition: DECELERATE 0.2; + target: "terminology.popmedia"; + } + program { name: "popmedia_mov"; + signal: "popmedia,movie"; + source: "terminology"; + action: STATE_SET "movie" 0.0; + transition: DECELERATE 0.2; + target: "terminology.popmedia"; + } + program { name: "popmedia_img2"; + signal: "popmedia,image"; + source: "terminology"; + action: STATE_SET "visible" 0.0; + transition: DECELERATE 0.2; + target: "popmedia_clip"; + target: "popmedia_dismiss"; + target: "popmedia_shadow"; + target: "popmedia_fill"; + target: "popmedia_overlay"; + target: "popmedia_bevel"; + target: "popmedia_glint"; + target: "popmedia_glintclip"; + target: "popmedia_shine"; + } + program { name: "popmedia_scale2"; + signal: "popmedia,scale"; + source: "terminology"; + action: STATE_SET "visible" 0.0; + transition: DECELERATE 0.2; + target: "popmedia_clip"; + target: "popmedia_dismiss"; + target: "popmedia_shadow"; + target: "popmedia_fill"; + target: "popmedia_overlay"; + target: "popmedia_bevel"; + target: "popmedia_glint"; + target: "popmedia_glintclip"; + target: "popmedia_shine"; + } + program { name: "popmedia_edje2"; + signal: "popmedia,edje"; + source: "terminology"; + action: STATE_SET "visible" 0.0; + transition: DECELERATE 0.2; + target: "popmedia_clip"; + target: "popmedia_dismiss"; + target: "popmedia_shadow"; + target: "popmedia_fill"; + target: "popmedia_overlay"; + target: "popmedia_bevel"; + target: "popmedia_glint"; + target: "popmedia_glintclip"; + target: "popmedia_shine"; + } + program { name: "popmedia_mov2"; + signal: "popmedia,movie"; + source: "terminology"; + action: STATE_SET "visible" 0.0; + transition: DECELERATE 0.2; + target: "popmedia_clip"; + target: "popmedia_dismiss"; + target: "popmedia_shadow"; + target: "popmedia_fill"; + target: "popmedia_overlay"; + target: "popmedia_bevel"; + target: "popmedia_glint"; + target: "popmedia_glintclip"; + target: "popmedia_shine"; + } + //////////////////////////////////////////////////////////////////// // overlayed options and controls part { name: "terminology.about"; type: SWALLOW; @@ -630,6 +944,118 @@ collections { } } +////////////////////////////////////////////////////////////////////////////// + //// an object overlayd on text that is a link + group { name: "terminology/link"; + images { + image: "lk_bottom.png" COMP; + image: "lk_left.png" COMP; + image: "lk_right.png" COMP; + } + parts { + part { name: "bottom"; + mouse_events: 0; + description { state: "default" 0.0; + image.normal: "lk_bottom.png"; + image.border: 9 9 0 0; + align: 0.5 1.0; + min: 20 8; + rel1.offset: -6 0; + rel1.relative: 0.0 1.0; + rel2.offset: 5 0; + color: 100 200 255 255; + fill.smooth: 0; + } + } + part { name: "l"; + mouse_events: 0; + description { state: "default" 0.0; + image.normal: "lk_left.png"; + align: 0.0 1.0; + min: 4 4; + rel1.offset: 16 -1; + rel1.relative: 0.0 1.0; + rel2.offset: 16 -1; + rel2.relative: 0.0 1.0; + color: 100 200 255 0; + } + description { state: "out" 0.0; + inherit: "default" 0.0; + min: 16 16; + rel1.offset: -10 -1; + rel2.offset: -10 -1; + color: 180 220 255 255; + } + description { state: "out2" 0.0; + inherit: "default" 0.0; + min: 32 32; + rel1.offset: -26 -1; + rel2.offset: -26 -1; + color: 100 200 255 0; + } + } + part { name: "r"; + mouse_events: 0; + description { state: "default" 0.0; + image.normal: "lk_right.png"; + align: 1.0 1.0; + min: 4 4; + rel1.offset: -15 0; + rel1.relative: 1.0 1.0; + rel2.offset: -15 0; + rel2.relative: 1.0 1.0; + color: 100 200 255 0; + } + description { state: "out" 0.0; + inherit: "default" 0.0; + min: 16 16; + rel1.offset: 9 -1; + rel2.offset: 9 -1; + color: 180 220 255 255; + } + description { state: "out2" 0.0; + inherit: "default" 0.0; + min: 32 32; + rel1.offset: 25 -1; + rel2.offset: 25 -1; + color: 100 200 255 0; + } + } + part { name: "event"; type: RECT; + mouse_events: 1; + repeat_events: 1; + description { state: "default" 0.0; + color: 0 0 0 0; + } + } + programs { + program { name: "show"; + signal: "show"; + source: ""; + action: STATE_SET "out" 0.0; + transition: LINEAR 0.3; + target: "l"; + target: "r"; + after: "show2"; + } + program { name: "show2"; + action: STATE_SET "default" 0.0; + action: STATE_SET "out2" 0.0; + transition: LINEAR 0.3; + target: "l"; + target: "r"; + after: "show3"; + } + program { name: "show3"; + action: STATE_SET "default" 0.0; + target: "l"; + target: "r"; + after: "show"; + } + } + } + } + ////////////////////////////////////////////////////////////////////////////// //// the multimedia controls group { name: "terminology/mediactrl"; diff --git a/data/themes/images/Makefile.am b/data/themes/images/Makefile.am index 86d3d0f1..4491429d 100644 --- a/data/themes/images/Makefile.am +++ b/data/themes/images/Makefile.am @@ -21,4 +21,10 @@ media_pause.png \ media_play.png \ media_stop.png \ media_knob_pos.png \ -media_knob_vol.png +media_knob_vol.png \ +pm_fill.png \ +pm_overlay.png \ +pm_shadow.png \ +lk_bottom.png \ +lk_left.png \ +lk_right.png diff --git a/data/themes/images/lk_bottom.png b/data/themes/images/lk_bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..7b7007de0ae26cc38ea9cc1e30fe8f09382f7a7c GIT binary patch literal 257 zcmV+c0sj7pP)Px#yGcYrR5;7E(#=W(Q49s(FVj(5H-duT-uLrad?_DB{Glr=Gre(>TZV3(1`dJb zl9O|80x~nO#3ds;A|j*62aMPh;)3MI!i+XnW56|bg{zg_=&C3D6xwouzQhg>xWl$; zYed5Vdwk-zH^#+-xwgE;6YdvI{8#;iugV|Yei$PnGqau9GvgUAD>?9rx5fMkEh6%y zE;9$*l=8>=hBY17;~n2PL_~8wJTo^%x~;tC4NP?hC-v|L4U|XC{2PJ&00000NkvXX Hu0mjfSw3sd literal 0 HcmV?d00001 diff --git a/data/themes/images/lk_left.png b/data/themes/images/lk_left.png new file mode 100644 index 0000000000000000000000000000000000000000..3db09dcd55aeb6412b2125190d72178165b3a8dd GIT binary patch literal 364 zcmV-y0h9iTP)Px$CP_p=R5;7U(#tMnQ544U-#$)4xx_$7bc_v%#}Mz~8H_zcKSe)|8400Pbef2W zyDD_mGFi$&y28j#c6PFMzW@5xh3`HEBBBferNoy25m8|zZy!DMKMSf;IDuA*@6nBj z-e({$fEH#@;Tl)CkBBG4Fi_pFU11tic`p*w8Rn)=@f|MH$#O${f-~Hvn-9Htaqy6$ z8f~oN2($Sf=YJ<6{xu=ZF^*sy^H{_hPO~R%{7y%=7`PeCzX6%V4=iCF2PxXe9{%7Q z9rQ}Go_CN1tY8B>DLBM7cGJyW{bs95iHPWB#=kk4pV-XIqZxb5eR-%qtmZ4^CPk5e zU)Vx7V|%E|{}!ZC&IIPNxs#dwEK9g7!`3t*Razg*F-JnWczOm)Ux>lcc88t-0000< KMNUMnLSTYw@teT_ literal 0 HcmV?d00001 diff --git a/data/themes/images/lk_right.png b/data/themes/images/lk_right.png new file mode 100644 index 0000000000000000000000000000000000000000..715bdc36ca3699ace9c64dd79c01e0026416abb6 GIT binary patch literal 338 zcmV-Y0j>UtP)Px$3`s;mR5;7U(Md`JK@`UEUnLz;QDc-K5h6|~IBYzQ$8qf$yoY!V1vl;-a6-i? zLSnmlEkRmIRu&XhoBubw$A6zRERg543ZK~@U2B*?6Rkdx6FlM-y{rVz!nJ{UEMO+yBi!NvAKwW| zTw7SiV#J=qAue!-cl1(9dG@30EZSJZYKX1i0B5+yTLFu>m6&h~>)6Cn2yS2>r?|vR zKU@f8F`y-EhkHBjUJUJ`4DL@*!%hrpEB?DU#yOtLU`TnMk6=0~G%*rxSGXzGRR$LV kMS{_Q6T0XWtNIOwFPG3=af?(8q5uE@07*qoM6N<$f{xLIRsaA1 literal 0 HcmV?d00001 diff --git a/data/themes/images/pm_fill.png b/data/themes/images/pm_fill.png new file mode 100644 index 0000000000000000000000000000000000000000..8ef098f1079934e4613aa1be1eb2bd3bbb5c2f0b GIT binary patch literal 254 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1SD0tpLGH$#^NA%Cx&(BWL^R}J3L(+Lo)8Y zy}FU}r~!}bMRiw!M~p!!|8H(;as9$=9_RSy_RQB_A0FJ0IDA*N_WpMpe;1EaXTH}) zf9c>bp8Vw9%$YMMsce0jw$1KZ;p^DY*k6V7p05gh`YtUjwD_E5dbiy7+U>Xh-dp_i y-F7+I^8Mc*?^;*3`~L2S415pBMhD_8J}_stxKF(LDsCFk4-B5JelF{r5}E)<$Z4zq literal 0 HcmV?d00001 diff --git a/data/themes/images/pm_overlay.png b/data/themes/images/pm_overlay.png new file mode 100644 index 0000000000000000000000000000000000000000..3c25c7302a1704550261564612497b0e1f297107 GIT binary patch literal 8673 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.bitmap = EINA_TRUE; config->font.name = eina_stringshare_add("nexus.pcf"); config->font.size = 10; + config->helper.email = eina_stringshare_add("xdg-email");; + config->helper.url.general = eina_stringshare_add("xdg-open"); + config->helper.url.video = eina_stringshare_add("xdg-open"); + config->helper.url.image = eina_stringshare_add("xdg-open"); + config->helper.local.general = eina_stringshare_add("xdg-open"); + config->helper.local.video = eina_stringshare_add("xdg-open"); + config->helper.local.image = eina_stringshare_add("xdg-open"); + config->helper.inline_please = EINA_TRUE; config->scrollback = 2000; config->theme = eina_stringshare_add("default.edj"); config->background = NULL; diff --git a/src/bin/config.h b/src/bin/config.h index e54f1f43..9bb2068c 100644 --- a/src/bin/config.h +++ b/src/bin/config.h @@ -12,6 +12,15 @@ struct _Config int size; unsigned char bitmap; } font; + struct { + const char *email; + struct { + const char *general; + const char *video; + const char *image; + } url, local; + Eina_Bool inline_please; + } helper; const char *theme; const char *background; const char *wordsep; diff --git a/src/bin/main.c b/src/bin/main.c index c7ce5dbd..92a79c97 100644 --- a/src/bin/main.c +++ b/src/bin/main.c @@ -13,6 +13,7 @@ int _log_domain = -1; static Evas_Object *win = NULL, *bg = NULL, *term = NULL, *media = NULL; +static Evas_Object *popmedia = NULL; static Evas_Object *conform = NULL; static Ecore_Timer *flush_timer = NULL; static Eina_Bool focused = EINA_FALSE; @@ -94,6 +95,43 @@ _cb_bell(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event __UNUSE } } +static void +_cb_popmedia_done(void *data __UNUSED__, Evas_Object *obj __UNUSED__, const char *sig __UNUSED__, const char *src __UNUSED__) +{ + if (popmedia) + { + evas_object_del(popmedia); + popmedia = NULL; + termio_mouseover_suspend_pushpop(term, -1); + } +} + +static void +_cb_popup(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event __UNUSED__) +{ + Evas_Object *o; + Config *config = termio_config_get(term); + const char *src; + int type = 0; + + if (!config) return; + src = termio_link_get(term); + if (!src) return; + if (popmedia) evas_object_del(popmedia); + if (!popmedia) termio_mouseover_suspend_pushpop(term, 1); + popmedia = o = media_add(win, src, config, MEDIA_POP, &type); + edje_object_part_swallow(bg, "terminology.popmedia", o); + evas_object_show(o); + if (type == TYPE_IMG) + edje_object_signal_emit(bg, "popmedia,image", "terminology"); + else if (type == TYPE_SCALE) + edje_object_signal_emit(bg, "popmedia,scale", "terminology"); + else if (type == TYPE_EDJE) + edje_object_signal_emit(bg, "popmedia,edje", "terminology"); + else if (type == TYPE_MOV) + edje_object_signal_emit(bg, "popmedia,movie", "terminology"); +} + void main_trans_update(const Config *config) { @@ -120,6 +158,7 @@ main_media_update(const Config *config) if (media) evas_object_del(media); o = media = media_add(win, config->background, config, MEDIA_BG, &type); edje_object_part_swallow(bg, "terminology.background", o); + evas_object_show(o); if (type == TYPE_IMG) edje_object_signal_emit(bg, "media,image", "terminology"); else if (type == TYPE_SCALE) @@ -128,7 +167,6 @@ main_media_update(const Config *config) edje_object_signal_emit(bg, "media,edje", "terminology"); else if (type == TYPE_MOV) edje_object_signal_emit(bg, "media,movie", "terminology"); - evas_object_show(o); } else { @@ -378,6 +416,9 @@ elm_main(int argc, char **argv) theme_auto_reload_enable(o); elm_object_content_set(conform, o); evas_object_show(o); + + edje_object_signal_callback_add(o, "popmedia,done", "terminology", + _cb_popmedia_done, NULL); if (pos_set) { @@ -399,6 +440,7 @@ elm_main(int argc, char **argv) evas_object_smart_callback_add(o, "change", _cb_change, NULL); evas_object_smart_callback_add(o, "exited", _cb_exited, NULL); evas_object_smart_callback_add(o, "bell", _cb_bell, NULL); + evas_object_smart_callback_add(o, "popup", _cb_popup, NULL); evas_object_show(o); main_trans_update(config); diff --git a/src/bin/media.c b/src/bin/media.c index d9e87500..30277dd1 100644 --- a/src/bin/media.c +++ b/src/bin/media.c @@ -143,13 +143,32 @@ _type_img_calc(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_ { int iw, ih; - iw = w; - ih = (sd->ih * w) / sd->iw; - if (ih < h) + if (sd->mode == MEDIA_BG) { - ih = h; - iw = (sd->iw * h) / sd->ih; - if (iw < w) iw = w; + iw = w; + ih = (sd->ih * w) / sd->iw; + if (ih < h) + { + ih = h; + iw = (sd->iw * h) / sd->ih; + if (iw < w) iw = w; + } + } + else if (sd->mode == MEDIA_POP) + { + iw = w; + ih = (sd->ih * w) / sd->iw; + if (ih > h) + { + ih = h; + iw = (sd->iw * h) / sd->ih; + if (iw > w) iw = w; + } + if ((iw > sd->iw) || (ih > sd->ih)) + { + iw = sd->iw; + ih = sd->ih; + } } x += ((w - iw) / 2); y += ((h - ih) / 2); @@ -208,13 +227,27 @@ _type_scale_calc(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Eva { int iw, ih; - iw = w; - ih = (sd->ih * w) / sd->iw; - if (ih < h) + if (sd->mode == MEDIA_BG) { - ih = h; - iw = (sd->iw * h) / sd->ih; - if (iw < w) iw = w; + iw = w; + ih = (sd->ih * w) / sd->iw; + if (ih < h) + { + ih = h; + iw = (sd->iw * h) / sd->ih; + if (iw < w) iw = w; + } + } + else if (sd->mode == MEDIA_POP) + { + iw = w; + ih = (sd->ih * w) / sd->iw; + if (ih > h) + { + ih = h; + iw = (sd->iw * h) / sd->ih; + if (iw > w) iw = w; + } } x += ((w - iw) / 2); y += ((h - ih) / 2); @@ -502,14 +535,28 @@ _type_mov_calc(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_ ratio = emotion_object_ratio_get(sd->o_img); if (ratio > 0.0) sd->iw = (sd->ih * ratio) + 0.5; else ratio = (double)sd->iw / (double)sd->ih; - - iw = w; - ih = w / ratio; - if (ih < h) + + if (sd->mode == MEDIA_BG) { - ih = h; - iw = h * ratio; - if (iw < w) iw = w; + iw = w; + ih = w / ratio; + if (ih < h) + { + ih = h; + iw = h * ratio; + if (iw < w) iw = w; + } + } + else if (sd->mode == MEDIA_POP) + { + iw = w; + ih = w / ratio; + if (ih > h) + { + ih = h; + iw = h * ratio; + if (iw > w) iw = w; + } } x += ((w - iw) / 2); y += ((h - ih) / 2); @@ -706,3 +753,15 @@ media_volume_set(Evas_Object *obj, double vol) emotion_object_audio_volume_set(sd->o_img, vol); edje_object_part_drag_value_set(sd->o_ctrl, "terminology.voldrag", vol, vol); } + +int +media_src_type_get(const char *src) +{ + int type = TYPE_UNKNOWN; + + if (_is_fmt(src, extn_img)) type = TYPE_IMG; + else if (_is_fmt(src, extn_scale)) type = TYPE_SCALE; + else if (_is_fmt(src, extn_edj)) type = TYPE_EDJE; + else if (_is_fmt(src, extn_mov)) type = TYPE_MOV; + return type; +} diff --git a/src/bin/media.h b/src/bin/media.h index 1aa8779a..8d99e93b 100644 --- a/src/bin/media.h +++ b/src/bin/media.h @@ -2,11 +2,13 @@ #define _MEDIA_H__ 1 #define MEDIA_BG 0 +#define MEDIA_POP 1 -#define TYPE_IMG 0 -#define TYPE_SCALE 1 -#define TYPE_EDJE 2 -#define TYPE_MOV 3 +#define TYPE_UNKNOWN -1 +#define TYPE_IMG 0 +#define TYPE_SCALE 1 +#define TYPE_EDJE 2 +#define TYPE_MOV 3 #include "config.h" @@ -16,5 +18,6 @@ void media_play_set(Evas_Object *obj, Eina_Bool play); void media_position_set(Evas_Object *obj, double pos); void media_volume_set(Evas_Object *obj, double vol); void media_stop(Evas_Object *obj); +int media_src_type_get(const char *src); #endif diff --git a/src/bin/options.c b/src/bin/options.c index 67332663..c58bdeca 100644 --- a/src/bin/options.c +++ b/src/bin/options.c @@ -3,6 +3,7 @@ #include #include "options.h" #include "options_font.h" +#include "options_helpers.h" #include "options_behavior.h" #include "options_video.h" #include "options_theme.h" @@ -55,6 +56,13 @@ _cb_op_behavior(void *data, Evas_Object *obj __UNUSED__, void *event __UNUSED__) options_behavior(op_opbox, data); } +static void +_cb_op_helpers(void *data, Evas_Object *obj __UNUSED__, void *event __UNUSED__) +{ + elm_box_clear(op_opbox); + options_helpers(op_opbox, data); +} + static void _cb_op_tmp_chg(void *data, Evas_Object *obj __UNUSED__, void *event __UNUSED__) { @@ -136,6 +144,8 @@ options_toggle(Evas_Object *win, Evas_Object *bg, Evas_Object *term) "Video", _cb_op_video, term); elm_toolbar_item_append(o, "system-run", "Behavior", _cb_op_behavior, term); + elm_toolbar_item_append(o, "document-open", + "Helpers", _cb_op_helpers, term); elm_box_pack_end(op_tbox, o); evas_object_show(o); diff --git a/src/bin/options_helpers.c b/src/bin/options_helpers.c new file mode 100644 index 00000000..7f300f5a --- /dev/null +++ b/src/bin/options_helpers.c @@ -0,0 +1,373 @@ +#include "private.h" + +#include +#include "config.h" +#include "termio.h" +#include "options.h" +#include "options_helpers.h" +#include "main.h" + +static void +_cb_op_helper_inline_chg(void *data, Evas_Object *obj, void *event __UNUSED__) +{ + Evas_Object *term = data; + Config *config = termio_config_get(term); + config->helper.inline_please = elm_check_state_get(obj); + config_save(config, NULL); +} + +static void +_cb_op_helper_email_chg(void *data, Evas_Object *obj, void *event __UNUSED__) +{ + Evas_Object *term = data; + Config *config = termio_config_get(term); + char *txt; + + if (config->helper.email) + { + eina_stringshare_del(config->helper.email); + config->helper.email = NULL; + } + txt = elm_entry_markup_to_utf8(elm_object_text_get(obj)); + if (txt) + { + config->helper.email = eina_stringshare_add(txt); + free(txt); + } + config_save(config, NULL); +} + +static void +_cb_op_helper_url_image_chg(void *data, Evas_Object *obj, void *event __UNUSED__) +{ + Evas_Object *term = data; + Config *config = termio_config_get(term); + char *txt; + + if (config->helper.url.image) + { + eina_stringshare_del(config->helper.url.image); + config->helper.email = NULL; + } + txt = elm_entry_markup_to_utf8(elm_object_text_get(obj)); + if (txt) + { + config->helper.url.image = eina_stringshare_add(txt); + free(txt); + } + config_save(config, NULL); +} + +static void +_cb_op_helper_url_video_chg(void *data, Evas_Object *obj, void *event __UNUSED__) +{ + Evas_Object *term = data; + Config *config = termio_config_get(term); + char *txt; + + if (config->helper.url.video) + { + eina_stringshare_del(config->helper.url.video); + config->helper.email = NULL; + } + txt = elm_entry_markup_to_utf8(elm_object_text_get(obj)); + if (txt) + { + config->helper.url.video = eina_stringshare_add(txt); + free(txt); + } + config_save(config, NULL); +} + +static void +_cb_op_helper_url_general_chg(void *data, Evas_Object *obj, void *event __UNUSED__) +{ + Evas_Object *term = data; + Config *config = termio_config_get(term); + char *txt; + + if (config->helper.url.general) + { + eina_stringshare_del(config->helper.url.general); + config->helper.email = NULL; + } + txt = elm_entry_markup_to_utf8(elm_object_text_get(obj)); + if (txt) + { + config->helper.url.general = eina_stringshare_add(txt); + free(txt); + } + config_save(config, NULL); +} + +static void +_cb_op_helper_local_image_chg(void *data, Evas_Object *obj, void *event __UNUSED__) +{ + Evas_Object *term = data; + Config *config = termio_config_get(term); + char *txt; + + if (config->helper.local.image) + { + eina_stringshare_del(config->helper.local.image); + config->helper.email = NULL; + } + txt = elm_entry_markup_to_utf8(elm_object_text_get(obj)); + if (txt) + { + config->helper.local.image = eina_stringshare_add(txt); + free(txt); + } + config_save(config, NULL); +} + +static void +_cb_op_helper_local_video_chg(void *data, Evas_Object *obj, void *event __UNUSED__) +{ + Evas_Object *term = data; + Config *config = termio_config_get(term); + char *txt; + + if (config->helper.local.video) + { + eina_stringshare_del(config->helper.local.video); + config->helper.email = NULL; + } + txt = elm_entry_markup_to_utf8(elm_object_text_get(obj)); + if (txt) + { + config->helper.local.video = eina_stringshare_add(txt); + free(txt); + } + config_save(config, NULL); +} + +static void +_cb_op_helper_local_general_chg(void *data, Evas_Object *obj, void *event __UNUSED__) +{ + Evas_Object *term = data; + Config *config = termio_config_get(term); + char *txt; + + if (config->helper.local.general) + { + eina_stringshare_del(config->helper.local.general); + config->helper.email = NULL; + } + txt = elm_entry_markup_to_utf8(elm_object_text_get(obj)); + if (txt) + { + config->helper.local.general = eina_stringshare_add(txt); + free(txt); + } + config_save(config, NULL); +} + +void +options_helpers(Evas_Object *opbox, Evas_Object *term) +{ + Config *config = termio_config_get(term); + Evas_Object *o, *bx, *sc; + char *txt; + + o = elm_check_add(opbox); + evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, 0.0); + evas_object_size_hint_align_set(o, EVAS_HINT_FILL, 0.5); + elm_object_text_set(o, "Inline if possible"); + elm_check_state_set(o, config->helper.inline_please); + elm_box_pack_end(opbox, o); + evas_object_show(o); + evas_object_smart_callback_add(o, "changed", + _cb_op_helper_inline_chg, term); + + o = elm_separator_add(opbox); + evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, 0.0); + evas_object_size_hint_align_set(o, EVAS_HINT_FILL, 0.5); + elm_separator_horizontal_set(o, EINA_TRUE); + elm_box_pack_end(opbox, o); + evas_object_show(o); + + sc = o = elm_scroller_add(opbox); + evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL); + elm_box_pack_end(opbox, o); + evas_object_show(o); + + bx = o = elm_box_add(opbox); + evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, 0.0); + evas_object_size_hint_align_set(o, EVAS_HINT_FILL, 0.0); + elm_object_content_set(sc, o); + evas_object_show(o); + + o = elm_label_add(bx); + evas_object_size_hint_weight_set(o, 0.0, 0.0); + evas_object_size_hint_align_set(o, 0.0, 0.5); + elm_object_text_set(o, "E-mail:"); + elm_box_pack_end(bx, o); + evas_object_show(o); + + o = elm_entry_add(bx); + evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, 0.0); + evas_object_size_hint_align_set(o, EVAS_HINT_FILL, 0.5); + elm_entry_single_line_set(o, EINA_TRUE); + elm_entry_scrollable_set(o, EINA_TRUE); + elm_entry_scrollbar_policy_set(o, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF); + txt = elm_entry_utf8_to_markup(config->helper.email); + if (txt) + { + elm_object_text_set(o, txt); + free(txt); + } + elm_box_pack_end(bx, o); + evas_object_show(o); + evas_object_smart_callback_add(o, "changed", + _cb_op_helper_email_chg, term); + + o = elm_label_add(bx); + evas_object_size_hint_weight_set(o, 0.0, 0.0); + evas_object_size_hint_align_set(o, 0.0, 0.5); + elm_object_text_set(o, "URL (Images):"); + elm_box_pack_end(bx, o); + evas_object_show(o); + + o = elm_entry_add(bx); + evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, 0.0); + evas_object_size_hint_align_set(o, EVAS_HINT_FILL, 0.5); + elm_entry_single_line_set(o, EINA_TRUE); + elm_entry_scrollable_set(o, EINA_TRUE); + elm_entry_scrollbar_policy_set(o, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF); + txt = elm_entry_utf8_to_markup(config->helper.url.image); + if (txt) + { + elm_object_text_set(o, txt); + free(txt); + } + elm_box_pack_end(bx, o); + evas_object_show(o); + evas_object_smart_callback_add(o, "changed", + _cb_op_helper_url_image_chg, term); + + o = elm_label_add(bx); + evas_object_size_hint_weight_set(o, 0.0, 0.0); + evas_object_size_hint_align_set(o, 0.0, 0.5); + elm_object_text_set(o, "URL (Video):"); + elm_box_pack_end(bx, o); + evas_object_show(o); + + o = elm_entry_add(bx); + evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, 0.0); + evas_object_size_hint_align_set(o, EVAS_HINT_FILL, 0.5); + elm_entry_single_line_set(o, EINA_TRUE); + elm_entry_scrollable_set(o, EINA_TRUE); + elm_entry_scrollbar_policy_set(o, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF); + txt = elm_entry_utf8_to_markup(config->helper.url.video); + if (txt) + { + elm_object_text_set(o, txt); + free(txt); + } + elm_box_pack_end(bx, o); + evas_object_show(o); + evas_object_smart_callback_add(o, "changed", + _cb_op_helper_url_video_chg, term); + + o = elm_label_add(bx); + evas_object_size_hint_weight_set(o, 0.0, 0.0); + evas_object_size_hint_align_set(o, 0.0, 0.5); + elm_object_text_set(o, "URL (All):"); + elm_box_pack_end(bx, o); + evas_object_show(o); + + o = elm_entry_add(bx); + evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, 0.0); + evas_object_size_hint_align_set(o, EVAS_HINT_FILL, 0.5); + elm_entry_single_line_set(o, EINA_TRUE); + elm_entry_scrollable_set(o, EINA_TRUE); + elm_entry_scrollbar_policy_set(o, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF); + txt = elm_entry_utf8_to_markup(config->helper.url.general); + if (txt) + { + elm_object_text_set(o, txt); + free(txt); + } + elm_box_pack_end(bx, o); + evas_object_show(o); + evas_object_smart_callback_add(o, "changed", + _cb_op_helper_url_general_chg, term); + + o = elm_label_add(bx); + evas_object_size_hint_weight_set(o, 0.0, 0.0); + evas_object_size_hint_align_set(o, 0.0, 0.5); + elm_object_text_set(o, "Local (Images):"); + elm_box_pack_end(bx, o); + evas_object_show(o); + + o = elm_entry_add(bx); + evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, 0.0); + evas_object_size_hint_align_set(o, EVAS_HINT_FILL, 0.5); + elm_entry_single_line_set(o, EINA_TRUE); + elm_entry_scrollable_set(o, EINA_TRUE); + elm_entry_scrollbar_policy_set(o, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF); + txt = elm_entry_utf8_to_markup(config->helper.local.image); + if (txt) + { + elm_object_text_set(o, txt); + free(txt); + } + elm_box_pack_end(bx, o); + evas_object_show(o); + evas_object_smart_callback_add(o, "changed", + _cb_op_helper_local_image_chg, term); + + o = elm_label_add(bx); + evas_object_size_hint_weight_set(o, 0.0, 0.0); + evas_object_size_hint_align_set(o, 0.0, 0.5); + elm_object_text_set(o, "Local (Video):"); + elm_box_pack_end(bx, o); + evas_object_show(o); + + o = elm_entry_add(bx); + evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, 0.0); + evas_object_size_hint_align_set(o, EVAS_HINT_FILL, 0.5); + elm_entry_single_line_set(o, EINA_TRUE); + elm_entry_scrollable_set(o, EINA_TRUE); + elm_entry_scrollbar_policy_set(o, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF); + txt = elm_entry_utf8_to_markup(config->helper.local.video); + if (txt) + { + elm_object_text_set(o, txt); + free(txt); + } + elm_box_pack_end(bx, o); + evas_object_show(o); + evas_object_smart_callback_add(o, "changed", + _cb_op_helper_local_video_chg, term); + + o = elm_label_add(bx); + evas_object_size_hint_weight_set(o, 0.0, 0.0); + evas_object_size_hint_align_set(o, 0.0, 0.5); + elm_object_text_set(o, "Local (All):"); + elm_box_pack_end(bx, o); + evas_object_show(o); + + o = elm_entry_add(bx); + evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, 0.0); + evas_object_size_hint_align_set(o, EVAS_HINT_FILL, 0.5); + elm_entry_single_line_set(o, EINA_TRUE); + elm_entry_scrollable_set(o, EINA_TRUE); + elm_entry_scrollbar_policy_set(o, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF); + txt = elm_entry_utf8_to_markup(config->helper.local.general); + if (txt) + { + elm_object_text_set(o, txt); + free(txt); + } + elm_box_pack_end(bx, o); + evas_object_show(o); + evas_object_smart_callback_add(o, "changed", + _cb_op_helper_local_general_chg, term); + + evas_object_size_hint_weight_set(opbox, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(opbox, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_show(o); +} diff --git a/src/bin/options_helpers.h b/src/bin/options_helpers.h new file mode 100644 index 00000000..da422e47 --- /dev/null +++ b/src/bin/options_helpers.h @@ -0,0 +1 @@ +void options_helpers(Evas_Object *opbox, Evas_Object *term); diff --git a/src/bin/termio.c b/src/bin/termio.c index 3813b696..9bf7437c 100644 --- a/src/bin/termio.c +++ b/src/bin/termio.c @@ -10,6 +10,7 @@ #include "keyin.h" #include "config.h" #include "utils.h" +#include "media.h" typedef struct _Termio Termio; @@ -43,6 +44,12 @@ struct _Termio } sel1, sel2; Eina_Bool sel : 1; } backup; + struct { + char *string; + int x1, y1, x2, y2; + int suspend; + Eina_List *objs; + } link; int zoom_fontsize_start; int scroll; unsigned int last_keyup; @@ -51,6 +58,7 @@ struct _Termio Termpty *pty; Ecore_Animator *anim; Ecore_Timer *delayed_size_timer; + Ecore_Timer *link_do_timer; Ecore_Job *mouse_move_job; Evas_Object *win; Config *config; @@ -59,6 +67,7 @@ struct _Termio Eina_Bool have_sel : 1; Eina_Bool noreqsize : 1; Eina_Bool composing : 1; + Eina_Bool didclick : 1; }; static Evas_Smart *_smart = NULL; @@ -100,8 +109,8 @@ coord_forward(Termio *sd, int *x, int *y) return EINA_TRUE; } -static void -_smart_mouseover_apply(Evas_Object *obj) +static char * +_magic_string_find(Evas_Object *obj, int cx, int cy, int *x1r, int *y1r, int *x2r, int *y2r) { Termio *sd = evas_object_smart_data_get(obj); char *s; @@ -109,11 +118,11 @@ _smart_mouseover_apply(Evas_Object *obj) int x1, x2, y1, y2, len; Eina_Bool goback = EINA_TRUE, goforward = EINA_FALSE, extend = EINA_FALSE; - if (!sd) return; - x1 = sd->mouse.cx; - y1 = sd->mouse.cy; - x2 = sd->mouse.cx; - y2 = sd->mouse.cy; + if (!sd) return NULL; + x1 = cx; + y1 = cy; + x2 = cx; + y2 = cy; if (!coord_back(sd, &x1, &y1)) goback = EINA_FALSE; for (;;) { @@ -125,6 +134,7 @@ _smart_mouseover_apply(Evas_Object *obj) { if ((!strncasecmp(s, "http://", 7))|| (!strncasecmp(s, "https://", 8)) || + (!strncasecmp(s, "file://", 7)) || (!strncasecmp(s, "ftp://", 6))) { goback = EINA_FALSE; @@ -154,7 +164,8 @@ _smart_mouseover_apply(Evas_Object *obj) else if (s[0] == '\'') endmatch = '\''; else if (s[0] == '<') endmatch = '>'; if ((!strncasecmp((s + 1), "www.", 4)) || - (!strncasecmp((s + 1), "ftp.", 4))) + (!strncasecmp((s + 1), "ftp.", 4)) || + (!strncasecmp((s + 1), "/", 1))) { goback = EINA_FALSE; coord_forward(sd, &x1, &y1); @@ -164,6 +175,9 @@ _smart_mouseover_apply(Evas_Object *obj) goback = EINA_FALSE; coord_forward(sd, &x1, &y1); } + else if (s[0] == '=') + { + } else { free(s); @@ -178,7 +192,9 @@ _smart_mouseover_apply(Evas_Object *obj) if (len > 1) { if (((endmatch) && (s[len - 1] == endmatch)) || - ((!endmatch) && (isspace(s[len - 1])))) + ((!endmatch) && + ((isspace(s[len - 1])) || (s[len - 1] == '>')) + )) { goforward = EINA_FALSE; coord_back(sd, &x2, &y2); @@ -194,7 +210,7 @@ _smart_mouseover_apply(Evas_Object *obj) { if (!coord_back(sd, &x1, &y1)) goback = EINA_FALSE; } - else if (!extend) + if ((!extend) && (!goback)) { goforward = EINA_TRUE; extend = EINA_TRUE; @@ -222,21 +238,307 @@ _smart_mouseover_apply(Evas_Object *obj) } else break; } - if (!isspace(s[0])) + if ((!isspace(s[0])) && (len > 1)) { if ((strchr(s, '@')) || (!strncasecmp(s, "http://", 7))|| (!strncasecmp(s, "https://", 8)) || (!strncasecmp(s, "ftp://", 6)) || + (!strncasecmp(s, "file://", 7)) || (!strncasecmp(s, "www.", 4)) || - (!strncasecmp(s, "ftp.", 4))) + (!strncasecmp(s, "ftp.", 4)) || + (!strncasecmp(s, "/", 1)) + ) { - printf("FOUND: '%s' @ %i,%i -> %i,%i\n", s, x1, y1, x2, y2); - // XXX: record coords and url string + if (x1r) *x1r = x1; + if (y1r) *y1r = y1; + if (x2r) *x2r = x2; + if (y2r) *y2r = y2; + return s; } } free(s); } + return NULL; +} + +static void +_activate_link(Evas_Object *obj) +{ + Termio *sd = evas_object_smart_data_get(obj); + Config *config = termio_config_get(obj); + char buf[PATH_MAX], *s; + const char *path = NULL, *cmd = NULL; + Eina_Bool url = EINA_FALSE, email = EINA_FALSE, handled = EINA_FALSE; + int type; + + if (!sd) return; + if (!config) return; + if (!sd->link.string) return; + if ((!strncasecmp(sd->link.string, "http://", 7))|| + (!strncasecmp(sd->link.string, "https://", 8)) || + (!strncasecmp(sd->link.string, "ftp://", 6)) || + (!strncasecmp(sd->link.string, "www.", 4)) || + (!strncasecmp(sd->link.string, "ftp.", 4))) + { + url = EINA_TRUE; + } + else if ((!strncasecmp(sd->link.string, "file://", 7)) || + (!strncasecmp(sd->link.string, "/", 1))) + { + path = sd->link.string; + if (!strncasecmp(sd->link.string, "file://", 7)) path = path + 7; + } + else if (strchr(sd->link.string, '@')) + { + email = EINA_TRUE; + } + + s = eina_str_escape(sd->link.string); + if (!s) return; + if (email) + { + // run mail client + cmd = "xdg-email"; + + if ((config->helper.email) && + (config->helper.email[0])) + cmd = config->helper.email; + snprintf(buf, sizeof(buf), "%s %s", cmd, s); + } + else if (path) + { + // locally accessible file + cmd = "xdg-open"; + + type = media_src_type_get(sd->link.string); + if (config->helper.inline_please) + { + if ((type == TYPE_IMG) || + (type == TYPE_SCALE) || + (type == TYPE_EDJE)) + { + evas_object_smart_callback_call(obj, "popup", NULL); + handled = EINA_TRUE; + } + else if (type == TYPE_MOV) + { + evas_object_smart_callback_call(obj, "popup", NULL); + handled = EINA_TRUE; + } + } + if (!handled) + { + if ((type == TYPE_IMG) || + (type == TYPE_SCALE) || + (type == TYPE_EDJE)) + { + if ((config->helper.local.image) && + (config->helper.local.image[0])) + cmd = config->helper.local.image; + } + else if (type == TYPE_MOV) + { + if ((config->helper.local.video) && + (config->helper.local.video[0])) + cmd = config->helper.local.video; + } + else + { + if ((config->helper.local.general) && + (config->helper.local.general[0])) + cmd = config->helper.local.general; + } + snprintf(buf, sizeof(buf), "%s %s", cmd, s); + } + } + else if (url) + { + // remote file needs ecore-con-url + cmd = "xdg-open"; + + type = media_src_type_get(sd->link.string); + if (config->helper.inline_please) + { + if ((type == TYPE_IMG) || + (type == TYPE_SCALE) || + (type == TYPE_EDJE)) + { + // XXX: begin fetch of url, once done, show + evas_object_smart_callback_call(obj, "popup", NULL); + handled = EINA_TRUE; + } + else if (type == TYPE_MOV) + { + // XXX: if no http:// add + evas_object_smart_callback_call(obj, "popup", NULL); + handled = EINA_TRUE; + } + } + if (!handled) + { + if ((type == TYPE_IMG) || + (type == TYPE_SCALE) || + (type == TYPE_EDJE)) + { + if ((config->helper.url.image) && + (config->helper.url.image[0])) + cmd = config->helper.url.image; + } + else if (type == TYPE_MOV) + { + if ((config->helper.url.video) && + (config->helper.url.video[0])) + cmd = config->helper.url.video; + } + else + { + if ((config->helper.url.general) && + (config->helper.url.general[0])) + cmd = config->helper.url.general; + } + snprintf(buf, sizeof(buf), "%s %s", cmd, s); + } + } + else + { + free(s); + return; + } + free(s); + if (!handled) ecore_exe_run(buf, NULL); +} + +static Eina_Bool +_cb_link_up_delay(void *data) +{ + Termio *sd = evas_object_smart_data_get(data); + + if (!sd) return EINA_FALSE; + sd->link_do_timer = NULL; + if (!sd->didclick) _activate_link(data); + sd->didclick = EINA_FALSE; + return EINA_FALSE; +} + +static void +_cb_link_up(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event) +{ + Evas_Event_Mouse_Up *ev = event; + Termio *sd = evas_object_smart_data_get(data); + + if (!sd) return; + if (ev->button == 1) + { + if (sd->link_do_timer) ecore_timer_del(sd->link_do_timer); + sd->link_do_timer = ecore_timer_add(0.2, _cb_link_up_delay, data); + } +} + +static void +_update_link(Evas_Object *obj, Eina_Bool same_link, Eina_Bool same_geom) +{ + Termio *sd = evas_object_smart_data_get(obj); + + if (!sd) return; + + if (!same_link) + { + // check link and re-probe/fetch create popup preview + } + + if (!same_geom) + { + Evas_Coord ox, oy, ow, oh; + Evas_Object *o; + // fix up edje objects "underlining" the link + int y; + + evas_object_geometry_get(obj, &ox, &oy, &ow, &oh); + EINA_LIST_FREE(sd->link.objs, o) evas_object_del(o); + if ((sd->link.string) && (sd->link.suspend == 0)) + { + for (y = sd->link.y1; y <= sd->link.y2; y++) + { + o = edje_object_add(evas_object_evas_get(obj)); + evas_object_smart_member_add(o, obj); + theme_apply(o, sd->config, "terminology/link"); + + if (y == sd->link.y1) + { + evas_object_move(o, ox + (sd->link.x1 * sd->font.chw), + oy + (y * sd->font.chh)); + if (sd->link.y1 == sd->link.y2) + evas_object_resize(o, + ((sd->link.x2 - sd->link.x1 + 1) * sd->font.chw), + sd->font.chh); + else + evas_object_resize(o, + ((sd->grid.w - sd->link.x1) * sd->font.chw), + sd->font.chh); + } + else if (y == sd->link.y2) + { + evas_object_move(o, ox, oy + (y * sd->font.chh)); + evas_object_resize(o, + ((sd->link.x2 + 1) * sd->font.chw), + sd->font.chh); + } + else + { + evas_object_move(o, ox, oy + (y * sd->font.chh)); + evas_object_resize(o, (sd->grid.w * sd->font.chw), + sd->font.chh); + } + + sd->link.objs = eina_list_append(sd->link.objs, o); + evas_object_show(o); + evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_UP, + _cb_link_up, obj); + } + } + } +} + +static void +_smart_mouseover_apply(Evas_Object *obj) +{ + char *s; + int x1 = 0, y1 = 0, x2 = 0, y2 = 0; + Eina_Bool same_link = EINA_FALSE, same_geom = EINA_FALSE; + Termio *sd = evas_object_smart_data_get(obj); + + if (!sd) return; + + s = _magic_string_find(obj, sd->mouse.cx, sd->mouse.cy, + &x1, &y1, &x2, &y2); + if (!s) + { + if (sd->link.string) free(sd->link.string); + sd->link.string = NULL; + sd->link.x1 = -1; + sd->link.y1 = -1; + sd->link.x2 = -1; + sd->link.y2 = -1; + _update_link(obj, same_link, same_geom); + return; + } + + if ((sd->link.string) && (!strcmp(sd->link.string, s))) + same_link = EINA_TRUE; + if (sd->link.string) free(sd->link.string); + sd->link.string = s; + if ((x1 == sd->link.x1) && (y1 == sd->link.y1) && + (x2 == sd->link.x2) && (y2 == sd->link.y2)) + same_geom = EINA_TRUE; + if (((sd->link.suspend != 0) && (sd->link.objs)) || + ((sd->link.suspend == 0) && (!sd->link.objs))) + same_geom = EINA_FALSE; + sd->link.x1 = x1; + sd->link.y1 = y1; + sd->link.x2 = x2; + sd->link.y2 = y2; + _update_link(obj, same_link, same_geom); } static void @@ -1272,12 +1574,14 @@ _smart_cb_mouse_down(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__ if (!sd) return; _smart_xy_to_cursor(data, ev->canvas.x, ev->canvas.y, &cx, &cy); _rep_mouse_down(data, ev, cx, cy); + sd->didclick = EINA_FALSE; if (ev->button == 1) { if (ev->flags & EVAS_BUTTON_TRIPLE_CLICK) { _sel_line(data, cx, cy - sd->scroll); if (sd->cur.sel) _take_selection(data, ELM_SEL_TYPE_PRIMARY); + sd->didclick = EINA_TRUE; } else if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK) { @@ -1296,6 +1600,7 @@ _smart_cb_mouse_down(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__ _sel_word(data, cx, cy - sd->scroll); } if (sd->cur.sel) _take_selection(data, ELM_SEL_TYPE_PRIMARY); + sd->didclick = EINA_TRUE; } else { @@ -1304,7 +1609,11 @@ _smart_cb_mouse_down(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__ sd->backup.sel1.y = sd->cur.sel1.y; sd->backup.sel2.x = sd->cur.sel2.x; sd->backup.sel2.y = sd->cur.sel2.y; - if (sd->cur.sel) sd->cur.sel = 0; + if (sd->cur.sel) + { + sd->cur.sel = 0; + sd->didclick = EINA_TRUE; + } sd->cur.makesel = 1; sd->cur.sel1.x = cx; sd->cur.sel1.y = cy - sd->scroll; @@ -1336,6 +1645,7 @@ _smart_cb_mouse_up(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, sd->cur.makesel = 0; if (sd->cur.sel) { + sd->didclick = EINA_TRUE; sd->cur.sel2.x = cx; sd->cur.sel2.y = cy - sd->scroll; _selection_dbl_fix(data); @@ -1380,6 +1690,18 @@ _smart_cb_mouse_move(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__ } } +static void +_smart_cb_mouse_in(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event __UNUSED__) +{ + termio_mouseover_suspend_pushpop(data, -1); +} + +static void +_smart_cb_mouse_out(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event __UNUSED__) +{ + termio_mouseover_suspend_pushpop(data, 1); +} + static void _smart_cb_mouse_wheel(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event) { @@ -1468,6 +1790,7 @@ _smart_cb_gest_long_move(void *data, void *event __UNUSED__) if (!sd) return EVAS_EVENT_FLAG_ON_HOLD; evas_object_smart_callback_call(data, "options", NULL); + sd->didclick = EINA_TRUE; return EVAS_EVENT_FLAG_ON_HOLD; } @@ -1484,6 +1807,7 @@ _smart_cb_gest_zoom_start(void *data, void *event) sd->zoom_fontsize_start = config->font.size; _font_size_set(data, (double)sd->zoom_fontsize_start * p->zoom); } + sd->didclick = EINA_TRUE; return EVAS_EVENT_FLAG_ON_HOLD; } @@ -1500,6 +1824,7 @@ _smart_cb_gest_zoom_move(void *data, void *event) sd->zoom_fontsize_start = config->font.size; _font_size_set(data, (double)sd->zoom_fontsize_start * p->zoom); } + sd->didclick = EINA_TRUE; return EVAS_EVENT_FLAG_ON_HOLD; } @@ -1516,6 +1841,7 @@ _smart_cb_gest_zoom_end(void *data, void *event) sd->zoom_fontsize_start = config->font.size; _font_size_set(data, (double)sd->zoom_fontsize_start * p->zoom); } + sd->didclick = EINA_TRUE; return EVAS_EVENT_FLAG_ON_HOLD; } @@ -1532,6 +1858,7 @@ _smart_cb_gest_zoom_abort(void *data, void *event __UNUSED__) sd->zoom_fontsize_start = config->font.size; _font_size_set(data, sd->zoom_fontsize_start); } + sd->didclick = EINA_TRUE; return EVAS_EVENT_FLAG_ON_HOLD; } @@ -1631,6 +1958,10 @@ _smart_add(Evas_Object *obj) _smart_cb_mouse_up, obj); evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_MOVE, _smart_cb_mouse_move, obj); + evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_IN, + _smart_cb_mouse_in, obj); + evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_OUT, + _smart_cb_mouse_out, obj); evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_WHEEL, _smart_cb_mouse_wheel, obj); @@ -1643,6 +1974,8 @@ _smart_add(Evas_Object *obj) evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_OUT, _smart_cb_focus_out, obj); + sd->link.suspend = 1; + if (ecore_imf_init()) { const char *imf_id = ecore_imf_context_default_id_get(); @@ -1699,7 +2032,9 @@ static void _smart_del(Evas_Object *obj) { char *str; + Evas_Object *o; Termio *sd = evas_object_smart_data_get(obj); + if (!sd) return; if (sd->imf) { @@ -1714,9 +2049,12 @@ _smart_del(Evas_Object *obj) if (sd->cur.selo3) evas_object_del(sd->cur.selo3); if (sd->anim) ecore_animator_del(sd->anim); if (sd->delayed_size_timer) ecore_timer_del(sd->delayed_size_timer); + if (sd->link_do_timer) ecore_timer_del(sd->link_do_timer); if (sd->mouse_move_job) ecore_job_del(sd->mouse_move_job); if (sd->font.name) eina_stringshare_del(sd->font.name); if (sd->pty) termpty_free(sd->pty); + if (sd->link.string) free(sd->link.string); + EINA_LIST_FREE(sd->link.objs, o) evas_object_del(o); EINA_LIST_FREE(sd->seq, str) eina_stringshare_del(str); sd->cur.obj = NULL; sd->event = NULL; @@ -1993,6 +2331,7 @@ termio_selection_get(Evas_Object *obj, int c1x, int c1y, int c2x, int c2y) w = 0; last0 = -1; cells = termpty_cellrow_get(sd->pty, y, &w); + if (!cells) continue; if (w > sd->grid.w) w = sd->grid.w; start_x = c1x; end_x = c2x; @@ -2165,3 +2504,21 @@ termio_paste_clipboard(Evas_Object *obj) { _paste_selection(obj, ELM_SEL_TYPE_CLIPBOARD); } + +const char * +termio_link_get(const Evas_Object *obj) +{ + Termio *sd = evas_object_smart_data_get(obj); + EINA_SAFETY_ON_NULL_RETURN_VAL(sd, NULL); + return sd->link.string; +} + +void +termio_mouseover_suspend_pushpop(Evas_Object *obj, int dir) +{ + Termio *sd = evas_object_smart_data_get(obj); + if (!sd) return; + sd->link.suspend += dir; + if (sd->link.suspend < 0) sd->link.suspend = 0; + _smart_update_queue(obj, sd); +} diff --git a/src/bin/termio.h b/src/bin/termio.h index d7274681..108d5359 100644 --- a/src/bin/termio.h +++ b/src/bin/termio.h @@ -10,5 +10,6 @@ void termio_config_update(Evas_Object *obj); Config *termio_config_get(const Evas_Object *obj); void termio_copy_clipboard(Evas_Object *obj); void termio_paste_clipboard(Evas_Object *obj); - +const char *termio_link_get(const Evas_Object *obj); +void termio_mouseover_suspend_pushpop(Evas_Object *obj, int dir); #endif