edje_writer -> enventor

This commit is contained in:
ChunEon Park 2013-07-20 17:51:56 +09:00
commit 60b14b216c
64 changed files with 8272 additions and 0 deletions

62
Makefile Normal file
View File

@ -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)/$(<F)"
@$(CC) -c $(CFLAGS) $< -o $@ -I $(HEADERDIR)
$(BINARY): $(OBJECTS)
@echo " Linking $(@F)"
@$(CC) -o $(BINARY) $(OBJECTS) $(LDFLAGS)
$(EDJDIR)/enventor.edj: $(EDJDIR)/enventor.edc
@echo " Compilation of $(@D)/$(<F)"
@$(EDJE_CC) $(EDJE_FLAGS) $(EDJDIR)/enventor.edc $(EDJDIR)/enventor.edj
install: $(BINARY)
@echo "installation of executables"
@mkdir -p $(BINDIR)
@install -m 0755 $(BINARY) $(BINDIR)
@echo "installation of data"
@mkdir -p $(DATADIR)/edj
@install $(EDJDIR)/enventor.edj $(DATADIR)/edj
@mkdir -p $(DATADIR)/images
@install data/images/* $(DATADIR)/images
uninstall:
rm -rf $(DATADIR)
rm -rf $(BINDIR)/$(BINARY)
clean:
@rm -f $(EDJDIR)/*.edj *~ $(BINARY) $(SRCDIR)/*.o
@rm -f $(PROTODIR)/.proto.edc $(PROTODIR)/.proto.edj

22
README Normal file
View File

@ -0,0 +1,22 @@
Short Cut Keys:
Esc = Open/Close Menu
F5 = Show/Hide Line Number
F6 = Show/Hide Status
Ctrl+S = Save / Compile EDC
Ctrl+L = Load EDC
Ctrl+A = Select Text All
Ctrl+Double Click = Select a word
Ctrl+C = Copy Selected Text
Ctrl+V = Paste Copied Text
Ctrl+Home = Go to the Top line
Ctrl+End = Go to the Bottom line
Ctrl+H = Part Highlighting
Ctrl+, = Full Edit View
Ctrl+. = Full Edje View
Ctrl+/ = Split View
Command Line Usage:
enventor --help
enventor [input file] [-id image path] [-sd sound path]

3
build.sh Executable file
View File

@ -0,0 +1,3 @@
make clean
make
sudo make install

68
data/.proto/proto.edc Normal file
View File

@ -0,0 +1,68 @@
collections {
images {
image: "logo.png" COMP;
}
group { name: "main";
parts {
part { name: "logo";
type: IMAGE;
description { state: "default" 0.0;
rel1.relative: 0.0 0.0;
rel2.relative: 0.5 0.5;
image.normal: "logo.png";
}
description { state: "hide" 0.0;
inherit: "default" 0.0;
color: 127 127 127 127;
}
}
part { name: "rect";
type: RECT;
description { state: "default" 0.0;
rel1.relative: 0.5 0.0;
rel2.relative: 1.0 0.5;
color: 255 255 0 255;
}
}
part { name: "text";
type: TEXT;
scale: 1;
description { state: "default" 0.0;
rel1.relative: 0.0 0.5;
rel2.relative: 0.5 1.0;
color: 0 150 0 255;
text {
size: 25;
font: "Sans";
text: "Enventor";
align: 0.5 0.5;
}
}
}
part { name: "content";
type: SWALLOW;
description { state: "default" 0.0;
rel1.relative: 0.5 0.5;
rel2.relative: 1.0 1.0;
color: 255 255 0 255;
}
}
}
/*
programs {
program { name: "mouse_down";
signal: "mouse,down,1";
source: "logo";
action: STATE_SET "hide" 0.0;
target: "logo";
}
program { name: "mouse_up";
signal: "mouse,up,1";
source: "logo";
action: STATE_SET "default" 0.0;
target: "logo";
}
}
*/
}
}

BIN
data/.proto/proto.edj Normal file

Binary file not shown.

BIN
data/edc/.theme_ext.edc.swp Normal file

Binary file not shown.

108
data/edc/content.edc Normal file
View File

