Esempio n. 1
0
_Bool edit_mmove(EDIT *edit, int px, int py, int width, int height, int x, int y, int dx, int dy)
{
    if(utox_window_baseline && py > utox_window_baseline - font_small_lineheight - 4 * SCALE) {
        y += py - (utox_window_baseline - font_small_lineheight - 4 * SCALE);
        py = utox_window_baseline - font_small_lineheight - 4 * SCALE;
    }

    _Bool need_redraw = 0;

    _Bool mouseover = inrect(x, y, 0, 0, width - (edit->multiline ? SCROLL_WIDTH : 0), height);
    if(mouseover) {
        cursor = CURSOR_TEXT;
    }
    if(mouseover != edit->mouseover) {
        edit->mouseover = mouseover;
        if(edit != active_edit) {
            need_redraw = 1;
        }
    }

    if(edit->multiline) {
        need_redraw |= scroll_mmove(edit->scroll, px, py, width, height, x, y, dx, dy);
        y += scroll_gety(edit->scroll, height);
    }

    if(edit == active_edit && edit_select) {
        if (edit->select_completely) {
            edit_setfocus(edit);
            need_redraw = 1;
            return need_redraw;
        }
 
        setfont(FONT_TEXT);
        edit_sel.p2 = hittextmultiline(x - 2 * SCALE, width - 4 * SCALE - (edit->multiline ? SCROLL_WIDTH : 0), y - 2 * SCALE, INT_MAX, font_small_lineheight, edit->data, edit->length, edit->multiline);

        STRING_IDX start, length;
        if(edit_sel.p2 > edit_sel.p1) {
            start = edit_sel.p1;
            length = edit_sel.p2 - edit_sel.p1;
        } else {
            start = edit_sel.p2;
            length = edit_sel.p1 - edit_sel.p2;
        }

        if(start != edit_sel.start || length != edit_sel.length) {
            edit_sel.start = start;
            edit_sel.length = length;
            need_redraw = 1;
        }
    } else if(mouseover) {
        setfont(FONT_TEXT);
        edit->mouseover_char = hittextmultiline(x - 2 * SCALE, width - 4 * SCALE - (edit->multiline ? SCROLL_WIDTH : 0), y - 2 * SCALE, INT_MAX, font_small_lineheight, edit->data, edit->length, edit->multiline);
    }

    return need_redraw;
}
Esempio n. 2
0
uint16_t text_linedown(int width, int height, uint16_t p, uint16_t lineheight, char_t *str, uint16_t length, SCROLLABLE *scroll)
{
    //lazy
    int x, y;
    textxy(width, p, lineheight, str, length, &x, &y);

    y += lineheight;

    if(scroll->content_height > height) {
        double d1 = (double)y / (double)(scroll->content_height - height);
        double d2 = (double)(y - height + lineheight) / (double)(scroll->content_height - height);
        if(d2 > scroll->d) {
            scroll->d = d2 > 1.0 ? 1.0 : d2;
        } else if(d1 < scroll->d) {
            scroll->d = d1;
        }
    }

    return hittextmultiline(x, width, y, INT_MAX, lineheight, str, length, 1);
}
Esempio n. 3
0
_Bool messages_mmove(MESSAGES *m, int UNUSED(px), int UNUSED(py), int width, int UNUSED(height), int mx, int my, int dx, int UNUSED(dy))
{
    if(m->idown < m->data->n) {
        int maxwidth = width - MESSAGES_X - TIME_WIDTH;
        MSG_IMG *img_down = m->data->data[m->idown];
        if((img_down->msg_type == MSG_TYPE_IMAGE) && (img_down->w > maxwidth)) {
            img_down->position -= (double)dx / (double)(img_down->w - maxwidth);
            if(img_down->position > 1.0) {
                img_down->position = 1.0;
            } else if(img_down->position < 0.0) {
                img_down->position = 0.0;
            }
            cursor = CURSOR_ZOOM_OUT;
            return 1;
        }
    }

    if(mx < 0 || my < 0 || (uint32_t) my > m->data->height) {
        if(m->iover != MSG_IDX_MAX) {
            m->iover = MSG_IDX_MAX;
            return 1;
        }
        return 0;
    }

    setfont(FONT_TEXT);

    void **p = m->data->data;
    MSG_IDX i = 0, n = m->data->n;
    _Bool need_redraw = 0;

    while(i != n) {
        MESSAGE *msg = *p++;

        int dy = msg->height;

        if(my >= 0 && my < dy) {
            switch(msg->msg_type) {
            case MSG_TYPE_TEXT:
            case MSG_TYPE_ACTION_TEXT: {
                /* normal message */
                m->over = hittextmultiline(mx - MESSAGES_X, width - MESSAGES_X - TIME_WIDTH, my < 0 ? 0 : my, msg->height, font_small_lineheight, msg->msg, msg->length, 1);

                _Bool prev_urlmdown = m->urlmdown;
                if (m->urlover != STRING_IDX_MAX) {
                    m->urlmdown = 0;
                    m->urlover = STRING_IDX_MAX;
                }

                if(my < 0 || my >= dy || mx < MESSAGES_X || m->over == msg->length) {
                    break;
                }

                cursor = CURSOR_TEXT;

                char_t *str = msg->msg + m->over;
                while(str != msg->msg) {
                    str--;
                    if(*str == ' ' || *str == '\n') {
                        str++;
                        break;
                    }
                }

                char_t *end = msg->msg + msg->length;
                while(str != end && *str != ' ' && *str != '\n') {
                    if(( str == msg->msg || *(str - 1) == '\n' || *(str - 1) == ' ') && (m->urlover == STRING_IDX_MAX && end - str >= 7 && strcmp2(str, "http://") == 0)) {
                        cursor = CURSOR_HAND;
                        m->urlover = str - msg->msg;
                    }

                    if(( str == msg->msg || *(str - 1) == '\n' || *(str - 1) == ' ') && (m->urlover == STRING_IDX_MAX && end - str >= 8 && strcmp2(str, "https://") == 0)) {
                        cursor = CURSOR_HAND;
                        m->urlover = str - msg->msg;
                    }

                    str++;
                }

                if(m->urlover != STRING_IDX_MAX) {
                    m->urllen = (str - msg->msg) - m->urlover;
                    m->urlmdown = prev_urlmdown;
                }

                break;
            }

            case MSG_TYPE_IMAGE: {
                m->over = 0;

                MSG_IMG *img = (void*)msg;
                int maxwidth = width - MESSAGES_X - TIME_WIDTH;

                if(img->w > maxwidth) {
                    mx -= MESSAGES_X;
                    int w = img->w > maxwidth ? maxwidth : img->w;
                    int h = (img->zoom || img->w <= maxwidth) ? img->h : img->h * maxwidth / img->w;
                    if(mx >= 0 && my >= 0 && mx < w && my < h) {
                        m->over = 1;
                        cursor = CURSOR_ZOOM_IN + img->zoom;
                    }
                }
                break;
            }

            case MSG_TYPE_FILE: {
                uint8_t over = 0;
                MSG_FILE *file = (void*)msg;

                mx -= MESSAGES_X;
                if(mx >= 0 && mx < BM_FT_WIDTH && my >= 0 && my < BM_FT_HEIGHT) {
                    over = 3;
                    mx -= BM_FTM_WIDTH + SCALE;
                    if(mx >= 0) {
                        if(my < BM_FTB_HEIGHT + SCALE) {
                            // mouse is over the upper button (cancel)
                            over = 1;
                        } else if(my >= BM_FTB_HEIGHT + SCALE * 2) {
                            // mouse is over the lower button (pause / accept)
                            over = 2;
                        }
                    }
                }

                static const uint8_t f[16] = {
                    0b011,
                    0b001,

                    0b011,
                    0b011,

                    0b011,
                    0b011,

                    0b001,
                    0b001,

                    0b001,
                    0b001,

                    0b001,
                    0b001,

                    0b000,
                    0b000,

                    0b111,
                    0b111,
                };

                if(over && f[file->status * 2 + file->author] & (1 << (over - 1))) {
                    cursor = CURSOR_HAND;
                }

                if(over != m->over) {
                    need_redraw = 1;
                    m->over = over;
                }

                break;
            }
            }

            if((i != m->iover) && (m->iover != MSG_IDX_MAX) && ((msg->msg_type == MSG_TYPE_FILE) || (((MESSAGE*)(m->data->data[m->iover]))->msg_type == MSG_TYPE_FILE))) {
                need_redraw = 1; // Redraw file on hover-in/out.
            }

            m->iover = i;

            if(m->select) {
                MSG_IDX istart, iend;
                STRING_IDX start, end;
                if(i > m->idown) {
                    istart = m->idown;
                    iend = i;

                    start = m->down;
                    end = m->over;
                } else if(i < m->idown) {
                    iend = m->idown;
                    istart = i;

                    end = m->down;
                    start = m->over;
                } else {
                    istart = iend = i;
                    if(m->over >= m->down) {
                        start = m->down;
                        end = m->over;
                    } else {
                        end = m->down;
                        start = m->over;
                    }
                }

                if(start != m->data->start || istart != m->data->istart || end != m->data->end || iend != m->data->iend) {
                    m->data->start = start;
                    m->data->end = end;
                    m->data->istart = istart;
                    m->data->iend = iend;
                    need_redraw = 1;
                }

            }
            return need_redraw;
        }

        my -= dy;

        i++;
    }

    return 0;
}