1, UI can connect multi-pins with one line,
authoryu.dongliang <18588496441@163.com>
Wed, 11 Jun 2025 15:04:07 +0000 (23:04 +0800)
committeryu.dongliang <18588496441@163.com>
Wed, 11 Jun 2025 15:04:10 +0000 (23:04 +0800)
2, ses will output error log to UI,
3, if run with UI, ses don't exit the process when error.

main.c
scf_eda_pack.c
scf_eda_pack.h
ses_step_dc_diode.c
ses_step_dc_npn.c
ses_step_dc_pnp.c
ses_steps.c
ses_ui.c
ses_ui.h

diff --git a/main.c b/main.c
index fdfcc3487eeb28f4bf925c354937d3940ec0e1fe..db691cc13de0887460e2b9dd1faa09ed1bb9d9e5 100644 (file)
--- a/main.c
+++ b/main.c
@@ -519,9 +519,6 @@ int main(int argc, char* argv[])
                buf = NULL;
                len = 0;
 
-               if (ret < 0)
-                       return ret;
-
                fprintf(stderr, "# ");
        }
 
index eaadc2ee1fa480baf9acd86f3619802bd9045359..a484de7b0685b29a73e91b4ada77c5ed596fca91 100644 (file)
@@ -564,7 +564,7 @@ int scf_eline__add_line(ScfEline* el, ScfLine*  l)
        if (!el || !l)
                return -EINVAL;
 