@ -0,0 +1,108 @@
images {
image: "part_highlight.png" COMP;
image: "swallow.png" COMP;
}
group { name: "swallow";
parts {
part { name: "base";
type: RECT;
mouse_events: 0;
description { state: "default" 0.0;
color: 255 0 0 10;
}
}
part { name: "img";
type: IMAGE;
mouse_events: 0;
description { state: "default" 0.0;
image.normal: "swallow.png";
align: 0.5 0.5;
min: 0 0;
max: 60 60;
color: 255 255 255 127;
}
}
part { name: "frame_l";
type: RECT;
mouse_events: 0;
description { state: "default" 0.0;
align: 0 0.5;
rel1.relative: 0 0;
rel2.relative: 0 1;
color: 255 0 0 127;
min: 1 0;
fixed: 1 0;
}
}
part { name: "frame_r";
type: RECT;
mouse_events: 0;
description { state: "default" 0.0;
align: 1 0.5;
rel1.relative: 1 0;
rel2.relative: 1 1;
color: 255 0 0 127;
min: 1 0;
fixed: 1 0;
}
}
part { name: "frame_t";
type: RECT;
mouse_events: 0;
description { state: "default" 0.0;
align: 0.5 0;
rel1.relative: 0 0;
rel2.relative: 1 0;
color: 255 0 0 127;
min: 0 1;
fixed: 0 1;
}
}
part { name: "frame_b";
type: RECT;
mouse_events: 0;
description { state: "default" 0.0;
align: 0.5 1;
rel1.relative: 0 1;
rel2.relative: 1 1;
color: 255 0 0 127;
min: 0 1;
fixed: 0 1;
}
}
}
}
group { name: "part_highlight";
parts {
part { name: "base";
type: IMAGE;
mouse_events: 0;
description { state: "default" 0.0;
image.normal: "part_highlight.png";
image.border: 3 3 3 3;
image.border_scale: 1;
}
description { state: "transparent" 0.0;
inherit: "default" 0.0;
color: 255 255 255 0;
}
}
}
programs {
program { name: "load";
signal: "load";
action: STATE_SET "transparent" 0.0;
target: "base";
transition: LINEAR 0.65;
after: "anim";
}
program { name: "anim";
action: STATE_SET "default" 0.0;
target: "base";
transition: LINEAR 0.65;
after: "load";
}
}
}

7
data/edc/enventor.edc Normal file
View File

@ -0,0 +1,7 @@
collections {
#include "content.edc"
#include "images.edc"
#include "theme_ext.edc"
#include "layout.edc"
#include "menu.edc"
}

26
data/edc/images.edc Normal file
View File

