Browse Source

Add partial support for resizing grids (WIP)

master
cancel 6 years ago
parent
commit
e0fe4647c1
  1. 20
      field.c
  2. 3
      field.h
  3. 12
      gbuffer.c
  4. 63
      tui_main.c

20
field.c

@ -17,6 +17,8 @@ void field_init_fill(Field* f, Usz height, Usz width, Glyph fill_char) {
f->width = (U16)width; f->width = (U16)width;
} }
void field_deinit(Field* f) { free(f->buffer); }
void field_resize_raw(Field* f, Usz height, Usz width) { void field_resize_raw(Field* f, Usz height, Usz width) {
assert(height <= ORCA_Y_MAX && width <= ORCA_X_MAX); assert(height <= ORCA_Y_MAX && width <= ORCA_X_MAX);
Usz cells = height * width; Usz cells = height * width;
@ -31,8 +33,6 @@ void field_resize_raw_if_necessary(Field* field, Usz height, Usz width) {
} }
} }
void field_deinit(Field* f) { free(f->buffer); }
void field_copy(Field* src, Field* dest) { void field_copy(Field* src, Field* dest) {
field_resize_raw_if_necessary(dest, src->height, src->width); field_resize_raw_if_necessary(dest, src->height, src->width);
gbuffer_copy_subrect(src->buffer, dest->buffer, src->height, src->width, gbuffer_copy_subrect(src->buffer, dest->buffer, src->height, src->width,
@ -40,6 +40,22 @@ void field_copy(Field* src, Field* dest) {
src->width); src->width);
} }
void field_resize_filled(Field* field, Usz height, Usz width, Glyph fill_char) {
assert(height <= ORCA_Y_MAX && width <= ORCA_X_MAX);
Usz old_height = field->height;
Usz old_width = field->width;
if (old_height == height && old_width == width)
return;
Usz old_cells = old_height * old_width;
Usz new_cells = height * width;
field->buffer = realloc(field->buffer, new_cells * sizeof(Glyph));
if (old_cells < new_cells) {
memset(field->buffer + old_cells, fill_char, (new_cells - old_cells) * sizeof(Glyph));
}
field->height = (U16)height;
field->width = (U16)width;
}
static inline bool glyph_char_is_valid(char c) { return c >= '!' && c <= '~'; } static inline bool glyph_char_is_valid(char c) { return c >= '!' && c <= '~'; }
void field_fput(Field* f, FILE* stream) { void field_fput(Field* f, FILE* stream) {

3
field.h

@ -3,9 +3,10 @@
void field_init(Field* field); void field_init(Field* field);
void field_init_fill(Field* field, Usz height, Usz width, Glyph fill_char); void field_init_fill(Field* field, Usz height, Usz width, Glyph fill_char);
void field_deinit(Field* field);
void field_resize_raw(Field* field, Usz height, Usz width); void field_resize_raw(Field* field, Usz height, Usz width);
void field_resize_raw_if_necessary(Field* field, Usz height, Usz width); void field_resize_raw_if_necessary(Field* field, Usz height, Usz width);
void field_deinit(Field* field); void field_resize_filled(Field* field, Usz height, Usz width, Glyph fill_char);
void field_copy(Field* src, Field* dest); void field_copy(Field* src, Field* dest);
void field_fput(Field* field, FILE* stream); void field_fput(Field* field, FILE* stream);

12
gbuffer.c

@ -26,16 +26,16 @@ void gbuffer_copy_subrect(Glyph* src, Glyph* dest, Usz src_height,
Usz copy_bytes = row_copy * sizeof(Glyph); Usz copy_bytes = row_copy * sizeof(Glyph);
Glyph* src_p = src + src_y * src_width + src_x; Glyph* src_p = src + src_y * src_width + src_x;
Glyph* dest_p = dest + dest_y * dest_width + dest_x; Glyph* dest_p = dest + dest_y * dest_width + dest_x;
Usz src_stride; Isz src_stride;
Usz dest_stride; Isz dest_stride;
if (src_y >= dest_y) { if (src_y >= dest_y) {
src_stride = src_width; src_stride = (Isz)src_width;
dest_stride = dest_width; dest_stride = (Isz)dest_width;
} else { } else {
src_p += (ny - 1) * src_width; src_p += (ny - 1) * src_width;
dest_p += (ny - 1) * dest_width; dest_p += (ny - 1) * dest_width;
src_stride = -src_width; src_stride = -(Isz)src_width;
dest_stride = -dest_width; dest_stride = -(Isz)dest_width;
} }
Usz iy = 0; Usz iy = 0;
for (;;) { for (;;) {

63
tui_main.c

@ -296,13 +296,21 @@ void draw_field(WINDOW* win, int term_h, int term_w, int pos_y, int pos_x,
(void)term_w; (void)term_w;
if (field_w > Bufcount) if (field_w > Bufcount)
return; return;
if (pos_y >= term_h || pos_x >= term_w)
return;
Usz num_y = (Usz)term_h - (Usz)pos_y;
Usz num_x = (Usz)term_w - (Usz)pos_x;
if (field_h < num_y)
num_y = field_h;
if (field_w < num_x)
num_x = field_w;
chtype buffer[Bufcount]; chtype buffer[Bufcount];
bool use_rulers = ruler_spacing_y != 0 && ruler_spacing_x != 0; bool use_rulers = ruler_spacing_y != 0 && ruler_spacing_x != 0;
for (Usz y = 0; y < field_h; ++y) { for (Usz y = 0; y < num_y; ++y) {
Glyph const* gline = gbuffer + y * field_w; Glyph const* gline = gbuffer + y * field_w;
Mark const* mline = mbuffer + y * field_w; Mark const* mline = mbuffer + y * field_w;
bool use_y_ruler = use_rulers && y % ruler_spacing_y == 0; bool use_y_ruler = use_rulers && y % ruler_spacing_y == 0;
for (Usz x = 0; x < field_w; ++x) { for (Usz x = 0; x < num_x; ++x) {
Glyph g = gline[x]; Glyph g = gline[x];
Mark m = mline[x]; Mark m = mline[x];
if (g == '.') { if (g == '.') {
@ -312,10 +320,43 @@ void draw_field(WINDOW* win, int term_h, int term_w, int pos_y, int pos_x,
buffer[x] = chtype_of_cell(g, m); buffer[x] = chtype_of_cell(g, m);
} }
wmove(win, pos_y + (int)y, pos_x); wmove(win, pos_y + (int)y, pos_x);
waddchnstr(win, buffer, (int)field_w); waddchnstr(win, buffer, (int)num_x);
// Trying to clear to eol with 0 chars remaining on line will clear whole
// line from start
if (pos_x + (int)num_x != term_w) {
wmove(win, pos_y + (int)y, pos_x + (int)num_x);
wclrtoeol(win);
}
} }
} }
void tui_cursor_confine(Tui_cursor* tc, Usz height, Usz width) {
if (height == 0 || width == 0)
return;
if (tc->y >= height)
tc->y = height - 1;
if (tc->x >= width)
tc->x = width - 1;
}
void tui_resize_grid(Field* field, Markmap_reusable* markmap,
Field* scratch_field, Isz delta_h, Isz delta_w,
Tui_cursor* tui_cursor, bool* needs_remarking) {
Isz new_height = (Isz)field->height + delta_h;
Isz new_width = (Isz)field->width + delta_w;
if (new_height < 1 || new_width < 1)
return;
field_copy(field, scratch_field);
field_resize_filled(field, (Usz)new_height, (Usz)new_width, '.');
gbuffer_copy_subrect(scratch_field->buffer, field->buffer,
scratch_field->height, scratch_field->width,
field->height, field->width, 0, 0, 0, 0,
scratch_field->height, scratch_field->width);
tui_cursor_confine(tui_cursor, (Usz)new_height, (Usz)new_width);
markmap_reusable_ensure_size(markmap, (Usz)new_height, (Usz)new_width);
*needs_remarking = true;
}
int main(int argc, char** argv) { int main(int argc, char** argv) {
static struct option tui_options[] = {{"help", no_argument, 0, 'h'}, static struct option tui_options[] = {{"help", no_argument, 0, 'h'},
{NULL, 0, NULL, 0}}; {NULL, 0, NULL, 0}};
@ -527,6 +568,22 @@ int main(int argc, char** argv) {
if (ruler_spacing_y < 16) if (ruler_spacing_y < 16)
++ruler_spacing_y; ++ruler_spacing_y;
break; break;
case '(':
tui_resize_grid(&field, &markmap_r, &scratch_field, 0, -1, &tui_cursor,
&needs_remarking);
break;
case ')':
tui_resize_grid(&field, &markmap_r, &scratch_field, 0, 1, &tui_cursor,
&needs_remarking);
break;
case '_':
tui_resize_grid(&field, &markmap_r, &scratch_field, -1, 0, &tui_cursor,
&needs_remarking);
break;
case '+':
tui_resize_grid(&field, &markmap_r, &scratch_field, 1, 0, &tui_cursor,
&needs_remarking);
break;
case ' ': case ' ':
undo_history_push(&undo_hist, &field, tick_num); undo_history_push(&undo_hist, &field, tick_num);
orca_run(field.buffer, markmap_r.buffer, field.height, field.width, orca_run(field.buffer, markmap_r.buffer, field.height, field.width,

Loading…
Cancel
Save