int widget_padding_get_right ( const widget *wid ) { int distance = distance_get_pixel ( wid->padding.right, ORIENTATION_HORIZONTAL ); distance += distance_get_pixel ( wid->border.right, ORIENTATION_HORIZONTAL ); distance += distance_get_pixel ( wid->margin.right, ORIENTATION_HORIZONTAL ); return distance; }
int widget_padding_get_bottom ( const widget *wid ) { int distance = distance_get_pixel ( wid->padding.bottom, ORIENTATION_VERTICAL ); distance += distance_get_pixel ( wid->border.bottom, ORIENTATION_VERTICAL ); distance += distance_get_pixel ( wid->margin.bottom, ORIENTATION_VERTICAL ); return distance; }
static int listview_get_desired_height ( widget *wid ) { listview *lv = (listview *) wid; if ( lv == NULL || lv->widget.enabled == FALSE ) { return 0; } int spacing = distance_get_pixel ( lv->spacing, ORIENTATION_VERTICAL ); int h = lv->menu_lines; if ( !( lv->fixed_num_lines ) ) { if ( lv->dynamic ) { h = MIN ( lv->menu_lines, lv->req_elements ); } else { h = MIN ( lv->menu_lines, lv->max_displayed_lines ); } } if ( h == 0 ) { if ( lv->dynamic && !lv->fixed_num_lines ) { // Hide widget fully. return 0; } return widget_padding_get_padding_height ( WIDGET ( lv ) ); } int height = widget_padding_get_padding_height ( WIDGET ( lv ) ); height += h * ( lv->element_height + spacing ) - spacing; return height; }
static void listview_resize ( widget *wid, short w, short h ) { listview *lv = (listview *) wid; lv->widget.w = MAX ( 0, w ); lv->widget.h = MAX ( 0, h ); int height = lv->widget.h - widget_padding_get_padding_height ( WIDGET ( lv ) ); int spacing_vert = distance_get_pixel ( lv->spacing, ORIENTATION_VERTICAL ); lv->max_rows = ( spacing_vert + height ) / ( lv->element_height + spacing_vert ); lv->max_elements = lv->max_rows * lv->menu_columns; if ( lv->scrollbar->widget.index == 0 ) { widget_move ( WIDGET ( lv->scrollbar ), widget_padding_get_left ( WIDGET ( lv ) ), widget_padding_get_top ( WIDGET ( lv ) ) ); } else { widget_move ( WIDGET ( lv->scrollbar ), lv->widget.w - widget_padding_get_right ( WIDGET ( lv ) ) - widget_get_width ( WIDGET ( lv->scrollbar ) ), widget_padding_get_top ( WIDGET ( lv ) ) ); } widget_resize ( WIDGET ( lv->scrollbar ), widget_get_width ( WIDGET ( lv->scrollbar ) ), height ); listview_recompute_elements ( lv ); widget_queue_redraw ( wid ); }
static int box_get_desired_height ( widget *wid ) { box *b = (box *) wid; int spacing = distance_get_pixel ( b->spacing, b->type ); int height = 0; if ( b->type == ROFI_ORIENTATION_VERTICAL ) { int active_widgets = 0; for ( GList *iter = g_list_first ( b->children ); iter != NULL; iter = g_list_next ( iter ) ) { widget * child = (widget *) iter->data; if ( !child->enabled ) { continue; } active_widgets++; if ( child->expand == TRUE ) { height += widget_get_desired_height ( child ); continue; } height += widget_get_desired_height ( child ); } if ( active_widgets > 0 ) { height += ( active_widgets - 1 ) * spacing; } } else { for ( GList *iter = g_list_first ( b->children ); iter != NULL; iter = g_list_next ( iter ) ) { widget * child = (widget *) iter->data; if ( !child->enabled ) { continue; } height = MAX ( widget_get_desired_height ( child ), height ); } } height += widget_padding_get_padding_height ( wid ); return height; }
scrollbar *scrollbar_create ( widget *parent, const char *name ) { scrollbar *sb = g_malloc0 ( sizeof ( scrollbar ) ); widget_init ( WIDGET ( sb ), parent, WIDGET_TYPE_SCROLLBAR, name ); sb->widget.x = 0; sb->widget.y = 0; sb->width = rofi_theme_get_distance ( WIDGET ( sb ), "handle-width", DEFAULT_SCROLLBAR_WIDTH ); int width = distance_get_pixel ( sb->width, ROFI_ORIENTATION_HORIZONTAL ); sb->widget.w = widget_padding_get_padding_width ( WIDGET ( sb ) ) + width; sb->widget.h = widget_padding_get_padding_height ( WIDGET ( sb ) ); sb->widget.draw = scrollbar_draw; sb->widget.free = scrollbar_free; sb->widget.trigger_action = scrollbar_trigger_action; sb->widget.motion_notify = scrollbar_motion_notify; sb->widget.get_desired_height = scrollbar_get_desired_height; sb->length = 10; sb->pos = 0; sb->pos_length = 4; return sb; }
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 ); } }
static void listview_draw ( widget *wid, cairo_t *draw ) { unsigned int offset = 0; listview *lv = (listview *) wid; if ( lv->scroll_type == LISTVIEW_SCROLL_CONTINIOUS ) { offset = scroll_continious ( lv ); } else { offset = scroll_per_page ( lv ); } // Set these all together to make sure they update consistently. scrollbar_set_max_value ( lv->scrollbar, lv->req_elements ); scrollbar_set_handle_length ( lv->scrollbar, lv->cur_columns * lv->max_rows ); if ( lv->reverse ) { scrollbar_set_handle ( lv->scrollbar, lv->req_elements - lv->selected - 1 ); } else { scrollbar_set_handle ( lv->scrollbar, lv->selected ); } lv->last_offset = offset; int spacing_vert = distance_get_pixel ( lv->spacing, ORIENTATION_VERTICAL ); int spacing_hori = distance_get_pixel ( lv->spacing, ORIENTATION_HORIZONTAL ); int left_offset = widget_padding_get_left ( wid ); int top_offset = widget_padding_get_top ( wid ); if ( lv->scrollbar->widget.index == 0 ) { left_offset += spacing_hori + lv->scrollbar->widget.w; } if ( lv->cur_elements > 0 && lv->max_rows > 0 ) { // Set new x/y possition. unsigned int max = MIN ( lv->cur_elements, lv->req_elements - offset ); if ( lv->rchanged ) { unsigned int width = lv->widget.w - spacing_hori * ( lv->cur_columns - 1 ); width -= widget_padding_get_padding_width ( wid ); if ( widget_enabled ( WIDGET ( lv->scrollbar ) ) ) { width -= spacing_hori; width -= widget_get_width ( WIDGET ( lv->scrollbar ) ); } unsigned int element_width = ( width ) / lv->cur_columns; for ( unsigned int i = 0; i < max; i++ ) { unsigned int ex = left_offset + ( ( i ) / lv->max_rows ) * ( element_width + spacing_hori ); if ( lv->reverse ) { unsigned int ey = wid->h - ( widget_padding_get_bottom ( wid ) + ( ( i ) % lv->max_rows ) * ( lv->element_height + spacing_vert ) ) - lv->element_height; textbox_moveresize ( lv->boxes[i], ex, ey, element_width, lv->element_height ); } else { unsigned int ey = top_offset + ( ( i ) % lv->max_rows ) * ( lv->element_height + spacing_vert ); textbox_moveresize ( lv->boxes[i], ex, ey, element_width, lv->element_height ); } update_element ( lv, i, i + offset, TRUE ); widget_draw ( WIDGET ( lv->boxes[i] ), draw ); } lv->rchanged = FALSE; } else { for ( unsigned int i = 0; i < max; i++ ) { update_element ( lv, i, i + offset, FALSE ); widget_draw ( WIDGET ( lv->boxes[i] ), draw ); } } } widget_draw ( WIDGET ( lv->scrollbar ), draw ); }
static void hori_calculate_size ( box *b ) { int spacing = distance_get_pixel ( b->spacing, ROFI_ORIENTATION_HORIZONTAL ); int expanding_widgets = 0; int active_widgets = 0; int rem_width = widget_padding_get_remaining_width ( WIDGET ( b ) ); int rem_height = widget_padding_get_remaining_height ( WIDGET ( b ) ); for ( GList *iter = g_list_first ( b->children ); iter != NULL; iter = g_list_next ( iter ) ) { widget * child = (widget *) iter->data; if ( child->enabled && child->expand == FALSE ) { widget_resize ( child, widget_get_desired_width ( child ), //child->w, rem_height ); } } b->max_size = 0; for ( GList *iter = g_list_first ( b->children ); iter != NULL; iter = g_list_next ( iter ) ) { widget * child = (widget *) iter->data; if ( !child->enabled ) { continue; } active_widgets++; if ( child->expand == TRUE ) { expanding_widgets++; continue; } // Size used by fixed width widgets. if ( child->h > 0 ) { b->max_size += child->w; } } b->max_size += MAX ( 0, ( ( active_widgets - 1 ) * spacing ) ); if ( b->max_size > ( rem_width ) ) { b->max_size = rem_width; g_debug ( "Widgets to large (width) for box: %d %d", b->max_size, b->widget.w ); return; } if ( active_widgets > 0 ) { int left = widget_padding_get_left ( WIDGET ( b ) ); double rem = rem_width - b->max_size; int index = 0; for ( GList *iter = g_list_first ( b->children ); iter != NULL; iter = g_list_next ( iter ) ) { widget * child = (widget *) iter->data; if ( child->enabled == FALSE ) { continue; } if ( child->expand == TRUE ) { // Re-calculate to avoid round issues leaving one pixel left. int expanding_widgets_size = ( rem ) / ( expanding_widgets - index ); widget_move ( child, left, widget_padding_get_top ( WIDGET ( b ) ) ); left += expanding_widgets_size; widget_resize ( child, expanding_widgets_size, rem_height ); left += spacing; rem -= expanding_widgets_size; index++; } else { widget_move ( child, left, widget_padding_get_top ( WIDGET ( b ) ) ); left += widget_get_width ( child ); left += spacing; } } } b->max_size += widget_padding_get_padding_width ( WIDGET ( b ) ); }
static void vert_calculate_size ( box *b ) { int spacing = distance_get_pixel ( b->spacing, ROFI_ORIENTATION_VERTICAL ); int expanding_widgets = 0; int active_widgets = 0; int rem_width = widget_padding_get_remaining_width ( WIDGET ( b ) ); int rem_height = widget_padding_get_remaining_height ( WIDGET ( b ) ); for ( GList *iter = g_list_first ( b->children ); iter != NULL; iter = g_list_next ( iter ) ) { widget * child = (widget *) iter->data; if ( child->enabled && child->expand == FALSE ) { widget_resize ( child, rem_width, widget_get_desired_height ( child ) ); } } b->max_size = 0; for ( GList *iter = g_list_first ( b->children ); iter != NULL; iter = g_list_next ( iter ) ) { widget * child = (widget *) iter->data; if ( !child->enabled ) { continue; } active_widgets++; if ( child->expand == TRUE ) { expanding_widgets++; continue; } if ( child->h > 0 ) { b->max_size += child->h; } } if ( active_widgets > 0 ) { b->max_size += ( active_widgets - 1 ) * spacing; } if ( b->max_size > rem_height ) { b->max_size = rem_height; g_debug ( "Widgets to large (height) for box: %d %d", b->max_size, b->widget.h ); return; } if ( active_widgets > 0 ) { int top = widget_padding_get_top ( WIDGET ( b ) ); double rem = rem_height - b->max_size; int index = 0; for ( GList *iter = g_list_first ( b->children ); iter != NULL; iter = g_list_next ( iter ) ) { widget * child = (widget *) iter->data; if ( child->enabled == FALSE ) { continue; } if ( child->expand == TRUE ) { // Re-calculate to avoid round issues leaving one pixel left. int expanding_widgets_size = ( rem ) / ( expanding_widgets - index ); widget_move ( child, widget_padding_get_left ( WIDGET ( b ) ), top ); top += expanding_widgets_size; widget_resize ( child, rem_width, expanding_widgets_size ); top += spacing; rem -= expanding_widgets_size; index++; } else { widget_move ( child, widget_padding_get_left ( WIDGET ( b ) ), top ); top += widget_get_height ( child ); top += spacing; } } } b->max_size += widget_padding_get_padding_height ( WIDGET ( b ) ); }