@ -0,0 +1,26 @@
images {
image: "plus.png" COMP;
image: "minus.png" COMP;
}
group { name: "plus_img";
parts {
part { name: "img";
type: IMAGE;
description { state: "default" 0.0;
image.normal: "plus.png";
}
}
}
}
group { name: "minus_img";
parts {
part { name: "img";
type: IMAGE;
description { state: "default" 0.0;
image.normal: "minus.png";
}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 952 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 981 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 230 B

BIN
data/edc/images/bt_glow.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 343 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 305 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 482 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 285 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 275 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 480 B

BIN
data/edc/images/cur_box.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 187 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 391 B

BIN
data/edc/images/cur_hi.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 252 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 200 B

BIN
data/edc/images/folder.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 746 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 691 B

BIN
data/edc/images/minus.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 201 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 302 B

BIN
data/edc/images/plus.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 207 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 509 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 286 B

BIN
data/edc/images/swallow.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

BIN
data/edc/images/warning.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 762 B

272
data/edc/layout.edc Normal file
View File

@ -0,0 +1,272 @@
styles {
style { name: "entry_statusbar_style";
base: "font=Sans font_size=11 color=#000000 text_class=entry color=#606060";
}
}
group { name: "slider_layout";
parts {
part { name: "bg";
type: RECT;
description { state: "default" 0.0;
min: 100 25;
color: 225 225 225 255;
}
}
part { name: "elm.swallow.plus";
type: SWALLOW;
description { state: "default" 0.0;
min: 20 20;
fixed: 1 1;
align: 0 0.5;
rel1.relative: 0.0 0.5;
rel1.offset: 5 0;
rel2.relative: 0.0 0.5;
}
}
part { name: "elm.swallow.minus";
type: SWALLOW;
description { state: "default" 0.0;
min: 20 20;
fixed: 1 1;
align: 0 0.5;
rel1.to: "elm.swallow.plus";
rel2.to: "elm.swallow.plus";
rel1.relative: 1.0 0.5;
rel2.relative: 1.0 0.5;
rel1.offset: 1 0;
}
}
part { name: "elm.swallow.slider";
type: SWALLOW;
description { state: "default" 0.0;
rel1.to_x: "elm.swallow.minus";
rel1.offset: 10 0;
}
}
}
}
group { name: "statusbar_layout";
parts {
part { name: "base_clip";
type: RECT;
description { state: "default" 0.0;
color: 255 255 255 255;
}
description { state: "hide" 0.0;
color: 0 0 0 0;
}
}
part { name: "elm.text.view_size";
type: TEXTBLOCK;
scale: 1;
clip_to: "base_clip";
description {
rel2.relative: 0.0 1.0;
align: 0 0.5;
min: 120 0;
fixed: 1 0;
text.style: "entry_statusbar_style";
}
}
part { name: "elm.text.cur_pos";
type: TEXTBLOCK;
scale: 1;
clip_to: "base_clip";
description {
rel1.to: "elm.text.view_size";
rel1.relative: 1 0.0;
rel2.to: "elm.text.view_size";
rel2.relative: 1 1.0;
min: 180 0;
fixed: 1 0;
align: 0 0.5;
text.style: "entry_statusbar_style";
}
}
part { name: "elm.text.file_group_name";
type: TEXTBLOCK;
scale: 1;
clip_to: "base_clip";
description {
rel1.to: "elm.text.cur_pos";
rel1.relative: 1 0.0;
rel2.to: "elm.text.line";
rel2.relative: 0 1.0;
align: 1 0.5;
text.style: "entry_statusbar_style";
}
}
part { name: "elm.text.line";
type: TEXTBLOCK;
scale: 1;
clip_to: "base_clip";
description {
rel1.relative: 1 0;
align: 1 0.5;
min: 100 0;
fixed: 1 0;
text.style: "entry_statusbar_style";
}
}
part { name: "elm.text.info_msg";
type: TEXT;
scale: 1;
description { state: "default" 0.0;
align: 0 0.5;
color: 0 0 0 0;
text {
font: "Sans";
size: 11;
align: 0 0.5;
}
}
description { state: "show" 0.0;
inherit: "default" 0.0;
color: 255 0 0 255;
}
}
program { name: "info_msg_show";
signal: "elm,action,info_msg,show";
source: "";
action: STATE_SET "hide" 0.0;
target: "base_clip";
transition: DECELERATE 0.15;
after: "info_msg_show2";
}
program { name: "info_msg_show2";
action: STATE_SET "show" 0.0;
target: "elm.text.info_msg";
transition: DECELERATE 0.3;
}
program { name: "info_msg_hide";
signal: "elm,action,info_msg,hide";
source: "";
action: STATE_SET "default" 0.0;
target: "elm.text.info_msg";
transition: DECELERATE 0.3;
after: "info_msg_hide2";
}
program { name: "info_msg_hide2";
action: STATE_SET "default" 0.0;
target: "base_clip";
transition: DECELERATE 0.3;
}
}
}
group { name: "main_layout";
parts {
part { name: "base";
type: RECT;
scale: 1;
description {
min: 640 440;
visible: 0;
}
}
part { name: "elm.swallow.panes";
type: SWALLOW;
scale: 1;
description {
rel1.relative: 0 0;
rel2.relative: 1 0;
rel2.to_y: "elm.swallow.statusbar";
}
}
part { name: "statusbar_clip";
type: RECT;
scale: 1;
description { state: "default" 0.0;
rel1.relative: 0 1;
rel2.relative: 1 1;
align: 0.5 1;
min: 0 12;
fixed: 0 1;
}
description { state: "hide" 0.0;
inherit: "default" 0.0;
align: 0.5 0;
}
}
part { name: "elm.swallow.statusbar";
type: SWALLOW;
scale: 1;
clip_to: "statusbar_clip";
description { state: "default" 0.0;
rel1.to: "statusbar_clip";
rel2.to: "statusbar_clip";
}
}
}
programs {
program { name: "statusbar_show";
signal: "elm,state,statusbar,show";
action: STATE_SET "default" 0.0;
target: "statusbar_clip";
transition: DECELERATE 0.35;
}
program { name: "statusbar_hide";
signal: "elm,state,statusbar,hide";
action: STATE_SET "hide" 0.0;
target: "statusbar_clip";
transition: DECELERATE 0.35;
}
}
}
group { name: "edit_layout";
parts {
part { name: "base_clip";
type: RECT;
description { state: "default" 0.0;
rel1.to: "elm.swallow.linenumber";
rel2.to: "elm.swallow.linenumber";
rel2.relative: 1 1;
}
description { state: "hide" 0.0;
rel1.to: "elm.swallow.linenumber";
rel2.to: "elm.swallow.linenumber";
rel2.relative: 0 1;
}
}
part { name: "elm.swallow.linenumber";
type: SWALLOW;
scale: 1;
clip_to: "base_clip";
mouse_events: 0;
description {
fixed: 1 0;
align: 0 0.5;
min: 15 0;
rel1.relative: 0 0;
rel1.offset: 3 0;
rel2.relative: 0 1;
}
}
part { name: "elm.swallow.edit";
type: SWALLOW;
scale: 1;
description {
align: 0.5 0.5;
rel1.relative: 1 0;
rel1.to: "base_clip";
}
}
}
programs {
program { name: "linenumber_show";
signal: "elm,state,linenumber,show";
action: STATE_SET "default" 0.0;
target: "base_clip";
transition: DECELERATE 0.35;
}
program { name: "linenumber_hide";
signal: "elm,state,linenumber,hide";
action: STATE_SET "hide" 0.0;
target: "base_clip";
transition: DECELERATE 0.35;
}
}
}

883
data/edc/menu.edc Normal file
View File

@ -0,0 +1,883 @@
images {
image: "menu_layout.png" COMP;
image: "folder.png" COMP;
image: "preference.png" COMP;
image: "content_glow.png" COMP;
image: "warning.png" COMP;
}
group { name: "fileselector_layout";
parts {
part { name: "clipper";
type: RECT;
description { state: "default" 0.0;
color: 127 127 127 127;
}
description { state: "show" 0.0;
color: 255 255 255 255;
}
}
part { name: "bg";
type: RECT;
clip_to: "clipper";
description { state: "default" 0.0;
color: 50 50 50 100;
}
}
part { name: "base_frame_img";
type: IMAGE;
scale: 1;
clip_to: "clipper";
description {
min: 600 400;
max: 600 400;
fixed: 1 1;
color: 255 255 255 255;
image.normal: "menu_layout.png";
image.border: 8 8 8 8;
image.border_scale: 1;
}
}
part { name: "base_frame";
type: RECT;
clip_to: "clipper";
description {
rel1 { to: "base_frame_img"; offset: 10 10; }
rel2 { to: "base_frame_img"; offset: -21 -11; }
visible: 0;
}
}
part { name: "elm.swallow.fileselector";
type: SWALLOW;
clip_to: "clipper";
description {
rel1 { to: "base_frame"; }
rel2 { to: "base_frame"; }
}
}
part { name: "event_blocker";
type: RECT;
description { state: "default" 0.0;
color: 0 0 0 0;
visible: 1;
}
description { state: "hide" 0.0;
inherit: "default" 0.0;
visible: 0;
}
}
}
programs {
program { name: "load";
signal: "load";
action: STATE_SET "show" 0.0;
transition: "DECELERATE" 0.5;
target: "clipper";
after: "event_blocker_hide";
}
program { name: "dismiss";
signal: "elm,state,dismiss";
source: "";
action: STATE_SET "default" 0.0;
// transition: "DECELERATE" 0.125;
target: "clipper";
target: "event_blocker";
after: "dismiss_done";
}
program { name: "event_blocker_hide";
signal: "elm,state,event_blocker,hide";
source: "";
action: STATE_SET "hide" 0.0;
target: "event_blocker";
}
program { name: "dismiss_done";
action: SIGNAL_EMIT "elm,state,dismiss,done" "";
}
}
}
group { name: "warning_layout";
parts {
part { name: "clipper";
type: RECT;
description { state: "default" 0.0;
color: 127 127 127 127;
}
description {state: "show" 0.0;
color: 255 255 255 255;
}
}
part { name: "bg";
type: RECT;
clip_to: "clipper";
description { state: "default" 0.0;
color: 50 50 50 100;
}
}
part { name: "base_frame_img";
type: IMAGE;
scale: 1;
clip_to: "clipper";
description {
min: 300 150;
max: 300 150;
fixed: 1 1;
color: 255 255 255 255;
image.normal: "menu_layout.png";
image.border: 8 8 8 8;
image.border_scale: 1;
}
}
part { name: "base_frame";
type: RECT;
clip_to: "clipper";
description {
rel1 { to: "base_frame_img"; offset: 10 10; }
rel2 { to: "base_frame_img"; offset: -11 -11; }
visible: 0;
}
}
part { name: "title_bg";
type: RECT;
scale: 1;
description {
rel1.to_y: "elm.text.title";
rel1.to_x: "base_frame";
rel2.to_y: "elm.text.title";
rel2.to_x: "base_frame";
color: 25 25 25 25;
}
}
part { name: "warning_img";
type: IMAGE;
clip_to: "clipper";
description {
min: 20 20;
max: 20 20;
fixed: 1 1;
align: 1 0.5;
rel1.to: "elm.text.title";
rel2.to: "elm.text.title";
rel2.offset: -8 -1;
rel1.relative: 0 0.5;
rel2.relative: 0 0.5;
image.normal: "warning.png";
}
}
part { name: "elm.text.title";
type: TEXT;
clip_to: "clipper";
scale: 1;
description {
rel1.to: "base_frame";
rel2.to: "base_frame";
rel1.relative: 0.5 0;
rel2.relative: 0.5 0;
text.text: "EDC has been changed";
text {
font: "Sans";
size: 14;
align: 0.5 0;
min: 1 1;
}
fixed: 1 1;
color: 30 30 30 255;
align: 0.5 0;
}
}
part { name: "elm.text.desc";
type: TEXT;
clip_to: "clipper";
scale: 1;
description {
rel1 { to: "elm.text.title"; relative: 0.5 1; offset: 0 10; }
rel2 { to: "elm.text.title"; relative: 0.5 1; }
text.text: "Without save, you will lost last changes!";
text {
font: "Sans";
size: 12;
align: 0.5 0;
min: 1 1;
}
align: 0.5 0;
fixed: 1 1;
color: 30 30 30 255;
}
}
part { name: "elm.text.question";
type: TEXT;
clip_to: "clipper";
scale: 1;
description {
rel1 { to: "elm.text.desc"; relative: 0.5 1; offset: 0 10; }
rel2 { to: "elm.text.desc"; relative: 0.5 1; }
text.text: "Are you sure you want to do this?";
text {
font: "Sans";
size: 12;
align: 0.5 0;
min: 1 1;
}
align: 0.5 0;
fixed: 1 1;
color: 30 30 30 255;
}
}
part { name: "elm.swallow.save";
type: SWALLOW;
clip_to: "clipper";
scale: 1;
description {
rel1.to: "base_frame";
rel2.to: "base_frame";
rel1.relative: 0 1;
rel2.relative: 0 1;
rel1.offset: 20 0;
rel2.offset: -1 -10;
min: 70 35;
align: 0 1;
fixed: 1 1;
}
}
part { name: "elm.swallow.no";
type: SWALLOW;
clip_to: "clipper";
scale: 1;
description {
rel1.to: "elm.swallow.save";
rel2.to: "elm.swallow.save";
rel1.relative: 1 0;
rel2.relative: 1 1;
rel1.offset: 15 0;
min: 70 35;
align: 0 0.5;
fixed: 1 1;
}
}
part { name: "elm.swallow.yes";
type: SWALLOW;
clip_to: "clipper";
scale: 1;
description {
rel1.to: "elm.swallow.no";
rel2.to: "elm.swallow.no";
rel1.relative: 1 0;
rel2.relative: 1 1;
rel1.offset: 15 0;
min: 70 35;
align: 0 0.5;
fixed: 1 1;
color: 0 0 0 255;
}
}
part { name: "event_blocker";
type: RECT;
description { state: "default" 0.0;
color: 0 0 0 0;
visible: 1;
}
description { state: "hide" 0.0;
inherit: "default" 0.0;
visible: 0;
}
}
}
programs {
program { name: "load";
signal: "load";
action: STATE_SET "show" 0.0;
transition: "DECELERATE" 0.25;
target: "clipper";
after: "event_blocker_hide";
}
program { name: "dismiss";
signal: "elm,state,dismiss";
source: "";
action: STATE_SET "default" 0.0;
transition: "DECELERATE" 0.125;
target: "clipper";
target: "event_blocker";
after: "dismiss_done";
}
program { name: "event_blocker_hide";
signal: "elm,state,event_blocker,hide";
source: "";
action: STATE_SET "hide" 0.0;
target: "event_blocker";
}
program { name: "dismiss_done";
action: SIGNAL_EMIT "elm,state,dismiss,done" "";
}
}
}
group { name: "button_layout";
parts {
part { name: "shine";
type: IMAGE;
scale: 1;
description {
align: 0.5 0.5;
image.normal: "content_glow.png";
rel1.to: "elm.swallow.btn";
rel2.to: "elm.swallow.btn";
rel1.relative: -0.41 -0.41;
rel2.relative: 1.41 1.41;
}
}
part { name: "elm.swallow.btn";
type: SWALLOW;
scale: 1;
description { state: "default" 0.0;
align: 0.5 0.5;
min: 50 50;
rel1.relative: 0.5 0.5;
rel2.relative: 0.5 0.5;
fixed: 1 1;
}
description { state: "zoom" 0.0;
inherit: "default" 0.0;
min: 80 80;
}
}
}
programs {
program { name: "btn_effect";
signal: "elm,action,btn,zoom";
source: "";
action: STATE_SET "zoom" 0.0;
target: "elm.swallow.btn";
transition: LINEAR 0.25;
}
}
}
group { name: "menu_layout";
parts {
part { name: "bg";
type: RECT;
description { state: "default" 0.0;
color: 0 0 0 0;
}
description { state: "show" 0.0;
color: 50 50 50 160;
}
}
part { name: "clipper";
type: RECT;
description { state: "default" 0.0;
color: 255 255 255 0;
}
description { state: "show" 0.0;
color: 255 255 255 255;
}
}
part { name: "base_frame";
type: RECT;
scale: 1;
description {
align: 0.5 0.5;
min: 640 0;
fixed: 1 0;
rel1.relative: 0.5 0;
rel2.relative: 0.5 1;
visible: 0;
}
}
part { name: "padding1";
type: RECT;
scale: 1;
description { state: "default" 0.0;
rel1.relative: 0 0.5;
rel2.relative: 0 0.5;
rel1.to: "base_frame";
rel2.to: "base_frame";
min: 23 80;
fixed: 1 1;
align: 0 0.5;
visible: 0;
}
}
part { name: "elm.swallow.new_btn";
type: SWALLOW;
scale: 1;
clip_to: "clipper";
description { state: "default" 0.0;
rel1.to: "padding1";
rel2.to: "padding1";
rel1.relative: 1 0;
align: 0 0.5;
min: 80 80;
fixed: 1 1;
}
}
part { name: "padding2";
type: RECT;
scale: 1;
description { state: "default" 0.0;
rel1.to: "elm.swallow.new_btn";
rel2.to: "elm.swallow.new_btn";
rel1.relative: 1 0;
min: 23 80;
fixed: 1 1;
align: 0 0.5;
visible: 0;
}
}
part { name: "elm.swallow.save_btn";
type: SWALLOW;
scale: 1;
clip_to: "clipper";
description { state: "default" 0.0;
rel1.to: "padding2";
rel2.to: "padding2";
rel1.relative: 1 0;
align: 0 0.5;
min: 80 80;
fixed: 1 1;
}
}
part { name: "padding3";
type: RECT;
scale: 1;
description { state: "default" 0.0;
rel1.to: "elm.swallow.save_btn";
rel2.to: "elm.swallow.save_btn";
rel1.relative: 1 0;
min: 23 80;
fixed: 1 1;
align: 0 0.5;
visible: 0;
}
}
part { name: "elm.swallow.load_btn";
type: SWALLOW;
scale: 1;
clip_to: "clipper";
description { state: "default" 0.0;
rel1.to: "padding3";
rel2.to: "padding3";
rel1.relative: 1 0;
align: 0 0.5;
min: 80 80;
fixed: 1 1;
}
}
part { name: "padding4";
type: RECT;
scale: 1;
description { state: "default" 0.0;
rel1.to: "elm.swallow.load_btn";
rel2.to: "elm.swallow.load_btn";
rel1.relative: 1 0;
min: 23 80;
fixed: 1 1;
align: 0 0.5;
visible: 0;
}
}
part { name: "elm.swallow.setting_btn";
type: SWALLOW;
scale: 1;
clip_to: "clipper";
description { state: "default" 0.0;
rel1.to: "padding4";
rel2.to: "padding4";
rel1.relative: 1 0;
align: 0 0.5;
min: 80 80;
fixed: 1 1;
}
}
part { name: "padding5";
type: RECT;
scale: 1;
description { state: "default" 0.0;
rel1.to: "elm.swallow.setting_btn";
rel2.to: "elm.swallow.setting_btn";
rel1.relative: 1 0;
min: 23 80;
fixed: 1 1;
align: 0 0.5;
visible: 0;
}
}
part { name: "elm.swallow.help_btn";
type: SWALLOW;
scale: 1;
clip_to: "clipper";
description { state: "default" 0.0;
rel1.to: "padding5";
rel2.to: "padding5";
rel1.relative: 1 0;
align: 0 0.5;
min: 80 80;
fixed: 1 1;
}
}
part { name: "padding6";
type: RECT;
scale: 1;
description { state: "default" 0.0;
rel1.to: "elm.swallow.help_btn";
rel2.to: "elm.swallow.help_btn";
rel1.relative: 1 0;
min: 23 80;
fixed: 1 1;
align: 0 0.5;
visible: 0;
}
}
part { name: "elm.swallow.exit_btn";
type: SWALLOW;
scale: 1;
clip_to: "clipper";
description { state: "default" 0.0;
rel1.to: "padding6";
rel2.to: "padding6";
rel1.relative: 1 0;
align: 0 0.5;
min: 80 80;
fixed: 1 1;
}
}
part { name: "event_blocker";
type: RECT;
description { state: "default" 0.0;
color: 0 0 0 0;
visible: 1;
}
description { state: "hide" 0.0;
inherit: "default" 0.0;
visible: 0;
}
}
}
programs {
program { name: "load";
signal: "load";
action: STATE_SET "show" 0.0;
transition: "DECELERATE" 0.25;
target: "bg";
target: "clipper";
after: "event_blocker_hide";
}
program { name: "event_blocker_hide";
signal: "elm,state,event_blocker,hide";
source: "";
action: STATE_SET "hide" 0.0;
target: "event_blocker";
}
program { name: "dismiss";
signal: "elm,state,dismiss";
source: "";
action: STATE_SET "default" 0.0;
transition: "DECELERATE" 0.125;
target: "bg";
target: "event_blocker";
target: "clipper";
after: "dismiss_done";
}
program { name: "dismiss_done";
action: SIGNAL_EMIT "elm,state,dismiss,done" "";
}
}
}
group { name: "setting_layout";
parts {
part { name: "clipper";
type: RECT;
description { state: "default" 0.0;
color: 127 127 127 127;
}
description { state: "show" 0.0;
color: 255 255 255 255;
}
part { name: "bg";
type: RECT;
clip_to: "clipper";
description { state: "default" 0.0;
color: 50 50 50 100;
}
}
part { name: "base_frame_img";
type: IMAGE;
scale: 1;
clip_to: "clipper";
description {
min: 600 400;
max: 600 400;
fixed: 1 1;
color: 255 255 255 255;
image.normal: "menu_layout.png";
image.border: 8 8 8 8;
image.border_scale: 1;
}
}
part { name: "base_frame";
type: RECT;
clip_to: "clipper";
description {
rel1 {to: "base_frame_img"; offset: 10 10;}
rel2 {to: "base_frame_img"; offset: -21 -11;}
visible: 0;
}
}
part { name: "img_path_frame";
type: RECT;
clip_to: "clipper";
description {
rel1 {to: "base_frame"; relative: 0 0;}
rel2 {to: "base_frame"; relative: 1 0;}
align: 0.5 0;
visible: 0;
min: 0 60;
fixed: 0 1;
}
}
part { name: "snd_path_frame";
type: RECT;
clip_to: "clipper";
description {
rel1 {to: "img_path_frame"; relative: 0 1;}
rel2 {to: "img_path_frame"; relative: 1 1;}
align: 0.5 0;
visible: 0;
min: 0 60;
fixed: 0 1;
}
}
part { name: "preference_frame";
type: RECT;
clip_to: "clipper";
description {
rel1 {to: "snd_path_frame"; relative: 0 1;}
rel2 {to: "snd_path_frame"; relative: 1 1;}
align: 0.5 0;
visible: 0;
min: 0 200;
fixed: 0 1;
}
}
part { name: "img_path_icon";
type: IMAGE;
scale: 1;
clip_to: "clipper";
description {
align: 0 0;
min: 20 20;
max: 20 20;
fixed: 1 1;
rel1.to: "img_path_frame";
rel2.to: "img_path_frame";
image.normal: "folder.png";
}
}
part { name: "img_path_guide";
type: TEXT;
scale: 1;
clip_to: "clipper";
description {
rel1 {to: "img_path_icon"; relative: 1 0; offset: 5 1;}
rel2 {to: "img_path_icon"; relative: 1 1;}
color: 30 30 30 255;
align: 0 0.5;
fixed: 1 1;
text {
font: "Sans";
text: "Image Paths:";
size: 12;
align: 0 0.5;
min: 1 0;
}
}
}
part { name: "elm.swallow.img_path_entry";
type: SWALLOW;
scale: 1;
clip_to: "clipper";
description {
align: 0 0;
fixed: 1 1;
rel1.to_x: "img_path_guide";
rel1.to_y: "img_path_guide";
rel1.offset: 0 5;
rel1.relative: 0 1;
rel2.to: "img_path_frame";
}
}
part { name: "snd_path_icon";
type: IMAGE;
scale: 1;
clip_to: "clipper";
description {
align: 0 0;
min: 20 20;
max: 20 20;
fixed: 1 1;
rel1.to: "snd_path_frame";
rel2.to: "snd_path_frame";
image.normal: "folder.png";
}
}
part { name: "snd_path_guide";
type: TEXT;
scale: 1;
clip_to: "clipper";
description {
rel1 {to: "snd_path_icon"; relative: 1 0; offset: 5 1;}
rel2 {to: "snd_path_icon"; relative: 1 1;}
color: 30 30 30 255;
align: 0 0.5;
fixed: 1 1;
text {
font: "Sans";
text: "Sound Paths:";
size: 12;
align: 0 0.5;
min: 1 0;
}
}
}
part { name: "elm.swallow.snd_path_entry";
type: SWALLOW;
scale: 1;
clip_to: "clipper";
description {
align: 0 0;
fixed: 1 1;
rel1.to_x: "snd_path_guide";
rel1.to_y: "snd_path_guide";
rel1.offset: 0 5;
rel1.relative: 0 1;
rel2.to: "snd_path_frame";
}
}
part { name: "preference_icon";
type: IMAGE;
scale: 1;
clip_to: "clipper";
description {
align: 0 0;
min: 20 20;
max: 20 20;
fixed: 1 1;
rel1.to: "preference_frame";
rel2.to: "preference_frame";
image.normal: "preference.png";
}
}
part { name: "preference_guide";
type: TEXT;
scale: 1;
clip_to: "clipper";
description {
rel1 {to: "preference_icon"; relative: 1 0; offset: 5 1;}
rel2 {to: "preference_icon"; relative: 1 1;}
color: 30 30 30 255;
align: 0 0;
fixed: 1 1;
text {
font: "Sans";
text: "Preferences:";
size: 12;
align: 0 0;
min: 1 0;
}
}
}
part { name: "preference_bg";
type: RECT;
scale: 1;
description {
rel1.to_x: "preference_guide";
rel1.to_y: "preference_guide";
rel1.offset: 0 5;
rel1.relative: 0 1;
rel2.to: "preference_frame";
color: 170 170 170 170;
}
}
part { name: "elm.swallow.preference";
type: SWALLOW;
scale: 1;
clip_to: "clipper";
description {
rel1.to_x: "preference_guide";
rel1.to_y: "preference_guide";
rel1.offset: 0 10;
rel1.relative: 0 1;
rel2.to: "preference_frame";
}
}
part { name: "elm.swallow.reset_btn";
type: SWALLOW;
scale: 1;
clip_to: "clipper";
description {
align: 0 1;
min: 70 35;
fixed: 1 1;
rel1.to: "base_frame";
rel1.relative: 0 1;
rel2.to: "base_frame";
rel2.relative: 0 1;
}
}
part { name: "elm.swallow.apply_btn";
type: SWALLOW;
scale: 1;
clip_to: "clipper";
description {
align: 1 1;
min: 70 35;
fixed: 1 1;
rel1.to: "base_frame";
rel1.relative: 1 1;
rel2.to: "base_frame";
rel2.relative: 1 1;
}
}
part { name: "event_blocker";
type: RECT;
description { state: "default" 0.0;
color: 0 0 0 0;
visible: 1;
}
description { state: "hide" 0.0;
inherit: "default" 0.0;
visible: 0;
}
}
}
programs {
program { name: "load";
signal: "load";
action: STATE_SET "show" 0.0;
transition: "DECELERATE" 0.5;
target: "clipper";
after: "event_blocker_hide";
}
program { name: "dismiss";
signal: "elm,state,dismiss";
source: "";
action: STATE_SET "default" 0.0;
// transition: "DECELERATE" 0.125;
target: "clipper";
target: "event_blocker";
after: "dismiss_done";
}
program { name: "event_blocker_hide";
signal: "elm,state,event_blocker,hide";
source: "";
action: STATE_SET "hide" 0.0;
target: "event_blocker";
}
program { name: "dismiss_done";
action: SIGNAL_EMIT "elm,state,dismiss,done" "";
}
}
}

2655
data/edc/theme_ext.edc Normal file

File diff suppressed because it is too large Load Diff

BIN
data/images/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

BIN
data/sample/bg.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

BIN
data/sample/clouds.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

BIN
data/sample/etypers.edj Normal file

Binary file not shown.

BIN
data/sample/input_bg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 976 B

300
data/sample/sample.edc Normal file
View File

@ -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";
}
}
}

BIN
data/sample/sample.edj Normal file

Binary file not shown.

BIN
data/sample/sky.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

View File

@ -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";
}
}
}

