diff --git a/src/newifc/GNUmakefile b/src/newifc/GNUmakefile index ddfdf6cd942fb836b2677c8919c48c92f8431016..d32f8aea9d5fa7c2d96c7a9c32a83a360b473697 100644 --- a/src/newifc/GNUmakefile +++ b/src/newifc/GNUmakefile @@ -25,7 +25,7 @@ newifc.c: genapi newifc.h: newifc.c -newifc.o: newifc.c root_window.c label.c sizer.c sizer_cell.c +newifc.o: newifc.c root_window.c label.c sizer.c sizer_cell.c newifc_nongen.c newifc_nongen_after.c libnewifc.a: libnewifc.a(newifc.o) ranlib $@ diff --git a/src/newifc/genapi.c b/src/newifc/genapi.c index 4b83cdc8cd64638a8f836daae828940f68112781..576e7887c88af122e571cb75283acf5bf88679f9 100644 --- a/src/newifc/genapi.c +++ b/src/newifc/genapi.c @@ -481,12 +481,12 @@ main(int argc, char **argv) fputs("struct NewIfc_render_context {\n" " struct vmem_cell *vmem;\n" + " int32_t xpos;\n" + " int32_t ypos;\n" " uint16_t dwidth;\n" " uint16_t dheight;\n" " uint16_t width;\n" " uint16_t height;\n" - " uint16_t xpos;\n" - " uint16_t ypos;\n" "};\n\n", internal_header); fputs("struct lo_size {\n" diff --git a/src/newifc/label.c b/src/newifc/label.c index 92408cd08e9b56e15e309c4533ab65e952607ca8..6157a8d6360f3bcc50c8ee00ffb07d899af99892 100644 --- a/src/newifc/label.c +++ b/src/newifc/label.c @@ -94,9 +94,9 @@ label_do_render(NewIfcObj obj, struct NewIfc_render_context *ctx) size_t c = (ctx->ypos + y) * ctx->dwidth + ctx->xpos; for (size_t x = 0; x < ctx->width; x++, c++) { if (y == ypos && x >= xpos && x < xpos + tsz) - set_vmem_cell(&ctx->vmem[c], l->api.fg_colour, l->api.bg_colour, l->text[x - xpos], l->api.font); + set_vmem_cell(ctx, x, y, l->api.fg_colour, l->api.bg_colour, l->text[x - xpos], l->api.font); else - set_vmem_cell(&ctx->vmem[c], l->api.fg_colour, l->api.bg_colour, ' ', l->api.font); + set_vmem_cell(ctx, x, y, l->api.fg_colour, l->api.bg_colour, ' ', l->api.font); } } return NewIfc_error_none; diff --git a/src/newifc/newifc_nongen.c b/src/newifc/newifc_nongen.c index b80861ec16a38eda59901c67e7aa5b86aca039ac..e921b34b50e62222b6c09deb2a452a8be416a7fd 100644 --- a/src/newifc/newifc_nongen.c +++ b/src/newifc/newifc_nongen.c @@ -1,3 +1,4 @@ +#include <assert.h> #include <stdlib.h> #include "newifc.h" @@ -423,9 +424,22 @@ NI_setup_globals(NewIfcObj obj, NewIfcObj parent) return NewIfc_error_none; } +#include <stdio.h> static void -set_vmem_cell(struct vmem_cell *cell, uint32_t fg, uint32_t bg, uint8_t ch, uint8_t font) +set_vmem_cell(struct NewIfc_render_context *ctx, uint16_t x, uint16_t y, uint32_t fg, uint32_t bg, uint8_t ch, uint8_t font) { + int py = ctx->ypos + y; + int px = ctx->xpos + x; + struct vmem_cell *cell; + +assert(ctx->width < 100); +assert(x < 100); +fprintf(stderr, "Printing at %hux%hu (%hu + %hu of %hu) in %hux%hu\n", px, py, ctx->xpos, x, ctx->width, ctx->dwidth, ctx->dheight); + if (px < 0 || x >= ctx->width) + return; + if (py < 0 || y >= ctx->height) + return; + cell = &ctx->vmem[py * ctx->dwidth + px]; if (bg != NI_TRANSPARENT) cell->bg = bg; if (fg != NI_TRANSPARENT) { diff --git a/src/newifc/newifc_nongen_after.c b/src/newifc/newifc_nongen_after.c new file mode 100644 index 0000000000000000000000000000000000000000..eb6d839ceca044cdd515e8676f17c6c4827370c2 --- /dev/null +++ b/src/newifc/newifc_nongen_after.c @@ -0,0 +1,104 @@ +#ifdef BUILD_TESTS +#include "CuTest.h" +#endif + +NI_err +NI_set_focus(NewIfcObj obj, bool value) { + NI_err ret; + if (obj == NULL) + return NewIfc_error_invalid_arg; + if (NI_set_locked(obj, true) == NewIfc_error_none) { + NewIfcObj remove_focus; + ret = call_bool_change_handlers(obj, NewIfc_focus, value); + if (ret != NewIfc_error_none) { + NI_set_locked(obj, false); + return ret; + } + if (value == false) { + if (obj->root == obj) { + NI_set_locked(obj, false); + return NewIfc_error_invalid_arg; + } + remove_focus = obj->parent; + } + else { + // If we already have focus, remove focus from all children... + if (obj->focus) { + remove_focus = obj; + } + // Otherwise, walk up the tree setting focus until we get to an item that does. + // When we get there, remove focus from its children + else { + for (remove_focus = obj; remove_focus->focus == false && remove_focus->root != remove_focus; remove_focus = remove_focus->parent) + ; + } + ret = obj->set(obj, NewIfc_focus, value); + } + NI_walk_children(remove_focus, true, remove_focus_cb, NULL); + if (ret == NewIfc_error_not_implemented) { + obj->focus = value; + ret = NewIfc_error_none; + } + NI_set_locked(obj, false); + } + else + ret = NewIfc_error_lock_failed; + return ret; +} + +#ifdef BUILD_TESTS + +#include <stdio.h> +void test_api(CuTest *ct) +{ + char *s; + NewIfcObj obj = NULL; + NewIfcObj robj = NULL; + static const char *new_title = "New Title"; + struct vmem_cell cells; + uint32_t u32; + int32_t i32; + uint16_t u16; + uint8_t u8; + enum NewIfc_alignment a; + + CuAssertTrue(ct, NI_create(NewIfc_root_window, NULL, &robj) == NewIfc_error_none); + CuAssertTrue(ct, NI_set_fill_character_color(robj, NI_CYAN) == NewIfc_error_none); + CuAssertTrue(ct, NI_get_fill_character_color(robj, &u32) == NewIfc_error_none && u32 == NI_CYAN); + CuAssertTrue(ct, NI_set_fill_colour(robj, NI_BLUE) == NewIfc_error_none); + CuAssertTrue(ct, NI_get_fill_colour(robj, &u32) == NewIfc_error_none && u32 == NI_BLUE); + CuAssertTrue(ct, NI_set_fill_character(robj, 0xb0) == NewIfc_error_none); + CuAssertTrue(ct, NI_get_fill_character(robj, &u8) == NewIfc_error_none && u8 == 0xb0); + + CuAssertTrue(ct, NI_create(NewIfc_label, robj, &obj) == NewIfc_error_none); + CuAssertTrue(ct, NI_set_bg_colour(obj, NI_CYAN) == NewIfc_error_none); + CuAssertTrue(ct, NI_get_bg_colour(obj, &u32) == NewIfc_error_none && u32 == NI_CYAN); + CuAssertTrue(ct, NI_set_fg_colour(obj, NI_WHITE) == NewIfc_error_none); + CuAssertTrue(ct, NI_get_fg_colour(obj, &u32) == NewIfc_error_none && u32 == NI_WHITE); + CuAssertTrue(ct, NI_set_text(obj, new_title) == NewIfc_error_none); + CuAssertTrue(ct, NI_get_text(obj, &s) == NewIfc_error_none && strcmp(s, new_title) == 0); + CuAssertTrue(ct, NI_set_left_pad(obj, 1) == NewIfc_error_none); + CuAssertTrue(ct, NI_get_left_pad(obj, &u16) == NewIfc_error_none && u16 == 1); + CuAssertTrue(ct, NI_set_right_pad(obj, 1) == NewIfc_error_none); + CuAssertTrue(ct, NI_get_right_pad(obj, &u16) == NewIfc_error_none && u16 == 1); + CuAssertTrue(ct, NI_set_align(obj, NewIfc_align_centre) == NewIfc_error_none); + CuAssertTrue(ct, NI_get_align(obj, &a) == NewIfc_error_none && a == NewIfc_align_centre); + CuAssertTrue(ct, NI_set_height(obj, 1) == NewIfc_error_none); + CuAssertTrue(ct, NI_get_height(obj, &i32) == NewIfc_error_none && i32 == 1); + + CuAssertTrue(ct, robj->do_render(robj, NULL) == NewIfc_error_none); + size_t sz = strlen(new_title); +#if 0 + for (size_t i = 0; i < sz; i++) { + ciolib_vmem_gettext(i+36,1,i+36,1,&cells); + CuAssertTrue(ct, cells.ch == new_title[i]); + CuAssertTrue(ct, cells.fg == obj->fg_colour); + CuAssertTrue(ct, cells.bg == obj->bg_colour); + CuAssertTrue(ct, cells.font == obj->font); + } +#endif +sleep(2); + CuAssertTrue(ct, NI_destroy(robj) == NewIfc_error_none); +} + +#endif diff --git a/src/newifc/root_window.c b/src/newifc/root_window.c index c2f6c418e29240a8c9752498dba57ce776bc76e7..fe86e6d2136f95d4bae8df34a67a4d90e4a1d9ae 100644 --- a/src/newifc/root_window.c +++ b/src/newifc/root_window.c @@ -162,12 +162,9 @@ rw_do_render_recurse(NewIfcObj obj, struct NewIfc_render_context *ctx) // Fill background of child area if (obj->fill_colour != NI_TRANSPARENT || obj->fill_character_colour != NI_TRANSPARENT) { - size_t c; for (size_t y = 0; y < obj->child_height; y++) { - c = (y + ctx->ypos + obj->child_ypos) * ctx->dwidth; for (size_t x = 0; x < obj->child_width; x++) { - set_vmem_cell(&ctx->vmem[c], obj->fill_character_colour, obj->fill_colour, obj->fill_character, obj->fill_font); - c++; + set_vmem_cell(ctx, x + obj->child_xpos, y + obj->child_ypos, obj->fill_character_colour, obj->fill_colour, obj->fill_character, obj->fill_font); } } } @@ -176,27 +173,20 @@ rw_do_render_recurse(NewIfcObj obj, struct NewIfc_render_context *ctx) size_t c; for (size_t y = 0; y < obj->layout_size.height; y++) { if ((y < obj->top_pad) || (y >= (obj->layout_size.height - obj->bottom_pad))) { - c = (y + ctx->ypos + obj->ypos) * ctx->dwidth; for (size_t x = 0; x < obj->layout_size.width; x++) { - set_vmem_cell(&ctx->vmem[c], obj->fg_colour, obj->bg_colour, ' ', obj->font); + set_vmem_cell(ctx, x, y, obj->fg_colour, obj->bg_colour, ' ', obj->font); c++; } } else { if (obj->left_pad) { - c = (y + ctx->ypos + obj->ypos) * ctx->dwidth; for (size_t x = 0; x < obj->left_pad; x++) { - set_vmem_cell(&ctx->vmem[c], obj->fg_colour, obj->bg_colour, ' ', obj->font); - c++; + set_vmem_cell(ctx, x, y, obj->fg_colour, obj->bg_colour, ' ', obj->font); } } if (obj->right_pad) { - c = (y + ctx->ypos + obj->ypos) * ctx->dwidth; - c += obj->layout_size.width; - c -= obj->right_pad; for (size_t x = 0; x < obj->right_pad; x++) { - set_vmem_cell(&ctx->vmem[c], obj->fg_colour, obj->bg_colour, ' ', obj->font); - c++; + set_vmem_cell(ctx, x + obj->width - obj->right_pad, y, obj->fg_colour, obj->bg_colour, ' ', obj->font); } } } diff --git a/src/newifc/sizer_cell.c b/src/newifc/sizer_cell.c new file mode 100644 index 0000000000000000000000000000000000000000..92a905b2e6cf30af7b6e1c6a592edccd6ca13597 --- /dev/null +++ b/src/newifc/sizer_cell.c @@ -0,0 +1,115 @@ +#include <assert.h> +#include <stdarg.h> +#include <stdlib.h> // malloc()/free() + +#define CIOLIB_NO_MACROS +#include "ciolib.h" +#include "genwrap.h" +#include "strwrap.h" +#include "threadwrap.h" + +#include "newifc.h" +#include "newifc_internal.h" + +#ifdef BUILD_TESTS +#include "CuTest.h" +#endif + +struct sizer_cell { + struct newifc_api api; +}; + +static NI_err +sizer_cell_set(NewIfcObj obj, int attr, ...) +{ + struct sizer_cell *s = (struct sizer_cell *)obj; + NI_err ret = NewIfc_error_none; + va_list ap; + size_t c; + size_t idx; + uint8_t olds; + uint8_t *neww; + + va_start(ap, attr); + switch (attr) { + default: + ret = NewIfc_error_not_implemented; + break; + } + va_end(ap); + + return ret; +} + +static NI_err +sizer_cell_get(NewIfcObj obj, int attr, ...) +{ + struct sizer_cell *s = (struct sizer_cell *)obj; + NI_err ret = NewIfc_error_none; + va_list ap; + size_t c; + size_t idx; + + va_start(ap, attr); + switch (attr) { + default: + ret = NewIfc_error_not_implemented; + break; + } + + return ret; +} + +static NI_err +sizer_cell_do_render(NewIfcObj obj, struct NewIfc_render_context *ctx) +{ + (void)obj; + (void)ctx; + return NewIfc_error_none; +} + +static NI_err +sizer_cell_destroy(NewIfcObj newobj) +{ + struct sizer_cell *s = (struct sizer_cell *)newobj; + + if (s == NULL) + return NewIfc_error_invalid_arg; + free(s); + return NewIfc_error_none; +} + +static NI_err +NewIFC_sizer_cell(NewIfcObj parent, NewIfcObj *newobj) +{ + struct sizer_cell *news; + + if (newobj == NULL) + return NewIfc_error_invalid_arg; + if (parent->type != NewIfc_sizer) + return NewIfc_error_invalid_arg; + *newobj = NULL; + news = calloc(1, sizeof(struct sizer_cell)); + if (news == NULL) + return NewIfc_error_allocation_failure; + NI_err ret = NI_setup_globals(&news->api, parent); + if (ret != NewIfc_error_none) { + free(news); + return ret; + } + news->api.get = &sizer_cell_get; + news->api.set = &sizer_cell_set; + news->api.do_render = &sizer_cell_do_render; + news->api.destroy = &sizer_cell_destroy; + *newobj = (NewIfcObj)news; + return NewIfc_error_none; +} + +#ifdef BUILD_TESTS + +void test_sizer_cell(CuTest *ct) +{ + // TODO: Write tests... +} + +#endif