* recognised has "wrap-" stripped and is used for the
* head and tail. Default is fg:blue,underline
* hide - Text is hidden if cursor is not within range.
- * NOT YET IMPLEMENTED
*
* "nn" is measured in "points" which is 1/10 the nominal width of chars
* in the default font size, which is called "10". A positive value is
* it.
*/
uint8_t hide; /* This and consecutive render_items
- * with the same hide nmber form a
+ * with the same hide number form a
* hidden extent which is visible when
* the cursor is in it.
*/
char *wrap_head, *wrap_tail, *wrap_attr;
int head_length, tail_length;
char *line safe;
+ char *background;
bool word_wrap;
bool image;
int curspos;
* which should leave either a trailing comma, or an
* empty string.
*/
- buf_append(&attr, ',');
old_len = attr.len;
+ buf_append(&attr, ',');
foreach_attr(a, v, st, line) {
if (amatch(a, "centre") || amatch(a, "center") ||
amatch(a, "ctab")) {
/* strip one more ',' */
if (attr.len > 0)
attr.len -= 1;
- if (attr.len <= wrap_depth)
+ if (wrap && attr.len <= wrap_depth)
wrap = 0;
- if (attr.len <= hide_depth)
+ if (hide && attr.len <= hide_depth)
hide = 0;
break;
case ack:
int splitpos, int len,
int maxwidth)
{
- struct rline_data *rd = &p->data;
+ struct rline_data *rd = p->data;
struct call_return cr;
char tb[] = " ";
char *str = rd->line + ri->start + splitpos;
char *str safe,
const char *attr)
{
- struct rline_data *rd = &p->data;
+ struct rline_data *rd = p->data;
return call_ret(all, "Draw:text-size", p,
-1, NULL, str,
int offset,
int x, int y)
{
- struct rline_data *rd = &p->data;
+ struct rline_data *rd = p->data;
char tmp;
char *str;
int len;
char *str safe,
int x, int y)
{
- struct rline_data *rd = &p->data;
+ struct rline_data *rd = p->data;
home_call(focus, "Draw:text", p,
-1, NULL, str,
* 3 if both.
* 0 if neither
*/
- struct rline_data *rd = &p->data;
+ struct rline_data *rd = p->data;
struct render_item *ri, *wraprl;
- int shift_left = pane_attr_get_int(focus, "shift_left", 0);
+ int shift_left = pane_attr_get_int(focus, "render-wrap", -1);
bool wrap = shift_left < 0;
int wrap_margin;
int right_margin;
int x, y;
int ret = 0;
bool seen_rtab = False;
+ unsigned int offset_hide = 0;
if (!rd->content)
return ret;
offset == rd->measure_offset) {
/* No change */
for (ri = rd->content ; ri ; ri = ri->next) {
+ if (ri->hidden)
+ continue;
if (ri->eol && rd->line[ri->start] == '\n')
ret |= 1;
if (ri->eol && rd->line[ri->start] == '\f')
/* 0 means right edge for right_margin, and left edge for all others */
right_margin = p->w - calc_pos(-rd->right_margin, p->w, rd->curs_width);
+ if (offset >= 0)
+ for (ri = rd->content ; ri ; ri = ri->next)
+ if (offset < ri->start + ri->len) {
+ offset_hide = ri->hide;
+ break;
+ }
+
+ rd->width = 0;
for (ri = rd->content; ri; ri = ri->next) {
+ ri->hidden = (ri->hide && ri->hide != offset_hide);
+ if (ri->hidden) {
+ ri->width = 0;
+ continue;
+ }
if (ri->len == 0 ||
(unsigned char)rd->line[ri->start] >= ' ') {
cr = do_measure(p, ri, 0, -1, -1);
if (cr.i2 > rd->ascent)
rd->ascent = cr.i2;
ri->width = ri->eol ? 0 : cr.x;
- ri->hidden = False;
+ rd->width += ri->width;
if (ri->start <= offset && offset <= ri->start + ri->len) {
cr = measure_str(p, "M", ri->attr);
*/
x = left_margin - (shift_left > 0 ? shift_left : 0);
y = rd->space_above * curs_height / 10;
- rd->width = 0;
for (ri = rd->content; ri; ri = ri->next) {
int w, margin;
struct render_item *ri2;
ri->y = y;
+ if (ri->hidden) {
+ ri->x = x;
+ continue;
+ }
if (ri->tab != TAB_UNSET)
x = left_margin + calc_pos(ri->tab,
right_margin - left_margin,
rd->curs_width);
if (ri->eol) {
/* EOL */
- if (x > rd->width)
- rd->width = x;
ri->x = x;
x = 0; /* Don't include shift. probably not margin */
if (rd->line[ri->start])
wrap_margin = left_margin + rd->head_length;
for (ri = rd->content ; wrap && ri ; ri = ri->next) {
int splitpos;
+ if (ri->hidden)
+ continue;
if (ri->wrap && (wraprl == NULL || ri->wrap != wraprl->wrap))
wraprl = ri;
if (ri->wrap_margin)
static void draw_line(struct pane *p safe, struct pane *focus safe, int offset)
{
- struct rline_data *rd = &p->data;
+ struct rline_data *rd = p->data;
struct render_item *ri;
char *wrap_tail = rd->wrap_tail ?: "\\";
char *wrap_head = rd->wrap_head ?: "";
- home_call(focus, "Draw:clear", p);
+ home_call(focus, "Draw:clear", p, 0, NULL, rd->background);
if (!rd->content)
return;
* We do not consider the eol render_item
*/
struct call_return cr;
- struct rline_data *rd = &p->data;
+ struct rline_data *rd = p->data;
struct render_item *r, *ri = NULL;
int splitpos = 0;
int start = 0;
for (r = rd->content; r ; r = r->next) {
int split;
+ if (r->hidden)
+ continue;
if (r->y <= y && r->x <= x) {
ri = r;
start = r->start;
cr = do_measure(p, ri, splitpos, -1, x - ri->x);
if ((splitpos ? ri->wrap_x : ri->x ) + cr.x > x &&
ri->y + rd->line_height * (1 + splitpos) > y &&
- xyattr)
- *xyattr = ri->attr;
+ xyattr) {
+ /* This is a bit of a hack.
+ * We stick the x,y co-ords of the start
+ * of the current attr in front of the
+ * attrs so render-lines can provide a
+ * good location for a menu
+ */
+ char buf[100];
+ struct render_item *ri2;
+ int ax = ri->x;
+ for (ri2 = rd->content; ri2 != ri; ri2 = ri2->next)
+ if (strcmp(ri2->attr, ri->attr) == 0)
+ ax = ri2->x;
+ snprintf(buf, sizeof(buf), "%dx%d,", ax, y);
+ *xyattr = strconcat(p, buf, ri->attr);
+ }
if (cr.s)
return cr.s - rd->line;
return start + cr.i;
struct xy xy = {0,0};
int split;
int st;
- struct rline_data *rd = &p->data;
+ struct rline_data *rd = p->data;
struct render_item *r, *ri = NULL;
for (r = rd->content; r; r = r->next) {
+ if (r->hidden)
+ continue;
if (offset < r->start)
break;
ri = r;
int dodraw,
int offset, int want_xypos, short x, short y)
{
- struct rline_data *rd = &p->data;
+ struct rline_data *rd = p->data;
char *fname = NULL;
const char *orig_line = line;
short width, height;
struct xy xyscale = pane_scale(focus);
int scale = xyscale.x;
struct xy size= {-1, -1};
+ char mode[30] = "";
const char *a, *v;
const char *end;
*/
map_offset = v - orig_line;
parse_map(v, &rows, &cols);
+ if (rows > 0 && cols > 0)
+ snprintf(mode, sizeof(mode),
+ ":%dx%d", cols, rows);
}
}
pane_resize(p, (p->parent->w - width)/2, p->y, width, height);
}
if (fname && dodraw)
- home_call(focus, "Draw:image", p, 5, NULL, fname,
- 0, NULL, NULL, cols, rows);
+ home_call(focus, "Draw:image", p, 0, NULL, fname,
+ 0, NULL, mode);
free(fname);
DEF_CMD(renderline_draw)
{
- struct rline_data *rd = &ci->home->data;
+ struct rline_data *rd = ci->home->data;
struct xy xy;
int offset = -1;
DEF_CMD(renderline_refresh)
{
- struct rline_data *rd = &ci->home->data;
+ struct rline_data *rd = ci->home->data;
int offset = -1;
if (rd->curspos >= 0)
DEF_CMD(renderline_measure)
{
- struct rline_data *rd = &ci->home->data;
+ struct rline_data *rd = ci->home->data;
int ret;
if (rd->image)
DEF_CMD(renderline_findxy)
{
- struct rline_data *rd = &ci->home->data;
+ struct rline_data *rd = ci->home->data;
const char *xyattr = NULL;
int pos;
DEF_CMD(renderline_get)
{
- struct rline_data *rd = &ci->home->data;
+ struct rline_data *rd = ci->home->data;
char buf[20];
const char *val = buf;
DEF_CMD(renderline_set)
{
- struct rline_data *rd = &ci->home->data;
+ struct rline_data *rd = ci->home->data;
const char *old = rd->line;
char *prefix = pane_attr_get(ci->focus, "prefix");
bool word_wrap = pane_attr_get_int(ci->focus, "word-wrap", 0) != 0;
+ bool bg_changed = False;
if (!ci->str)
return -Enoarg;
if (prefix)
- prefix = cvt(strconcat(ci->home, "<bold>", prefix, "</>"));
-
+ prefix = strconcat(ci->home, ACK SOH "bold" STX,
+ prefix, // No mark in prefix!
+ ETX);
if (prefix)
rd->line = strconcat(NULL, prefix, ci->str);
else
rd->prefix_bytes = strlen(prefix?:"");
cvt(rd->line + rd->prefix_bytes);
+ if (ci->str2 && !rd->background) {
+ rd->background = strdup(ci->str2);
+ bg_changed = True;
+ } else if (!ci->str2 && rd->background) {
+ free(rd->background);
+ rd->background = NULL;
+ bg_changed = True;
+ } else if (ci->str2 && rd->background &&
+ strcmp(ci->str2, rd->background) != 0) {
+ free(rd->background);
+ rd->background = strdup(ci->str2);
+ bg_changed = True;
+ }
+
rd->curspos = ci->num;
- if (strcmp(rd->line, old) != 0 ||
+ if (strcmp(rd->line, old) != 0 || bg_changed ||
(old && word_wrap != rd->word_wrap)) {
pane_damaged(ci->home, DAMAGED_REFRESH);
pane_damaged(ci->home->parent, DAMAGED_REFRESH);
return 1;
}
-DEF_CMD(renderline_close)
+DEF_CMD_CLOSED(renderline_close)
{
- struct rline_data *rd = &ci->home->data;
+ struct rline_data *rd = ci->home->data;
struct render_item *ri = rd->content;
free((void*)rd->line);
aupdate(&rd->wrap_head, NULL);
aupdate(&rd->wrap_tail, NULL);
aupdate(&rd->wrap_attr, NULL);
+ aupdate(&rd->background, NULL);
return 1;
}
key_add(rl_map, "get-attr", &renderline_get);
key_add(rl_map, "render-line:set", &renderline_set);
key_add(rl_map, "Close", &renderline_close);
- key_add(rl_map, "Free", &edlib_do_free);
}
p = pane_register(ci->focus, ci->num, &renderline_handle.c);
if (!p)
return Efail;
- rd = &p->data;
+ rd = p->data;
rd->line = strdup(ETX); // Imposible string
return comm_call(ci->comm2, "cb", p);