138
include/common.h Normal file
View File

@ -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

274
src/config_data.c Normal file
View File

@ -0,0 +1,274 @@
#include <Elementary.h>
#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;
}

660
src/edc_editor.c Normal file
View File

@ -0,0 +1,660 @@
#include <Elementary.h>
#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<br/>", 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, "<br/>");
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, "<br/>")) 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, "<br/>")) goto err;
}
if (!eina_strbuf_append_length(strbuf, line->start, line->length))
goto err;
line_num++;
//Append line number
sprintf(buf, "%d<br/>", 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;
}

408
src/edc_parser.c Normal file
View File

@ -0,0 +1,408 @@
#include <Elementary.h>
#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("&quot;");
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 = "&quot;";
int quot_len = 6; // strlen("&quot;");
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;
}

226
src/edc_viewer.c Normal file
View File

@ -0,0 +1,226 @@
#include <Elementary.h>
#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);
}

147
src/fake_obj.c Normal file
View File

@ -0,0 +1,147 @@
#define EDJE_EDIT_IS_UNSTABLE_AND_I_KNOW_ABOUT_IT 1
#include <Elementary.h>
#include <Edje_Edit.h>
#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);
}

474
src/main.c Normal file
View File

@ -0,0 +1,474 @@
#include <Elementary.h>
#include <Eio.h>
#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;
}

