commit 60b14b216c01474467fb328f49927be45f23aec5 Author: ChunEon Park Date: Sat Jul 20 17:51:56 2013 +0900 edje_writer -> enventor diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..5184fa5 --- /dev/null +++ b/Makefile @@ -0,0 +1,62 @@ +SRCDIR=src +HEADERDIR=include +EDJDIR=data/edc +OBJECTS=$(SRCDIR)/main.o \ + $(SRCDIR)/menu.o \ + $(SRCDIR)/edc_viewer.o \ + $(SRCDIR)/edc_editor.o \ + $(SRCDIR)/statusbar.o \ + $(SRCDIR)/syntax_color.o \ + $(SRCDIR)/config_data.o \ + $(SRCDIR)/edc_parser.o \ + $(SRCDIR)/panes.o \ + $(SRCDIR)/fake_obj.o +EDJS=$(EDJDIR)/enventor.edj +BINARY=enventor +DIRNAME=enventor + +PREFIX=/usr/local +BINDIR=$(PREFIX)/bin +DATADIR=$(PREFIX)/share/enventor +PROTODIR=/tmp + +CC = gcc + +CFLAGS = `pkg-config --cflags elementary evas eina eio` +CFLAGS += -g -W -Wextra -Wall +LDFLAGS = `pkg-config --libs elementary evas eina eio` + +EDJE_CC = edje_cc +EDJE_FLAGS = -id data/edc/images + +all: $(OBJECTS) $(BINARY) $(EDJS) + +%.o : %.c + @echo " Compilation of $(@D)/$( 0) cancel_timer(v); + v = timer(1.0, "timer0", 0); + set_int(sbvis_timer, v); + } + } + + program { name: "highlight_show"; + signal: "elm,action,focus_highlight,show"; + source: "elm"; + action: STATE_SET "enabled" 0.0; + transition: ACCELERATE 0.3; + target: "focus_highlight"; + target: "conf_over"; + } + program { name: "highlight_hide"; + signal: "elm,action,focus_highlight,hide"; + source: "elm"; + action: STATE_SET "default" 0.0; + transition: DECELERATE 0.3; + target: "focus_highlight"; + target: "conf_over"; + } + } +} +*/ +group { name: "elm/entry/base/enventor"; + parts { + part { name: "elm.text"; + type: TEXTBLOCK; + mouse_events: 1; + scale: 1; + entry_mode: EDITABLE; + select_mode: EXPLICIT; + multiline: 1; + source: "elm/entry/selection/enventor"; // selection under + source4: "elm/entry/cursor/enventor"; // cursorover + source5: "elm/entry/anchor/enventor"; // anchor under + description { state: "default" 0.0; + /* we gotta use 0 0 here, because of scrolled entries */ + fixed: 0 0; + align: 0 0; + text { + style: "entry_edit_style"; + min: 0 1; + align: 0.0 0.0; + } + } + } + } + programs { + program { name: "focus"; + signal: "load"; + source: ""; + action: FOCUS_SET; + target: "elm.text"; + } + } +} + +group { name: "elm/entry/base-nowrap-noedit/enventor"; + inherit: "elm/entry/base/enventor"; + parts { + part { name: "elm.text"; + entry_mode: PLAIN; + description { state: "default" 0.0; + align: 0 0; + text { + style: "entry_edit_style"; + min: 1 1; + align: 0.0 0.0; + } + } + } + } +} + +group { name: "elm/entry/base-nowrap/enventor"; + inherit: "elm/entry/base/enventor"; + parts { + part { name: "elm.text"; + select_mode: EXPLICIT; + description { state: "default" 0.0; + align: 0 0; + text { + style: "entry_edit_style"; + min: 1 1; + align: 0.0 0.0; + } + } + } + } +} + +group { name: "elm/entry/base-nowrap-noedit/linenumber"; + inherit: "elm/entry/base/enventor"; + parts { + part { name: "elm.text"; + entry_mode: PLAIN; + description { state: "default" 0.0; + align: 0 0; + text { + style: "entry_linenumber_style"; + min: 1 1; + align: 0.0 0.0; + } + } + } + } +} + +group { name: "elm/entry/base-single/enventor"; + inherit: "elm/entry/base/enventor"; + parts { + part { name: "elm.text"; + multiline: 0; + description { state: "default" 0.0; + align: 0.0 0.5; + text { + style: "entry_single_textblock_style"; + min: 1 1; + max: 0 0; + align: 0.0 0.5; + } + } + description { state: "disabled" 0.0; + inherit: "default" 0.0; + text { + style: "entry_single_textblock_disabled_style"; + } + } + } + } +} + +group { name: "elm/entry/cursor/enventor"; + images { + image: "cur_box.png" COMP; + image: "cur_hi.png" COMP; + image: "cur_shad.png" COMP; + image: "cur_shine.png" COMP; + image: "cur_glow.png" COMP; + } + parts { + part { name: "clip2"; + type: RECT; + mouse_events: 0; + description { state: "default" 0.0; + rel1.to: "clip"; + rel2.to: "clip"; + visible: 0; + } + description { state: "focused" 0.0; + inherit: "default" 0.0; + visible: 1; + } + } + part { name: "clip"; + type: RECT; + mouse_events: 0; + clip_to: "clip2"; + description { state: "default" 0.0; + rel1.offset: -10 0; + rel2.offset: 9 9; + visible: 0; + } + description { state: "visible" 0.0; + inherit: "default" 0.0; + visible: 1; + } + } + part { name: "bg"; + mouse_events: 0; + clip_to: "clip"; + description { state: "default" 0.0; + rel1.to: "base"; + rel1.offset: -2 0; + rel2.to: "base"; + rel2.offset: 1 1; + image.border: 2 2 2 2; + image.border_scale: 1; + image.normal: "cur_shad.png"; + } + } + part { name: "base"; + mouse_events: 0; + scale: 1; + clip_to: "clip"; + description { state: "default" 0.0; + min: 2 2; + align: 0.5 1.0; + rel1.relative: 0.0 1.0; + rel1.offset: 0 -1; + rel2.relative: 1.0 1.0; + rel2.offset: -1 -1; + image.normal: "cur_box.png"; + } + } + part { name: "hi"; + mouse_events: 0; + clip_to: "clip"; + description { state: "default" 0.0; + rel1.to: "base"; + rel2.to: "base"; + rel2.relative: 1.0 0.5; + image.normal: "cur_hi.png"; + } + } + part { name: "shine"; + mouse_events: 0; + clip_to: "clip"; + clip_to: "clip2"; + description { state: "default" 0.0; + rel1.to: "base"; + rel2.to: "base"; + rel2.relative: 1.0 0.75; + image.border: 2 2 1 0; + image.border_scale: 1; + image.normal: "cur_shine.png"; + fill.smooth: 0; + } + } + part { name: "glow"; + mouse_events: 0; + clip_to: "clip2"; + description { state: "default" 0.0; + rel1.to: "base"; + rel1.relative: 0.0 -2.0; + rel1.offset: -2 0; + rel2.to: "base"; + rel2.relative: 1.0 0.0; + rel2.offset: 1 1; + image.border: 2 2 0 4; + image.border_scale: 1; + image.normal: "cur_glow.png"; + fill.smooth: 0; + color: 255 255 255 0; + visible: 0; + } + description { state: "visible" 0.0; + inherit: "default" 0.0; + color: 255 255 255 55; + visible: 1; + } + } + } + programs { + program { name: "blink"; + action: STATE_SET "visible" 0.0; + in: 0.2 0.0; + target: "clip"; + after: "blink2"; + } + program { name: "blink2"; + action: STATE_SET "visible" 0.0; + in: 0.2 0.0; + target: "glow"; + after: "blink3"; + } + program { name: "blink3"; + action: STATE_SET "default" 0.0; + in: 0.2 0.0; + target: "glow"; + after: "blink4"; + } + program { name: "blink4"; + action: STATE_SET "default" 0.0; + in: 0.2 0.0; + target: "clip"; + after: "blink"; + } + program { name: "noblink"; + action: ACTION_STOP; + target: "blink"; + target: "blink2"; + target: "blink3"; + target: "blink4"; + after: "noblink2"; + } + program { name: "noblink2"; + action: STATE_SET "default" 0.0; + target: "clip"; + target: "glow"; + } + program { name: "focused"; + signal: "elm,action,focus"; + source: "elm"; + action: STATE_SET "focused" 0.0; + target: "clip2"; + after: "blink"; + } + program { name: "unfocused"; + signal: "elm,action,unfocus"; + source: "elm"; + action: STATE_SET "default" 0.0; + target: "clip2"; + after: "noblink"; + } + } +} + +group { name: "elm/entry/selection/enventor"; + parts { + part { name: "bg"; + type: RECT; + mouse_events: 0; + description { state: "default" 0.0; + color: 128 128 128 128; + } + } + } +} + +group { name: "elm/entry/anchor/enventor"; + parts { + part { name: "bg"; + type: RECT; + mouse_events: 0; + description { state: "default" 0.0; + color: 128 0 0 64; + } + } + } +} + +/* +group { name: "elm/entry/base-mixedwrap/enventor"; + inherit: "elm/entry/base/enventor"; + parts { + part { name: "elm.guide"; + type: TEXTBLOCK; + mouse_events: 0; + scale: 1; + description { state: "default" 0.0; + rel1.to: "elm.text"; + rel2.to: "elm.text"; + text { + style: "entry_textblock_guide_style_mixedwrap"; + min: 0 1; + align: 0.0 0.0; + } + } + description { state: "hidden" 0.0; + inherit: "default" 0.0; + visible: 0; + } + } + part { name: "elm.text"; + description { state: "default" 0.0; + fixed: 1 0; + text { + style: "entry_textblock_style_mixedwrap"; + min: 0 1; + align: 0.0 0.0; + } + } + description { state: "disabled" 0.0; + inherit: "default" 0.0; + text { + style: "entry_textblock_disabled_style_mixedwrap"; + min: 0 1; + } + } + } + } +} + +group { name: "elm/entry/base-charwrap/enventor"; + inherit: "elm/entry/base/enventor"; + parts { + part { name: "elm.guide"; + type: TEXTBLOCK; + mouse_events: 0; + scale: 1; + description { state: "default" 0.0; + rel1.to: "elm.text"; + rel2.to: "elm.text"; + text { + style: "entry_textblock_guide_style_charwrap"; + min: 0 1; + align: 0.0 0.0; + } + } + description { state: "hidden" 0.0; + inherit: "default" 0.0; + visible: 0; + } + } + part { name: "elm.text"; + description { state: "default" 0.0; + fixed: 1 0; + text { + style: "entry_textblock_style_charwrap"; + min: 0 1; + align: 0.0 0.0; + } + } + description { state: "disabled" 0.0; + inherit: "default" 0.0; + text { + style: "entry_textblock_disabled_style_charwrap"; + min: 0 1; + } + } + } + } +} + +group { name: "elm/entry/base-single/enventor"; + inherit: "elm/entry/base/enventor"; + parts { + part { name: "elm.guide"; + type: TEXTBLOCK; + mouse_events: 0; + scale: 1; + description { state: "default" 0.0; + rel1.to: "elm.text"; + rel2.to: "elm.text"; + text { + style: "entry_single_textblock_guide_style"; + min: 0 1; + align: 0.0 0.0; + } + } + description { state: "hidden" 0.0; + inherit: "default" 0.0; + visible: 0; + } + } + part { name: "elm.text"; + multiline: 0; + description { state: "default" 0.0; + text { + style: "entry_single_textblock_style"; + min: 1 1; + max: 0 0; + align: 0.0 0.5; + } + } + description { state: "disabled" 0.0; + inherit: "default" 0.0; + text { + style: "entry_single_textblock_disabled_style"; + } + } + } + } +} + +group { name: "elm/entry/base-single-noedit/enventor"; + inherit: "elm/entry/base/enventor"; + parts { + part { name: "elm.text"; + entry_mode: PLAIN; + multiline: 0; + source: "elm/entry/selection/enventor"; // selection under + source4: ""; // cursorover + source5: "elm/entry/anchor/enventor"; // anchor under + description { state: "default" 0.0; + text { + style: "entry_single_textblock_style"; + min: 1 1; + max: 0 0; + align: 0.0 0.5; + } + } + description { state: "disabled" 0.0; + inherit: "default" 0.0; + text { + style: "entry_single_textblock_disabled_style"; + } + } + } + } +} + +group { name: "elm/entry/base-noedit/enventor"; + inherit: "elm/entry/base/enventor"; + parts { + part { name: "elm.text"; + entry_mode: PLAIN; + source: "elm/entry/selection/enventor"; // selection under + source4: ""; // cursorover + source5: "elm/entry/anchor/enventor"; // anchor under + description { state: "default" 0.0; + fixed: 1 0; + text { + style: "entry_textblock_style"; + min: 0 1; + align: 0.0 0.0; + } + } + description { state: "disabled" 0.0; + inherit: "default" 0.0; + text { + style: "entry_textblock_disabled_style"; + } + } + } + } +} + +group { name: "elm/entry/base-noedit-mixedwrap/enventor"; + inherit: "elm/entry/base/enventor"; + parts { + part { name: "elm.text"; + entry_mode: PLAIN; + source: "elm/entry/selection/enventor"; // selection under + source4: ""; // cursorover + source5: "elm/entry/anchor/enventor"; // anchor under + description { state: "default" 0.0; + fixed: 1 0; + text { + style: "entry_textblock_style_mixedwrap"; + min: 0 1; + align: 0.0 0.0; + } + } + description { state: "disabled" 0.0; + inherit: "default" 0.0; + text { + style: "entry_textblock_disabled_style_mixedwrap"; + } + } + } + } +} + +group { name: "elm/entry/base-noedit-charwrap/enventor"; + inherit: "elm/entry/base/enventor"; + parts { + part { name: "elm.text"; + entry_mode: PLAIN; + source: "elm/entry/selection/enventor"; // selection under + source4: ""; // cursorover + source5: "elm/entry/anchor/enventor"; // anchor under + description { state: "default" 0.0; + fixed: 1 0; + text { + style: "entry_textblock_style_charwrap"; + min: 0 1; + align: 0.0 0.0; + } + } + description { state: "disabled" 0.0; + inherit: "default" 0.0; + text { + style: "entry_textblock_disabled_style_charwrap"; + } + } + } + } +} + +group { name: "elm/entry/base-password/enventor"; + inherit: "elm/entry/base/enventor"; + parts { + part { name: "elm.guide"; + type: TEXTBLOCK; + mouse_events: 0; + scale: 1; + description { state: "default" 0.0; + rel1.to: "elm.text"; + rel2.to: "elm.text"; + text { + style: "entry_single_textblock_guide_style"; + min: 0 1; + align: 0.0 0.0; + } + } + description { state: "hidden" 0.0; + inherit: "default" 0.0; + visible: 0; + } + } + part { name: "elm.text"; + entry_mode: PASSWORD; + multiline: 0; + source: "elm/entry/selection/enventor"; // selection under + source4: "elm/entry/cursor/enventor"; // cursorover + source5: "elm/entry/anchor/enventor"; // anchor under + description { state: "default" 0.0; + text { + style: "entry_single_textblock_style"; + repch: "*"; + min: 1 1; + max: 0 0; + align: 0.0 0.5; + } + } + description { state: "disabled" 0.0; + inherit: "default" 0.0; + text { + style: "entry_single_textblock_disabled_style"; + } + } + } + } +} +*/ + +group { name: "elm/ctxpopup/bg/enventor"; + parts { + part { name: "ctxpopup_bg"; + type: RECT; + mouse_events: 1; + description { state: "default" 0.0; + color: 0 0 0 0; + } + description { state: "visible" 0.0; + inherit: "default" 0.0; + color: 0 0 0 15; + } + } + } + programs { + program { name: "clicked_event"; + signal: "mouse,clicked,1"; + source: "ctxpopup_bg"; + action: SIGNAL_EMIT "elm,action,click" ""; + } + program { name: "show"; + signal: "elm,state,show"; + source: "elm"; + action: STATE_SET "visible" 0.0; + target: "ctxpopup_bg"; + transition: LINEAR 0.25; + } + program { name: "hide"; + signal: "elm,state,hide"; + source: "elm"; + action: STATE_SET "default" 0.0; + target: "ctxpopup_bg"; + transition: LINEAR 0.25; + } + } +} + +group { name: "elm/list/base/enventor"; + data { + item: "focus_highlight" "on"; + } + script { + public sbvis_v, sbvis_h; + } + images { + image: "shelf_inset.png" COMP; + image: "sl_bt2_2.png" COMP; + image: "bt_sm_base2.png" COMP; + image: "bt_sm_shine.png" COMP; + image: "bt_sm_hilight.png" COMP; + image: "sb_runnerh.png" COMP; + image: "sb_runnerv.png" COMP; + image: "arrow_up.png" COMP; + image: "arrow_down.png" COMP; + image: "arrow_right.png" COMP; + image: "arrow_left.png" COMP; + } + parts { + part { name: "bg"; + type: RECT; + mouse_events: 0; + description { state: "default" 0.0; + rel1.offset: 1 1; + rel2.offset: -2 -2; + color: 255 255 255 0; + } + } + part { name: "clipper"; + type: RECT; + mouse_events: 0; + description { state: "default" 0.0; + rel1.to: "bg"; + rel2.to: "bg"; + } + } + part { name: "elm.swallow.content"; + type: SWALLOW; + clip_to: "clipper"; + description { state: "default" 0.0; + rel2 { + to_x: "sb_vbar"; + to_y: "sb_hbar"; + relative: 1.0 1.0; + offset: -1 -1; + } + } + description { state: "both" 0.0; + inherit: "default" 0.0; + rel2.relative: 0.0 1.0; + } + description { state: "vertical" 0.0; + inherit: "default" 0.0; + rel2.relative: 0.0 1.0; + } + description { state: "horizontal" 0.0; + inherit: "default" 0.0; + rel2.relative: 1.0 0.0; + } + } + part { name: "conf_over"; + mouse_events: 0; + description { state: "default" 0.0; + image { + normal: "shelf_inset.png"; + border: 7 7 7 7; + middle: 0; + } + fill.smooth: 0; + } + } + part { name: "focus_highlight"; + mouse_events: 0; + description { state: "default" 0.0; + rel1.offset: -1 -1; + rel2.offset: 0 0; + image { + normal: "sl_bt2_2.png"; + border: 7 7 7 7; + middle: 0; + } + fill.smooth: 0; + color: 200 155 0 0; + } + description { state: "enabled" 0.0; + inherit: "default" 0.0; + color: 200 155 0 255; + } + } + part { name: "elm.scrollbar.base"; + type: SWALLOW; + mouse_events: 0; + description { state: "default" 0.0; + min: 13 13; + fixed: 1 1; + align: 1.0 1.0; + rel1.relative: 1.0 1.0; + rel2.offset: 12 12; + } + description { state: "vertical" 0.0; + inherit: "default" 0.0; + align: 1.0 0.0; + rel2.offset: -2 12; + } + description { state: "horizontal" 0.0; + inherit: "default" 0.0; + align: 0.0 1.0; + rel2.offset: 12 -2; + } + description { state: "both" 0.0; + inherit: "default" 0.0; + align: 1.0 1.0; + rel2.offset: -2 -2; + } + } + part { name: "sb_vbar_clip_master"; + type: RECT; + mouse_events: 0; + description { state: "default" 0.0; + } + description { state: "hidden" 0.0; + visible: 0; + } + } + part { name: "sb_vbar_clip"; + type: RECT; + mouse_events: 0; + clip_to: "sb_vbar_clip_master"; + description { state: "default" 0.0; + rel1.to: "sb_vbar_clip_master"; + rel2.to: "sb_vbar_clip_master"; + } + description { state: "hidden" 0.0; + inherit: "default" 0.0; + visible: 0; + max: 0 99999; + } + } + part { name: "sb_vbar"; + type: RECT; + mouse_events: 0; + clip_to: "sb_vbar_clip"; + description { state: "default" 0.0; + min: 13 0; + fixed: 1 1; + color: 0 0 0 0; + align: 0.0 0.5; + rel1 { + to_y: "sb_vbar_a1"; + to_x: "elm.scrollbar.base"; + relative: 0.0 1.0; + offset: 0 -1; + } + rel2 { + to_y: "sb_vbar_a2"; + relative: 1.0 0.0; + offset: -1 -2; + } + } + } + part { name: "sb_vbar_runner"; + mouse_events: 0; + clip_to: "sb_vbar_clip"; + description { state: "default" 0.0; + min: 3 0; + max: 3 99999; + fixed: 1 1; + align: 1.0 0.5; + rel1 { + to: "sb_vbar"; + relative: 0.5 0.0; + offset: 0 2; + } + rel2 { + to: "sb_vbar"; + relative: 0.5 1.0; + offset: 0 -2; + } + image { + normal: "sb_runnerv.png"; + border: 0 0 4 4; + } + fill.smooth: 0; + } + } + part { name: "sb_vbar_p1"; + type: RECT; + mouse_events: 1; + clip_to: "sb_vbar_clip"; + description { state: "default" 0.0; + color: 0 0 0 0; + fixed: 1 1; + rel1 { + to: "sb_vbar_a1"; + relative: 0.0 1.0; + } + rel2 { + to: "elm.dragable.vbar"; + relative: 1.0 0.0; + } + } + } + part { name: "sb_vbar_p2"; + type: RECT; + mouse_events: 1; + clip_to: "sb_vbar_clip"; + description { state: "default" 0.0; + color: 0 0 0 0; + fixed: 1 1; + rel1 { + to: "elm.dragable.vbar"; + relative: 0.0 1.0; + } + rel2 { + to: "sb_vbar_a2"; + relative: 1.0 0.0; + } + } + } + part { name: "sb_vbar_a1"; + type: RECT; + mouse_events: 1; + clip_to: "sb_vbar_clip"; + description { state: "default" 0.0; + min: 13 13; + fixed: 1 1; + align: 0.5 0.0; + aspect: 1.0 1.0; + aspect_preference: HORIZONTAL; + color: 0 0 0 0; + rel1 { + to_y: "sb_vbar_clip"; + to_x: "elm.scrollbar.base"; + relative: 0.0 0.0; + offset: 0 1; + } + rel2 { + to: "elm.scrollbar.base"; + relative: 1.0 0.0; + offset: -1 -2; + } + } + } + part { name: "sb_vbar_a1_arrow"; + mouse_events: 0; + clip_to: "sb_vbar_clip"; + description { state: "default" 0.0; + rel1.to: "sb_vbar_a1"; + rel2.to: "sb_vbar_a1"; + image.normal: "arrow_up.png"; + } + description { state: "clicked" 0.0; + inherit: "default" 0.0; + rel1.offset: 0 -1; + rel2.offset: -1 -2; + } + } + part { name: "sb_vbar_a2"; + type: RECT; + mouse_events: 1; + clip_to: "sb_vbar_clip"; + description { state: "default" 0.0; + min: 13 13; + fixed: 1 1; + align: 0.5 1.0; + aspect: 1.0 1.0; + aspect_preference: HORIZONTAL; + color: 0 0 0 0; + rel1.to: "elm.scrollbar.base"; + rel2 { + to: "elm.scrollbar.base"; + relative: 1.0 0.0; + } + } + } + part { name: "sb_vbar_a2_arrow"; + mouse_events: 0; + clip_to: "sb_vbar_clip"; + description { state: "default" 0.0; + rel1.to: "sb_vbar_a2"; + rel2.to: "sb_vbar_a2"; + image.normal: "arrow_down.png"; + } + description { state: "clicked" 0.0; + inherit: "default" 0.0; + rel1.offset: 0 1; + rel2.offset: -1 0; + } + } + part { name: "elm.dragable.vbar"; + type: RECT; + mouse_events: 1; + clip_to: "sb_vbar_clip"; + dragable { + x: 0 0 0; + y: 1 1 0; + confine: "sb_vbar"; + } + description { state: "default" 0.0; + min: 13 20; + fixed: 1 1; + aspect: 1.0 0.5; + aspect_preference: VERTICAL; + align: 0.5 0.0; + color: 0 0 0 0; + rel1 { + to_y: "sb_vbar"; + to_x: "elm.scrollbar.base"; + relative: 0.0 0.0; + } + rel2.to_y: "sb_vbar"; + } + } + part { name: "elm.dragable.vbar.image"; + mouse_events: 0; + clip_to: "sb_vbar_clip"; + description { state: "default" 0.0; + rel1.to: "elm.dragable.vbar"; + rel2.to: "elm.dragable.vbar"; + image { + normal: "bt_sm_base2.png"; + border: 6 6 6 6; + } + } + } + part { name: "sb_vbar_over1"; + clip_to: "sb_vbar_clip"; + mouse_events: 0; + description { state: "default" 0.0; + rel1.to: "elm.dragable.vbar.image"; + rel2 { + to: "elm.dragable.vbar.image"; + relative: 1.0 0.5; + } + image { + normal: "bt_sm_hilight.png"; + border: 6 6 6 0; + } + } + } + part { name: "sb_vbar_over2"; + clip_to: "sb_vbar_clip"; + mouse_events: 0; + description { state: "default" 0.0; + rel1.to: "elm.dragable.vbar.image"; + rel2.to: "elm.dragable.vbar.image"; + image { + normal: "bt_sm_shine.png"; + border: 6 6 6 0; + } + } + } + part { name: "sb_hbar_clip_master"; + type: RECT; + mouse_events: 0; + description { state: "default" 0.0; + } + description { state: "hidden" 0.0; + visible: 0; + } + } + part { name: "sb_hbar_clip"; + type: RECT; + mouse_events: 0; + clip_to: "sb_hbar_clip_master"; + description { state: "default" 0.0; + rel1.to: "sb_hbar_clip_master"; + rel2.to: "sb_hbar_clip_master"; + } + description { state: "hidden" 0.0; + inherit: "default" 0.0; + visible: 0; + max: 99999 0; + } + } + part { name: "sb_hbar"; + type: RECT; + mouse_events: 0; + clip_to: "sb_hbar_clip"; + description { state: "default" 0.0; + min: 0 13; + fixed: 1 1; + color: 0 0 0 0; + align: 0.5 0.5; + rel1 { + to_x: "sb_hbar_a1"; + to_y: "elm.scrollbar.base"; + relative: 1.0 0.0; + offset: -1 0; + } + rel2 { + to_x: "sb_hbar_a2"; + relative: 0.0 1.0; + offset: -2 -1; + } + } + } + part { name: "sb_hbar_runner"; + mouse_events: 0; + clip_to: "sb_hbar_clip"; + description { state: "default" 0.0; + min: 0 3; + max: 99999 3; + fixed: 1 1; + align: 0.5 0.5; + rel1 { + to: "sb_hbar"; + relative: 0.0 0.5; + offset: 2 0; + } + rel2 { + to: "sb_hbar"; + relative: 1.0 0.5; + offset: -2 0; + } + image { + normal: "sb_runnerh.png"; + border: 4 4 0 0; + } + fill.smooth: 0; + } + } + part { name: "elm.dragable.hbar"; + type: RECT; + mouse_events: 1; + clip_to: "sb_hbar_clip"; + dragable { + x: 1 1 0; + y: 0 0 0; + confine: "sb_hbar"; + } + description { state: "default" 0.0; + min: 20 13; + fixed: 1 1; + aspect_preference: HORIZONTAL; + align: 0.0 1.0; + color: 0 0 0 0; + rel1 { + to_x: "sb_hbar"; + relative: 0.0 1.0; + } + rel2.to_x: "sb_hbar"; + } + } + part { name: "elm.dragable.hbar.image"; + mouse_events: 0; + clip_to: "sb_hbar_clip"; + description { state: "default" 0.0; + rel1.to: "elm.dragable.hbar"; + rel2.to: "elm.dragable.hbar"; + image { + normal: "bt_sm_base2.png"; + border: 6 6 6 6; + } + } + } + part { name: "sb_hbar_over1"; + clip_to: "sb_hbar_clip"; + mouse_events: 0; + description { state: "default" 0.0; + rel1.to: "elm.dragable.hbar.image"; + rel2 { + to: "elm.dragable.hbar.image"; + relative: 1.0 0.5; + } + image { + normal: "bt_sm_hilight.png"; + border: 6 6 6 0; + } + } + } + part { name: "sb_hbar_over2"; + clip_to: "sb_hbar_clip"; + mouse_events: 0; + description { state: "default" 0.0; + rel1.to: "elm.dragable.hbar.image"; + rel2.to: "elm.dragable.hbar.image"; + image { + normal: "bt_sm_shine.png"; + border: 6 6 6 0; + } + } + } + part { name: "sb_hbar_p1"; + type: RECT; + mouse_events: 1; + clip_to: "sb_hbar_clip"; + description { state: "default" 0.0; + color: 0 0 0 0; + fixed: 1 1; + rel1 { + to: "sb_hbar_a1"; + relative: 1.0 0.0; + } + rel2 { + to: "elm.dragable.hbar"; + relative: 0.0 1.0; + } + } + } + part { name: "sb_hbar_p2"; + type: RECT; + mouse_events: 1; + clip_to: "sb_hbar_clip"; + description { state: "default" 0.0; + color: 0 0 0 0; + fixed: 1 1; + rel1 { + to: "elm.dragable.hbar"; + relative: 1.0 0.0; + } + rel2 { + to: "sb_hbar_a2"; + relative: 0.0 1.0; + } + } + } + part { name: "sb_hbar_a1"; + type: RECT; + mouse_events: 1; + clip_to: "sb_hbar_clip"; + description { state: "default" 0.0; + min: 13 13; + fixed: 1 1; + align: 0.0 1.0; + aspect: 1.0 1.0; + aspect_preference: VERTICAL; + color: 0 0 0 0; + rel1 { + to_x: "sb_hbar_clip"; + to_y: "elm.scrollbar.base"; + relative: 0.0 0.0; + } + rel2 { + to: "elm.scrollbar.base"; + relative: 0.0 1.0; + offset: -1 -1; + } + } + } + part { name: "sb_hbar_a1_arrow"; + mouse_events: 0; + clip_to: "sb_hbar_clip"; + description { state: "default" 0.0; + rel1.to: "sb_hbar_a1"; + rel2.to: "sb_hbar_a1"; + image.normal: "arrow_left.png"; + } + description { state: "clicked" 0.0; + inherit: "default" 0.0; + rel1.offset: -1 0; + rel2.offset: -2 -1; + } + } + part { name: "sb_hbar_a2"; + type: RECT; + mouse_events: 1; + clip_to: "sb_hbar_clip"; + description { state: "default" 0.0; + min: 13 13; + align: 1.0 1.0; + aspect: 1.0 1.0; + fixed: 1 1; + aspect_preference: VERTICAL; + color: 0 0 0 0; + rel1 { + to: "elm.scrollbar.base"; + relative: 1.0 0.0; + } + rel2 { + to: "elm.scrollbar.base"; + relative: 0.0 1.0; + } + } + } + part { name: "sb_hbar_a2_arrow"; + mouse_events: 0; + clip_to: "sb_hbar_clip"; + description { state: "default" 0.0; + rel1.to: "sb_hbar_a2"; + rel2.to: "sb_hbar_a2"; + image.normal: "arrow_right.png"; + } + description { state: "clicked" 0.0; + inherit: "default" 0.0; + rel1.offset: 1 0; + rel2.offset: 0 -1; + } + } + part { name: "disabler"; + type: RECT; + description { state: "default" 0.0; + rel1.to: "clipper"; + rel2.to: "clipper"; + color: 0 0 0 0; + visible: 0; + } + description { state: "disabled" 0.0; + inherit: "default" 0.0; + visible: 1; + color: 128 128 128 128; + } + } + programs { + program { name: "load"; + signal: "load"; + source: ""; + script { + set_state(PART:"sb_hbar_clip", "hidden", 0.0); + set_state(PART:"sb_vbar_clip", "hidden", 0.0); + set_int(sbvis_h, 0); + set_int(sbvis_v, 0); + } + } + program { name: "vbar_show"; + signal: "elm,action,show,vbar"; + source: "elm"; + script { + set_state(PART:"sb_vbar_clip_master", "default", 0.0); + set_int(sbvis_v, 1); + if (get_int(sbvis_h)) { + set_state(PART:"elm.swallow.content", "both", 0.0); + set_state(PART:"elm.scrollbar.base", "both", 0.0); + } else { + set_state(PART:"elm.scrollbar.base", "vertical", 0.0); + set_state(PART:"elm.swallow.content", "vertical", 0.0); + } + emit("do-show-vbar", ""); + } + } + program { name: "vbar_hide"; + signal: "elm,action,hide,vbar"; + source: "elm"; + script { + set_state(PART:"sb_vbar_clip_master", "hidden", 0.0); + set_int(sbvis_v, 0); + if (get_int(sbvis_h)) { + set_state(PART:"elm.swallow.content", "horizontal", 0.0); + set_state(PART:"elm.scrollbar.base", "horizontal", 0.0); + } else { + set_state(PART:"elm.swallow.content", "default", 0.0); + set_state(PART:"elm.scrollbar.base", "default", 0.0); + } + emit("do-hide-vbar", ""); + } + } + program { name: "sb_vbar_down"; + signal: "mouse,down,1"; + source: "elm.dragable.vbar"; + action: STATE_SET "clicked" 0.0; + target: "elm.dragable.vbar"; + } + program { name: "sb_vbar_up"; + signal: "mouse,up,1"; + source: "elm.dragable.vbar"; + action: STATE_SET "default" 0.0; + target: "elm.dragable.vbar"; + } + program { name: "sb_vbar_show"; + signal: "do-show-vbar"; + source: ""; + action: STATE_SET "default" 0.0; + transition: LINEAR 0.1; + target: "sb_vbar_clip"; + } + program { name: "sb_vbar_hide"; + signal: "do-hide-vbar"; + source: ""; + action: STATE_SET "hidden" 0.0; + transition: LINEAR 1.0; + target: "sb_vbar_clip"; + } + program { name: "sb_vbar_press"; + signal: "mouse,down,1"; + source: "elm.dragable.vbar"; + action: SIGNAL_EMIT "elm,vbar,press" "elm"; + } + program { name: "sb_vbar_unpress"; + signal: "mouse,up,1"; + source: "elm.dragable.vbar"; + action: SIGNAL_EMIT "elm,vbar,unpress" "elm"; + } + program { name: "sb_vbar_a1_down"; + signal: "mouse,down,1"; + source: "sb_vbar_a1"; + action: STATE_SET "clicked" 0.0; + target: "sb_vbar_a1_arrow"; + } + program { name: "sb_vbar_a1_down2"; + signal: "mouse,down,1"; + source: "sb_vbar_a1"; + action: DRAG_VAL_STEP 0.0 -1.0; + target: "elm.dragable.vbar"; + } + program { name: "sb_vbar_a1_up"; + signal: "mouse,up,1"; + source: "sb_vbar_a1"; + action: STATE_SET "default" 0.0; + target: "sb_vbar_a1_arrow"; + } + program { name: "sb_vbar_a2_down"; + signal: "mouse,down,1"; + source: "sb_vbar_a2"; + action: STATE_SET "clicked" 0.0; + target: "sb_vbar_a2_arrow"; + } + program { name: "sb_vbar_a2_down2"; + signal: "mouse,down,1"; + source: "sb_vbar_a2"; + action: DRAG_VAL_STEP 0.0 1.0; + target: "elm.dragable.vbar"; + } + program { name: "sb_vbar_a2_up"; + signal: "mouse,up,1"; + source: "sb_vbar_a2"; + action: STATE_SET "default" 0.0; + target: "sb_vbar_a2_arrow"; + } + program { name: "sb_vbar_p1_down"; + signal: "mouse,down,1"; + source: "sb_vbar_p1"; + action: DRAG_VAL_PAGE 0.0 -1.0; + target: "elm.dragable.vbar"; + } + program { name: "sb_vbar_p2_down"; + signal: "mouse,down,1"; + source: "sb_vbar_p2"; + action: DRAG_VAL_PAGE 0.0 1.0; + target: "elm.dragable.vbar"; + } + program { name: "hbar_show"; + signal: "elm,action,show,hbar"; + source: "elm"; + script { + set_state(PART:"sb_hbar_clip_master", "default", 0.0); + set_int(sbvis_h, 1); + if (get_int(sbvis_v)) { + set_state(PART:"elm.swallow.content", "both", 0.0); + set_state(PART:"elm.scrollbar.base", "both", 0.0); + } else { + set_state(PART:"elm.swallow.content", "horizontal", 0.0); + set_state(PART:"elm.scrollbar.base", "horizontal", 0.0); + } + emit("do-show-hbar", ""); + } + } + program { name: "hbar_hide"; + signal: "elm,action,hide,hbar"; + source: "elm"; + script { + set_state(PART:"sb_hbar_clip_master", "hidden", 0.0); + set_int(sbvis_h, 0); + if (get_int(sbvis_v)) { + set_state(PART:"elm.swallow.content", "vertical", 0.0); + set_state(PART:"elm.scrollbar.base", "vertical", 0.0); + } else { + set_state(PART:"elm.swallow.content", "default", 0.0); + set_state(PART:"elm.scrollbar.base", "default", 0.0); + } + emit("do-hide-hbar", ""); + } + } + program { name: "sb_hbar_down"; + signal: "mouse,down,1"; + source: "elm.dragable.hbar"; + action: STATE_SET "clicked" 0.0; + target: "elm.dragable.hbar"; + } + program { name: "sb_hbar_up"; + signal: "mouse,up,1"; + source: "elm.dragable.hbar"; + action: STATE_SET "default" 0.0; + target: "elm.dragable.hbar"; + } + program { name: "sb_hbar_show"; + signal: "do-show-hbar"; + source: ""; + action: STATE_SET "default" 0.0; + transition: LINEAR 0.1; + target: "sb_hbar_clip"; + } + program { name: "sb_hbar_hide"; + signal: "do-hide-hbar"; + source: ""; + action: STATE_SET "hidden" 0.0; + transition: LINEAR 1.0; + target: "sb_hbar_clip"; + } + program { name: "sb_hbar_press"; + signal: "mouse,down,1"; + source: "elm.dragable.hbar"; + action: SIGNAL_EMIT "elm,hbar,press" "elm"; + } + program { name: "sb_hbar_unpress"; + signal: "mouse,up,1"; + source: "elm.dragable.hbar"; + action: SIGNAL_EMIT "elm,hbar,unpress" "elm"; + } + program { name: "sb_hbar_a1_down"; + signal: "mouse,down,1"; + source: "sb_hbar_a1"; + action: STATE_SET "clicked" 0.0; + target: "sb_hbar_a1_arrow"; + } + program { name: "sb_hbar_a1_down2"; + signal: "mouse,down,1"; + source: "sb_hbar_a1"; + action: DRAG_VAL_STEP -1.0 0.0; + target: "elm.dragable.hbar"; + } + program { name: "sb_hbar_a1_up"; + signal: "mouse,up,1"; + source: "sb_hbar_a1"; + action: STATE_SET "default" 0.0; + target: "sb_hbar_a1_arrow"; + } + program { name: "sb_hbar_a2_down"; + signal: "mouse,down,1"; + source: "sb_hbar_a2"; + action: STATE_SET "clicked" 0.0; + target: "sb_hbar_a2_arrow"; + } + program { name: "sb_hbar_a2_down2"; + signal: "mouse,down,1"; + source: "sb_hbar_a2"; + action: DRAG_VAL_STEP 1.0 0.0; + target: "elm.dragable.hbar"; + } + program { name: "sb_hbar_a2_up"; + signal: "mouse,up,1"; + source: "sb_hbar_a2"; + action: STATE_SET "default" 0.0; + target: "sb_hbar_a2_arrow"; + } + program { name: "sb_hbar_p1_down"; + signal: "mouse,down,1"; + source: "sb_hbar_p1"; + action: DRAG_VAL_PAGE -1.0 0.0; + target: "elm.dragable.hbar"; + } + program { name: "sb_hbar_p2_down"; + signal: "mouse,down,1"; + source: "sb_hbar_p2"; + action: DRAG_VAL_PAGE 1.0 0.0; + target: "elm.dragable.hbar"; + } + program { name: "disable"; + signal: "elm,state,disabled"; + source: "elm"; + action: STATE_SET "disabled" 0.0; + target: "disabler"; + } + program { name: "enable"; + signal: "elm,state,enabled"; + source: "elm"; + action: STATE_SET "default" 0.0; + target: "disabler"; + } + } + } +} + +group { name: "elm/panes/vertical/enventor"; + images { + image: "bt_base1.png" COMP; + image: "bt_base2.png" COMP; + image: "bt_hilight.png" COMP; + image: "bt_shine.png" COMP; + image: "bt_glow.png" COMP; + image: "arrow_right.png" COMP; + image: "arrow_left.png" COMP; + } + parts { + part { name: "whole"; + type: RECT; + mouse_events: 0; + description { state: "default" 0.0; + visible: 0; + } + } + //2 contents + part { name: "whole_left"; + type: RECT; + mouse_events: 0; + description { state: "default" 0.0; + rel2.to_x: "elm.bar"; + rel2.relative: 0.0 1.0; + visible: 1; + } + } + part { name: "elm.swallow.left"; + type: SWALLOW; + clip_to: "whole_left"; + description { state: "default" 0.0; + rel1.to: "whole_left"; + rel2.to: "whole_left"; + } + } + part { name: "whole_right"; + type: RECT; + mouse_events: 0; + description { state: "default" 0.0; + rel1.to_x: "elm.bar"; + rel1.relative: 1.0 0.0; + visible: 1; + } + } + part { name: "elm.swallow.right"; + type: SWALLOW; + clip_to: "whole_right"; + description { state: "default" 0.0; + rel1.to: "whole_right"; + rel2.to: "whole_right"; + } + } + //BAR + part { name: "elm.bar"; + mouse_events: 1; + dragable { + confine: "whole"; + x: 1 1 1; + y: 0 0 0; + } + description { state: "default" 0.0; + max: 15 9999; + min: 15 100; + fixed: 1 1; + rel1.relative: 0.0 0.5; + rel2.relative: 1.0 0.5; + image { + normal: "bt_base2.png"; + border: 7 7 7 7; + } + image.middle: SOLID; + } + description { state: "clicked" 0.0; + inherit: "default" 0.0; + image.normal: "bt_base1.png"; + image.middle: SOLID; + } + description { state: "disabled" 0.0; + inherit: "default" 0.0; + visible: 0; + } + } + part { name: "over1"; + mouse_events: 0; + description { state: "default" 0.0; + rel1.to: "elm.bar"; + rel2.to: "elm.bar"; + rel2.relative: 1.0 0.5; + image { + normal: "bt_hilight.png"; + border: 7 7 7 0; + } + } + description { state: "disabled" 0.0; + inherit: "default" 0.0; + visible: 0; + } + } + part { name: "over2"; + mouse_events: 1; + repeat_events: 1; + ignore_flags: ON_HOLD; + description { state: "default" 0.0; + rel1.to: "elm.bar"; + rel2.to: "elm.bar"; + image { + normal: "bt_shine.png"; + border: 7 7 7 7; + } + } + description { state: "disabled" 0.0; + inherit: "default" 0.0; + visible: 0; + } + } + part { name: "over3"; + mouse_events: 1; + repeat_events: 1; + description { state: "default" 0.0; + color: 255 255 255 0; + rel1.to: "elm.bar"; + rel2.to: "elm.bar"; + image { + normal: "bt_glow.png"; + border: 12 12 12 12; + } + fill.smooth : 0; + } + description { state: "clicked" 0.0; + inherit: "default" 0.0; + visible: 1; + color: 255 255 255 255; + } + } + part { name:"bar_disabled"; + type: RECT; + description { state:"default" 0.0; + rel1.to_x: "elm.bar"; + rel2.to_x: "elm.bar"; + color: 0 0 0 0; + visible: 0; + } + description { state: "disabled" 0.0; + inherit: "default" 0.0; + visible: 1; + } + } + part { name: "elm.swallow.left_arrow"; + type: SWALLOW; + description { state: "default" 0.0; + min: 0 20; + fixed: 1 1; + align: 0.5 1; + rel1.to: "elm.bar"; + rel2.to: "elm.bar"; + rel1.relative: 0 0; + rel2.relative: 1 0; + rel1.offset: 0 -10; + rel2.offset: -1 -11; + color: 125 0 0 125; + } + } + part { name: "elm.swallow.right_arrow"; + type: SWALLOW; + description { state: "default" 0.0; + min: 0 20; + fixed: 1 1; + align: 0.5 0; + rel1.to: "elm.bar"; + rel2.to: "elm.bar"; + rel1.relative: 0 1; + rel2.relative: 1 1; + rel1.offset: 0 10; + rel2.offset: -1 -9; + color: 125 0 0 125; + } + } + //Arrow + part { name: "arrow_right"; + repeat_events: 1; + description { state: "default" 0.0; + min: 45 45; + max: 45 45; + color: 255 255 255 0; + + rel1.relative: 1.0 0.5; + rel1.to_x: "elm.bar"; + rel1.offset: 45/2 -45/2; + + rel2.relative: 1.0 0.5; + rel2.to_x: "elm.bar"; + rel2.offset: 45/2 45/2; + + image.normal: "arrow_right.png"; + + fixed: 1 1; + } + description { state: "default" 0.1; + inherit: "default" 0.0; + image.normal: "arrow_left.png"; + } + description { state: "anim_1" 0.0; + inherit: "default" 0.0; + color: 255 255 255 200; + rel1.offset: (45/2 + 10) -45/2; + rel2.offset: (45/2 +10) 45/2; + } + description { state: "anim_1" 0.1; + inherit: "default" 0.0; + image.normal: "arrow_left.png"; + color: 255 255 255 200; + rel1.offset: (45/2 + 10) -45/2; + rel2.offset: (45/2 +10) 45/2; + } + description { state: "anim_2" 0.0; + inherit: "default" 0.0; + color: 255 255 255 0; + rel1.offset: (45/2 + 20) -45/2; + rel2.offset: (45/2 + 20) 45/2; + } + description { state: "anim_2" 0.1; + inherit: "default" 0.0; + image.normal: "arrow_left.png"; + color: 255 255 255 0; + rel1.offset: (45/2 + 20) -45/2; + rel2.offset: (45/2 + 20) 45/2; + } + } + part { name: "arrow_left"; + repeat_events: 1; + description { state: "default" 0.0; + min: 45 45; + max: 45 45; + color: 255 255 255 0; + + rel1.relative: 0.0 0.5; + rel1.to_x: "elm.bar"; + rel1.offset: -45/2 -45/2; + + rel2.relative: 0.0 0.5; + rel2.to_x: "elm.bar"; + rel2.offset: -45/2 45/2; + + image.normal: "arrow_left.png"; + + fixed: 1 1; + } + description { state: "default" 0.1; + inherit: "default" 0.0; + image.normal: "arrow_right.png"; + } + description { state: "anim_1" 0.0; + inherit: "default" 0.0; + color: 255 255 255 200; + rel1.offset: (-45/2 - 10) -45/2; + rel2.offset: (-45/2 - 10) 45/2; + } + description { state: "anim_1" 0.1; + inherit: "default" 0.0; + image.normal: "arrow_right.png"; + color: 255 255 255 200; + rel1.offset: (-45/2 - 10) -45/2; + rel2.offset: (-45/2 - 10) 45/2; + } + description { state: "anim_2" 0.0; + inherit: "default" 0.0; + color: 255 255 255 0; + rel1.offset: (-45/2 - 20) -45/2; + rel2.offset: (-45/2 - 20) 45/2; + } + description { state: "anim_2" 0.1; + inherit: "default" 0.0; + image.normal: "arrow_right.png"; + color: 255 255 255 0; + rel1.offset: (-45/2 - 20) -45/2; + rel2.offset: (-45/2 - 20) 45/2; + } + } + } + programs { + program { + name: "button_click"; + signal: "mouse,down,1"; + source: "over2"; + action: SIGNAL_EMIT "elm,action,press" ""; + after: "button_click_anim"; + after: "arrow_anim_start"; + } + program { + name: "button_click_anim"; + action: STATE_SET "clicked" 0.0; + target: "elm.bar"; + } + program { + name: "button_unclick"; + signal: "mouse,up,1"; + source: "over2"; + action: SIGNAL_EMIT "elm,action,unpress" ""; + after: "button_unclick_anim"; + after: "arrow_anim_stop"; + } + program { + name: "button_unclick_anim"; + action: STATE_SET "default" 0.0; + target: "elm.bar"; + } + program { + name: "button_click2"; + signal: "mouse,down,1"; + source: "over3"; + action: STATE_SET "clicked" 0.0; + target: "over3"; + } + program { + name: "button_unclick2"; + signal: "mouse,up,1"; + source: "over3"; + action: STATE_SET "default" 0.0; + transition: DECELERATE 0.5; + target: "over3"; + } + program { + name: "button_unclick3"; + signal: "mouse,up,1"; + source: "over2"; + action: SIGNAL_EMIT "elm,action,click" ""; + } + program { + name: "button_down_double"; + signal: "mouse,down,1,double"; + source: "over3"; + action: SIGNAL_EMIT "elm,action,click,double" ""; + } + + //arrows animation + program { + name: "arrow_anim_start"; + script { + new st[31]; + new Float:vl; + get_state(PART:"arrow_left", st, 30, vl); + if (vl == 0.0) { + run_program(PROGRAM:"arrow_anim_start_ltr"); + } + else { + run_program(PROGRAM:"arrow_anim_start_rtl"); + } + } + } + program { + name: "arrow_anim_stop"; + script { + new st[31]; + new Float:vl; + get_state(PART:"arrow_left", st, 30, vl); + if (vl == 0.0) { + run_program(PROGRAM:"arrow_anim_stop_ltr"); + } + else { + run_program(PROGRAM:"arrow_anim_stop_rtl"); + } + } + } + + program { + name: "arrow_anim_start_ltr"; + action: STATE_SET "anim_1" 0.0; + target: "arrow_right"; + target: "arrow_left"; + transition: LINEAR 0.6; + after: "arrow_anim_1_ltr"; + } + program { + name: "arrow_anim_1_ltr"; + action: STATE_SET "anim_2" 0.0; + target: "arrow_right"; + target: "arrow_left"; + transition: LINEAR 0.6; + after: "arrow_anim_2_ltr"; + } + program { + name: "arrow_anim_2_ltr"; + action: STATE_SET "default" 0.0; + target: "arrow_right"; + target: "arrow_left"; + after: "arrow_anim_start_ltr"; + } + program { + name: "arrow_anim_stop_ltr"; + action: ACTION_STOP; + target: "arrow_anim_start_ltr"; + target: "arrow_anim_1_ltr"; + target: "arrow_anim_2_ltr"; + after: "arrow_anim_stop_1_ltr"; + } + program { + name: "arrow_anim_stop_1_ltr"; + action: STATE_SET "default" 0.0; + target: "arrow_right"; + target: "arrow_left"; + transition: DECELERATE 0.4; + } + program { + name: "arrow_anim_start_rtl"; + action: STATE_SET "anim_1" 0.1; + target: "arrow_right"; + target: "arrow_left"; + transition: LINEAR 0.6; + after: "arrow_anim_1_rtl"; + } + program { + name: "arrow_anim_1_rtl"; + action: STATE_SET "anim_2" 0.1; + target: "arrow_right"; + target: "arrow_left"; + transition: LINEAR 0.6; + after: "arrow_anim_2_rtl"; + } + program { + name: "arrow_anim_2_rtl"; + action: STATE_SET "default" 0.1; + target: "arrow_right"; + target: "arrow_left"; + after: "arrow_anim_start_rtl"; + } + program { + name: "arrow_anim_stop_rtl"; + action: ACTION_STOP; + target: "arrow_anim_start_rtl"; + target: "arrow_anim_1_rtl"; + target: "arrow_anim_2_rtl"; + after: "arrow_anim_stop_1_rtl"; + } + program { + name: "arrow_anim_stop_1_rtl"; + action: STATE_SET "default" 0.1; + target: "arrow_right"; + target: "arrow_left"; + transition: DECELERATE 0.4; + } + program { name: "to_rtl"; + signal: "edje,state,rtl"; + source: "edje"; + script { + new st[31]; + new Float:vl; + get_state(PART:"arrow_left", st, 30, vl); + if (vl == 0.0) { + set_state(PART:"arrow_left", st, 0.1); + } + get_state(PART:"arrow_right", st, 30, vl); + if (vl == 0.0) { + set_state(PART:"arrow_right", st, 0.1); + } + } + } + program { name: "to_ltr"; + signal: "edje,state,ltr"; + source: "edje"; + script { + new st[31]; + new Float:vl; + get_state(PART:"arrow_left", st, 30, vl); + if (vl == 0.1) { + set_state(PART:"arrow_left", st, 0.0); + } + get_state(PART:"arrow_right", st, 30, vl); + if (vl == 0.1) { + set_state(PART:"arrow_right", st, 0.0); + } + } + } + //fix the pane + program { + name: "panes_fixed"; + signal: "elm,panes,fixed"; + source: "elm"; + action: STATE_SET "disabled" 0.0; + target: "elm.bar"; + target: "over1"; + target: "bar_disabled"; + } + //allow the movement by interaction + program { + name: "panes_unfixed"; + signal: "elm,panes,unfixed"; + source: "elm"; + action: STATE_SET "default" 0.0; + target: "elm.bar"; + target: "over1"; + target: "bar_disabled"; + } + } +} + + diff --git a/data/images/logo.png b/data/images/logo.png new file mode 100644 index 0000000..7dbae67 Binary files /dev/null and b/data/images/logo.png differ diff --git a/data/sample/bg.jpg b/data/sample/bg.jpg new file mode 100644 index 0000000..3766f47 Binary files /dev/null and b/data/sample/bg.jpg differ diff --git a/data/sample/clouds.png b/data/sample/clouds.png new file mode 100644 index 0000000..dedfc51 Binary files /dev/null and b/data/sample/clouds.png differ diff --git a/data/sample/etypers.edj b/data/sample/etypers.edj new file mode 100644 index 0000000..15f52ff Binary files /dev/null and b/data/sample/etypers.edj differ diff --git a/data/sample/input_bg.png b/data/sample/input_bg.png new file mode 100644 index 0000000..5d4fc77 Binary files /dev/null and b/data/sample/input_bg.png differ diff --git a/data/sample/sample.edc b/data/sample/sample.edc new file mode 100644 index 0000000..914c841 --- /dev/null +++ b/data/sample/sample.edc @@ -0,0 +1,300 @@ +collections { + images { + image: "bg.jpg" COMP; + image: "sky.jpg" COMP; + image: "clouds.png" COMP; + image: "input_bg.png" COMP; + } + group { name: "etyper"; + parts { + part { name: "bg"; + type: IMAGE; + description { state: "default" 0.0; + image.normal: "bg.jpg"; + } + } + part { name: "sky"; + type: IMAGE; + description { state: "default" 0.0; + image.normal: "sky.jpg"; + aspect: 1.0 2.5; + color: 255 255 255 255; + } + description { state: "drift" 0.0; + inherit: "default" 0.0; + fill { + origin { + relative: 0.5 0.0; + } + } + } + } + part { name: "enemies"; + type: SWALLOW; + description { state: "default" 0.0; + } + } + part { name: "clouds"; + type: IMAGE; + description { state: "default" 0.0; + image.normal: "clouds.png"; + fill { + origin { + relative: 0.0 0.0; + } + size { + relative: 1.84722 1.0; + } + } + } + description { state: "drift" 0.0; + inherit: "default" 0.0; + fill { + origin { + relative: 1.847220 0.0; + } + size { + relative: 1.84722 1.0; + } + } + } + } + part { name: "defense_wall"; + type: SWALLOW; + description { state: "default" 0.0; + rel1.relative: 0.5 0.95; + rel2.relative: 1.0 1.0; + } + } + part { name: "score"; + type: TEXT; + scale: 1; + description { state: "default" 0.0; + text { font: "Sans:style=Bold"; + size: 12; + min: 0 0; + max: 1 0; + align: 0 0; + text: "Score:"; + } + color: 0 0 200 200; + align: 0 0; + min: 0 20; + fixed: 0 1; + rel2.relative: 1 0; + } + } + part { name: "score_value"; + type: TEXT; + scale: 1; + description { state: "default" 0.0; + text { font: "Sans:style=Bold"; + size: 12; + min: 0 0; + max: 1 0; + align: 0 0; + text: "0"; + } + color: 200 200 200 200; + align: 0 0; + rel1.to: "score"; + rel1.relative: 1 0; + } + } + part { name: "level"; + type: TEXT; + scale: 1; + description { state: "default" 0.0; + text { font: "Sans:style=Bold"; + size: 12; + min: 0 0; + max: 1 0; + align: 0 0; + text: "Level:"; + } + color: 0 0 200 200; + align: 0 0; + min: 0 20; + fixed: 0 1; + rel1.to: "score"; + rel1.relative: 0 1; + rel2.relative: 1 0; + } + } + part { name: "level_value"; + type: TEXT; + scale: 1; + description { state: "default" 0.0; + text { font: "Sans:style=Bold"; + size: 12; + min: 0 0; + max: 1 0; + align: 0 0; + text: "1"; + } + color: 200 200 200 200; + align: 0 0 ; + rel1.relative: 1 0; + rel1.to: "level"; + } + } + part { name: "correct"; + type: TEXT; + scale: 1; + description { state: "default" 0.0; + text { font: "Sans:style=Bold"; + size: 12; + min: 0 0; + max: 1 0; + align: 0 0; + text: "Correct:"; + } + color: 0 0 200 200; + align: 0 0; + rel1.to: "level"; + rel1.relative: 0 1; + } + } + part { name: "correct_value"; + type: TEXT; + scale: 1; + description { state: "default" 0.0; + text { font: "Sans:style=Bold"; + size: 12; + min: 0 0; + max: 1 0; + align: 0 0; + text: "100%"; + } + color: 200 200 200 200; + align: 0 0 ; + rel1.relative: 1 0; + rel1.to: "correct"; + } + } + part { name: "input_clipper"; + type: RECT; + description { state: "default" 0.0; + align: 0.5 1; + min: 170 30; + max: 170 30; + fixed: 1 1; + rel1.relative: 0.5 0.95; + rel2.relative: 0.5 0.95; + } + } + part { name: "input_bg"; + type: IMAGE; + description { state: "default" 0.0; + rel1.to: "input_clipper"; + rel2.to: "input_clipper"; + fixed: 1 1; + image { normal:"input_bg.png"; + border: 3 3 3 3; + } + color: 130 130 130 130; + } + } + part { name: "entry"; + type: SWALLOW; + clip_to: "input_clipper"; + description { state: "default" 0.0; + rel1.to: "input_clipper"; + rel2.to: "input_clipper"; + align: 0.5 0.5; + fixed: 1 1; + } + } + part { name: "effect_overlay"; + type: RECT; + mouse_events: 0; + description { state: "default" 0.0; + color: 0 0 0 0; + } + description { state: "hit" 0.0; + color: 200 0 0 200; + } + description { state: "gameover" 0.0; + color: 255 255 255 255; + } + } + part { name: "gameover"; + type: TEXT; + scale: 1; + description { state: "default" 0.0; + text { font: "Sans:style=Bold"; + size: 30; + min: 0 0; + max: 1 0; + align: 0.5 0.5; + text: "Game Over"; + } + color: 0 0 0 0; + align: 0.5 0.5; + } + description { state: "gameover" 0.0; + inherit: "default" 0.0; + color: 100 100 100 255; + } + } + } + programs { + program { name: "sky_anim1"; + signal: "load"; + action: STATE_SET "drift" 0.0; + transition: LINEAR 30.0; + target: "sky"; + after: "sky_anim2"; + } + program { name: "sky_anim2"; + action: STATE_SET "default" 0.0; + target: "sky"; + after: "sky_anim1"; + } + program { name: "clouds_anim1"; + signal: "load"; + action: STATE_SET "drift" 0.0; + transition: LINEAR 10.0; + target: "clouds"; + after: "clouds_anim2"; + } + program { name: "clouds_anim2"; + action: STATE_SET "default" 0.0; + target: "clouds"; + after: "clouds_anim1"; + } + program { name: "hit"; + signal: "elm,state,hit"; + source: "etypers"; + action: STATE_SET "hit" 0.0; + target: "effect_overlay"; + after: "hit2"; + } + program { name: "hit2"; + action: STATE_SET "default" 0.0; + target: "effect_overlay"; + transition: DECELERATE 1; + } + program { name: "gameover"; + signal: "elm,state,gameover"; + source: "etypers"; + action: STATE_SET "hit" 0.0; + target: "effect_overlay"; + after: "gameover2"; + } + program { name: "gameover2"; + action: STATE_SET "gameover" 0.0; + target: "effect_overlay"; + target: "gameover"; + transition: LINEAR 1.0; + } + program { name: "gamereset"; + signal: "elm,state,gamereset"; + source: "etypers"; + action: STATE_SET "default" 0.0; + target: "effect_overlay"; + target: "effect_overlay"; + target: "gameover"; + } + } + } diff --git a/data/sample/sample.edj b/data/sample/sample.edj new file mode 100644 index 0000000..6f1f9a6 Binary files /dev/null and b/data/sample/sample.edj differ diff --git a/data/sample/sky.jpg b/data/sample/sky.jpg new file mode 100644 index 0000000..6132e7c Binary files /dev/null and b/data/sample/sky.jpg differ diff --git a/data/syntax/color_syntax.src b/data/syntax/color_syntax.src new file mode 100644 index 0000000..b1f0248 --- /dev/null +++ b/data/syntax/color_syntax.src @@ -0,0 +1,19 @@ +group "Edje_Writer" struct { + group "Syntax_Group1" struct { + group "Color_RGBA" struct { + value "r" uint: 255; + value "g" uint: 0; + value "b" uint: 0; + value "a" uint: 255; + } + group "keyword" list { + value "val" string: "COMP"; + value "val" string: "IMAGE"; + value "val" string: "RECT"; + value "val" string: "SWALLOW"; + value "val" string: "TEXT"; + value "val" string: "TEXTBLOCK"; + value "val" string: "STATE_SET"; + } + } +} diff --git a/include/common.h b/include/common.h new file mode 100644 index 0000000..a00b36e --- /dev/null +++ b/include/common.h @@ -0,0 +1,138 @@ +#ifndef __COMMON_H__ +#define __COMMON_H__ + + +#define DEBUG_MODE 1 + +#ifdef DEBUG_MODE + #define DFUNC_BEGIN() printf("%s - begin\n", __func__) + #define DFUNC_END() printf("%s - end\n", __func__) + #define DFUNC_NAME() printf("%s(%d)\n", __func__, __LINE__) +#else + #define DFUNC_BEGIN() + #define DFUNC_END() + #define DFUNC_NAME() +#endif + +#define PROTO_EDC_PATH "/tmp/.proto.edc" + +extern char EDJE_PATH[PATH_MAX]; + +struct attr_value_s +{ + Eina_List *strs; + float min; + float max; + Eina_Bool integer : 1; +}; + +typedef struct menu_s menu_data; +typedef struct viewer_s view_data; +typedef struct app_s app_data; +typedef struct statusbar_s stats_data; +typedef struct editor_s edit_data; +typedef struct syntax_color_s color_data; +typedef struct config_s option_data; +typedef struct parser_s parser_data; +typedef struct attr_value_s attr_value; +typedef struct fake_obj_s fake_obj; + +//edit functions +edit_data *edit_init(Evas_Object *win, stats_data *sd, option_data *od); +void edit_term(edit_data *ed); +void edit_edc_read(edit_data *ed, const char *file_path); +void edit_focus_set(edit_data *ed); +Evas_Object *edit_obj_get(edit_data *ed); +Eina_Bool edit_changed_get(edit_data *ed); +void edit_changed_reset(edit_data *ed); +void edit_line_number_toggle(edit_data *ed); +void edit_editable_set(edit_data *ed, Eina_Bool editable); +void edit_save(edit_data *ed); +const char *edit_group_name_get(edit_data *ed); +void edit_new(edit_data* ed); +void edit_part_changed_cb_set(edit_data *ed, void (*cb)(void *data, const char *part_name), void *data); +void edit_cur_part_update(edit_data *ed); + +//menu functions +menu_data *menu_init(Evas_Object *win, edit_data *ed, option_data *od, view_data *vd, void (*close_cb)(void *data), void *data); +void menu_term(menu_data *md); +Eina_Bool menu_option_toggle(); +void menu_ctxpopup_register(Evas_Object *ctxpopup); +Eina_Bool menu_edc_load(menu_data *md); +void menu_exit(menu_data *md); + +//view functions +view_data * view_init(Evas_Object *parent, const char *group, stats_data *sd, + option_data *od); +void view_term(view_data *vd); +Evas_Object *view_obj_get(view_data *vd); +void view_new(view_data *vd, const char *group); +void view_part_highlight_set(view_data *vd, const char *part_name); +Eina_Bool view_reload_need_get(view_data *vd); +void view_reload_need_set(view_data *vd, Eina_Bool reload); +void view_update(view_data *vd); + +//stats functions +stats_data *stats_init(Evas_Object *parent, option_data *od); +void stats_term(stats_data *sd); +void stats_view_size_update(stats_data *sd); +void stats_cursor_pos_update(stats_data *sd, Evas_Coord x, Evas_Coord y, + float rel_x, float rel_y); +void stats_info_msg_update(stats_data *sd, const char *msg); +void stats_line_num_update(stats_data *sd, int cur_line, int max_line); +Evas_Object *stats_obj_get(stats_data *sd); +void stats_edc_file_set(stats_data *sd, const char *group_name); + +//syntax color +color_data *color_init(); +void color_term(color_data *cd); +const char *color_cancel(color_data *cd, const char *str, int length); +const char *color_apply(color_data *cd, const char *str, int length, + Eina_Bool realtime); + +//config data +option_data *option_init(const char *edc_path, const char *edc_img_path, + const char *edc_snd_path); +void option_term(option_data *od); +const char *option_edc_path_get(option_data *od); +const char *option_edj_path_get(option_data *od); +const char *option_edc_img_path_get(option_data *od); +const char *option_edc_snd_path_get(option_data *od); +void option_edc_img_path_set(option_data *od, const char *edc_img_path); +void option_edc_snd_path_set(option_data *od, const char *edc_snd_path); +const Eina_List *option_edc_img_path_list_get(option_data *od); +const Eina_List *option_edc_snd_path_list_get(option_data *od); +void option_update_cb_set(option_data *od, + void (*cb)(void *data, option_data *od), + void *data); +void option_stats_bar_set(option_data *od, Eina_Bool enabled); +void option_linenumber_set(option_data *od, Eina_Bool enabled); +Eina_Bool option_stats_bar_get(option_data *od); +Eina_Bool option_linenumber_get(option_data *od); +void option_apply(option_data *od); +void option_edc_path_set(option_data *od, const char *edc_path); +void option_view_size_get(option_data *od, Evas_Coord *w, Evas_Coord *h); +void option_view_size_set(option_data *od, Evas_Coord w, Evas_Coord h); +Eina_Bool option_part_highlight_get(option_data *od); +void option_part_highlight_set(option_data *od, Eina_Bool highlight); + +//parser +parser_data *parser_init(); +void parser_term(parser_data *pd); +Eina_Stringshare *parser_group_name_get(parser_data *pd, Evas_Object *entry); +void parser_part_name_get(parser_data *pd, Evas_Object *entry, void (*cb)(void *data, Eina_Stringshare *part_name), void *data); +Eina_Bool parser_type_name_compare(parser_data *pd, const char *str); +const char *parser_markup_escape(parser_data *pd EINA_UNUSED, const char *str); +attr_value *parser_attribute_get(parser_data *pd, const char *text, const char *cur); + +//panes +Evas_Object *panes_create(Evas_Object *parent); +void panes_full_view_right(Evas_Object *panes); +void panes_full_view_left(Evas_Object *panes); +void panes_full_view_cancel(Evas_Object *panes); + +//fake obj +void fake_obj_new(Evas_Object *layout); +void fake_obj_del(Evas_Object *layout); + +#endif diff --git a/src/config_data.c b/src/config_data.c new file mode 100644 index 0000000..3d91492 --- /dev/null +++ b/src/config_data.c @@ -0,0 +1,274 @@ +#include +#include "common.h" + +struct config_s +{ + const char *edc_path; + const char *edj_path; + + Eina_List *edc_img_path_list; + Eina_List *edc_snd_path_list; + Eina_Strbuf *edc_img_path_buf; //pre-stored image paths for edc compile. + Eina_Strbuf *edc_snd_path_buf; //pre-stored sound paths for edc compile. + + void (*update_cb)(void *data, option_data *od); + void *update_cb_data; + Evas_Coord_Size view_size; + + Eina_Bool stats_bar : 1; + Eina_Bool linenumber : 1; + Eina_Bool part_highlight : 1; +}; + +void +option_view_size_set(option_data *od, Evas_Coord w, Evas_Coord h) +{ + od->view_size.w = w; + od->view_size.h = h; +} + +void +option_view_size_get(option_data *od, Evas_Coord *w, Evas_Coord *h) +{ + if (w) *w = od->view_size.w; + if (h) *h = od->view_size.h; +} + +static void +option_edj_path_update(option_data *od) +{ + //apply edj path also + char buf[PATH_MAX]; + char edj_path[PATH_MAX]; + + char *ext = strstr(od->edc_path, ".edc"); + const char *file = ecore_file_file_get(od->edc_path); + if (ext && file) + snprintf(buf, (ext - file) + 1, "%s", file); + else + strncpy(buf, file, sizeof(buf)); + sprintf(edj_path, "%s/%s.edj", ecore_file_dir_get(od->edc_path), buf); + + eina_stringshare_replace(&od->edj_path, edj_path); +} + +void +option_edc_path_set(option_data *od, const char *edc_path) +{ + eina_stringshare_replace(&od->edc_path, edc_path); + option_edj_path_update(od); +} + +option_data * +option_init(const char *edc_path, const char *edc_img_path, + const char *edc_snd_path) +{ + option_data *od = calloc(1, sizeof(option_data)); + + od->edc_path = eina_stringshare_add(edc_path); + option_edj_path_update(od); + option_edc_img_path_set(od, edc_img_path); + option_edc_snd_path_set(od, edc_snd_path); + + od->linenumber = EINA_TRUE; + od->part_highlight = EINA_TRUE; + + return od; +} + +void +option_term(option_data *od) +{ + eina_stringshare_del(od->edc_path); + eina_stringshare_del(od->edj_path); + + Eina_List *l; + Eina_Stringshare *str; + + //free the image paths + EINA_LIST_FOREACH(od->edc_img_path_list, l, str) + eina_stringshare_del(str); + eina_list_free(od->edc_img_path_list); + + //free the sound paths + EINA_LIST_FOREACH(od->edc_snd_path_list, l, str) + eina_stringshare_del(str); + eina_list_free(od->edc_snd_path_list); + + free(od); +} + +void +option_edc_snd_path_set(option_data *od, const char *edc_snd_path) +{ + //Free the existing paths + Eina_List *l; + const char *s; + EINA_LIST_FOREACH(od->edc_snd_path_list, l, s) + eina_stringshare_del(s); + od->edc_snd_path_list = eina_list_free(od->edc_snd_path_list); + + if (od->edc_snd_path_buf) eina_strbuf_free(od->edc_snd_path_buf); + od->edc_snd_path_buf = eina_strbuf_new(); + + //parse paths by ';' + const char *lex; + Eina_Stringshare *append; + + while(edc_snd_path && (strlen(edc_snd_path) > 0)) + { + lex = strstr(edc_snd_path, ";"); + if (lex) + { + append = eina_stringshare_add_length(edc_snd_path, + (lex - edc_snd_path)); + od->edc_snd_path_list = eina_list_append(od->edc_snd_path_list, + append); + eina_strbuf_append(od->edc_snd_path_buf, " -sd "); + eina_strbuf_append(od->edc_snd_path_buf, append); + lex++; + } + else + { + append = eina_stringshare_add(edc_snd_path); + od->edc_snd_path_list = eina_list_append(od->edc_snd_path_list, + append); + eina_strbuf_append(od->edc_snd_path_buf, " -sd "); + eina_strbuf_append(od->edc_snd_path_buf, append); + } + + edc_snd_path = lex; + } +} + + +void +option_edc_img_path_set(option_data *od, const char *edc_img_path) +{ + //Free the existing paths + Eina_List *l; + const char *s; + EINA_LIST_FOREACH(od->edc_img_path_list, l, s) + eina_stringshare_del(s); + od->edc_img_path_list = eina_list_free(od->edc_img_path_list); + + if (od->edc_img_path_buf) eina_strbuf_free(od->edc_img_path_buf); + od->edc_img_path_buf = eina_strbuf_new(); + + //parse paths by ';' + const char *lex; + Eina_Stringshare *append; + + while(edc_img_path && (strlen(edc_img_path) > 0)) + { + lex = strstr(edc_img_path, ";"); + if (lex) + { + append = eina_stringshare_add_length(edc_img_path, + (lex - edc_img_path)); + od->edc_img_path_list = eina_list_append(od->edc_img_path_list, + append); + eina_strbuf_append(od->edc_img_path_buf, " -id "); + eina_strbuf_append(od->edc_img_path_buf, append); + lex++; + } + else + { + append = eina_stringshare_add(edc_img_path); + od->edc_img_path_list = eina_list_append(od->edc_img_path_list, + append); + eina_strbuf_append(od->edc_img_path_buf, " -id "); + eina_strbuf_append(od->edc_img_path_buf, append); + } + + edc_img_path = lex; + } +} + +void +option_apply(option_data *od) +{ + if (od->update_cb) od->update_cb(od->update_cb_data, od); +} + +const Eina_List * +option_edc_img_path_list_get(option_data *od) +{ + return od->edc_img_path_list; +} + +const Eina_List * +option_edc_snd_path_list_get(option_data *od) +{ + return od->edc_snd_path_list; +} + +const char * +option_edc_img_path_get(option_data *od) +{ + if (!od->edc_img_path_buf) return NULL; + return eina_strbuf_string_get(od->edc_img_path_buf); +} + +const char * +option_edc_snd_path_get(option_data *od) +{ + if (!od->edc_snd_path_buf) return NULL; + return eina_strbuf_string_get(od->edc_snd_path_buf); +} + +const char * +option_edc_path_get(option_data *od) +{ + return od->edc_path; +} + +const char * +option_edj_path_get(option_data *od) +{ + return od->edj_path; +} + +Eina_Bool +option_linenumber_get(option_data *od) +{ + return od->linenumber; +} + +Eina_Bool +option_stats_bar_get(option_data *od) +{ + return od->stats_bar; +} + +void +option_linenumber_set(option_data *od, Eina_Bool enabled) +{ + od->linenumber = enabled; +} + +void +option_stats_bar_set(option_data *od, Eina_Bool enabled) +{ + od->stats_bar = enabled; +} + +void +option_update_cb_set(option_data *od, void (*cb)(void *data, option_data *od), + void *data) +{ + od->update_cb = cb; + od->update_cb_data = data; +} + +Eina_Bool +option_part_highlight_get(option_data *od) +{ + return od->part_highlight; +} + +void +option_part_highlight_set(option_data *od, Eina_Bool highlight) +{ + od->part_highlight = highlight; +} diff --git a/src/edc_editor.c b/src/edc_editor.c new file mode 100644 index 0000000..0c04503 --- /dev/null +++ b/src/edc_editor.c @@ -0,0 +1,660 @@ +#include +#include "common.h" + +//FIXME: Make flexible +const int MAX_LINE_DIGIT_CNT = 10; + +struct editor_s +{ + Evas_Object *en_edit; + Evas_Object *en_line; + Evas_Object *scroller; + Evas_Object *layout; + Evas_Object *ctxpopup; + Evas_Object *parent; + + color_data *cd; + stats_data *sd; + option_data *od; + parser_data *pd; + menu_data *md; + + int line_max; + Eina_Stringshare *edc_path; + Eina_Stringshare *group_name; + Eina_Stringshare *part_name; + + Ecore_Idler *syntax_color_timer; + + void (*part_changed_cb)(void *data, const char *part_name); + void *part_changed_cb_data; + + Eina_Bool edit_changed : 1; + Eina_Bool linenumber : 1; + Eina_Bool ctrl_pressed : 1; +}; + +static void +last_line_inc(edit_data *ed) +{ + char buf[MAX_LINE_DIGIT_CNT]; + + ed->line_max++; + snprintf(buf, sizeof(buf), "%d
", ed->line_max); + elm_entry_entry_append(ed->en_line, buf); +} + +static void +line_decrease(edit_data *ed, int cnt) +{ + if (cnt < 1) return; + + Evas_Object *textblock = elm_entry_textblock_get(ed->en_line); + Evas_Textblock_Cursor *cur1 = evas_object_textblock_cursor_new(textblock); + evas_textblock_cursor_line_set(cur1, (ed->line_max - cnt)); + evas_textblock_cursor_word_start(cur1); + + Evas_Textblock_Cursor *cur2 = evas_object_textblock_cursor_new(textblock); + evas_textblock_cursor_line_set(cur2, ed->line_max); + evas_textblock_cursor_paragraph_last(cur2); + + evas_textblock_cursor_range_delete(cur1, cur2); + + evas_textblock_cursor_free(cur1); + evas_textblock_cursor_free(cur2); + + elm_entry_calc_force(ed->en_line); + + ed->line_max -= cnt; +} + +static void +syntax_color_apply(edit_data *ed) +{ + //FIXME: Optimize here by applying color syntax for only changed lines + ed->syntax_color_timer = NULL; + + Evas_Object *tb = elm_entry_textblock_get(ed->en_edit); + char *text = (char *) evas_object_textblock_text_markup_get(tb); + + int pos = elm_entry_cursor_pos_get(ed->en_edit); + + char *utf8 = (char *) color_cancel(ed->cd, text, strlen(text)); + if (!utf8) return; + + utf8 = strdup(utf8); + const char *translated = color_apply(ed->cd, utf8, strlen(utf8), EINA_TRUE); + + elm_entry_entry_set(ed->en_edit, NULL); + elm_entry_entry_append(ed->en_edit, translated); + elm_entry_cursor_pos_set(ed->en_edit, pos); +DFUNC_NAME(); + free(utf8); +} + +static Eina_Bool +syntax_color_timer_cb(void *data) +{ + edit_data *ed = data; + syntax_color_apply(ed); + return ECORE_CALLBACK_CANCEL; +} + +static Eina_Bool +syntax_color_animator_cb(void *data) +{ + edit_data *ed = data; + syntax_color_apply(ed); + return ECORE_CALLBACK_CANCEL; +} + +static int +deleted_line_cnt(const char *str) +{ + int num = 0; + + while(str) + { + str = strstr(str, "
"); + if (str) { num++; str++; } + else break; + } + return num; +} + +static void +edit_changed_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info) +{ + Elm_Entry_Change_Info *info = event_info; + edit_data *ed = data; + ed->edit_changed = EINA_TRUE; + + if (info->insert) + { + if (!strcmp(info->change.insert.content, "
")) last_line_inc(ed); + } + else + { + //Check the deleted line + int num = deleted_line_cnt(info->change.del.content); + line_decrease(ed, num); + } + + if (ed->syntax_color_timer) ecore_timer_del(ed->syntax_color_timer); + ed->syntax_color_timer = ecore_timer_add(0.25, syntax_color_timer_cb, ed); +} + +static void +save_msg_show(edit_data *ed) +{ + if (!option_stats_bar_get(ed->od)) return; + + char buf[PATH_MAX]; + + if (ed->edit_changed) + snprintf(buf, sizeof(buf), "File saved. \"%s\"", ed->edc_path); + else + snprintf(buf, sizeof(buf), "Already saved. \"%s\"", ed->edc_path); + + stats_info_msg_update(ed->sd, buf); +} + +void +edit_save(edit_data *ed) +{ + if (!ed->edit_changed) + { + save_msg_show(ed); + return; + } + + const char *text = elm_entry_entry_get(ed->en_edit); + Evas_Object *tb = elm_entry_textblock_get(ed->en_edit); + const char *text2 = evas_textblock_text_markup_to_utf8(tb, text); + + FILE *fp = fopen(ed->edc_path, "w"); + if (!fp) return; + + fputs(text2, fp); + fclose(fp); + + save_msg_show(ed); + //FIXME: If compile edc here? we can edit_changed FALSE; + //ed->edit_changed = EINA_FALSE; +} + +static void +ctxpopup_dismiss_cb(void *data, Evas_Object *obj, void *event_info EINA_UNUSED) +{ + edit_data *ed = data; + evas_object_del(obj); + ed->ctxpopup = NULL; + elm_object_disabled_set(ed->layout, EINA_FALSE); + elm_object_focus_set(ed->en_edit, EINA_TRUE); +} + +static void +ctxpopup_it_cb(void *data, Evas_Object *obj, void *event_info) +{ + edit_data *ed = data; + + Elm_Object_Item *it = event_info; + elm_entry_entry_insert(ed->en_edit, elm_object_item_text_get(it)); + + elm_ctxpopup_dismiss(obj); +} + +static void +slider_dismiss_cb(void *data, Evas_Object *obj, void *event_info EINA_UNUSED) +{ + edit_data *ed = data; + Evas_Object *layout = elm_object_content_get(obj); + Evas_Object *slider = elm_object_part_content_get(layout, + "elm.swallow.slider"); + char buf[128]; + attr_value *attr = evas_object_data_get(slider, "attr"); + if (attr->integer) + { + snprintf(buf, sizeof(buf), "%d", + (int) roundf(elm_slider_value_get(slider))); + } + else + { + //if the last digit number is 0 then round up. + double val = elm_slider_value_get(slider); + snprintf(buf, sizeof(buf), "%0.2f", val); + double round_down = atof(buf); + snprintf(buf, sizeof(buf), "%0.1f", val); + double round_down2 = atof(buf); + if (fabs(round_down - round_down2) < 0.0005) + snprintf(buf, sizeof(buf), "%0.1f", val); + else + snprintf(buf, sizeof(buf), "%0.2f", val); + } + elm_entry_entry_insert(ed->en_edit, buf); + ed->edit_changed = EINA_TRUE; + edit_save(ed); +} + +static void +btn_plus_cb(void *data, Evas_Object *obj EINA_UNUSED, + void *event_info EINA_UNUSED) +{ + Evas_Object *slider = data; + attr_value *attr = evas_object_data_get(slider, "attr"); + double value = elm_slider_value_get(slider); + + if (attr->integer) elm_slider_value_set(slider, value + 1); + else elm_slider_value_set(slider, value + 0.01); +} + +static void +btn_minus_cb(void *data, Evas_Object *obj EINA_UNUSED, + void *event_info EINA_UNUSED) +{ + Evas_Object *slider = data; + attr_value *attr = evas_object_data_get(slider, "attr"); + double value = elm_slider_value_get(slider); + + if (attr->integer) elm_slider_value_set(slider, value - 1); + else elm_slider_value_set(slider, value - 0.01); +} + +static void +edit_attr_candidate_show(edit_data *ed, attr_value *attr, int x, int y, const char *selected) +{ + //Show up the list of the types + Evas_Object *ctxpopup = elm_ctxpopup_add(ed->parent); + elm_object_style_set(ctxpopup, elm_app_name_get()); + + //case of strings + if (attr->strs) + { + Eina_List *l; + Eina_Stringshare *candidate; + EINA_LIST_FOREACH(attr->strs, l, candidate) + elm_ctxpopup_item_append(ctxpopup, candidate, NULL, ctxpopup_it_cb, + ed); + } + //case of numbers + else + { + //Layout + Evas_Object *layout = elm_layout_add(ed->en_edit); + elm_layout_file_set(layout, EDJE_PATH, "slider_layout"); + evas_object_show(layout); + + elm_object_content_set(ctxpopup, layout); + + //Slider + Evas_Object *slider = elm_slider_add(ed->en_edit); + elm_object_scale_set(slider, 1.2125); + if (attr->integer) elm_slider_unit_format_set(slider, "%1.0f"); + else elm_slider_unit_format_set(slider, "%1.2f"); + elm_slider_span_size_set(slider, 120); + elm_slider_indicator_show_set(slider, EINA_FALSE); + elm_slider_min_max_set(slider, attr->min, attr->max); + elm_slider_value_set(slider, atof(selected)); + evas_object_data_set(slider, "attr", attr); + evas_object_show(slider); + + elm_object_part_content_set(layout, "elm.swallow.slider", slider); + + Evas_Object *btn; + Evas_Object *img; + + //Minus Button + btn = elm_button_add(layout); + evas_object_show(btn); + evas_object_smart_callback_add(btn, "clicked", btn_minus_cb, slider); + + elm_object_part_content_set(layout, "elm.swallow.minus", btn); + + //Minus Image + img = elm_image_add(btn); + elm_image_file_set(img, EDJE_PATH, "minus_img"); + evas_object_show(img); + + elm_object_content_set(btn, img); + + //Plus Button + btn = elm_button_add(layout); + evas_object_show(btn); + evas_object_smart_callback_add(btn, "clicked", btn_plus_cb, slider); + + elm_object_part_content_set(layout, "elm.swallow.plus", btn); + + //Plus Image + img = elm_image_add(btn); + elm_image_file_set(img, EDJE_PATH, "plus_img"); + evas_object_show(img); + + elm_object_content_set(btn, img); + + evas_object_smart_callback_add(ctxpopup, "dismissed", + slider_dismiss_cb, ed); + } + + evas_object_smart_callback_add(ctxpopup, "dismissed", ctxpopup_dismiss_cb, + ed); + evas_object_move(ctxpopup, x, y); + evas_object_show(ctxpopup); + + menu_ctxpopup_register(ctxpopup); + elm_object_disabled_set(ed->layout, EINA_TRUE); + + ed->ctxpopup = ctxpopup; +} + +static void +edit_mouse_down_cb(void *data EINA_UNUSED, Evas *e EINA_UNUSED, + Evas_Object *obj, void *event_info EINA_UNUSED) +{ + Evas_Event_Mouse_Down *ev = event_info; + + if (ev->button == 1) + { + elm_entry_select_none(obj); + return; + } +} + +static void +cur_line_pos_set(edit_data *ed) +{ + if (!option_stats_bar_get(ed->od)) return; + + Evas_Coord y, h; + elm_entry_cursor_geometry_get(ed->en_edit, NULL, &y, NULL, &h); + stats_line_num_update(ed->sd, (y / h) + 1, ed->line_max); +} + +static void +edit_cursor_double_clicked_cb(void *data, Evas_Object *obj, + void *event_info EINA_UNUSED) +{ + edit_data *ed = data; + + if (ed->ctrl_pressed) return; + + const char *selected = elm_entry_selection_get(obj); + if (!selected) return; + selected = parser_markup_escape(ed->pd, selected); + + Evas_Object *textblock = elm_entry_textblock_get(obj); + Evas_Textblock_Cursor *cursor = evas_object_textblock_cursor_get(textblock); + const char *str = evas_textblock_cursor_paragraph_text_get(cursor); + char *text = elm_entry_markup_to_utf8(str); + char *cur = strstr(text, selected); + + //Get the attribute values + attr_value * attr = parser_attribute_get(ed->pd, text, cur); + if (!attr) goto end; + + int x, y; + evas_pointer_output_xy_get(evas_object_evas_get(obj), &x, &y); + edit_attr_candidate_show(ed, attr, x, y, selected); + +end: + free(text); +} + +static void +part_name_get_cb(void *data, Eina_Stringshare *part_name) +{ + edit_data *ed = data; + ed->part_name = part_name; + if (ed->part_changed_cb) + ed->part_changed_cb(ed->part_changed_cb_data, ed->part_name); +} + +void +edit_cur_part_update(edit_data *ed) +{ + if (!option_part_highlight_get(ed->od)) return; + + parser_part_name_get(ed->pd, ed->en_edit, part_name_get_cb, ed); +} + +static void +edit_cursor_changed_cb(void *data, Evas_Object *obj EINA_UNUSED, + void *event_info EINA_UNUSED) +{ + edit_data *ed = data; + cur_line_pos_set(ed); + edit_cur_part_update(ed); +} + +void +edit_part_changed_cb_set(edit_data *ed, void (*cb)(void *data, const char *part_name), void *data) +{ + ed->part_changed_cb = cb; + ed->part_changed_cb_data = data; +} + +static Eina_Bool +key_down_cb(void *data, int type EINA_UNUSED, void *ev) +{ + Ecore_Event_Key *event = ev; + edit_data *ed = data; + + //Control Key + if (!strcmp("Control_L", event->keyname)) + ed->ctrl_pressed = EINA_TRUE; + + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +key_up_cb(void *data, int type EINA_UNUSED, void *ev) +{ + Ecore_Event_Key *event = ev; + edit_data *ed = data; + + //Control Key + if (!strcmp("Control_L", event->keyname)) + ed->ctrl_pressed = EINA_FALSE; + + return ECORE_CALLBACK_PASS_ON; +} + +edit_data * +edit_init(Evas_Object *parent, stats_data *sd, option_data *od) +{ + parser_data *pd = parser_init(); + color_data *cd = color_init(); + + edit_data *ed = calloc(1, sizeof(edit_data)); + ed->sd = sd; + ed->pd = pd; + ed->cd = cd; + ed->od = od; + + ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, key_down_cb, ed); + ecore_event_handler_add(ECORE_EVENT_KEY_UP, key_up_cb, ed); + + //Scroller + Evas_Object *scroller = elm_scroller_add(parent); + //FIXME: Scroller bars doesn't appeard? + elm_scroller_policy_set(scroller, ELM_SCROLLER_POLICY_AUTO, + ELM_SCROLLER_POLICY_AUTO); + elm_object_focus_allow_set(scroller, EINA_FALSE); + evas_object_size_hint_weight_set(scroller, EVAS_HINT_EXPAND, + EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(scroller, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_show(scroller); + + //Layout + Evas_Object *layout = elm_layout_add(scroller); + elm_layout_file_set(layout, EDJE_PATH, "edit_layout"); + evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(layout, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_show(layout); + + elm_object_content_set(scroller, layout); + + //Line Number Entry + Evas_Object *en_line = elm_entry_add(layout); + elm_object_style_set(en_line, "linenumber"); + elm_entry_editable_set(en_line, EINA_FALSE); + elm_entry_line_wrap_set(en_line, EINA_FALSE); + evas_object_size_hint_weight_set(en_line, 0, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(en_line, 0, EVAS_HINT_FILL); + evas_object_show(en_line); + + elm_object_part_content_set(layout, "elm.swallow.linenumber", en_line); + + //EDC Editor Entry + Evas_Object *en_edit = elm_entry_add(layout); + elm_object_style_set(en_edit, elm_app_name_get()); + elm_entry_context_menu_disabled_set(en_edit, EINA_TRUE); + elm_entry_line_wrap_set(en_edit, EINA_FALSE); + evas_object_smart_callback_add(en_edit, "changed,user", edit_changed_cb, ed); + evas_object_smart_callback_add(en_edit, "cursor,changed", + edit_cursor_changed_cb, ed); + evas_object_smart_callback_add(en_edit, "clicked,double", + edit_cursor_double_clicked_cb, ed); + evas_object_size_hint_weight_set(en_edit, EVAS_HINT_EXPAND, + EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(en_edit, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_event_callback_add(en_edit, EVAS_CALLBACK_MOUSE_DOWN, + edit_mouse_down_cb, ed); + evas_object_show(en_edit); + + elm_object_focus_set(en_edit, EINA_TRUE); + + elm_object_part_content_set(layout, "elm.swallow.edit", en_edit); + + ed->scroller = scroller; + ed->en_line = en_line; + ed->en_edit = en_edit; + ed->layout = layout; + ed->parent = parent; + ed->linenumber = EINA_TRUE; + + edit_line_number_toggle(ed); + + return ed; +} + +void +edit_editable_set(edit_data *ed, Eina_Bool editable) +{ + elm_entry_editable_set(ed->en_edit, editable); +} + +Evas_Object * +edit_obj_get(edit_data *ed) +{ + return ed->scroller; +} + +void +edit_term(edit_data *ed) +{ + color_data *cd = ed->cd; + parser_data *pd = ed->pd; + + if (ed->group_name) eina_stringshare_del(ed->group_name); + if (ed->syntax_color_timer) ecore_timer_del(ed->syntax_color_timer); + free(ed); + + color_term(cd); + parser_term(pd); +} + +void +edit_edc_read(edit_data *ed, const char *file_path) +{ + char buf[MAX_LINE_DIGIT_CNT]; + + Eina_File *file = eina_file_open(file_path, EINA_FALSE); + if (!file) goto err; + + Eina_Iterator *itr = eina_file_map_lines(file); + if (!itr) goto err; + + Eina_Strbuf *strbuf = eina_strbuf_new(); + if (!strbuf) goto err; + + Eina_File_Line *line; + int line_num = 0; + + EINA_ITERATOR_FOREACH(itr, line) + { + //Append edc code + if (line_num > 0) + { + if (!eina_strbuf_append(strbuf, "
")) goto err; + } + + if (!eina_strbuf_append_length(strbuf, line->start, line->length)) + goto err; + line_num++; + + //Append line number + sprintf(buf, "%d
", line_num); + elm_entry_entry_append(ed->en_line, buf); + } + + elm_entry_entry_append(ed->en_edit, eina_strbuf_string_get(strbuf)); + + ed->line_max = line_num; + ed->edc_path = eina_stringshare_add(file_path); + if (ed->group_name) eina_stringshare_del(ed->group_name); + ed->group_name = parser_group_name_get(ed->pd, ed->en_edit); + + stats_edc_file_set(ed->sd, ed->group_name); + ecore_animator_add(syntax_color_animator_cb, ed); + +err: + if (strbuf) eina_strbuf_free(strbuf); + if (itr) eina_iterator_free(itr); + if (file) eina_file_close(file); +} + +void +edit_focus_set(edit_data *ed) +{ + elm_object_focus_set(ed->en_edit, EINA_TRUE); +} + +Eina_Bool +edit_changed_get(edit_data *ed) +{ + return ed->edit_changed; +} + +void +edit_changed_reset(edit_data *ed) +{ + ed->edit_changed = EINA_FALSE; +} + +void +edit_line_number_toggle(edit_data *ed) +{ + Eina_Bool linenumber = option_linenumber_get(ed->od); + if (ed->linenumber == linenumber) return; + ed->linenumber = linenumber; + + if (linenumber) + elm_object_signal_emit(ed->layout, "elm,state,linenumber,show", ""); + else + elm_object_signal_emit(ed->layout, "elm,state,linenumber,hide", ""); +} + +void +edit_new(edit_data *ed) +{ + elm_entry_entry_set(ed->en_edit, ""); + elm_entry_entry_set(ed->en_line, ""); + edit_edc_read(ed, option_edc_path_get(ed->od)); + ed->edit_changed = EINA_TRUE; +} + +const char * +edit_group_name_get(edit_data *ed) +{ + return ed->group_name; +} diff --git a/src/edc_parser.c b/src/edc_parser.c new file mode 100644 index 0000000..691bbfb --- /dev/null +++ b/src/edc_parser.c @@ -0,0 +1,408 @@ +#include +#include "common.h" + +struct parser_s +{ + Eina_List *attrs; //FIXME: Use Inlist + Ecore_Thread *thread; +}; + +typedef struct parser_attr_s +{ + Eina_Stringshare *keyword; + attr_value value; +} parser_attr; + +typedef struct part_name_thread_data_s +{ + parser_data *pd; + char *utf8; + int cur_pos; + const char *part_name; + void (*cb)(void *data, Eina_Stringshare *part_name); + void *cb_data; +} part_name_td; + +static void +parser_type_init(parser_data *pd) +{ + parser_attr *attr; + + //FIXME: construct from the configuration file. + Eina_List *types = NULL; + types = eina_list_append(types, eina_stringshare_add("RECT")); + types = eina_list_append(types, eina_stringshare_add("TEXT")); + types = eina_list_append(types, eina_stringshare_add("IMAGE")); + types = eina_list_append(types, eina_stringshare_add("SWALLOW")); + types = eina_list_append(types, eina_stringshare_add("TEXTBLOCK")); + types = eina_list_append(types, eina_stringshare_add("GRADIENT")); + types = eina_list_append(types, eina_stringshare_add("GROUP")); + types = eina_list_append(types, eina_stringshare_add("BOX")); + types = eina_list_append(types, eina_stringshare_add("TABLE")); + types = eina_list_append(types, eina_stringshare_add("EXTERNAL")); + types = eina_list_append(types, eina_stringshare_add("PROXY")); + types = eina_list_append(types, eina_stringshare_add("SPACER")); + + attr = calloc(1, sizeof(parser_attr)); + attr->keyword = eina_stringshare_add("type"); + attr->value.strs = types; + pd->attrs = eina_list_append(pd->attrs, attr); + + Eina_List *comps = NULL; + comps = eina_list_append(comps, eina_stringshare_add("RAW")); + comps = eina_list_append(comps, eina_stringshare_add("USER")); + comps = eina_list_append(comps, eina_stringshare_add("COMP")); + comps = eina_list_append(comps, eina_stringshare_add("LOSSY")); + + attr = calloc(1, sizeof(parser_attr)); + attr->keyword = eina_stringshare_add("image"); + attr->value.strs = comps; + pd->attrs = eina_list_append(pd->attrs, attr); + + Eina_List *transit = NULL; + transit = eina_list_append(transit, eina_stringshare_add("LINEAR")); + transit = eina_list_append(transit, eina_stringshare_add("ACCELERATE")); + transit = eina_list_append(transit, eina_stringshare_add("DECELERATE")); + transit = eina_list_append(transit, eina_stringshare_add("SINUSOIDAL")); + transit = eina_list_append(transit, eina_stringshare_add("ACCELERATE_FACTOR")); + transit = eina_list_append(transit, eina_stringshare_add("DECELERATE_FACTOR")); + transit = eina_list_append(transit, eina_stringshare_add("SINUSOIDAL_FACTOR")); + transit = eina_list_append(transit, eina_stringshare_add("DIVISOR_INTERP")); + transit = eina_list_append(transit, eina_stringshare_add("BOUNCE")); + transit = eina_list_append(transit, eina_stringshare_add("SPRING")); + + attr = calloc(1, sizeof(parser_attr)); + attr->keyword = eina_stringshare_add("transition"); + attr->value.strs = transit; + pd->attrs = eina_list_append(pd->attrs, attr); + + attr = calloc(1, sizeof(parser_attr)); + attr->keyword = eina_stringshare_add("color"); + attr->value.min = 0; + attr->value.max = 255; + attr->value.integer = EINA_TRUE; + pd->attrs = eina_list_append(pd->attrs, attr); + + attr = calloc(1, sizeof(parser_attr)); + attr->keyword = eina_stringshare_add("relative"); + attr->value.min = 0.0; + attr->value.max = 1; + pd->attrs = eina_list_append(pd->attrs, attr); + + attr = calloc(1, sizeof(parser_attr)); + attr->keyword = eina_stringshare_add("scale"); + attr->value.min = 0; + attr->value.max = 1; + attr->value.integer = EINA_TRUE; + pd->attrs = eina_list_append(pd->attrs, attr); + + attr = calloc(1, sizeof(parser_attr)); + attr->keyword = eina_stringshare_add("fixed"); + attr->value.min = 0; + attr->value.max = 1; + attr->value.integer = EINA_TRUE; + pd->attrs = eina_list_append(pd->attrs, attr); + + attr = calloc(1, sizeof(parser_attr)); + attr->keyword = eina_stringshare_add("aspect"); + attr->value.min = 0.0; + attr->value.max = 1.0; + pd->attrs = eina_list_append(pd->attrs, attr); + + attr = calloc(1, sizeof(parser_attr)); + attr->keyword = eina_stringshare_add("align"); + attr->value.min = 0.0; + attr->value.max = 1.0; + pd->attrs = eina_list_append(pd->attrs, attr); + + attr = calloc(1, sizeof(parser_attr)); + attr->keyword = eina_stringshare_add("size"); + attr->value.min = 1; + attr->value.max = 255; + attr->value.integer = EINA_TRUE; + pd->attrs = eina_list_append(pd->attrs, attr); + + attr = calloc(1, sizeof(parser_attr)); + attr->keyword = eina_stringshare_add("min"); + attr->value.min = 0; + attr->value.max = 1000; + attr->value.integer = EINA_TRUE; + pd->attrs = eina_list_append(pd->attrs, attr); + + attr = calloc(1, sizeof(parser_attr)); + attr->keyword = eina_stringshare_add("max"); + attr->value.min = 0; + attr->value.max = 1000; + attr->value.integer = EINA_TRUE; + pd->attrs = eina_list_append(pd->attrs, attr); + + attr = calloc(1, sizeof(parser_attr)); + attr->keyword = eina_stringshare_add("mouse_events"); + attr->value.min = 0; + attr->value.max = 1000; + attr->value.integer = EINA_TRUE; + pd->attrs = eina_list_append(pd->attrs, attr); + +} + +attr_value * +parser_attribute_get(parser_data *pd, const char *text, const char *cur) +{ + if (!text || !cur) return NULL; + + char *p = (char *) cur; + + Eina_List *l; + parser_attr *attr; + Eina_Bool instring = EINA_FALSE; + Eina_Bool necessary = EINA_FALSE; + + while (p >= text) + { + if (*p == ':') + { + necessary = EINA_TRUE; + break; + } + if (*p == '\"') instring = !instring; + p--; + } + if (!p || instring || !necessary) return NULL; + + while (p > text) + { + if ((*p == ';') || (*p == '.') || (*p == ' ')) break; + p--; + } + + if (!p) return NULL; + if (p != text) p++; + + EINA_LIST_FOREACH(pd->attrs, l, attr) + { + if (strstr(p, attr->keyword)) + return &attr->value; + } + + return NULL; +} + +parser_data * +parser_init() +{ + parser_data *pd = calloc(1, sizeof(parser_data)); + parser_type_init(pd); + return pd; +} + +void +parser_term(parser_data *pd) +{ + if (pd->thread) ecore_thread_cancel(pd->thread); + + Eina_List *l, *ll; + parser_attr *attr; + Eina_Stringshare *str; + + EINA_LIST_FOREACH(pd->attrs, l, attr) + { + eina_stringshare_del(attr->keyword); + + EINA_LIST_FOREACH(attr->value.strs, ll, str) + eina_stringshare_del(str); + eina_list_free(attr->value.strs); + free(attr); + } + eina_list_free(pd->attrs); + + free(pd); +} + +const char * +parser_markup_escape(parser_data *pd EINA_UNUSED, const char *str) +{ + const char *escaped = strchr(str, '>'); + if (!escaped) return str; + if ((escaped + 1) >= (str + strlen(str))) return str; + escaped++; + + return escaped; +} + +static void +part_name_thread_blocking(void *data, Ecore_Thread *thread EINA_UNUSED) +{ + part_name_td *td = data; + + char *utf8 = td->utf8; + int cur_pos = td->cur_pos; + + char *p = utf8; + char *end = utf8 + cur_pos; + + const char *quot = "\""; + int quot_len = 1; // strlen("""); + const char *part = "part"; + int part_len = 4; //strlen("part"); + const char *parts = "parts"; + int parts_len = 5; //strlen("parts"); + + int bracket = 0; + const char *part_name = NULL; + int part_name_len = 0; + Eina_Bool part_in = EINA_FALSE; + + while (p <= end) + { + //Skip "" range + if (*p == *quot) + { + p += quot_len; + p = strstr(p, quot); + if (!p) goto end; + p += quot_len; + } + + if (part_in && (*p == '{')) + { + bracket++; + p++; + continue; + } + + if (part_in && (*p == '}') && (p < end)) + { + bracket--; + p++; + if (bracket == 0) part_in = EINA_FALSE; + continue; + } + if (strncmp(p, parts, parts_len)) + { + if (!strncmp(p, part, part_len)) + { + p += part_len; + char *name_begin = strstr(p, quot); + if (!name_begin) goto end; + name_begin += quot_len; + p = name_begin; + char *name_end = strstr(p, quot); + if (!name_end) goto end; + part_name = name_begin; + part_name_len = name_end - name_begin; + p = name_end + quot_len; + bracket = 1; + part_in = EINA_TRUE; + continue; + } + } + p++; + } + if (part_name) + { + if (bracket == 0) + { + part_name = NULL; + goto end; + } + else + part_name = eina_stringshare_add_length(part_name, part_name_len); + } + +end: + if (utf8) + { + free(utf8); + td->utf8 = NULL; + } + td->part_name = part_name; +} + +static void +part_name_thread_end(void *data, Ecore_Thread *thread EINA_UNUSED) +{ + part_name_td *td = data; + Eina_Stringshare *part_name = td->part_name; + td->cb(td->cb_data, part_name); + td->pd->thread = NULL; + free(td); +} + +static void +part_name_thread_cancel(void *data, Ecore_Thread *thread EINA_UNUSED) +{ + part_name_td *td = data; + td->pd->thread = NULL; + if (td->utf8) free(td->utf8); + free(td); +} + +void +parser_part_name_get(parser_data *pd, Evas_Object *entry, void (*cb)(void *data, Eina_Stringshare *part_name), void *data) +{ + if (pd->thread) ecore_thread_cancel(pd->thread); + + part_name_td *td = calloc(1, sizeof(part_name_td)); + if (!td) return; + + Evas_Object *tb = elm_entry_textblock_get(entry); + char *text = (char *) evas_object_textblock_text_markup_get(tb); + if (!text) return; + + char *utf8 = elm_entry_markup_to_utf8(text); + if (!utf8) return; + + td->pd = pd; + td->utf8 = utf8; + td->cur_pos = elm_entry_cursor_pos_get(entry); + td->cb = cb; + td->cb_data = data; + + pd->thread = ecore_thread_run(part_name_thread_blocking, + part_name_thread_end, + part_name_thread_cancel, + td); +} + +Eina_Stringshare +*parser_group_name_get(parser_data *pd EINA_UNUSED, Evas_Object *entry) +{ + Evas_Object *tb = elm_entry_textblock_get(entry); + char *text = (char *) evas_object_textblock_text_markup_get(tb); + char *p = text; + + const char *quot = """; + int quot_len = 6; // strlen("""); + const char *group = "group"; + int group_len = 5; //strlen("group"); + + while (p < (text + strlen(text))) + { + //Skip "" range + if (!strncmp(p, quot, quot_len)) + { + p += quot_len; + p = strstr(p, quot); + if (!p) return NULL; + p += quot_len; + } + + if (!strncmp(p, group, group_len)) + { + p += group_len; + char *name_begin = strstr(p, quot); + if (!name_begin) return NULL; + name_begin += quot_len; + p = name_begin; + char *name_end = strstr(p, quot); + if (!name_end) return NULL; + return eina_stringshare_add_length(name_begin, + name_end - name_begin); + break; + } + p++; + } + return NULL; +} + + diff --git a/src/edc_viewer.c b/src/edc_viewer.c new file mode 100644 index 0000000..5a9b6a6 --- /dev/null +++ b/src/edc_viewer.c @@ -0,0 +1,226 @@ +#include +#include "common.h" + +struct viewer_s +{ + stats_data *sd; + option_data *od; + + Evas_Object *parent; + Evas_Object *layout; + Evas_Object *scroller; + + Evas_Object *part_obj; + Evas_Object *part_highlight; + + Eina_Stringshare *group_name; + Eina_Stringshare *part_name; + + Eina_Bool view_reload; +}; + +static void +part_obj_geom_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, + void *event_info EINA_UNUSED) +{ + view_data *vd = data; + Evas_Object *part_highlight = vd->part_highlight; + + //Create Part Highlight Object + if (!part_highlight && vd->part_name) + { + part_highlight = elm_layout_add(vd->scroller); + evas_object_smart_member_add(part_highlight, vd->scroller); + elm_layout_file_set(part_highlight, EDJE_PATH, "part_highlight"); + evas_object_pass_events_set(part_highlight, EINA_TRUE); + evas_object_show(part_highlight); + } + + Evas_Coord x, y, w , h; + evas_object_geometry_get(obj, &x, &y, &w, &h); + evas_object_move(part_highlight, x, y); + evas_object_resize(part_highlight, w, h); + + vd->part_highlight = part_highlight; +} + +static void +part_obj_del_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, + void *event_info EINA_UNUSED) +{ + view_data *vd = data; + vd->part_obj = NULL; +} + +static void +layout_resize_cb(void *data, Evas *e EINA_UNUSED, + Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + view_data *vd = data; + if (!option_stats_bar_get(vd->od)) return; + + Evas_Coord w, h; + evas_object_geometry_get(obj, NULL, NULL, &w, &h); + option_view_size_set(vd->od, w, h); + stats_view_size_update(vd->sd); +} + +static void +layout_mouse_move_cb(void *data, Evas *e EINA_UNUSED, + Evas_Object *obj EINA_UNUSED, void *event_info) +{ + view_data *vd = data; + if (!option_stats_bar_get(vd->od)) return; + + Evas_Event_Mouse_Move *ev = event_info; + + Evas_Coord x, y, w, h; + evas_object_geometry_get(obj, &x, &y, &w, &h); + stats_cursor_pos_update(vd->sd, ev->cur.canvas.x - x, ev->cur.canvas.y - y, + (float) (ev->cur.canvas.x - x) / (float) w, + (float) (ev->cur.canvas.y - y) / (float) h); +} + +static Evas_Object * +view_scroller_create(Evas_Object *parent) +{ + Evas_Object *scroller = elm_scroller_add(parent); + elm_object_focus_allow_set(scroller, EINA_FALSE); + evas_object_size_hint_weight_set(scroller, EVAS_HINT_EXPAND, + EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(scroller, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_show(scroller); + + return scroller; +} + + +static Evas_Object * +view_obj_create(view_data *vd, const char *file_path, const char *group) +{ + Evas_Object *layout = elm_layout_add(vd->scroller); + vd->view_reload = !elm_layout_file_set(layout, file_path, group); + evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, + EVAS_HINT_EXPAND); + evas_object_event_callback_add(layout, EVAS_CALLBACK_RESIZE, + layout_resize_cb, vd); + evas_object_event_callback_add(layout, EVAS_CALLBACK_MOUSE_MOVE, + layout_mouse_move_cb, vd); + evas_object_show(layout); + + return layout; +} + +static Eina_Bool +view_obj_idler_cb(void *data) +{ + view_data *vd = data; + vd->layout = view_obj_create(vd, option_edj_path_get(vd->od), + vd->group_name); + elm_object_content_set(vd->scroller, vd->layout); + + fake_obj_new(vd->layout); + + return ECORE_CALLBACK_CANCEL; +} + +void +view_new(view_data *vd, const char *group) +{ + eina_stringshare_replace(&vd->group_name, group); + ecore_idler_add(view_obj_idler_cb, vd); +} + +void +view_reload_need_set(view_data *vd, Eina_Bool reload) +{ + vd->view_reload = reload; +} + +Eina_Bool +view_reload_need_get(view_data *vd) +{ + return vd->view_reload; +} + +view_data * +view_init(Evas_Object *parent, const char *group, stats_data *sd, + option_data *od) +{ + view_data *vd = calloc(1, sizeof(view_data)); + vd->parent = parent; + vd->sd = sd; + vd->od = od; + vd->scroller = view_scroller_create(parent); + + view_new(vd, group); + + return vd; +} + +void +view_term(view_data *vd) +{ + if (vd->group_name) eina_stringshare_del(vd->group_name); + if (vd->part_name) eina_stringshare_del(vd->part_name); + + if (vd->part_obj) + evas_object_event_callback_del(vd->part_obj, EVAS_CALLBACK_DEL, + part_obj_del_cb); + + free(vd); +} + +Evas_Object * +view_obj_get(view_data *vd) +{ + return vd->scroller; +} + +void +view_part_highlight_set(view_data *vd, const char *part_name) +{ + if (!vd->layout) return; + + if (!part_name) + { + if (vd->part_highlight) + { + evas_object_del(vd->part_highlight); + vd->part_highlight = NULL; + } + if (vd->part_name) + { + eina_stringshare_del(vd->part_name); + vd->part_name = NULL; + } + return; + } + if (vd->part_obj && (vd->part_name == part_name)) return; + + //Delete the previous part callbacks + if (vd->part_obj) + { + evas_object_event_callback_del(vd->part_obj, EVAS_CALLBACK_RESIZE, + part_obj_geom_cb); + evas_object_event_callback_del(vd->part_obj, EVAS_CALLBACK_MOVE, + part_obj_geom_cb); + evas_object_event_callback_del(vd->part_obj, EVAS_CALLBACK_DEL, + part_obj_del_cb); + } + Evas_Object *edje = elm_layout_edje_get(vd->layout); + + Evas_Object *part_obj = + (Evas_Object *) edje_object_part_object_get(edje, part_name); + if (!part_obj) return; + evas_object_event_callback_add(part_obj, EVAS_CALLBACK_RESIZE, + part_obj_geom_cb, vd); + evas_object_event_callback_add(part_obj, EVAS_CALLBACK_MOVE, + part_obj_geom_cb, vd); + evas_object_event_callback_add(part_obj, EVAS_CALLBACK_DEL, part_obj_del_cb, + vd); + + vd->part_obj = part_obj; + eina_stringshare_replace(&vd->part_name, part_name); + part_obj_geom_cb(vd, evas_object_evas_get(edje), part_obj, NULL); +} diff --git a/src/fake_obj.c b/src/fake_obj.c new file mode 100644 index 0000000..97028e5 --- /dev/null +++ b/src/fake_obj.c @@ -0,0 +1,147 @@ +#define EDJE_EDIT_IS_UNSTABLE_AND_I_KNOW_ABOUT_IT 1 + +#include +#include +#include "common.h" + +typedef struct part_obj_s +{ + Evas_Object *obj; + Eina_Stringshare *name; +} part_obj; + +struct fake_obj_s +{ + Evas_Object *layout; + Eina_List *swallows; +}; + +const char *FAKEOBJ = "fakeobj"; + +void +fake_objs_update(fake_obj *fo) +{ + Evas_Object *edje = elm_layout_edje_get(fo->layout); + Eina_List *parts = edje_edit_parts_list_get(edje); + Eina_List *l, *l_next, *l2; + char *part_name; + Edje_Part_Type type; + part_obj *po; + + Eina_Bool removed = EINA_TRUE; + + //Remove the fake swallow objects that parts are removed. + EINA_LIST_FOREACH_SAFE(fo->swallows, l, l_next, po) + { + EINA_LIST_FOREACH(parts, l2, part_name) + { + if (strlen(po->name) > strlen(part_name)) + { + if (strcmp(po->name, part_name)) continue; + } + else + { + if (strcmp(part_name, po->name)) continue; + } + + if (edje_edit_part_type_get(edje, part_name) != + EDJE_PART_TYPE_SWALLOW) continue; + + removed = EINA_FALSE; + } + if (removed) + { + evas_object_del(po->obj); + eina_stringshare_del(po->name); + fo->swallows = eina_list_remove(fo->swallows, l); + free(po); + } + } + + //Add new part object or Update changed part. + EINA_LIST_FOREACH(parts, l, part_name) + { + type = edje_edit_part_type_get(edje, part_name); + + if (type == EDJE_PART_TYPE_SWALLOW) + { + //Check this part is exist + if (edje_object_part_swallow_get(edje, part_name)) continue; + + //New part. Add fake object. + Evas_Object *obj = elm_layout_add(fo->layout); + elm_layout_file_set(obj, EDJE_PATH, "swallow"); + evas_object_show(obj); + elm_object_part_content_set(fo->layout, part_name, obj); + + part_obj *po = malloc(sizeof(part_obj)); + if (!po) continue; + + po->obj = obj; + po->name = eina_stringshare_add(part_name); + fo->swallows = eina_list_append(fo->swallows, po); + } + } +} + +static Eina_Bool +animator_cb(void *data) +{ + fake_obj *fo = data; + fake_objs_update(fo); + return ECORE_CALLBACK_CANCEL; +} + +static void +edje_change_file_cb(void *data, Evas_Object *obj EINA_UNUSED, + const char *emission EINA_UNUSED, + const char *source EINA_UNUSED) +{ + fake_obj *fo = data; + fake_objs_update(fo); +} + +static void +layout_del_cb(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, + void *event_info EINA_UNUSED) +{ + fake_obj_del(obj); +} + +void fake_obj_new(Evas_Object *layout) +{ + fake_obj *fo = evas_object_data_get(layout, FAKEOBJ); + if (fo) return; + + fo = calloc(1, sizeof(fake_obj)); + + edje_object_signal_callback_add(elm_layout_edje_get(layout), + "edje,change,file", "edje", + edje_change_file_cb, fo); + + ecore_animator_add(animator_cb, fo); + evas_object_data_set(layout, FAKEOBJ, fo); + + evas_object_event_callback_add(layout, EVAS_CALLBACK_DEL, layout_del_cb, fo); + + fo->layout = layout; +} + +void fake_obj_del(Evas_Object *layout) +{ + fake_obj *fo = evas_object_data_get(layout, FAKEOBJ); + if (fo) return; + + Eina_List *l; + part_obj *po; + EINA_LIST_FOREACH(fo->swallows, l, po) + { + evas_object_del(po->obj); + eina_stringshare_del(po->name); + free(po); + } + eina_list_free(fo->swallows); + + evas_object_data_set(layout, FAKEOBJ, NULL); + evas_object_event_callback_del(layout, EVAS_CALLBACK_DEL, layout_del_cb); +} diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..6af577f --- /dev/null +++ b/src/main.c @@ -0,0 +1,474 @@ +#include +#include +#include "common.h" + +char EDJE_PATH[PATH_MAX]; + +struct app_s +{ + edit_data *ed; + view_data *vd; + menu_data *md; + stats_data *sd; + option_data *od; + + Evas_Object *layout; + Evas_Object *panes; + Evas_Object *win; + + Eina_Bool ctrl_pressed : 1; + Eina_Bool menu_opened : 1; +}; + +static const char *EDJE_CC_CMD; + +static Eina_Bool +rebuild_edc() +{ + system(EDJE_CC_CMD); + return EINA_TRUE; +} + +Eina_Bool +edc_changed_cb(void *data, int type EINA_UNUSED, void *event) +{ + //FIXME: Why does this callback called multiple times? + Eio_Monitor_Event *ev = event; + app_data *ad = data; + + if (!edit_changed_get(ad->ed)) return ECORE_CALLBACK_RENEW; + + if (strcmp(ev->filename, option_edc_path_get(ad->od))) + return ECORE_CALLBACK_RENEW; + + rebuild_edc(); + edit_changed_reset(ad->ed); + + return ECORE_CALLBACK_RENEW; +} + +static Eina_Bool +edje_cc_cmd_set(option_data *od) +{ + Eina_Strbuf *buf = eina_strbuf_new(); + if (!buf) return EINA_FALSE; + eina_strbuf_append_printf(buf, "edje_cc -fastcomp %s %s %s %s", + option_edc_path_get(od), + option_edj_path_get(od), + option_edc_img_path_get(od), + option_edc_snd_path_get(od)); + eina_strbuf_append(buf, " > /dev/null"); + EDJE_CC_CMD = eina_strbuf_string_steal(buf); + eina_strbuf_free(buf); + + return EINA_TRUE; +} + +static void +win_delete_request_cb(void *data, Evas_Object *obj EINA_UNUSED, + void *event_info EINA_UNUSED) +{ + app_data *ad = data; + menu_exit(ad->md); +} + +static Eina_Bool +base_gui_construct(app_data *ad) +{ + char buf[PATH_MAX]; + + //Window + Evas_Object *win = elm_win_util_standard_add(elm_app_name_get(), + "Edje Writer"); + elm_win_focus_highlight_enabled_set(win, EINA_TRUE); + evas_object_smart_callback_add(win, "delete,request", win_delete_request_cb, + ad); + evas_object_show(win); + + //Window icon + Evas_Object *icon = evas_object_image_add(evas_object_evas_get(win)); + snprintf(buf, sizeof(buf), "%s/images/logo.png", elm_app_data_dir_get()); + evas_object_image_file_set(icon, buf, NULL); + evas_object_show(icon); + elm_win_icon_object_set(win, icon); + + //Base Layout + Evas_Object *layout = elm_layout_add(win); + elm_layout_file_set(layout, EDJE_PATH, "main_layout"); + evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, + EVAS_HINT_EXPAND); + elm_win_resize_object_add(win, layout); + evas_object_show(layout); + + //Panes + Evas_Object *panes = panes_create(layout); + elm_object_part_content_set(layout, "elm.swallow.panes", panes); + + ad->win = win; + ad->layout = layout; + ad->panes = panes; + + return EINA_TRUE; +} + +static Eina_Bool +edc_proto_setup(option_data *od) +{ + Eina_Bool success = EINA_TRUE; + +if (!ecore_file_exists(option_edc_path_get(od))) + { + EINA_LOG_INFO("No working edc file exists. Copy a proto.edc"); + success = eina_file_copy("./data/.proto/proto.edc", + option_edc_path_get(od), + EINA_FILE_COPY_DATA, NULL, NULL); + } + + if (!success) + { + EINA_LOG_ERR("Cannot find proto.edc in ./data/.proto/"); + return EINA_FALSE; + } + + rebuild_edc(); + + return EINA_TRUE; +} + +static Eina_Bool +main_key_up_cb(void *data, int type EINA_UNUSED, void *ev) +{ + Ecore_Event_Key *event = ev; + app_data *ad = data; + + if (!strcmp("Control_L", event->keyname)) + { + edit_editable_set(ad->ed, EINA_TRUE); + ad->ctrl_pressed = EINA_FALSE; + } + + return ECORE_CALLBACK_PASS_ON; +} + +static void +statusbar_toggle(app_data *ad) +{ + if (option_stats_bar_get(ad->od)) + elm_object_signal_emit(ad->layout, "elm,state,statusbar,show", ""); + else + elm_object_signal_emit(ad->layout, "elm,state,statusbar,hide", ""); +} + +static void +part_highlight_toggle(app_data *ad) +{ + Eina_Bool highlight = option_part_highlight_get(ad->od); + if (highlight) edit_cur_part_update(ad->ed); + else view_part_highlight_set(ad->vd, NULL); + + if (!option_stats_bar_get(ad->od)) return; + if (highlight) + stats_info_msg_update(ad->sd, "Part Highlighting Enabled"); + else + stats_info_msg_update(ad->sd, "Part Highlighting Disabled"); +} + +static Eina_Bool +main_key_down_cb(void *data, int type EINA_UNUSED, void *ev) +{ + Ecore_Event_Key *event = ev; + app_data *ad = data; + + if (ad->ctrl_pressed) + { + //Save + if (!strcmp(event->keyname, "s") || !strcmp(event->keyname, "S")) + { + edit_save(ad->ed); + return ECORE_CALLBACK_DONE; + } + //Load + if (!strcmp(event->keyname, "l") || !strcmp(event->keyname, "L")) + { + ad->menu_opened = menu_edc_load(ad->md); + return ECORE_CALLBACK_DONE; + } + //Copy + if (!strcmp(event->keyname, "c") || !strcmp(event->keyname, "C")) + return ECORE_CALLBACK_PASS_ON; + //Paste + if (!strcmp(event->keyname, "v") || !strcmp(event->keyname, "V")) + return ECORE_CALLBACK_PASS_ON; + //Select All + if (!strcmp(event->keyname, "a") || !strcmp(event->keyname, "A")) + return ECORE_CALLBACK_PASS_ON; + //Part Highlight + if (!strcmp(event->keyname, "h") || !strcmp(event->keyname, "H")) + { + option_part_highlight_set(ad->od, + !option_part_highlight_get(ad->od)); + part_highlight_toggle(ad); + return ECORE_CALLBACK_DONE; + } + if (!strcmp(event->keyname, "comma")) + { + panes_full_view_left(ad->panes); + return ECORE_CALLBACK_DONE; + } + if (!strcmp(event->keyname, "period")) + { + panes_full_view_right(ad->panes); + return ECORE_CALLBACK_DONE; + } + if (!strcmp(event->keyname, "slash")) + { + panes_full_view_cancel(ad->panes); + return ECORE_CALLBACK_DONE; + } + + return ECORE_CALLBACK_DONE; + } + + //Main Menu + if (!strcmp(event->keyname, "Escape")) + { + ad->menu_opened = menu_option_toggle(); + if (!ad->menu_opened) + edit_focus_set(ad->ed); + return ECORE_CALLBACK_DONE; + } + + if (ad->menu_opened) return ECORE_CALLBACK_PASS_ON; + + //Control Key + if (!strcmp("Control_L", event->keyname)) + { + ad->ctrl_pressed = EINA_TRUE; + } + //Line Number + else if (!strcmp(event->keyname, "F5")) + { + option_linenumber_set(ad->od, !option_linenumber_get(ad->od)); + edit_line_number_toggle(ad->ed); + return ECORE_CALLBACK_DONE; + } + //Statusbar + else if (!strcmp(event->keyname, "F6")) + { + option_stats_bar_set(ad->od, !option_stats_bar_get(ad->od)); + statusbar_toggle(ad); + return ECORE_CALLBACK_DONE; + } + + return ECORE_CALLBACK_PASS_ON; +} + +static void +part_changed_cb(void *data, const char *part_name) +{ + app_data *ad = data; + view_part_highlight_set(ad->vd, part_name); +} + +static void +edc_edit_set(app_data *ad, stats_data *sd, option_data *od) +{ + edit_data *ed = edit_init(ad->panes, sd, od); + edit_edc_read(ed, option_edc_path_get(od)); + elm_object_part_content_set(ad->panes, "right", edit_obj_get(ed)); + edit_part_changed_cb_set(ed, part_changed_cb, ad); + ad->ed = ed; +} + +static void +edc_view_set(app_data *ad, option_data *od, stats_data *sd) +{ + const char *group = edit_group_name_get(ad->ed); + view_data *vd = view_init(ad->panes, group, sd, od); + elm_object_part_content_set(ad->panes, "left", view_obj_get(vd)); + ad->vd = vd; +} + +static void +statusbar_set(app_data *ad, option_data *od) +{ + stats_data *sd = stats_init(ad->layout, od); + elm_object_part_content_set(ad->layout, "elm.swallow.statusbar", + stats_obj_get(sd)); + ad->sd = sd; + option_stats_bar_set(ad->od, EINA_TRUE); + statusbar_toggle(ad); +} + +static void +option_update_cb(void *data, option_data *od) +{ + app_data *ad = data; + edje_cc_cmd_set(od); + edit_line_number_toggle(ad->ed); + statusbar_toggle(ad); + part_highlight_toggle(ad); + + //previous build was failed, Need to rebuild then reload the edj. + if (view_reload_need_get(ad->vd)) + { + rebuild_edc(); + edit_changed_reset(ad->ed); + view_new(ad->vd, edit_group_name_get(ad->ed)); + part_changed_cb(ad, NULL); + } + //If the edc is reloaded, then rebuild it! + else if (edit_changed_get(ad->ed)) + { + rebuild_edc(); + edit_changed_reset(ad->ed); + } +} + +static void +args_dispatch(int argc, char **argv, char *edc_path, char *img_path, + char *snd_path) +{ + Eina_Bool default_edc = EINA_TRUE; + Eina_Bool default_img = EINA_TRUE; + Eina_Bool default_snd = EINA_TRUE; + + //No arguments. set defaults + if (argc == 1) goto defaults; + + //Help + if ((argc >=2 ) && !strcmp(argv[1], "--help")) + { + fprintf(stdout, "Usage: enventor [input file] [-id image path] [-sd sound path]\n"); + exit(0); + } + + //edc path + if ((argc >= 2) && ecore_file_can_read(argv[1])) + { + sprintf(edc_path, "%s", argv[1]); + default_edc = EINA_FALSE; + } + else goto defaults; + + //edc image path + int cur_arg = 2; + + while (cur_arg < argc) + { + if (argc > (cur_arg + 1)) + { + if (!strcmp("-id", argv[cur_arg])) + { + sprintf(img_path, "%s", argv[cur_arg + 1]); + default_img = EINA_FALSE; + } + else if (!strcmp("-sd", argv[cur_arg])) + { + sprintf(snd_path, "%s", argv[cur_arg + 1]); + default_snd = EINA_FALSE; + } + } + cur_arg += 2; + } + +defaults: + if (default_edc) sprintf(edc_path, "%s", PROTO_EDC_PATH); + if (default_img) sprintf(img_path, "%s/images", elm_app_data_dir_get()); + if (default_snd) sprintf(snd_path, "%s/sounds", elm_app_data_dir_get()); +} + +static void +config_data_set(app_data *ad, int argc, char **argv) +{ + char edc_path[PATH_MAX]; + char img_path[PATH_MAX]; + char snd_path[PATH_MAX]; + + args_dispatch(argc, argv, edc_path, img_path, snd_path); + option_data *od = option_init(edc_path, img_path, snd_path); + option_update_cb_set(od, option_update_cb, ad); + ad->od = od; +} + +static void +elm_setup() +{ + elm_config_profile_set("standard"); + + //Recover the scale since it will be reset by elm_config_profile_set() + char *scale = getenv("ELM_SCALE"); + if (scale) elm_config_scale_set(atof(scale)); + + elm_config_scroll_bounce_enabled_set(EINA_FALSE); + elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED); + elm_app_info_set("/usr/local/bin", "enventor", + "/usr/local/share/enventor"); + + snprintf(EDJE_PATH, sizeof(EDJE_PATH), "%s/edj/enventor.edj", + elm_app_data_dir_get()); + + elm_theme_extension_add(NULL, EDJE_PATH); +} + +static void +menu_close_cb(void *data) +{ + app_data *ad = data; + ad->menu_opened = EINA_FALSE; +} + +static void +init(app_data *ad, int argc, char **argv) +{ + /*To add a key event handler before evas, here initialize the ecore_event + and add handlers. */ + ecore_event_init(); + ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, main_key_down_cb, ad); + ecore_event_handler_add(ECORE_EVENT_KEY_UP, main_key_up_cb, ad); + + elm_init(argc, argv); + elm_setup(); + config_data_set(ad, argc, argv); + + if (!edje_cc_cmd_set(ad->od)) return; + if (!edc_proto_setup(ad->od)) return; + if (!base_gui_construct(ad)) return; + + statusbar_set(ad, ad->od); + edc_edit_set(ad, ad->sd, ad->od); + edc_view_set(ad, ad->od, ad->sd); + ad->md = menu_init(ad->win, ad->ed, ad->od, ad->vd, menu_close_cb, ad); + + //FIXME: update the edc path whenever file is changed. + eio_monitor_add(option_edc_path_get(ad->od)); + ecore_event_handler_add(EIO_MONITOR_FILE_MODIFIED, edc_changed_cb, ad); +} + +static void +term(app_data *ad) +{ + menu_term(ad->md); + view_term(ad->vd); + edit_term(ad->ed); + stats_term(ad->sd); + option_term(ad->od); + + elm_shutdown(); + ecore_event_shutdown(); +} + +int +main(int argc, char **argv) +{ + app_data ad; + memset(&ad, 0x00, sizeof(app_data)); + + init(&ad, argc, argv); + + elm_run(); + + term(&ad); + + return 0; +} diff --git a/src/menu.c b/src/menu.c new file mode 100644 index 0000000..2b8f5b5 --- /dev/null +++ b/src/menu.c @@ -0,0 +1,755 @@ +#include +#include "common.h" + +struct menu_s +{ + Evas_Object *win; + Evas_Object *menu_layout; + Evas_Object *setting_layout; + Evas_Object *warning_layout; + Evas_Object *fileselector_layout; + Evas_Object *img_path_entry; + Evas_Object *snd_path_entry; + Evas_Object *toggle_stats; + Evas_Object *toggle_linenumber; + Evas_Object *toggle_highlight; + Evas_Object *ctxpopup; + + void (*close_cb)(void *data); + void *close_cb_data; + + option_data *od; + edit_data *ed; + view_data *vd; + + Eina_Bool menu_open : 1; +}; + +static menu_data *g_md; + +static void +warning_no_btn_cb(void *data, Evas_Object *obj EINA_UNUSED, + void *event_info EINA_UNUSED); +static void +new_save_btn_cb(void *data, Evas_Object *obj EINA_UNUSED, + void *event_info EINA_UNUSED); +static void +edc_reload(menu_data *md, const char *edc_path); + +static void +fileselector_close(menu_data *md) +{ + elm_object_signal_emit(md->fileselector_layout, "elm,state,dismiss", ""); +} + +static void +setting_close(menu_data *md) +{ + elm_object_signal_emit(md->setting_layout, "elm,state,dismiss", ""); +} + +static void +warning_close(menu_data *md) +{ + elm_object_signal_emit(md->warning_layout, "elm,state,dismiss", ""); +} + +static void +menu_close(menu_data *md, Eina_Bool toggled) +{ + elm_object_signal_emit(md->menu_layout, "elm,state,dismiss", ""); + + if (!toggled) + md->close_cb(md->close_cb_data); +} + +static void +fileselector_dismiss_done(void *data, Evas_Object *obj EINA_UNUSED, + const char *emission EINA_UNUSED, + const char *source EINA_UNUSED) +{ + menu_data *md = data; + evas_object_del(md->fileselector_layout); + md->fileselector_layout = NULL; + if (md->menu_layout) + { + elm_object_disabled_set(md->menu_layout, EINA_FALSE); + elm_object_focus_set(md->menu_layout, EINA_TRUE); + } +} + +static void +setting_dismiss_done(void *data, Evas_Object *obj EINA_UNUSED, + const char *emission EINA_UNUSED, + const char *source EINA_UNUSED) +{ + menu_data *md = data; + evas_object_del(md->setting_layout); + md->setting_layout = NULL; + elm_object_disabled_set(md->menu_layout, EINA_FALSE); + elm_object_focus_set(md->menu_layout, EINA_TRUE); +} + +static void +menu_dismiss_done(void *data, Evas_Object *obj EINA_UNUSED, + const char *emission EINA_UNUSED, + const char *source EINA_UNUSED) +{ + menu_data *md = data; + evas_object_del(md->menu_layout); + md->menu_layout = NULL; + md->menu_open = EINA_FALSE; +} + +static void +warning_dismiss_done(void *data, Evas_Object *obj EINA_UNUSED, + const char *emission EINA_UNUSED, + const char *source EINA_UNUSED) +{ + menu_data *md = data; + evas_object_del(md->warning_layout); + md->warning_layout = NULL; + if (md->menu_layout) + { + elm_object_disabled_set(md->menu_layout, EINA_FALSE); + elm_object_focus_set(md->menu_layout, EINA_TRUE); + } +} + +static void +warning_layout_create(menu_data *md, Evas_Smart_Cb yes_cb, + Evas_Smart_Cb save_cb) +{ + //Layout + Evas_Object *layout = elm_layout_add(md->win); + elm_layout_file_set(layout, EDJE_PATH, "warning_layout"); + elm_object_signal_callback_add(layout, "elm,state,dismiss,done", "", + warning_dismiss_done, md); + evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_win_resize_object_add(md->win, layout); + evas_object_show(layout); + + Evas_Object *btn; + + //Save Button + btn = elm_button_add(layout); + elm_object_style_set(btn, elm_app_name_get()); + elm_object_text_set(btn, "Save"); + evas_object_smart_callback_add(btn, "clicked", save_cb, md); + evas_object_show(btn); + elm_object_focus_set(btn, EINA_TRUE); + + elm_object_part_content_set(layout, "elm.swallow.save", btn); + + //No Button + btn = elm_button_add(layout); + elm_object_style_set(btn, elm_app_name_get()); + elm_object_text_set(btn, "No"); + evas_object_smart_callback_add(btn, "clicked", warning_no_btn_cb, md); + evas_object_show(btn); + + elm_object_part_content_set(layout, "elm.swallow.no", btn); + + //Yes Button + btn = elm_button_add(layout); + elm_object_style_set(btn, elm_app_name_get()); + elm_object_text_set(btn, "Yes"); + evas_object_smart_callback_add(btn, "clicked", yes_cb, md); + evas_object_show(btn); + + elm_object_part_content_set(layout, "elm.swallow.yes", btn); + + if (md->menu_layout) + elm_object_disabled_set(md->menu_layout, EINA_TRUE); + + md->warning_layout = layout; +} + +static void +setting_apply_btn_cb(void *data, Evas_Object *obj EINA_UNUSED, + void *event_info EINA_UNUSED) +{ + menu_data *md = data; + option_data *od = md->od; + + option_edc_img_path_set(od, elm_object_text_get(md->img_path_entry)); + option_edc_snd_path_set(od, elm_object_text_get(md->snd_path_entry)); + option_stats_bar_set(od, elm_check_state_get(md->toggle_stats)); + option_linenumber_set(od, elm_check_state_get(md->toggle_linenumber)); + option_part_highlight_set(od, elm_check_state_get(md->toggle_highlight)); + option_apply(od); + + setting_close(md); +} + +static void +img_path_entry_update(Evas_Object *entry, Eina_List *edc_img_paths) +{ + elm_entry_entry_set(entry, NULL); + + Eina_List *l; + char *edc_img_path; + EINA_LIST_FOREACH(edc_img_paths, l, edc_img_path) + { + elm_entry_entry_append(entry, edc_img_path); + elm_entry_entry_append(entry, ";"); + } +} + +static void +snd_path_entry_update(Evas_Object *entry, Eina_List *edc_snd_paths) +{ + elm_entry_entry_set(entry, NULL); + + Eina_List *l; + char *edc_snd_path; + EINA_LIST_FOREACH(edc_snd_paths, l, edc_snd_path) + { + elm_entry_entry_append(entry, edc_snd_path); + elm_entry_entry_append(entry, ";"); + } +} + +static void +setting_reset_btn_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, + void *event_info EINA_UNUSED) +{ + menu_data *md = data; + option_data *od = md->od; + + img_path_entry_update(md->img_path_entry, + (Eina_List *)option_edc_img_path_list_get(md->od)); + snd_path_entry_update(md->snd_path_entry, + (Eina_List *)option_edc_snd_path_list_get(md->od)); + elm_check_state_set(md->toggle_stats, option_stats_bar_get(od)); + elm_check_state_set(md->toggle_linenumber, option_linenumber_get(od)); +} + +static void +setting_open(menu_data *md) +{ + //Layout + Evas_Object *layout = elm_layout_add(md->win); + elm_layout_file_set(layout, EDJE_PATH, "setting_layout"); + elm_object_signal_callback_add(layout, "elm,state,dismiss,done", "", + setting_dismiss_done, md); + evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_win_resize_object_add(md->win, layout); + evas_object_show(layout); + + //Image Path Entry + Evas_Object *img_path_entry = elm_entry_add(layout); + elm_object_style_set(img_path_entry, elm_app_name_get()); + elm_entry_single_line_set(img_path_entry, EINA_TRUE); + elm_entry_scrollable_set(img_path_entry, EINA_TRUE); + img_path_entry_update(img_path_entry, + (Eina_List *)option_edc_img_path_list_get(md->od)); + evas_object_show(img_path_entry); + elm_object_focus_set(img_path_entry, EINA_TRUE); + + elm_object_part_content_set(layout, "elm.swallow.img_path_entry", + img_path_entry); + + //Sound Path Entry + Evas_Object *snd_path_entry = elm_entry_add(layout); + elm_object_style_set(snd_path_entry, elm_app_name_get()); + elm_entry_single_line_set(snd_path_entry, EINA_TRUE); + elm_entry_scrollable_set(snd_path_entry, EINA_TRUE); + snd_path_entry_update(snd_path_entry, + (Eina_List *)option_edc_snd_path_list_get(md->od)); + evas_object_show(snd_path_entry); + + elm_object_part_content_set(layout, "elm.swallow.snd_path_entry", + snd_path_entry); + + //Preference + Evas_Object *box = elm_box_add(layout); + evas_object_show(box); + + elm_object_part_content_set(layout, "elm.swallow.preference", box); + + Evas_Object *toggle; + + //Toggle (Tab bar) + toggle = elm_check_add(box); + elm_object_style_set(toggle, "toggle"); + elm_object_disabled_set(toggle, EINA_TRUE); + evas_object_size_hint_weight_set(toggle, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(toggle, EVAS_HINT_FILL, EVAS_HINT_FILL); + elm_object_text_set(toggle, "Tab Bar"); + evas_object_show(toggle); + + elm_box_pack_end(box, toggle); + + //Toggle (Tools) + toggle = elm_check_add(box); + elm_object_style_set(toggle, "toggle"); + elm_object_disabled_set(toggle, EINA_TRUE); + evas_object_size_hint_weight_set(toggle, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(toggle, EVAS_HINT_FILL, EVAS_HINT_FILL); + elm_object_text_set(toggle, "Tool Bar"); + evas_object_show(toggle); + + elm_box_pack_end(box, toggle); + + //Toggle (Status bar) + Evas_Object *toggle_stats = elm_check_add(box); + elm_object_style_set(toggle_stats, "toggle"); + elm_check_state_set(toggle_stats, option_stats_bar_get(md->od)); + evas_object_size_hint_weight_set(toggle_stats, EVAS_HINT_EXPAND, + EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(toggle_stats, EVAS_HINT_FILL, + EVAS_HINT_FILL); + elm_object_text_set(toggle_stats, "Status Bar"); + evas_object_show(toggle_stats); + + elm_box_pack_end(box, toggle_stats); + + //Toggle (Line Number) + Evas_Object *toggle_linenumber = elm_check_add(box); + elm_object_style_set(toggle_linenumber, "toggle"); + elm_check_state_set(toggle_linenumber, option_linenumber_get(md->od)); + evas_object_size_hint_weight_set(toggle_linenumber, EVAS_HINT_EXPAND, + EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(toggle_linenumber, EVAS_HINT_FILL, + EVAS_HINT_FILL); + elm_object_text_set(toggle_linenumber, "Line Number"); + evas_object_show(toggle_linenumber); + + elm_box_pack_end(box, toggle_linenumber); + + //Toggle (Part Highlighting) + Evas_Object *toggle_highlight = elm_check_add(box); + elm_object_style_set(toggle_highlight, "toggle"); + elm_check_state_set(toggle_highlight, option_part_highlight_get(md->od)); + evas_object_size_hint_weight_set(toggle_highlight, EVAS_HINT_EXPAND, + EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(toggle_highlight, EVAS_HINT_FILL, + EVAS_HINT_FILL); + elm_object_text_set(toggle_highlight, "Part Highlighting"); + evas_object_show(toggle_highlight); + + elm_box_pack_end(box, toggle_highlight); + + //Toggle (Auto Indentation) + toggle = elm_check_add(box); + elm_object_style_set(toggle, "toggle"); + elm_object_disabled_set(toggle, EINA_TRUE); + evas_object_size_hint_weight_set(toggle, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(toggle, EVAS_HINT_FILL, EVAS_HINT_FILL); + elm_object_text_set(toggle, "Auto Indentation"); + evas_object_show(toggle); + + elm_box_pack_end(box, toggle); + + //Toggle (Separate Window) + toggle = elm_check_add(box); + elm_object_style_set(toggle, "toggle"); + elm_object_disabled_set(toggle, EINA_TRUE); + evas_object_size_hint_weight_set(toggle, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(toggle, EVAS_HINT_FILL, EVAS_HINT_FILL); + elm_object_text_set(toggle, "Separate Window"); + evas_object_show(toggle); + + elm_box_pack_end(box, toggle); + + Evas_Object *btn; + + //Apply Button + btn = elm_button_add(layout); + elm_object_style_set(btn, elm_app_name_get()); + elm_object_text_set(btn, "Apply"); + evas_object_smart_callback_add(btn, "clicked", setting_apply_btn_cb, md); + evas_object_show(btn); + + elm_object_part_content_set(layout, "elm.swallow.apply_btn", btn); + + //Cancel Button + btn = elm_button_add(layout); + elm_object_style_set(btn, elm_app_name_get()); + elm_object_text_set(btn, "Reset"); + evas_object_smart_callback_add(btn, "clicked", setting_reset_btn_cb, md); + evas_object_show(btn); + + elm_object_part_content_set(layout, "elm.swallow.reset_btn", btn); + + elm_object_disabled_set(md->menu_layout, EINA_TRUE); + + md->setting_layout = layout; + md->img_path_entry = img_path_entry; + md->snd_path_entry = snd_path_entry; + md->toggle_stats = toggle_stats; + md->toggle_linenumber = toggle_linenumber; + md->toggle_highlight = toggle_highlight; +} + +static void +setting_btn_cb(void *data, Evas_Object *obj EINA_UNUSED, + void *event_info EINA_UNUSED) +{ + menu_data *md = data; + setting_open(md); +} + +static void +new_yes_btn_cb(void *data, Evas_Object *obj EINA_UNUSED, + void *event_info EINA_UNUSED) +{ + menu_data *md = data; + + edc_reload(md, PROTO_EDC_PATH); + warning_close(md); + menu_close(md, EINA_FALSE); +} + +static void +exit_yes_btn_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, + void *event_info EINA_UNUSED) +{ + elm_exit(); +} + +static void +exit_save_btn_cb(void *data, Evas_Object *obj EINA_UNUSED, + void *event_info EINA_UNUSED) +{ + menu_data *md = data; + edit_save(md->ed); + elm_exit(); +} + +void +menu_exit(menu_data *md) +{ + if (edit_changed_get(md->ed)) + warning_layout_create(md, exit_yes_btn_cb, exit_save_btn_cb); + else + elm_exit(); +} + +static void +exit_btn_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, + void *event_info EINA_UNUSED) +{ + menu_data *md = data; + menu_exit(md); +} + +static Evas_Object * +btn_create(Evas_Object *parent, const char *label, Evas_Smart_Cb cb, void *data, Eina_Bool disabled) +{ + Evas_Object *layout, *btn; + + layout = elm_layout_add(parent); + elm_layout_file_set(layout, EDJE_PATH, "button_layout"); + evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_show(layout); + + btn = elm_button_add(layout); + elm_object_style_set(btn, elm_app_name_get()); + evas_object_smart_callback_add(btn, "clicked", cb, data); + elm_object_disabled_set(btn, disabled); + elm_object_text_set(btn, label); + evas_object_show(btn); + + elm_object_part_content_set(layout, "elm.swallow.btn", btn); + + return layout; +} + +static Eina_Bool +btn_effect_timer_cb(void *data) +{ + Evas_Object *btn = data; + elm_object_signal_emit(btn, "elm,action,btn,zoom", ""); + return ECORE_CALLBACK_CANCEL; +} + +static void +edc_reload(menu_data *md, const char *edc_path) +{ + option_edc_path_set(md->od, edc_path); + edit_new(md->ed); + view_reload_need_set(md->vd, EINA_TRUE); + option_apply(md->od); +} + +static void +warning_no_btn_cb(void *data, Evas_Object *obj EINA_UNUSED, + void *event_info EINA_UNUSED) +{ + menu_data *md = data; + warning_close(md); +} + +static void +new_save_btn_cb(void *data, Evas_Object *obj EINA_UNUSED, + void *event_info EINA_UNUSED) +{ + menu_data *md = data; + + edit_save(md->ed); + edc_reload(md, PROTO_EDC_PATH); + warning_close(md); + menu_close(md, EINA_FALSE); +} + +static void +new_btn_cb(void *data, Evas_Object *obj EINA_UNUSED, + void *event_info EINA_UNUSED) +{ + menu_data *md = data; + + if (edit_changed_get(md->ed)) + warning_layout_create(md, new_yes_btn_cb, new_save_btn_cb); + else + { + edc_reload(md, PROTO_EDC_PATH); + menu_close(md, EINA_FALSE); + } +} + +static void +save_btn_cb(void *data, Evas_Object *obj EINA_UNUSED, + void *event_info EINA_UNUSED) +{ + menu_data *md = data; + edit_save(md->ed); +} + +static void +fileselector_done_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info) +{ + menu_data *md = data; + const char *selected = event_info; + + if (selected) + { + //Filter to read only edc extension file. + char *ext = strrchr(selected, '.'); + if (!ext || strcmp(ext, ".edc") || !ecore_file_can_read(selected)) + { + //show failed message box. + fileselector_close(md); + return; + } + + edc_reload(md, selected); + fileselector_close(md); + menu_close(md, EINA_FALSE); + } + else fileselector_close(md); +} + +static void +edc_file_load(menu_data *md) +{ + //Layout + Evas_Object *layout = elm_layout_add(md->win); + elm_layout_file_set(layout, EDJE_PATH, "fileselector_layout"); + elm_object_signal_callback_add(layout, "elm,state,dismiss,done", "", + fileselector_dismiss_done, md); + evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_win_resize_object_add(md->win, layout); + evas_object_show(layout); + + Evas_Object *fs = elm_fileselector_add(layout); + elm_fileselector_mime_types_filter_append(fs, NULL, "edc"); + elm_fileselector_path_set(fs, getenv("HOME")); + elm_fileselector_expandable_set(fs, EINA_FALSE); + evas_object_smart_callback_add(fs, "done", fileselector_done_cb, md); + evas_object_show(fs); + + elm_object_part_content_set(layout, "elm.swallow.fileselector", fs); + + if (md->menu_layout) + elm_object_disabled_set(md->menu_layout, EINA_TRUE); + elm_object_focus_set(fs, EINA_TRUE); + + md->fileselector_layout = layout; +} + +static void +load_yes_btn_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, + void *event_info EINA_UNUSED) +{ + menu_data *md = data; + edc_file_load(md); + warning_close(md); +} + +static void +load_save_btn_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, + void *event_info EINA_UNUSED) +{ + menu_data *md = data; + edit_save(md->ed); + edc_file_load(md); + warning_close(md); +} + +Eina_Bool +menu_edc_load(menu_data *md) +{ + if (edit_changed_get(md->ed)) + warning_layout_create(md, load_yes_btn_cb, load_save_btn_cb); + else + edc_file_load(md); + + return EINA_TRUE; +} + +static void +load_btn_cb(void *data, Evas_Object *obj EINA_UNUSED, + void *event_info EINA_UNUSED) +{ + menu_data *md = data; + menu_edc_load(md); +} + +static void +menu_open(menu_data *md) +{ + //Layout + Evas_Object *layout = elm_layout_add(md->win); + elm_layout_file_set(layout, EDJE_PATH, "menu_layout"); + elm_object_signal_callback_add(layout, "elm,state,dismiss,done", "", + menu_dismiss_done, md); + evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_win_resize_object_add(md->win, layout); + evas_object_show(layout); + + //Button + Evas_Object *btn; + + //Button(New) + btn = btn_create(layout, "New", new_btn_cb, md, EINA_FALSE); + elm_object_focus_set(btn, EINA_TRUE); + elm_object_part_content_set(layout, "elm.swallow.new_btn", btn); + ecore_timer_add(0, btn_effect_timer_cb, btn); + + //Button(Save) + btn = btn_create(layout, "Save", save_btn_cb, md, EINA_FALSE); + elm_object_part_content_set(layout, "elm.swallow.save_btn", btn); + ecore_timer_add(0.03, btn_effect_timer_cb, btn); + + //Button(Load) + btn = btn_create(layout, "Load", load_btn_cb, md, EINA_FALSE); + elm_object_part_content_set(layout, "elm.swallow.load_btn", btn); + ecore_timer_add(0.06, btn_effect_timer_cb, btn); + + //Button(Setting) + btn = btn_create(layout, "Setting", setting_btn_cb, md, EINA_FALSE); + elm_object_part_content_set(layout, "elm.swallow.setting_btn", btn); + ecore_timer_add(0.09, btn_effect_timer_cb, btn); + + //Button(Help) + btn = btn_create(layout, "Help", NULL, NULL, EINA_TRUE); + elm_object_part_content_set(layout, "elm.swallow.help_btn", btn); + ecore_timer_add(0.12, btn_effect_timer_cb, btn); + + //Button(Exit) + btn = btn_create(layout, "Exit", exit_btn_cb, md, EINA_FALSE); + elm_object_part_content_set(layout, "elm.swallow.exit_btn", btn); + ecore_timer_add(0.15, btn_effect_timer_cb, btn); + + md->menu_layout = layout; + + md->menu_open = EINA_TRUE; +} + +menu_data * +menu_init(Evas_Object *win, edit_data *ed, option_data *od, view_data *vd, + void (*close_cb)(void *data), void *data) +{ + menu_data *md = calloc(1, sizeof(menu_data)); + md->win = win; + md->ed = ed; + md->od = od; + md->vd = vd; + md->close_cb = close_cb; + md->close_cb_data = data; + g_md = md; + return md; +} + +void +menu_term(menu_data *md) +{ + if (!md) return; + free(md); +} + +Eina_Bool +menu_option_toggle() +{ + menu_data *md = g_md; + + //Level 2 Menus + if (md->menu_open) + { + if (md->setting_layout) + { + setting_close(md); + return EINA_TRUE; + } + else if (md->warning_layout) + { + warning_close(md); + return EINA_TRUE; + } + else if (md->fileselector_layout) + { + fileselector_close(md); + return EINA_TRUE; + } + } + + //Ctxpopup + if (md->ctxpopup) + { + elm_ctxpopup_dismiss(md->ctxpopup); + return EINA_FALSE; + } + //FileSelector + if (md->fileselector_layout) + { + fileselector_close(md); + return EINA_FALSE; + } + //Warning + if (md->warning_layout) + { + warning_close(md); + return EINA_FALSE; + } + //Main Menu + if (md->menu_open) + { + menu_close(md, EINA_TRUE); + return EINA_FALSE; + } + else + { + menu_open(md); + return EINA_TRUE; + } +} + +static void +ctxpopup_del_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, + void *event_info EINA_UNUSED) +{ + menu_data *md = data; + md->ctxpopup = NULL; +} + +void +menu_ctxpopup_register(Evas_Object *ctxpopup) +{ + menu_data *md = g_md; + md->ctxpopup = ctxpopup; + if (!ctxpopup) return; + evas_object_event_callback_add(ctxpopup, EVAS_CALLBACK_DEL, ctxpopup_del_cb, + md); +} diff --git a/src/panes.c b/src/panes.c new file mode 100644 index 0000000..a47b63b --- /dev/null +++ b/src/panes.c @@ -0,0 +1,168 @@ +#include +#include "common.h" + +typedef struct _transit_data +{ + double origin; + double delta; + Evas_Object *panes; +} transit_data; + +static double panes_last_right_size1 = 0.5; //when down the panes bar +static double panes_last_right_size2 = 0.5; //when up the panes bar + +static void +transit_op(void *data, Elm_Transit *transit EINA_UNUSED, double progress) +{ + transit_data *td = data; + elm_panes_content_right_size_set(td->panes, + td->origin + (td->delta * progress)); +} + +static void +transit_free(void *data, Elm_Transit *transit EINA_UNUSED) +{ + transit_data *td = data; + free(td); +} + +static void +press_cb(void *data EINA_UNUSED, Evas_Object *obj, + void *event_info EINA_UNUSED) +{ + panes_last_right_size1 = elm_panes_content_right_size_get(obj); +} + +static void +unpress_cb(void *data EINA_UNUSED, Evas_Object *obj, + void *event_info EINA_UNUSED) +{ + double right_size = elm_panes_content_right_size_get(obj); + if (panes_last_right_size1 != right_size) + panes_last_right_size2 = right_size; +} + +static void +double_click_cb(void *data EINA_UNUSED, Evas_Object *obj, + void *event_info EINA_UNUSED) +{ + const double TRANSIT_TIME = 0.25; + + transit_data *td = malloc(sizeof(transit_data)); + if (!td) return; + + td->origin = elm_panes_content_right_size_get(obj); + td->delta = panes_last_right_size2 - td->origin; + td->panes = obj; + + Elm_Transit *transit = elm_transit_add(); + elm_transit_effect_add(transit, transit_op, td, transit_free); + elm_transit_tween_mode_set(transit, ELM_TRANSIT_TWEEN_MODE_DECELERATE); + elm_transit_duration_set(transit, TRANSIT_TIME); + elm_transit_go(transit); +} + +static void +left_clicked_cb(void *data, Evas_Object *obj EINA_UNUSED, + void *event_info EINA_UNUSED) +{ + const double TRANSIT_TIME = 0.25; + + Evas_Object *panes = data; + double origin = elm_panes_content_right_size_get(panes); + if (origin == 1.0) return; + + transit_data *td = malloc(sizeof(transit_data)); + if (!td) return; + + td->origin = origin; + td->delta = 1.0 - td->origin; + td->panes = panes; + + Elm_Transit *transit = elm_transit_add(); + elm_transit_effect_add(transit, transit_op, td, transit_free); + elm_transit_tween_mode_set(transit, ELM_TRANSIT_TWEEN_MODE_DECELERATE); + elm_transit_duration_set(transit, TRANSIT_TIME); + elm_transit_go(transit); +} + +static void +right_clicked_cb(void *data, Evas_Object *obj EINA_UNUSED, + void *event_info EINA_UNUSED) +{ + const double TRANSIT_TIME = 0.25; + + Evas_Object *panes = data; + double origin = elm_panes_content_right_size_get(panes); + if (origin == 0.0) return; + + transit_data *td = malloc(sizeof(transit_data)); + if (!td) return; + + td->origin = origin; + td->delta = 0.0 - td->origin; + td->panes = panes; + + Elm_Transit *transit = elm_transit_add(); + elm_transit_effect_add(transit, transit_op, td, transit_free); + elm_transit_tween_mode_set(transit, ELM_TRANSIT_TWEEN_MODE_DECELERATE); + elm_transit_duration_set(transit, TRANSIT_TIME); + elm_transit_go(transit); +} + +void +panes_full_view_right(Evas_Object *panes) +{ + right_clicked_cb(panes, NULL, NULL); +} + +void +panes_full_view_left(Evas_Object *panes) +{ + left_clicked_cb(panes, NULL, NULL); +} + +void +panes_full_view_cancel(Evas_Object *panes) +{ + double_click_cb(NULL, panes, NULL); +} + +Evas_Object * +panes_create(Evas_Object *parent) +{ + //Panes + Evas_Object *panes = elm_panes_add(parent); + elm_object_style_set(panes, elm_app_name_get()); + evas_object_size_hint_weight_set(panes, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_smart_callback_add(panes, "clicked,double", + double_click_cb, NULL); + evas_object_smart_callback_add(panes, "press", + press_cb, NULL); + evas_object_smart_callback_add(panes, "unpress", + unpress_cb, NULL); + evas_object_show(panes); + + //Left Button + Evas_Object *left_arrow = elm_button_add(panes); + elm_object_text_set(left_arrow, "<"); + elm_object_focus_allow_set(left_arrow, EINA_FALSE); + evas_object_smart_callback_add(left_arrow, "clicked", left_clicked_cb, + panes); + evas_object_show(left_arrow); + + elm_object_part_content_set(panes, "elm.swallow.left_arrow", left_arrow); + + //Right Button + Evas_Object *right_arrow = elm_button_add(panes); + elm_object_text_set(right_arrow, ">"); + elm_object_focus_allow_set(right_arrow, EINA_FALSE); + evas_object_smart_callback_add(right_arrow, "clicked", right_clicked_cb, + panes); + evas_object_show(right_arrow); + + elm_object_part_content_set(panes, "elm.swallow.right_arrow", right_arrow); + + return panes; +} + diff --git a/src/statusbar.c b/src/statusbar.c new file mode 100644 index 0000000..b69ff6b --- /dev/null +++ b/src/statusbar.c @@ -0,0 +1,103 @@ +#include +#include "common.h" + +struct statusbar_s +{ + Evas_Object *layout; + Ecore_Timer *info_msg_timer; + + option_data *od; +}; + +void +stats_line_num_update(stats_data *sd, int cur_line, int max_line) +{ + char buf[128]; + snprintf(buf, sizeof(buf), + "Line [%d:%d]", cur_line, max_line); + elm_object_part_text_set(sd->layout, "elm.text.line", buf); +} + +void +stats_edc_file_set(stats_data *sd, const char *group_name) +{ + char buf[PATH_MAX]; + const char *filename = ecore_file_file_get(option_edc_path_get(sd->od)); + snprintf(buf, sizeof(buf), "File [%s] Group [%s]", filename, group_name); + elm_object_part_text_set(sd->layout, "elm.text.file_group_name", buf); +} + +stats_data * +stats_init(Evas_Object *parent, option_data *od) +{ + stats_data *sd = calloc(1, sizeof(stats_data)); + + Evas_Object *layout = elm_layout_add(parent); + elm_layout_file_set(layout, EDJE_PATH, "statusbar_layout"); + evas_object_show(layout); + + //FIXME: temporarily setup + elm_object_part_text_set(layout, "elm.text.cur_pos", + "Cursor [0,0] [0.00,0.00]"); + + sd->layout = layout; + sd->od = od; + + stats_edc_file_set(sd, NULL); + + return sd; +} + +Evas_Object * +stats_obj_get(stats_data *sd) +{ + return sd->layout; +} + +void +stats_term(stats_data *sd) +{ + if (sd->info_msg_timer) ecore_timer_del(sd->info_msg_timer); + free(sd); +} + +static Eina_Bool +info_msg_timer_cb(void *data) +{ + //Hide the save message + stats_data *sd = data; + if (!option_stats_bar_get(sd->od)) return ECORE_CALLBACK_CANCEL; + elm_object_signal_emit(sd->layout, "elm,action,info_msg,hide", ""); + sd->info_msg_timer = NULL; + return ECORE_CALLBACK_CANCEL; +} + +void +stats_info_msg_update(stats_data *sd, const char *msg) +{ + elm_object_part_text_set(sd->layout, "elm.text.info_msg", msg); + elm_object_signal_emit(sd->layout, "elm,action,info_msg,show", ""); + if (sd->info_msg_timer) ecore_timer_del(sd->info_msg_timer); + sd->info_msg_timer = ecore_timer_add(2, info_msg_timer_cb, sd); +} + +void +stats_view_size_update(stats_data *sd) +{ + Evas_Coord w, h; + option_view_size_get(sd->od, &w, &h); + + char buf[128]; + snprintf(buf, sizeof(buf), + "Size [%dx%d]", w, h); + elm_object_part_text_set(sd->layout, "elm.text.view_size", buf); +} + +void +stats_cursor_pos_update(stats_data *sd, Evas_Coord x, Evas_Coord y, float rel_x, float rel_y) +{ + char buf[128]; + snprintf(buf, sizeof(buf), + "Cursor [%d,%d] [%0.2f,%0.2f]", x, y, rel_x, rel_y); + elm_object_part_text_set(sd->layout, "elm.text.cur_pos", buf); +} diff --git a/src/syntax_color.c b/src/syntax_color.c new file mode 100644 index 0000000..32907d3 --- /dev/null +++ b/src/syntax_color.c @@ -0,0 +1,494 @@ +#include +#include "common.h" + +#define COLOR_INSERT(strbuf, src, length, cur, prev, cmp, color) \ + { \ + ret = color_markup_insert((strbuf), (src), (length), (cur), (prev), \ + (cmp), (color)); \ + if (ret == 1) continue; \ + else if (ret == -1) goto finished; \ + } \ + +struct syntax_color_s +{ + Eina_Strbuf *strbuf; + Eina_Stringshare *col1; + Eina_Stringshare *col2; + Eina_Stringshare *col3; + Eina_Stringshare *col4; + Eina_Stringshare *col5; + + Ecore_Timer *buf_flush_timer; + + Eina_Bool enabled : 1; +}; + +Eina_Bool +buf_flush_timer_cb(void *data) +{ + color_data *cd = data; + /* At this moment, I have no idea the policy of the eina strbuf. + If the string buffer wouldn't reduce the buffer size, it needs to prevent + the buffer size not to be grown endlessly. */ + eina_strbuf_free(cd->strbuf); + cd->strbuf = eina_strbuf_new(); + + return ECORE_CALLBACK_RENEW; +} + +color_data * +color_init() +{ + color_data *cd = calloc(1, sizeof(color_data)); + cd->strbuf = eina_strbuf_new(); + cd->buf_flush_timer = ecore_timer_add(1800, buf_flush_timer_cb, cd); + cd->col1 = eina_stringshare_add("424242"); + cd->col2 = eina_stringshare_add("a000a0"); + cd->col3 = eina_stringshare_add("0000a0"); + cd->col4 = eina_stringshare_add("969600"); + cd->col5 = eina_stringshare_add("009600"); + + return cd; +} + +void +color_term(color_data *cd) +{ + if (cd->buf_flush_timer) ecore_timer_del(cd->buf_flush_timer); + eina_strbuf_free(cd->strbuf); + eina_stringshare_del(cd->col1); + eina_stringshare_del(cd->col2); + eina_stringshare_del(cd->col3); + eina_stringshare_del(cd->col4); + eina_stringshare_del(cd->col5); + + free(cd); +} + +static int +color_markup_insert(Eina_Strbuf *strbuf, const char **src, int length, + char **cur, char **prev, const char *cmp, + Eina_Stringshare *color) +{ + char buf[128]; + + if (strncmp(*cur, cmp, strlen(cmp))) return 0; + + eina_strbuf_append_length(strbuf, *prev, *cur - *prev); + snprintf(buf, sizeof(buf), "%s", color, cmp); + eina_strbuf_append(strbuf, buf); + *cur += strlen(cmp); + if (*cur > (*src + length)) return -1; + *prev = *cur; + + return 1; +} + +static int +markup_skip(Eina_Strbuf *strbuf, const char **src, int length, char **cur, + char **prev) +{ + if ((*cur)[0] != '<') return 0; + + eina_strbuf_append_length(strbuf, *prev, (*cur - *prev)); + (*cur)++; + + if (*cur > (*src + length)) return -1; + *prev = *cur; + + *cur = strchr(*prev, '>'); + + if (*cur) + { + (*cur)++; + *prev = *cur; + return 1; + } + else + { + *prev = *cur; + return -1; + } + + return 1; +} + +static int +tab_skip(Eina_Strbuf *strbuf, const char **src, int length, char **cur, + char **prev) +{ + int cmp_size = 6; //strlen(""); + if (strncmp(*cur, "", cmp_size)) return 0; + eina_strbuf_append_length(strbuf, *prev, (*cur - *prev + cmp_size)); + *cur += cmp_size; + if (*cur > (*src + length)) return -1; + *prev = *cur; + + return 1; +} + +static int +br_skip(Eina_Strbuf *strbuf, const char **src, int length, char **cur, + char **prev) +{ + int cmp_size = 5; //strlen("
"); + if (strncmp(*cur, "
", cmp_size)) return 0; + eina_strbuf_append_length(strbuf, *prev, (*cur - *prev + cmp_size)); + *cur += cmp_size; + if (*cur > (*src + length)) return -1; + *prev = *cur; + + return 1; +} + +static int +comment_apply(Eina_Strbuf *strbuf, const char **src, int length, char **cur, + char **prev, const Eina_Stringshare *color, + Eina_Bool *inside_comment) +{ + if (!(*inside_comment)) + { + if ((*cur)[0] != '/') return 0; + if ((*cur) + 1 > ((*src) + length)) return -1; + if ((*cur)[1] != '*') return 0; + + eina_strbuf_append_length(strbuf, *prev, (*cur - *prev)); + + char buf[128]; + snprintf(buf, sizeof(buf), "/*", color); + eina_strbuf_append(strbuf, buf); + + int cmp_size = 2; //strlen("/*"); + + *cur += cmp_size; + + if (*cur > (*src + length)) + { + *inside_comment = EINA_TRUE; + return -1; + } + + *prev = *cur; + + *cur = strstr(*prev, "*/"); + + if (*cur) + { + eina_strbuf_append_length(strbuf, *prev, (*cur - *prev)); + eina_strbuf_append(strbuf, "*/"); + *cur += cmp_size; + *prev = *cur; + return 0; + } + + eina_strbuf_append(strbuf, *prev); + *prev = *cur; + + *inside_comment = EINA_TRUE; + return -1; + } + else + { + if ((*cur)[0] != '*') return 0; + if ((*cur) + 1 > ((*src) + length)) return -1; + if ((*cur)[1] != '/') return 0; + + eina_strbuf_append_length(strbuf, *prev, (*cur - *prev)); + eina_strbuf_append(strbuf, "*/"); + + int cmp_size = 2; //strlen("*/"); + + *cur += cmp_size; + *inside_comment = EINA_FALSE; + + if (*cur > (*src + length)) return -1; + *prev = *cur; + return 1; + } + + return -1; +} + +static int +comment2_apply(Eina_Strbuf *strbuf, const char **src, int length, char **cur, + char **prev, const Eina_Stringshare *color, + Eina_Bool *inside_comment) +{ + if (*inside_comment) return 0; + if ((*cur)[0] != '/') return 0; + if (((*cur) + 1) > ((*src) + length)) return -1; + if ((*cur)[1] != '/') return 0; + + eina_strbuf_append_length(strbuf, *prev, (*cur - *prev)); + + char buf[128]; + snprintf(buf, sizeof(buf), "//", color); + eina_strbuf_append(strbuf, buf); + + int cmp_size = 2; //strlen("//"); + *cur += cmp_size; + + if (*cur > (*src + length)) + { + eina_strbuf_append(strbuf, ""); + return -1; + } + + *prev = *cur; + + cmp_size = strlen("
"); + *cur = strstr(*prev, "
"); + + if (*cur) + { + eina_strbuf_append_length(strbuf, *prev, (*cur - *prev)); + eina_strbuf_append(strbuf, "
"); + *cur += cmp_size; + *prev = *cur; + return 1; + } + + eina_strbuf_append(strbuf, *prev); + *prev = *cur; + + eina_strbuf_append(strbuf, ""); + return -1; +} + +const char * +color_cancel(color_data *cd, const char *src, int length) +{ + if (!src || length < 1) return NULL; + + Eina_Strbuf *strbuf = cd->strbuf; + eina_strbuf_reset(strbuf); + + const char *str = NULL; + char *prev = (char *) src; + char *cur = (char *) src; + + while (cur && (cur <= (src + length))) + { + //escape EOL:
+ if (br_skip(strbuf, &src, length, &cur, &prev) == 1) + continue; + + //escape EOL: + if (tab_skip(strbuf, &src, length, &cur, &prev) == 1) + continue; + + //escape markups: <..> ~ + if (markup_skip(strbuf, &src, length, &cur, &prev) == 1) + continue; + + cur++; + } + + //Same with origin source. + if (prev == src) + str = src; + //Some color syntax is applied. + else + { + //append leftovers. + if (prev + 1 < cur) eina_strbuf_append(strbuf, prev); + str = eina_strbuf_string_get(strbuf); + } + return str; +} + +const char * +color_apply(color_data *cd, const char *src, int length, Eina_Bool realtime) +{ + static Eina_Bool inside_string = EINA_FALSE; + static Eina_Bool inside_comment = EINA_FALSE; + + //workaround code. need to improve it later. + if (realtime) + { + inside_string = EINA_FALSE; + inside_comment = EINA_FALSE; + } + + if (!src || length < 1) return NULL; + + Eina_Strbuf *strbuf = cd->strbuf; + eina_strbuf_reset(strbuf); + + const char *str = NULL; + char *prev = (char *) src; + char *cur = (char *) src; + int ret; + + while (cur && (cur <= (src + length))) + { + //escape empty string + if (cur[0] == ' ') + { + eina_strbuf_append_length(strbuf, prev, cur - prev); + eina_strbuf_append_char(strbuf, ' '); + ++cur; + prev = cur; + continue; + } + + //handle comment: /* ~ */ + ret = comment_apply(strbuf, &src, length, &cur, &prev, cd->col5, + &inside_comment); + if (ret == 1) continue; + else if (ret == -1) goto finished; + + //handle comment: // + ret = comment2_apply(strbuf, &src, length, &cur, &prev, cd->col5, + &inside_comment); + if (ret == 1) continue; + else if (ret == -1) goto finished; + + if (realtime) + { + //escape string: " ~ " + if (!strncmp(cur, """, strlen("""))) + { + eina_strbuf_append_length(strbuf, prev, cur - prev); + eina_strbuf_append(strbuf, """); + cur += strlen("""); + prev = cur; + inside_string = !inside_string; + continue; + } + } + else + { + //escape string: " ~ " + if (cur[0] == '\"') + { + eina_strbuf_append_length(strbuf, prev, cur - prev); + eina_strbuf_append_char(strbuf, '\"'); + cur++; + prev = cur; + inside_string = !inside_string; + continue; + } + } + + if (inside_string || inside_comment) + { + cur++; + continue; + } + + //FIXME: construct from the configuration file + //syntax group 1 + Eina_Stringshare *col1 = cd->col1; + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "{", col1); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "}", col1); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, ";", col1); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, ":", col1); + + //syntax group 2 + Eina_Stringshare *col2 = cd->col2; + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "collections", col2); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "description", col2); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "fill", col2); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "group", col2); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "images", col2); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "map", col2); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "origin", col2); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "parts", col2); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "part", col2); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "programs", col2); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "program", col2); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "rel1", col2); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "rel2", col2); + + //syntax group 3 + Eina_Stringshare *col3 = cd->col3; + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "action", col3); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "after", col3); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "align", col3); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "aspect", col3); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "border_scale", col3); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "border", col3); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "clip_to", col3); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "color", col3); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "fixed", col3); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "font", col3); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "inherit", col3); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "max", col3); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "min", col3); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "mouse_events", col3); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "name", col3); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "normal", col3); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "on", col3); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "scale", col3); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "signal", col3); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "state", col3); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "relative", col3); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "repeat_events", col3); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "source", col3); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "target", col3); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "to", col3); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "transition", col3); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "type", col3); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "visible", col3); + + //syntax group 4 + Eina_Stringshare *col4 = cd->col4; + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "ACCELERATE_FACTOR", + col4); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "ACCELERATE", col4); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "BOUNCE", col4); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "BOX", col4); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "COMP", col4); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "DECELERATE_FACTOR", + col4); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "DECELERATE", col4); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "DIVISOR_INTERP", col4); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "EXTERNAL", col4); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "GRADIENT", col4); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "GROUP", col4); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "IMAGE", col4); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "LINEAR", col4); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "LOSSY", col4); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "PROXY", col4); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "RAW", col4); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "RECT", col4); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "SINUSOIDAL_FACTOR", + col4); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "SINUSOIDAL", col4); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "SPACER", col4); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "SPRING", col4); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "STATE_SET", col4); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "SWALLOW", col4); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "TABLE", col4); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "TEXTBLOCK", col4); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "TEXT", col4); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "USER", col4); + + //duplicated groups 1 + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "image:", col3); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "size:", col3); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "text:", col3); + + //duplicated groups 2 + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "image", col2); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "text", col2); + COLOR_INSERT(strbuf, &src, length, &cur, &prev, "size", col2); + + cur++; + } + + //Same with origin source. + if (prev == src) + str = src; + //Some color syntax is applied. + else + { +finished: + //append leftovers. + if (prev + 1 < cur) eina_strbuf_append(strbuf, prev); + str = eina_strbuf_string_get(strbuf); + } + + return str; +}