Ejemplo n.º 1
0
/**
 * The range is the height - handle length.
 * r = h - handle;
 * handle is the element length of the handle* length of one element.
 * handle =  r / ( num ) * hl
 *
 * r = h - r / ( num) *hl
 * r*num = num*h - r*hl
 * r*num+r*hl = num*h;
 * r ( num+hl ) = num*h
 * r = (num*h)/(num+hl)
 */
static void scrollbar_draw ( widget *wid, cairo_t *draw )
{
    scrollbar    *sb = (scrollbar *) wid;
    unsigned int wh  = widget_padding_get_remaining_height ( wid );
    // Calculate position and size.
    unsigned int r      = ( sb->length * wh ) / ( (double) ( sb->length + sb->pos_length ) );
    unsigned int handle = wid->h - r;
    double       sec    = ( ( r ) / (double) ( sb->length - 1 ) );
    unsigned int height = handle;
    unsigned int y      = sb->pos * sec;
    // Set max pos.
    y = MIN ( y, wh - handle );
    // Never go out of bar.
    height = MAX ( 2, height );
    // Cap length;
    rofi_theme_get_color ( WIDGET ( sb ), "handle-color", draw );

    cairo_rectangle ( draw,
                      widget_padding_get_left ( wid ),
                      widget_padding_get_top ( wid ) + y,
                      widget_padding_get_remaining_width ( wid ),
                      height );
    cairo_fill ( draw );
}
Ejemplo n.º 2
0
void widget_draw ( widget *widget, cairo_t *d )
{
    // Check if enabled and if draw is implemented.
    if ( widget && widget->enabled && widget->draw ) {
        // Don't draw if there is no space.
        if ( widget->h < 1 || widget->w < 1 ) {
            widget->need_redraw = FALSE;
            return;
        }
        // Store current state.
        cairo_save ( d );
        int margin_left   = distance_get_pixel ( widget->margin.left, ORIENTATION_HORIZONTAL );
        int margin_top    = distance_get_pixel ( widget->margin.top, ORIENTATION_VERTICAL );
        int margin_right  = distance_get_pixel ( widget->margin.right, ORIENTATION_HORIZONTAL );
        int margin_bottom = distance_get_pixel ( widget->margin.bottom, ORIENTATION_VERTICAL );
        // Define a clipmask so we won't draw outside out widget.
        cairo_rectangle ( d,
                          widget->x + margin_left,
                          widget->y + margin_top,
                          widget->w - margin_right - margin_left,
                          widget->h - margin_top - margin_bottom
                          );
        cairo_clip ( d );
        cairo_set_source_rgba ( d, 1.0, 1.0, 1.0, 1.0 );
        rofi_theme_get_color ( widget, "background", d );
        cairo_paint ( d );

        // Set new x/y possition.
        cairo_translate ( d, widget->x, widget->y );
        cairo_set_source_rgba ( d, 0.0, 0.0, 0.0, 1.0 );

        int left   = distance_get_pixel ( widget->border.left, ORIENTATION_HORIZONTAL );
        int right  = distance_get_pixel ( widget->border.right, ORIENTATION_HORIZONTAL );
        int top    = distance_get_pixel ( widget->border.top, ORIENTATION_VERTICAL );
        int bottom = distance_get_pixel ( widget->border.bottom, ORIENTATION_VERTICAL );
        if ( left || top || right || bottom ) {
            cairo_save ( d );
            rofi_theme_get_color ( widget, "foreground", d );
            if ( left > 0 ) {
                cairo_set_line_width ( d, left );
                distance_get_linestyle ( widget->border.left, d );
                cairo_move_to ( d, margin_left + left / 2.0, margin_top );
                cairo_line_to ( d, margin_left + left / 2.0, widget->h - margin_bottom );
                cairo_stroke ( d );
            }
            if ( right > 0 ) {
                cairo_set_line_width ( d, right );
                distance_get_linestyle ( widget->border.right, d );
                cairo_move_to ( d, widget->w - margin_right - right / 2.0, 0 );
                cairo_line_to ( d, widget->w - margin_right - right / 2.0, widget->h - margin_bottom );
                cairo_stroke ( d );
            }
            if ( top > 0 ) {
                cairo_set_line_width ( d, top );
                distance_get_linestyle ( widget->border.top, d );
                cairo_move_to ( d, margin_left, margin_top + top / 2.0 );
                cairo_line_to ( d, widget->w - margin_right, margin_top + top / 2.0 );
                cairo_stroke ( d );
            }
            if ( bottom > 0 ) {
                cairo_set_line_width ( d, bottom );
                distance_get_linestyle ( widget->border.bottom, d );
                cairo_move_to ( d, margin_left, widget->h - bottom / 2.0 - margin_bottom );
                cairo_line_to ( d, widget->w - margin_right, widget->h - bottom / 2.0 - margin_bottom );
                cairo_stroke ( d );
            }
            cairo_restore ( d );
        }
        widget->draw ( widget, d );
        widget->need_redraw = FALSE;

        cairo_restore ( d );
    }
}
Ejemplo n.º 3
0
static void texbox_update ( textbox *tb )
{
    if ( tb->update ) {
        unsigned int offset = ( tb->flags & TB_INDICATOR ) ? DOT_OFFSET : 0;
        if ( tb->main_surface ) {
            cairo_destroy ( tb->main_draw );
            cairo_surface_destroy ( tb->main_surface );
            tb->main_draw    = NULL;
            tb->main_surface = NULL;
        }
        tb->main_surface = cairo_image_surface_create ( CAIRO_FORMAT_ARGB32, tb->widget.w, tb->widget.h );
        tb->main_draw    = cairo_create ( tb->main_surface );
        cairo_set_operator ( tb->main_draw, CAIRO_OPERATOR_OVER );

        pango_cairo_update_layout ( tb->main_draw, tb->layout );
        int font_height = textbox_get_font_height ( tb );

        int cursor_x      = 0;
        int cursor_y      = 0;
        int cursor_width  = 2; //MAX ( 2, font_height / 10 );
        int cursor_height = font_height;

        if ( tb->changed ) {
            __textbox_update_pango_text ( tb );
        }

        if ( tb->flags & TB_EDITABLE ) {
            // We want to place the cursor based on the text shown.
            const char     *text = pango_layout_get_text ( tb->layout );
            // Clamp the position, should not be needed, but we are paranoid.
            int            cursor_offset = MIN ( tb->cursor, g_utf8_strlen ( text, -1 ) );
            PangoRectangle pos;
            // convert to byte location.
            char           *offset = g_utf8_offset_to_pointer ( text, cursor_offset );
            pango_layout_get_cursor_pos ( tb->layout, offset - text, &pos, NULL );
            cursor_x      = pos.x / PANGO_SCALE;
            cursor_y      = pos.y / PANGO_SCALE;
            cursor_height = pos.height / PANGO_SCALE;
        }

        // Skip the side MARGIN on the X axis.
        int x = widget_padding_get_left ( WIDGET ( tb ) ) + offset;
        int y = 0;

        if ( tb->flags & TB_RIGHT ) {
            int line_width = 0;
            // Get actual width.
            pango_layout_get_pixel_size ( tb->layout, &line_width, NULL );
            x = ( tb->widget.w - line_width - widget_padding_get_right ( WIDGET ( tb ) ) - offset );
        }
        else if ( tb->flags & TB_CENTER ) {
            int tw = textbox_get_font_width ( tb );
            x = (  ( tb->widget.w - tw - widget_padding_get_padding_width ( WIDGET ( tb ) ) - offset ) ) / 2;
        }
        y = widget_padding_get_top ( WIDGET ( tb ) ) + ( pango_font_metrics_get_ascent ( p_metrics ) - pango_layout_get_baseline ( tb->layout ) ) / PANGO_SCALE;

        rofi_theme_get_color ( WIDGET ( tb ), "foreground", tb->main_draw );
        // Text
        rofi_theme_get_color ( WIDGET ( tb ), "text", tb->main_draw );
        // draw the cursor
        if ( tb->flags & TB_EDITABLE && tb->blink ) {
            cairo_rectangle ( tb->main_draw, x + cursor_x, y + cursor_y, cursor_width, cursor_height );
            cairo_fill ( tb->main_draw );
        }

        // Set ARGB
        // We need to set over, otherwise subpixel hinting wont work.
        //cairo_set_operator ( tb->main_draw, CAIRO_OPERATOR_OVER );
        cairo_move_to ( tb->main_draw, x, y );
        pango_cairo_show_layout ( tb->main_draw, tb->layout );

        if ( ( tb->flags & TB_INDICATOR ) == TB_INDICATOR && ( tb->tbft & ( SELECTED ) ) ) {
            cairo_arc ( tb->main_draw, DOT_OFFSET / 2.0, tb->widget.h / 2.0, 2.0, 0, 2.0 * M_PI );
            cairo_fill ( tb->main_draw );
        }

        tb->update = FALSE;
    }
}