755
src/menu.c Normal file
View File

@ -0,0 +1,755 @@
#include <Elementary.h>
#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);
}

168
src/panes.c Normal file
View File

@ -0,0 +1,168 @@
#include <Elementary.h>
#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;
}

103
src/statusbar.c Normal file
View File

@ -0,0 +1,103 @@
#include <Elementary.h>
#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),
"<align=right>Line [<color=#000000>%d</color>:<color=#000000>%d</color>]</align>", 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), "<align=right>File [<color=#000000>%s</color>] Group [<color=#000000>%s</color>]</align>", 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 [<color=#000000>0</color>,<color=#000000>0</color>] [<color=#000000>0.00</color>,<color=#000000>0.00</color>]");
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 [<color=#000000>%d</color>x<color=#000000>%d</color>]", 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 [<color=#000000>%d</color>,<color=#000000>%d</color>] [<color=#000000>%0.2f</color>,<color=#000000>%0.2f</color>]", x, y, rel_x, rel_y);
elm_object_part_text_set(sd->layout, "elm.text.cur_pos", buf);
}

494
src/syntax_color.c Normal file
View File

@ -0,0 +1,494 @@
#include <Elementary.h>
#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), "<color=#%s>%s</color>", 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("<tab/>");
if (strncmp(*cur, "<tab/>", 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("<br/>");
if (strncmp(*cur, "<br/>", 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=#%s>/*", 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, "*/</color>");
*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, "*/</color>");
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=#%s>//", color);
eina_strbuf_append(strbuf, buf);
int cmp_size = 2; //strlen("//");
*cur += cmp_size;
if (*cur > (*src + length))
{
eina_strbuf_append(strbuf, "</color>");
return -1;
}
*prev = *cur;
cmp_size = strlen("<br/>");
*cur = strstr(*prev, "<br/>");
if (*cur)
{
eina_strbuf_append_length(strbuf, *prev, (*cur - *prev));
eina_strbuf_append(strbuf, "</color><br/>");
*cur += cmp_size;
*prev = *cur;
return 1;
}
eina_strbuf_append(strbuf, *prev);
*prev = *cur;
eina_strbuf_append(strbuf, "</color>");
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: <br/>
if (br_skip(strbuf, &src, length, &cur, &prev) == 1)
continue;
//escape EOL: <tab/>
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: &quot; ~ &quot;
if (!strncmp(cur, "&quot;", strlen("&quot;")))
{
eina_strbuf_append_length(strbuf, prev, cur - prev);
eina_strbuf_append(strbuf, "&quot;");
cur += strlen("&quot;");
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;
}