コード例 #1
0
ファイル: z-doc.c プロジェクト: Alkalinear/poschengband
doc_pos_t doc_find_next(doc_ptr doc, cptr text, doc_pos_t start)
{
    int y;

    for (y = start.y; y <= doc->cursor.y; y++)
    {
        int          x = (y == start.y) ? start.x : 0;
        int          ncell = doc->width - x;
        doc_char_ptr cell = doc_char(doc, doc_pos_create(x, y));
        int          i = _line_find_str(cell, ncell, text);

        if (i >= 0)
        {
            doc->selection.start.x = x + i;
            doc->selection.start.y = y;

            doc->selection.stop.x = x + i + strlen(text);
            doc->selection.stop.y = y;

            return doc->selection.start;
        }
   }

    doc->selection = doc_region_invalid();
    return doc_pos_invalid();
}
コード例 #2
0
ファイル: z-doc.c プロジェクト: Alkalinear/poschengband
doc_pos_t doc_find_prev(doc_ptr doc, cptr text, doc_pos_t start)
{
    int y;

    for (y = start.y; y >= 0; y--)
    {
        int          ncell = (y == start.y) ? start.x - 1 : doc->width;
        doc_char_ptr cell = doc_char(doc, doc_pos_create(0, y));
        int          i = _line_find_str(cell, ncell, text);

        if (i >= 0)
        {
            doc->selection.start.x = i;
            doc->selection.start.y = y;

            doc->selection.stop.x = i + strlen(text);
            doc->selection.stop.y = y;

            return doc->selection.start;
        }
   }

    doc->selection = doc_region_invalid();
    return doc_pos_invalid();
}
コード例 #3
0
ファイル: z-doc.c プロジェクト: Alkalinear/poschengband
doc_region_t doc_range_all(doc_ptr doc)
{
    doc_region_t result;
    result.start = doc_pos_create(0, 0);
    result.stop = doc->cursor;
    return result;
}
コード例 #4
0
ファイル: gray_mage.c プロジェクト: poschengband/poschengband
static void _display(rect_t r, int options)
{
    doc_ptr doc = doc_alloc(r.cx);
    _list_spells(doc, options);
    doc_sync_term(doc, doc_range_all(doc), doc_pos_create(r.x, r.y));
    doc_free(doc);
}
コード例 #5
0
void msg_line_redraw(void)
{
    doc_sync_term(
        _msg_line_doc,
        doc_range_all(_msg_line_doc),
        doc_pos_create(_msg_line_rect.x, _msg_line_rect.y)
    );
    _msg_line_sync_pos = doc_cursor(_msg_line_doc);
}
コード例 #6
0
static void msg_line_sync(void)
{
    doc_sync_term(
        _msg_line_doc,
        doc_range_bottom(_msg_line_doc, _msg_line_sync_pos),
        doc_pos_create(_msg_line_rect.x, _msg_line_rect.y + _msg_line_sync_pos.y)
    );
    _msg_line_sync_pos = doc_cursor(_msg_line_doc);
    /*  inkey(); */
}
コード例 #7
0
ファイル: gray_mage.c プロジェクト: poschengband/poschengband
static void _display_spells_to_gain(object_type *o_ptr, rect_t r)
{
    doc_ptr doc = doc_alloc(r.cx);
    int     i;
    int     realm = tval2realm(o_ptr->tval);
    int     start_idx = o_ptr->sval * _SPELLS_PER_BOOK;

    doc_insert(doc, "<style:table>");
    doc_printf(doc, "<color:G>    %-20.20s Lvl  SP Fail Desc</color>\n", "Name");

    for (i = start_idx; i < start_idx + _SPELLS_PER_BOOK; i++)
        _list_spell(doc, realm, i, i - start_idx, _FROM_BOOK);

    doc_insert(doc, "</style>");

    doc_sync_term(doc, doc_range_all(doc), doc_pos_create(r.x, r.y));
    doc_free(doc);
}
コード例 #8
0
ファイル: z-doc.c プロジェクト: Alkalinear/poschengband
doc_pos_t doc_insert_doc(doc_ptr dest_doc, doc_ptr src_doc, int indent)
{
    doc_pos_t src_pos = doc_pos_create(0, 0);
    doc_pos_t dest_pos;

    if (dest_doc->cursor.x > 0)
        doc_newline(dest_doc);

    dest_pos = dest_doc->cursor;

    while (src_pos.y <= src_doc->cursor.y)
    {
        doc_char_ptr src = doc_char(src_doc, src_pos);
        doc_char_ptr dest;
        int          count = src_doc->width;
        int          i;

        dest_pos.x += indent;
        dest = doc_char(dest_doc, dest_pos);

        if (count > dest_doc->width - dest_pos.x)
            count = dest_doc->width - dest_pos.x;
        if (src_pos.y == src_doc->cursor.y && count > src_doc->cursor.x)
            count = src_doc->cursor.x;

        for (i = 0; i < count; i++)
        {
            dest->a = src->a;
            dest->c = src->c;

            dest++;
            src++;
        }

        dest_pos.x = 0;
        dest_pos.y++;

        src_pos.x = 0;
        src_pos.y++;
    }

    dest_doc->cursor = dest_pos;
    return dest_doc->cursor;
}
コード例 #9
0
void msg_line_clear(void)
{
    int i;
    int y = doc_cursor(_msg_line_doc).y;

    for (i = 0; i <= y; i++)
    {
        int row = _msg_line_rect.y + i;
        int cx = row ? _msg_line_rect.cx : 255; /* Hack */
        Term_erase(_msg_line_rect.x, row, cx);
    }
    doc_rollback(_msg_line_doc, doc_pos_create(0, 0));
    _msg_line_sync_pos = doc_cursor(_msg_line_doc);

    if (y > 0)
    {
        /* Note: We need not redraw the entire map if this proves too slow */
        p_ptr->redraw |= PR_MAP;
        if (_msg_line_rect.x <= 12)
            p_ptr->redraw |= PR_BASIC | PR_EQUIPPY;
    }
}
コード例 #10
0
ファイル: z-doc.c プロジェクト: Alkalinear/poschengband
static void _doc_process_tag(doc_ptr doc, doc_tag_ptr tag)
{
    if ( tag->type == DOC_TAG_CLOSE_COLOR
      || tag->type == DOC_TAG_CLOSE_STYLE
      || tag->type == DOC_TAG_CLOSE_INDENT )
    {
        doc_pop_style(doc);
    }
    else if (tag->type == DOC_TAG_COLOR)
    {
        assert(tag->arg);
        if (tag->arg_size == 1)
        {
            if (tag->arg[0] == '*')
                doc_pop_style(doc);
            else
            {
                doc_style_t style = *doc_current_style(doc); /* copy */
                switch (tag->arg[0])
                {
                case 'd': style.color = TERM_DARK; break;
                case 'w': style.color = TERM_WHITE; break;
                case 's': style.color = TERM_SLATE; break;
                case 'o': style.color = TERM_ORANGE; break;
                case 'r': style.color = TERM_RED; break;
                case 'g': style.color = TERM_GREEN; break;
                case 'b': style.color = TERM_BLUE; break;
                case 'u': style.color = TERM_UMBER; break;
                case 'D': style.color = TERM_L_DARK; break;
                case 'W': style.color = TERM_L_WHITE; break;
                case 'v': style.color = TERM_VIOLET; break;
                case 'y': style.color = TERM_YELLOW; break;
                case 'R': style.color = TERM_L_RED; break;
                case 'G': style.color = TERM_L_GREEN; break;
                case 'B': style.color = TERM_L_BLUE; break;
                case 'U': style.color = TERM_L_UMBER; break;
                }
                doc_push_style(doc, &style);
            }
        }
        else
        {
            string_ptr  arg = string_copy_sn(tag->arg, tag->arg_size);
            doc_style_t style = *doc_current_style(doc); /* copy */
            doc_style_f f = _get_doc_style_f(doc, string_buffer(arg));

            if (f)
                f(&style);

            {/* We don't copy the named style, just its color. */
             /* Also, we damn well better push a style or we'll be upset
                when the good little user pops! */
                doc_style_t copy = *doc_current_style(doc);
                copy.color = style.color;
                doc_push_style(doc, &copy);
            }
            string_free(arg);
        }
    }
    else if (tag->type == DOC_TAG_INDENT)
    {
        doc_style_t style = *doc_current_style(doc);
        style.left = doc->cursor.x;
        doc_push_style(doc, &style);
    }
    else
    {
        string_ptr arg = string_copy_sn(tag->arg, tag->arg_size);

        switch (tag->type)
        {
        case DOC_TAG_STYLE:
            if (tag->arg_size == 1 && tag->arg[0] == '*')
                doc_pop_style(doc);
            else
            {/* Better silently add one if name doesn't exist ... */
                doc_style_t copy = *doc_current_style(doc);
                doc_style_f f = _get_doc_style_f(doc, string_buffer(arg));

                if (f)
                    f(&copy);
                doc_push_style(doc, &copy);
            }
            break;
        case DOC_TAG_VAR:
            _doc_process_var(doc, string_buffer(arg));
            break;
        case DOC_TAG_TAB:
        {
            int pos = atoi(string_buffer(arg)) + doc_current_style(doc)->left;
            if (pos > doc->cursor.x)
                doc_insert_space(doc, pos - doc->cursor.x);
            else
                doc_rollback(doc, doc_pos_create(pos, doc->cursor.y));
            break;
        }
        case DOC_TAG_TOPIC:
        {
            doc_bookmark_ptr mark = malloc(sizeof(doc_bookmark_t));
            mark->name = arg; /* steal ownership */
            arg = NULL;
            mark->pos = doc->cursor;
            vec_add(doc->bookmarks, mark);
            break;
        }
        case DOC_TAG_LINK:
        {
            doc_link_ptr link = malloc(sizeof(doc_link_t));
            int          split = string_chr(arg, 0, '#');
            int          ch = 'a' + int_map_count(doc->links);

            if (split >= 0)
            {
                substring_t left = string_left(arg, split);
                substring_t right = string_right(arg, string_length(arg) - split - 1);

                link->file = substring_copy(&left);
                link->topic = substring_copy(&right);
            }
            else
            {
                link->file = arg; /* steal ownership */
                arg = NULL;
                link->topic = NULL;
            }
            link->location.start = doc->cursor;
            int_map_add(doc->links, ch, link);
            {
                /* TODO: This is flawed. Here's a real world example:
                   "(see below <link:birth.txt#PrimaryStats>)."
                   Can you see the problem? We might line break after "[a]" right
                   before ").". Instead, "[a])." should be treated as the current
                   word. To fix this, we'll need a parser with a token queue
                   that we can push onto, but this raises storage issues.
                */
                string_ptr s = string_alloc_format("<style:link>[%c]</style>", ch);
                doc_insert(doc, string_buffer(s));
                string_free(s);

                link->location.stop = doc->cursor;
            }
            break;
        }
        }

        string_free(arg);
    }
}
コード例 #11
0
ファイル: z-doc.c プロジェクト: Alkalinear/poschengband
doc_pos_t doc_pos_invalid(void)
{
    return doc_pos_create(-1, -1);
}
コード例 #12
0
ファイル: z-doc.c プロジェクト: Alkalinear/poschengband
int doc_display_aux(doc_ptr doc, cptr caption, int top, rect_t display)
{
    int     rc = _OK;
    int     i;
    char    finder_str[81];
    char    back_str[81];
    int     page_size;
    bool    done = FALSE;

    strcpy(finder_str, "");

    page_size = display.cy - 4;

    if (top < 0)
        top = 0;
    if (top > doc->cursor.y - page_size)
        top = MAX(0, doc->cursor.y - page_size);

    for (i = 0; i < display.cy; i++)
        Term_erase(display.x, display.y + i, display.cx);

    while (!done)
    {
        int cmd;

        Term_erase(display.x, display.y, display.cx);
        put_str(format("[%s, Line %d/%d]", caption, top, doc->cursor.y), display.y, display.x);
        doc_sync_term(doc, doc_region_create(0, top, doc->width, top + page_size - 1), doc_pos_create(display.x, display.y + 2));
        Term_erase(display.x, display.y + display.cy - 1, display.cx);
        put_str("[Press ESC to exit. Press ? for help]", display.y + display.cy - 1, display.x);

        cmd = inkey_special(TRUE);

        if ('a' <= cmd && cmd <= 'z')
        {
            doc_link_ptr link = int_map_find(doc->links, cmd);
            if (link)
            {
                rc = doc_display_help_aux(string_buffer(link->file), string_buffer(link->topic), display);
                if (rc == _UNWIND)
                    done = TRUE;
                continue;
            }
        }

        switch (cmd)
        {
        case '?':
            if (!strstr(caption, "helpinfo.txt"))
            {
                rc = doc_display_help_aux("helpinfo.txt", NULL, display);
                if (rc == _UNWIND)
                    done = TRUE;
            }
            break;
        case ESCAPE:
            done = TRUE;
            break;
        case 'q':
            done = TRUE;
            rc = _UNWIND;
            break;
        case SKEY_TOP:
        case '7':
            top = 0;
            break;
        case SKEY_BOTTOM:
        case '1':
            top = MAX(0, doc->cursor.y - page_size);
            break;
        case SKEY_PGUP:
        case '9':
            top -= page_size;
            if (top < 0) top = 0;
            break;
        case SKEY_PGDOWN:
        case '3':
            top += page_size;
            if (top > doc->cursor.y - page_size)
                top = MAX(0, doc->cursor.y - page_size);
            break;
        case SKEY_UP:
        case '8':
            top--;
            if (top < 0) top = 0;
            break;
        case SKEY_DOWN:
        case '2':
            top++;
            if (top > doc->cursor.y - page_size)
                top = MAX(0, doc->cursor.y - page_size);
            break;
        case '>':
        {
            doc_pos_t pos = doc_next_bookmark(doc, doc_pos_create(doc->width - 1, top));
            if (doc_pos_is_valid(pos))
            {
                top = pos.y;
                if (top > doc->cursor.y - page_size)
                    top = MAX(0, doc->cursor.y - page_size);
            }
            break;
        }
        case '<':
        {
            doc_pos_t pos = doc_prev_bookmark(doc, doc_pos_create(0, top));
            if (doc_pos_is_valid(pos))
                top = pos.y;
            else
                top = 0;
            break;
        }
        case '|':
        {
            FILE *fp2;
            char buf[1024];
            char name[82];
            int  cb;
            int  format = DOC_FORMAT_TEXT;

            strcpy(name, string_buffer(doc->name));

            if (!get_string("File name: ", name, 80)) break;
            path_build(buf, sizeof(buf), ANGBAND_DIR_USER, name);
            fp2 = my_fopen(buf, "w");
            if (!fp2)
            {
                msg_format("Failed to open file: %s", buf);
                break;
            }

            cb = strlen(buf);
            if (cb > 5 && strcmp(buf + cb - 5, ".html") == 0)
                format = DOC_FORMAT_HTML;
            else if (cb > 4 && strcmp(buf + cb - 4, ".htm") == 0)
                format = DOC_FORMAT_HTML;

            doc_write_file(doc, fp2, format);
            my_fclose(fp2);
            msg_format("Created file: %s", buf);
            msg_print(NULL);
            break;
        }
        case '/':
            Term_erase(display.x, display.y + display.cy - 1, display.cx);
            put_str("Find: ", display.y + display.cy - 1, display.x);
            strcpy(back_str, finder_str);
            if (askfor(finder_str, 80))
            {
                if (finder_str[0])
                {
                    doc_pos_t pos = doc->selection.stop;
                    if (!doc_pos_is_valid(pos))
                        pos = doc_pos_create(0, top);
                    pos = doc_find_next(doc, finder_str, pos);
                    if (doc_pos_is_valid(pos))
                    {
                        top = pos.y;
                        if (top > doc->cursor.y - page_size)
                            top = MAX(0, doc->cursor.y - page_size);
                    }
                }
            }
            else strcpy(finder_str, back_str);
            break;
        case '\\':
            Term_erase(display.x, display.y + display.cy - 1, display.cx);
            put_str("Find: ", display.y + display.cy - 1, display.x);
            strcpy(back_str, finder_str);
            if (askfor(finder_str, 80))
            {
                if (finder_str[0])
                {
                    doc_pos_t pos = doc->selection.start;
                    if (!doc_pos_is_valid(pos))
                        pos = doc_pos_create(doc->width, top + page_size);
                    pos = doc_find_prev(doc, finder_str, pos);
                    if (doc_pos_is_valid(pos))
                    {
                        top = pos.y;
                        if (top > doc->cursor.y - page_size)
                            top = MAX(0, doc->cursor.y - page_size);
                    }
                }
            }
            else strcpy(finder_str, back_str);
            break;
        default:
        {   /* BETA: Any unhandled keystroke will navigate to the next topic based
                     upon a comparison of the first letter. This is nice, say, for
                     viewing the Character Sheet and navigating to the various sections */
            doc_pos_t pos = doc_next_bookmark_char(doc, doc_pos_create(1, top), cmd);
            if (!doc_pos_is_valid(pos)) /* wrap */
                pos = doc_next_bookmark_char(doc, doc_pos_create(0, 0), cmd);
            if (doc_pos_is_valid(pos))
            {
                top = pos.y;
                if (top > doc->cursor.y - page_size)
                    top = MAX(0, doc->cursor.y - page_size);
            }
        }
        }
    }
    return rc;
}
コード例 #13
0
ファイル: z-doc.c プロジェクト: Alkalinear/poschengband
void doc_clear(doc_ptr doc)
{
    doc_rollback(doc, doc_pos_create(0, 0));
}
コード例 #14
0
ファイル: z-doc.c プロジェクト: Alkalinear/poschengband
doc_pos_t doc_insert_cols(doc_ptr dest_doc, doc_ptr src_cols[], int col_count, int spacing)
{
    int       src_y = 0;
    int       max_src_y = 0;
    doc_pos_t dest_pos;
    int       i;

    if (dest_doc->cursor.x > 0)
        doc_newline(dest_doc);

    dest_pos = dest_doc->cursor;

    for (i = 0; i < col_count; i++)
    {
        doc_ptr src_col = src_cols[i];
        max_src_y = MAX(src_col->cursor.y, max_src_y);
    }

    while (src_y <= max_src_y)
    {
        for (i = 0; i < col_count; i++)
        {
            doc_ptr src_col = src_cols[i];
            int     count = src_col->width;

            if (count > dest_doc->width - dest_pos.x)
                count = dest_doc->width - dest_pos.x;

            if (src_y <= src_col->cursor.y && count > 0)
            {
                doc_char_ptr dest = doc_char(dest_doc, dest_pos);
                doc_char_ptr src = doc_char(src_col, doc_pos_create(0, src_y));
                int          j;

                for (j = 0; j < count; j++)
                {
                    /* Hack: Attempt to prevent trailing spaces. For some reason,
                       this is causing oook to not display character dumps properly
                       from Windows builds. Interestingly, oook displays files correctly
                       from Linux even without this hack, which is puzzling since
                       the files seem identical on both platforms.*/
                    if (i == col_count - 1 && !src->c)
                    {
                        count = j;
                        break;
                    }

                    dest->a = src->a;
                    dest->c = src->c;

                    if (!dest->c)
                        dest->c = ' ';

                    dest++;
                    src++;
                }
            }
            dest_pos.x += count;

            if (i == col_count - 1)
                break;

            /* Spacing between columns */
            count = spacing;
            if (count > dest_doc->width - dest_pos.x)
                count = dest_doc->width - dest_pos.x;

            if (count > 0)
            {
                doc_char_ptr dest = doc_char(dest_doc, dest_pos);
                int          j;
                for (j = 0; j < count; j++)
                {
                    dest->a = TERM_WHITE;
                    dest->c = ' ';
                    dest++;
                }
            }
            dest_pos.x += count;
        }

        dest_pos.x = 0;
        dest_pos.y++;

        src_y++;
    }

    dest_doc->cursor = dest_pos;
    return dest_doc->cursor;
}