-       for (size_t i = 0; i < el->n_lines; i++) {
+       for (long i = 0; i < el->n_lines; i++) {
 
                if (el->lines[i] == l)
                        return 0;
@@ -579,21 +579,18 @@ int scf_eline__add_line(ScfEline* el, ScfLine*  l)
        return 0;
 }
 
-int scf_eline__del_line(ScfEline* el, ScfLine*  l)
+int scf_eline__del_line(ScfEline* el, ScfLine* l)
 {
        if (!el || !l)
                return -EINVAL;
 
-       void*   p;
-       size_t  i;
-       size_t  j;
+       void*  p;
+       long   i;
+       long   j;
 
        for (i = 0; i < el->n_lines; i++) {
 
-               if (el->lines[i]->x0 == l->x0
-                && el->lines[i]->y0 == l->y0
-                && el->lines[i]->x1 == l->x1
-                && el->lines[i]->y1 == l->y1) {
+               if (el->lines[i] == l) {
 
                        for (j = i + 1;  j  < el->n_lines; j++)
                                el->lines[j - 1] = el->lines[j];
@@ -1359,6 +1356,61 @@ void scf_efunction_find_pin(ScfEfunction* f, ScfEcomponent** pc, ScfEpin** pp, i
        }
 }
 
+int scf_epin_in_line(int px, int py, int x0, int y0, int x1, int y1)
+{
+       if (x0 == x1) {
+               if (x0 - 5 < px && px < x0 + 5) {
+
+                       if (y0 > y1)
+                               SCF_XCHG(y0, y1);
+
+                       if (y0 - 5 < py && py < y1 + 5)
+                               return 1;
+               }
+       } else if (y0 == y1) {
+               if (y0 - 5 < py && py < y0 + 5) {
+
+                       if (x0 > x1)
+                               SCF_XCHG(x0, x1);
+
+                       if (x0 - 5 < px && px < x1 + 5)
+                               return 1;
+               }
+       } else {
+               if (x0 > x1) {
+                       SCF_XCHG(x0, x1);
+                       SCF_XCHG(y0, y1);
+               }
+
+               double Y0 = y0;
+               double Y1 = y1;
+
+               if (y0 > y1) {
+                       Y0 = y1;
+                       Y1 = y0;
+               }
+
+               double k = (y1 - y0) / (double)(x1 - x0);
+               double x = (py - y0  + px / k + x0 * k) / (k + 1.0 / k);
+               double y = (x  - x0) * k  + y0;
+
+               double dx = px - x;
+               double dy = py - y;
+               double d  = sqrt(dx * dx + dy * dy);
+
+               if (x > x0 - 5
+                               && x < x1 + 5
+                               && y > Y0 - 5
+                               && y < Y1 + 5
+                               && d < 5) {
+                       scf_logi("--- k: %lg, px: %d, py: %d, x: %lg, y: %lg, d: %lg, (%d,%d)-->(%d,%d)\n", k, px, py, x, y, d, x0, y0, x1, y1);
+                       return 1;
+               }
+       }
+
+       return 0;
+}
+
 void scf_efunction_find_eline(ScfEfunction* f, ScfEline** pel, ScfLine** pl, int x, int y)
 {
        ScfEline*  el;
@@ -1373,10 +1425,7 @@ void scf_efunction_find_eline(ScfEfunction* f, ScfEline** pel, ScfLine** pl, int
                for (j = el->n_lines - 1; j >= 0; j--) {
                        l  = el->lines[j];
 
-                       if (x > l->x0 - 5
-                                       && x < l->x1 + 5
-                                       && y > l->y0 - 5
-                                       && y < l->y1 + 5) {
+                       if (scf_epin_in_line(x, y, l->x0, l->y0, l->x1, l->y1)) {
 
                                scf_logi("j: %ld, (%d, %d)-->(%d, %d), x: %d, y: %d\n", j, l->x0, l->y0, l->x1, l->y1, x, y);
 
index 1d1f8715d11cdf2ab2df202db3035ecd3633bcc3..71ab58386c8105c29c64c5efaf8de07b2e83e0c3 100644 (file)
@@ -607,6 +607,9 @@ long           scf_find_eline_index(ScfEfunction* f, int64_t lid);
 void           scf_efunction_find_pin  (ScfEfunction* f, ScfEcomponent** pc,  ScfEpin** pp, int x, int y);
 void           scf_efunction_find_eline(ScfEfunction* f, ScfEline**      pel, ScfLine** pl, int x, int y);
 
+int            scf_epin_in_line(int px, int py, int x0, int y0, int x1, int y1);
+
+
 #define EDA_INST_ADD_COMPONENT(_ef, _c, _type) \
        do { \
                _c = scf_ecomponent__alloc(_type); \
index f1b10dbe4c7c9fa2aa60c9f8585e90b1c97a7764..8edd6a50406afd407df718ec15e46414a42c71a0 100644 (file)
@@ -33,6 +33,9 @@ static int __dc_diode_status(ScfEfunction* root, ScfEfunction* f, ScfEline* LP,
                        scf_loge("short connected, ");
                        ses_pin_print(pb);
                        fprintf(stderr, "\n");
+
+                       printf("error: D%ld is short connected\n", c->id);
+                       fflush(stdout);
                        return -EINVAL;
                }
 
index fedf6e9c3d9cd2a0e8b9bd36fb1b5e8f9a7b02a0..31b90b9d04e7e2c97f560f3d850ebb8a6fda0abc 100644 (file)
@@ -35,6 +35,9 @@ static int __dc_npn_status(ScfEfunction* root, ScfEfunction* f, ScfEline* LP, Sc
                        scf_loge("short connected, ");
                        ses_pin_print(pb);
                        fprintf(stderr, "\n");
+
+                       printf("error: T%ld is short connected\n", c->id);
+                       fflush(stdout);
                        return -EINVAL;
                }
 
index 118a6128a91598df7261bb2f3ca5430f1a925f19..f463e773d7638684c7f7393c5cc19e5316660318 100644 (file)
@@ -35,6 +35,9 @@ static int __dc_pnp_status(ScfEfunction* root, ScfEfunction* f, ScfEline* LP, Sc
                        scf_loge("short connected, ");
                        ses_pin_print(pb);
                        fprintf(stderr, "\n");
+
+                       printf("error: T%ld is short connected\n", c->id);
+                       fflush(stdout);
                        return -EINVAL;
                }
 
index 1c580f4853d31d180972eb560ca5556612e4dd1a..005c23c9135915683db80dc209d49c56bbb39442 100644 (file)
@@ -28,17 +28,14 @@ static ses_step_t*  ses_steps_0[] =
 //     &ses_step_ac_input,
 };
 
-static ses_step_t*  ses_steps_1[] =
+static ses_step_t*  ses_steps_2[] =
 {
        &ses_step_dc_diode,
        &ses_step_dc_npn,
        &ses_step_dc_pnp,
 
        &ses_step_topo,
-};
 
-static ses_step_t*  ses_steps_2[] =
-{
        &ses_step_open,
        &ses_step_va_nodes,
 
@@ -71,8 +68,9 @@ static int __ses_analyse_input(ScfEfunction* f, int64_t ps, int64_t i, ses_ctx_t
 static int __ses_analyse_time(ScfEfunction* f, int64_t ps, int64_t i, ses_ctx_t* ctx)
 {
        ses_step_t* s;
+       int64_t     j;
 
-       int64_t j;
+       ctx->changed = 0;
 
        for (j = 0; j < sizeof(ses_steps_2) / sizeof(ses_steps_2[0]); j++) {
                s  = ses_steps_2[j];
@@ -90,31 +88,6 @@ static int __ses_analyse_time(ScfEfunction* f, int64_t ps, int64_t i, ses_ctx_t*
        return 0;
 }
 
-static int __ses_analyse_current(ScfEfunction* f, int64_t ps, int64_t i, ses_ctx_t* ctx)
-{
-       ses_step_t* s;
-
-       int64_t j;
-
-       ctx->changed = 0;
-
-       for (j = 0; j < sizeof(ses_steps_1) / sizeof(ses_steps_1[0]); j++) {
-               s  = ses_steps_1[j];
-
-               if (!s || !s->handler)
-                       continue;
-
-               int ret = s->handler(f, ps, i, ctx);
-               if (ret < 0) {
-                       scf_loge("analysis step '%s' ret: %d\n", s->name, ret);
-                       return ret;
-               }
-       }
-
-       scf_logi("--------------- ctx->changed: %d\n", ctx->changed);
-       return ctx->changed > 0 ? -EAGAIN : 0;
-}
-
 static void __ses_init_v(ScfEfunction* f)
 {
        ScfEcomponent* c;
@@ -172,22 +145,6 @@ int ses_steps_analyse(ScfEboard* b, ScfEfunction* f, int64_t ps, int64_t count,
                if (ret < 0)
                        return ret;
 
-               int j;
-               for (j = 0; j < 1; j++) {
-                       fprintf(stderr, "\n\033[33m%s(), %d(), j: %d\033[0m\n", __func__, __LINE__, j);
-
-                       ret = __ses_analyse_current(f, ps, i, ctx);
-
-                       if (-EAGAIN == ret)
-                               continue;
-
-                       if (0 == ret)
-                               break;
-
-                       if (ret < 0)
-                               break;
-               }
-
                ret = __ses_analyse_time(f, ps, i, ctx);
                if (ret < 0)
                        return ret;
index 5f87dcdd1f9f86dec918c6a3a097e2ca17a747f3..54b3bc4fba3026f8df5f0c3406adf03337541ab7 100644 (file)
--- a/ses_ui.c
+++ b/ses_ui.c
@@ -1,5 +1,41 @@
 #include"ses_ui.h"
 
+static void ui_add_line(ses_ui_t* ui, ScfEline* el, ScfLine* l)
+{
+       ScfEcomponent* c;
+       ScfEpin*       p;
+       long i;
+
+       for (i = 0; i + 1 < el->n_pins; i += 2) {
+               c  = ui->f->components[el->pins[i]];
+               p  = c->pins          [el->pins[i + 1]];
+
+               if (scf_epin_in_line(p->x, p->y, l->x0, l->y0, l->x1, l->y1)) {
+                       p->lid = el->id;
+
+                       scf_logi("\033[32m el%ld add c%ldp%ld\033[0m\n", el->id, p->cid, p->id);
+               }
+       }
+}
+
+static void ui_del_line(ses_ui_t* ui, ScfEline* el, ScfLine* l)
+{
+       ScfEcomponent* c;
+       ScfEpin*       p;
+       long i;
+
+       for (i = 0; i + 1 < el->n_pins; i += 2) {
+               c  = ui->f->components[el->pins[i]];
+               p  = c->pins          [el->pins[i + 1]];
+
+               if (scf_epin_in_line(p->x, p->y, l->x0, l->y0, l->x1, l->y1)) {
+                       p->lid = -1;
+
+                       scf_logi("\033[31m el%ld del c%ldp%ld\033[0m\n", el->id, p->cid, p->id);
+               }
+       }
+}
+
 static void ui_add_eline(ses_ui_t* ui, ScfEline* el)
 {
        ScfEcomponent* c;
@@ -152,6 +188,10 @@ static void ui_print_log(ui_log_t* log)
                case UI_DEL_LINE:
                        fprintf(stderr, "log: del %p el%ld, l: %p\n", log->el, log->el->id, log->l);
                        break;
+
+               case UI_ADD_PIN:
+                       fprintf(stderr, "log: add %p el%ld, %p c%ldp%ld\n", log->el, log->el->id, log->p, log->p->cid, log->p->id);
+                       break;
                default:
                        break;
        };
@@ -230,6 +270,10 @@ static void ui_add_log(ses_ui_t* ui, ui_log_t* log)
                        case UI_ADD_LINE:
                                scf_logw("free: add el %p, l %p\n", log->el, log->l);
                                break;
+
+                       case UI_ADD_PIN:
+                               scf_logw("free: add el %p, pin %p\n", log->el, log->p);
+                               break;
                        default:
                                break;
                };
@@ -328,10 +372,10 @@ static int button_transistor_clicked(ses_ui_t* ui, int type)
        c->pins[SCF_EDA_NPN_B]->y = c->y - 50;
 
        c->pins[SCF_EDA_NPN_C]->x = c->x - 100 * 7 / 8;
-       c->pins[SCF_EDA_NPN_C]->y = c->y + 50;
+       c->pins[SCF_EDA_NPN_C]->y = c->y + 10;
 
        c->pins[SCF_EDA_NPN_E]->x = c->x + 100 * 7 / 8;
-       c->pins[SCF_EDA_NPN_E]->y = c->y + 50;
+       c->pins[SCF_EDA_NPN_E]->y = c->y + 10;
 
        ui_log_t* log = calloc(1, sizeof(ui_log_t));
        if (!log)
@@ -431,10 +475,17 @@ static int button_add_line(ScfEline* el, ScfLine** pl, int x0, int y0, int x1, i
        if (!l)
                return -ENOMEM;
 
-       l->x0 = x0;
-       l->y0 = y0;
-       l->x1 = x1;
-       l->y1 = y1;
+       if (x0 < x1) {
+               l->x0 = x0;
+               l->y0 = y0;
+               l->x1 = x1;
+               l->y1 = y1;
+       } else {
+               l->x0 = x1;
+               l->y0 = y1;
+               l->x1 = x0;
+               l->y1 = y0;
+       }
 
        int ret = scf_eline__add_line(el, l);
        if (ret < 0) {
@@ -474,34 +525,37 @@ static int button_add_eline(ses_ui_t* ui, ScfEline** pel, ScfLine** pl, int x0,
        return 0;
 }
 
-static int button_connect_pin(ses_ui_t* ui, ScfEpin* p0, ScfEpin* p1)
+static int button_line_to(ses_ui_t* ui, int x0, int y0, int x1, int y1)
 {
-       ScfEline*  el = NULL;
-       ScfLine*   l  = NULL;
-       ui_log_t*  log;
+       ScfEcomponent* c;
+       ScfEpin*       p;
+       ScfEline*      el = NULL;
+       ScfLine*       l  = NULL;
+       ui_log_t*      log;
 
-       int ret;
+       long i;
+       long j;
+       int  ret;
 
-       scf_efunction_find_eline(ui->f, &el, &l, p0->x, p0->y);
+       scf_efunction_find_eline(ui->f, &el, &l, x0, y0);
        if (!el) {
-               ret = button_add_eline(ui, &el, &l, p0->x, p0->y, p1->x, p1->y);
-               if (ret < 0)
-                       return ret;
+               scf_efunction_find_eline(ui->f, &el, &l, x1, y1);
 
-               ret = scf_eline__add_pin(el, p0->cid, p0->id);
-               if (ret < 0)
-                       return ret;
-               p0->lid = el->id;
+               if (!el) {
+                       ret = button_add_eline(ui, &el, &l, x0, y0, x1, y1);
+                       if (ret < 0)
+                               return ret;
 
-               log = calloc(1, sizeof(ui_log_t));
-               if (!log)
-                       return -ENOMEM;
-               log->el   = el;
-               log->type = UI_ADD_ELINE;
+                       log = calloc(1, sizeof(ui_log_t));
+                       if (!log)
+                               return -ENOMEM;
+                       log->el   = el;
+                       log->type = UI_ADD_ELINE;
 
-               ui_add_log(ui, log);
+                       ui_add_log(ui, log);
+               }
        } else {
-               ret = button_add_line(el, &l, p0->x, p0->y, p1->x, p1->y);
+               ret = button_add_line(el, &l, x0, y0, x1, y1);
                if (ret < 0)
                        return ret;
 
@@ -510,18 +564,30 @@ static int button_connect_pin(ses_ui_t* ui, ScfEpin* p0, ScfEpin* p1)
                        return -ENOMEM;
                log->el   = el;
                log->l    = l;
-               log->p    = p1;
                log->type = UI_ADD_LINE;
 
                ui_add_log(ui, log);
        }
 
-       ret = scf_eline__add_pin(el, p1->cid, p1->id);
-       if (ret < 0)
-               return ret;
-       p1->lid = el->id;
+       for (i = 0; i < ui->f->n_components; i++) {
+               c  =        ui->f->components[i];
+
+               for (j = 0; j < c->n_pins; j++) {
+                       p  =        c->pins[j];
+
+                       if (scf_epin_in_line(p->x, p->y, x0, y0, x1, y1)) {
+
+                               ret = scf_eline__add_pin(el, p->cid, p->id);
+                               if (ret < 0)
+                                       return ret;
+
+                               p->lid = el->id;
+
+                               scf_logi("\033[32m el%ld add c%ldp%ld\033[0m\n", el->id, p->cid, p->id);
+                       }
+               }
+       }
 
-       scf_logi("\033[32m el%ld add c%ldp%ld, c%ldp%ld\033[0m\n", el->id, p0->cid, p0->id, p1->cid, p1->id);
        return 0;
 }
 
@@ -585,7 +651,23 @@ static int button_connect_pins(ses_ui_t* ui)
 
                } else {
                        scf_efunction_find_eline(ui->f, &el, &l, x, y);
-                       if (!el) {
+                       if (el) {
+                               int ret = scf_eline__add_pin(el, p->cid, p->id);
+                               if (ret < 0)
+                                       return ret;
+
+                               p->lid = el->id;
+
+                               scf_logi("\033[32m el%ld add c%ldp%ld\033[0m\n", el->id, p->cid, p->id);
+                               log = calloc(1, sizeof(ui_log_t));
+                               if (!log)
+                                       return -ENOMEM;
+                               log->el   = el;
+                               log->p    = p;
+                               log->type = UI_ADD_PIN;
+
+                               ui_add_log(ui, log);
+                       } else {
                                int dx = ui->cx - ui->c->x;
                                int dy = ui->cy - ui->c->y;
 
@@ -594,7 +676,7 @@ static int button_connect_pins(ses_ui_t* ui)
 
                                scf_efunction_find_eline(ui->f, &el, &l, x, y);
                                if (el) {
-                                       if (4 == el->n_pins) {
+                                       if (4 >= el->n_pins) {
                                                scf_efunction__del_eline(ui->f, el);
                                                ui_del_eline(ui, el);
 
@@ -773,8 +855,6 @@ void button_set_data(ses_ui_t* ui)
 static gboolean button_press_event(GtkWidget* self, GdkEventButton* event, gpointer user_data)
 {
        ses_ui_t* ui = user_data;
-       ScfEline* el = NULL;
-       ScfLine*  l  = NULL;
 
        if (gtk_widget_get_window(GTK_WIDGET(ui->gl_area)) == event->window) {
                ui->status = SES_UI_EDIT;
@@ -782,16 +862,15 @@ static gboolean button_press_event(GtkWidget* self, GdkEventButton* event, gpoin
                scf_logi("x: %f, y: %f\n", event->x, event->y);
 
                if (ui->f) {
-                       ui->c  = NULL;
-                       ui->p  = NULL;
+                       ui->c = NULL;
+                       ui->p = NULL;
 
-                       scf_efunction_find_pin  (ui->f, &ui->c,  &ui->p, event->x, event->y);
-                       scf_efunction_find_eline(ui->f, &el,     &l,     event->x, event->y);
+                       scf_efunction_find_pin(ui->f, &ui->c, &ui->p, event->x, event->y);
 
                        int64_t us = gettime();
 
                        if (ui->c && !ui->p) {
-                               if (us - ui->press_us < 100 * 1000) {
+                               if (us - ui->press_us < 10 * 1000) {
                                        scf_logw("us - ui->press_us: %ld\n", us - ui->press_us);
 
                                        button_set_data(ui);
@@ -810,9 +889,6 @@ static gboolean button_press_event(GtkWidget* self, GdkEventButton* event, gpoin
                                if (ui->p)
                                        fprintf(stderr, "p%ld", ui->p->id);
                        }
-
-                       if (el)
-                               fprintf(stderr, ", el%ld", el->id);
                }
                fprintf(stderr, "\n");
        }
@@ -830,61 +906,46 @@ static gboolean button_release_event(GtkWidget* self, GdkEventButton* event, gpo
 
                scf_logw("x: %f, y: %f\n", event->x, event->y);
 
-               if (ui->c) {
-                       if (!ui->p) {
-                               int dx = ui->c->x - ui->cx;
-                               int dy = ui->c->y - ui->cy;
-
-                               if (dx * dx + dy * dy > 25) {
-                                       log = calloc(1, sizeof(ui_log_t));
-                                       if (!log) {
-                                               gtk_gl_area_queue_render(ui->gl_area);
-                                               return TRUE;
-                                       }
-
-                                       log->c     = ui->c;
-                                       log->old_x = ui->cx;
-                                       log->old_y = ui->cy;
-                                       log->new_x = ui->c->x;
-                                       log->new_y = ui->c->y;
-                                       log->type  = UI_MOV_COMPONENT;
-
-                                       ui_add_log(ui, log);
-                               }
-
-                               button_connect_pins(ui);
+               if (ui->c && !ui->p) {
+                       int dx = ui->c->x - ui->cx;
+                       int dy = ui->c->y - ui->cy;
 
-                               if (!scf_list_empty(&ui->log)) {
-                                       log = scf_list_data(scf_list_tail(&ui->log), ui_log_t, list);
-                                       log->ok_flag = 1;
+                       if (dx * dx + dy * dy > 25) {
+                               log = calloc(1, sizeof(ui_log_t));
+                               if (!log) {
+                                       gtk_gl_area_queue_render(ui->gl_area);
+                                       return TRUE;
                                }
-                       } else {
-                               ScfEpin* p = ui->p;
-
-                               ui->c = NULL;
-                               ui->p = NULL;
 
-                               scf_efunction_find_pin(ui->f, &ui->c, &ui->p, event->x, event->y);
-                               if (ui->p) {
-                                       button_connect_pin(ui, p, ui->p);
+                               log->c     = ui->c;
+                               log->old_x = ui->cx;
+                               log->old_y = ui->cy;
+                               log->new_x = ui->c->x;
+                               log->new_y = ui->c->y;
+                               log->type  = UI_MOV_COMPONENT;
 
-                                       if (!scf_list_empty(&ui->log)) {
-                                               log = scf_list_data(scf_list_tail(&ui->log), ui_log_t, list);
-                                               log->ok_flag = 1;
-                                       }
-                               }
+                               ui_add_log(ui, log);
                        }
 
-                       ui->c  = NULL;
-                       ui->p  = NULL;
-                       ui->cx = 0;
-                       ui->cy = 0;
+                       button_connect_pins(ui);
+               } else {
+                       button_line_to(ui, ui->press_x, ui->press_y, event->x, event->y);
+               }
 
-                       ui->press_x = 0;
-                       ui->press_y = 0;
-                       ui->move_x  = 0;
-                       ui->move_y  = 0;
+               if (!scf_list_empty(&ui->log)) {
+                       log = scf_list_data(scf_list_tail(&ui->log), ui_log_t, list);
+                       log->ok_flag = 1;
                }
+
+               ui->c  = NULL;
+               ui->p  = NULL;
+               ui->cx = 0;
+               ui->cy = 0;
+
+               ui->press_x = 0;
+               ui->press_y = 0;
+               ui->move_x  = 0;
+               ui->move_y  = 0;
        }
 
        return TRUE;
@@ -924,6 +985,11 @@ static gboolean button_move_event(GtkWidget* self, GdkEventMotion* event, gpoint
                        ui->move_y = event->y;
                }
 
+               gtk_gl_area_queue_render(ui->gl_area);
+       } else {
+               ui->move_x = event->x;
+               ui->move_y = event->y;
+
                gtk_gl_area_queue_render(ui->gl_area);
        }
 
@@ -976,6 +1042,9 @@ static void apply_clicked(GtkButton* self, gpointer user_data)
        printf("./ses ./tmp.cpk -l 0 -t %fns -c %d\n", ns, count);
        fflush(stdout);
 
+       gtk_widget_set_sensitive(ui->back,    FALSE);
+       gtk_widget_set_sensitive(ui->forward, FALSE);
+
        ui->apply_index = -1;
        ui->show_index  = -1;
 
@@ -1117,17 +1186,16 @@ static void undo_clicked(GtkButton* self, gpointer user_data)
                        case UI_ADD_LINE:
                                scf_eline__del_line(log->el, log->l);
                                log->l->el  = NULL;
-
-                               if (log->p)
-                                       log->p->lid = -1;
                                break;
 
                        case UI_DEL_LINE:
                                scf_eline__add_line(log->el, log->l);
                                log->l->el = log->el;
+                               break;
 
-                               if (log->p)
-                                       log->p->lid = log->el->id;
+                       case UI_ADD_PIN:
+                               scf_eline__del_pin(log->el, log->p->cid, log->p->id);
+                               log->p->lid = -1;
                                break;
                        default:
                                break;
@@ -1199,6 +1267,11 @@ static void redo_clicked(GtkButton* self, gpointer user_data)
                                if (log->p)
                                        log->p->lid = -1;
                                break;
+
+                       case UI_ADD_PIN:
+                               scf_eline__add_pin(log->el, log->p->cid, log->p->id);
+                               log->p->lid = log->el->id;
+                               break;
                        default:
                                break;
                };
@@ -1262,9 +1335,15 @@ static gboolean timer_handler(gpointer user_data)
                return TRUE;
        }
 
-       if (!strncmp(buf, "ok: ", 3))
+       if (!strncmp(buf, "ok: ", 3)) {
                ui->apply_index = atol(buf + 4);
 
+       } else if (!strncmp(buf, "error:", 6)) {
+               GtkTextBuffer* log = gtk_text_view_get_buffer(ui->text_log);
+
+               gtk_text_buffer_set_text(log, buf, -1);
+       }
+
        if (ui->show_index < 0 && ui->apply_index > 0) {
                ui->show_index = 0;
                load_png(ui);
@@ -1328,6 +1407,7 @@ int main(int argc, char* argv[])
        GtkBuilder* builder;
        GObject*    window;
        GObject*    gl_area;
+       GObject*    text_log;
        GError*     error = NULL;
 
        gtk_init(&argc, &argv);
@@ -1340,12 +1420,15 @@ int main(int argc, char* argv[])
                return 1;
        }
 
-       window  = gtk_builder_get_object(builder, "main_window");
-       gl_area = gtk_builder_get_object(builder, "gl_area");
+       window   = gtk_builder_get_object(builder, "main_window");
+       gl_area  = gtk_builder_get_object(builder, "gl_area");
+       text_log = gtk_builder_get_object(builder, "text_log");
 
        ui.builder     = builder;
        ui.window      = GTK_WINDOW(window);
        ui.gl_area     = GTK_GL_AREA(gl_area);
+       ui.text_log    = GTK_TEXT_VIEW(text_log);
+
        ui.entry_ns    = GTK_ENTRY(gtk_builder_get_object(builder, "entry_ns"));
        ui.entry_count = GTK_ENTRY(gtk_builder_get_object(builder, "entry_count"));
 
index 03c0e901df2bdbeb024712879150a18c3fc416cc..827d449d24af59d3ac294467059a440267f33524 100644 (file)
--- a/ses_ui.h
+++ b/ses_ui.h
@@ -39,6 +39,8 @@ struct ui_log_s
 #define UI_DEL_ELINE      4
 #define UI_ADD_LINE       5
 #define UI_DEL_LINE       6
+#define UI_ADD_PIN        7
+#define UI_DEL_PIN        8
        int               type;
        uint32_t          ok_flag;
 };
@@ -51,6 +53,7 @@ struct ses_ui_s
        GtkBuilder*       builder;
        GtkWindow*        window;
        GtkGLArea*        gl_area;
+       GtkTextView*      text_log;
 
        GtkWidget*        undo;
        GtkWidget*        redo;
@@ -95,7 +98,7 @@ struct ses_ui_s
 };
 
 #define SES_UI_INIT(ui) {SCF_LIST_INIT(ui.log), &ui.log, \
-       NULL,NULL,NULL, \
+       NULL,NULL,NULL,NULL, \
        NULL,NULL,NULL,NULL, \
        NULL,NULL, \
        NULL,NULL, \