diff --git a/Makefile.am b/Makefile.am index 2aa6e36c..63798985 100644 --- a/Makefile.am +++ b/Makefile.am @@ -36,6 +36,7 @@ rofi_SOURCES=\ source/keyb.c\ config/config.c\ source/helper.c\ + source/widget.c\ source/textbox.c\ source/timings.c\ source/history.c\ @@ -58,6 +59,7 @@ rofi_SOURCES=\ include/helper.h\ include/timings.h\ include/history.h\ + include/widget.h\ include/textbox.h\ include/scrollbar.h\ include/xrmoptions.h\ @@ -142,6 +144,7 @@ rofi_test_SOURCES=\ test/history-test.c textbox_test_SOURCES=\ + source/widget.c\ source/textbox.c\ config/config.c\ source/keyb.c\ @@ -153,7 +156,9 @@ textbox_test_SOURCES=\ include/mode.h\ include/mode-private.h\ include/settings.h\ + include/widget.h\ include/textbox.h\ + include/widget.h\ include/x11-helper.h\ include/xrmoptions.h\ include/helper.h\ diff --git a/include/rofi.h b/include/rofi.h index 424f483e..316d4cb5 100644 --- a/include/rofi.h +++ b/include/rofi.h @@ -1,20 +1,14 @@ #ifndef ROFI_MAIN_H #define ROFI_MAIN_H #include +#include #include #include #include -#include "textbox.h" -#include -#include #include "timings.h" #include "keyb.h" #include "mode.h" -/** - * @defgroup Widgets Widgets - */ - /** * @defgroup Main Main * @{ diff --git a/include/scrollbar.h b/include/scrollbar.h index e3312854..960d241c 100644 --- a/include/scrollbar.h +++ b/include/scrollbar.h @@ -1,6 +1,7 @@ #ifndef ROFI_SCROLLBAR_H #define ROFI_SCROLLBAR_H #include +#include "widget.h" /** * @defgroup Scrollbar Scrollbar @@ -13,7 +14,7 @@ */ typedef struct _scrollbar { - short x, y, w, h; + Widget widget; unsigned int length; unsigned int pos; unsigned int pos_length; @@ -89,14 +90,5 @@ unsigned int scrollbar_clicked ( scrollbar *sb, int y ); */ void scrollbar_resize ( scrollbar *sb, int w, int h ); -/** - * @param sb scrollbar object - * @param x x pos in pixels - * @param y y pos in pixels - * - * Move the scrollbar. - */ -void scrollbar_move ( scrollbar *sb, int x, int y ); - /*@}*/ #endif // ROFI_SCROLLBAR_H diff --git a/include/textbox.h b/include/textbox.h index daa57aff..94fdcb7b 100644 --- a/include/textbox.h +++ b/include/textbox.h @@ -6,6 +6,7 @@ #include #include #include +#include "widget.h" /** * @defgroup Textbox Textbox @@ -21,8 +22,8 @@ typedef struct typedef struct { + Widget widget; unsigned long flags; - short x, y, w, h; short cursor; Color color_fg, color_bg; char *text; @@ -126,15 +127,6 @@ void textbox_cursor_end ( textbox *tb ); */ void textbox_cursor ( textbox *tb, int pos ); -/** - * @param tb Handle to the textbox - * @param x The new x coordinate to move the window to - * @param y The new y coordinate to move the window to - * - * Move the window to x,y position. - */ -void textbox_move ( textbox *tb, int x, int y ); - /** * @param tb Handle to the textbox * @param pos The position to insert the string at diff --git a/include/widget.h b/include/widget.h new file mode 100644 index 00000000..5540260a --- /dev/null +++ b/include/widget.h @@ -0,0 +1,47 @@ +#ifndef ROFI_WIDGET_H +#define ROFI_WIDGET_H + +/** + * @defgroup Widgets Widgets + * + * Generic Widget class + * + * @{ + */ +typedef struct _Widget +{ + /** X position relative to parent */ + short x; + /** Y position relative to parent */ + short y; + /** Width of the widget */ + short w; + /** Height of the widget */ + short h; +} Widget; + +/** Macro to get widget from an implementation (e.g. textbox/scrollbar) */ +#define WIDGET(a) (a != NULL?&(a->widget):NULL) + +/** + * @param widget The widget to check + * @param x The X position relative to parent window + * @param y the Y position relative to parent window + * + * Check if x,y falls within the widget. + * + * @return TRUE if x,y falls within the widget + */ +int widget_intersect ( const Widget *widget, int x, int y); + +/** + * @param widget The widget to move + * @param x The new X position relative to parent window + * @param y The new Y position relative to parent window + * + * Moves the widget. + */ +void widget_move(Widget *widget, short x, short y); + +/*@}*/ +#endif // ROFI_WIDGET_H diff --git a/include/x11-helper.h b/include/x11-helper.h index d8a7ecbc..b075feeb 100644 --- a/include/x11-helper.h +++ b/include/x11-helper.h @@ -1,5 +1,6 @@ #ifndef X11_ROFI_HELPER_H #define X11_ROFI_HELPER_H +#include /** * @defgroup X11Helper X11Helper diff --git a/source/dialogs/dmenu.c b/source/dialogs/dmenu.c index 819e6237..961b74a8 100644 --- a/source/dialogs/dmenu.c +++ b/source/dialogs/dmenu.c @@ -36,6 +36,7 @@ #include #include "rofi.h" #include "settings.h" +#include "textbox.h" #include "dialogs/dmenu.h" #include "helper.h" #include "xrmoptions.h" diff --git a/source/dialogs/drun.c b/source/dialogs/drun.c index 64165ece..1c029368 100644 --- a/source/dialogs/drun.c +++ b/source/dialogs/drun.c @@ -41,6 +41,7 @@ #include "rofi.h" #include "settings.h" #include "helper.h" +#include "textbox.h" #include "dialogs/drun.h" #define RUN_CACHE_FILE "rofi-2.runcache" diff --git a/source/dialogs/window.c b/source/dialogs/window.c index 129360d8..670caeea 100644 --- a/source/dialogs/window.c +++ b/source/dialogs/window.c @@ -41,6 +41,7 @@ #include "rofi.h" #include "settings.h" #include "helper.h" +#include "textbox.h" #include "x11-helper.h" #include "i3-support.h" #include "dialogs/window.h" diff --git a/source/mode.c b/source/mode.c index 63032f2b..3f229883 100644 --- a/source/mode.c +++ b/source/mode.c @@ -1,3 +1,6 @@ +#include +#include +#include #include "rofi.h" #include "xrmoptions.h" #include "x11-helper.h" diff --git a/source/rofi.c b/source/rofi.c index 6ad07a10..0fc7f536 100644 --- a/source/rofi.c +++ b/source/rofi.c @@ -52,6 +52,7 @@ #include #include "settings.h" +#include "mode.h" #include "rofi.h" #include "helper.h" #include "textbox.h" @@ -722,31 +723,6 @@ static int menu_keyboard_navigation ( MenuState *state, KeySym key, unsigned int return 0; } -/** - * @param state Internal state of the menu. - * @param xbe The mouse button press event. - * - * mouse navigation through the elements. - * - */ -static int intersect ( const textbox *tb, int x, int y ) -{ - if ( x >= ( tb->x ) && x < ( tb->x + tb->w ) ) { - if ( y >= ( tb->y ) && y < ( tb->y + tb->h ) ) { - return TRUE; - } - } - return FALSE; -} -static int sb_intersect ( const scrollbar *tb, int x, int y ) -{ - if ( x >= ( tb->x ) && x < ( tb->x + tb->w ) ) { - if ( y >= ( tb->y ) && y < ( tb->y + tb->h ) ) { - return TRUE; - } - } - return FALSE; -} static void menu_mouse_navigation ( MenuState *state, XButtonEvent *xbe ) { // Scroll event @@ -766,13 +742,13 @@ static void menu_mouse_navigation ( MenuState *state, XButtonEvent *xbe ) return; } else { - if ( state->scrollbar && sb_intersect ( state->scrollbar, xbe->x, xbe->y ) ) { + if ( state->scrollbar && widget_intersect ( &(state->scrollbar->widget), xbe->x, xbe->y ) ) { state->selected = scrollbar_clicked ( state->scrollbar, xbe->y ); state->update = TRUE; return; } for ( unsigned int i = 0; config.sidebar_mode == TRUE && i < num_modi; i++ ) { - if ( intersect ( modi[i].tb, xbe->x, xbe->y ) ) { + if ( widget_intersect ( &(modi[i].tb->widget), xbe->x, xbe->y ) ) { *( state->selected_line ) = 0; state->retv = MENU_QUICK_SWITCH | ( i & MENU_LOWER_MASK ); state->quit = TRUE; @@ -781,7 +757,7 @@ static void menu_mouse_navigation ( MenuState *state, XButtonEvent *xbe ) } } for ( unsigned int i = 0; i < state->max_elements; i++ ) { - if ( intersect ( state->boxes[i], xbe->x, xbe->y ) ) { + if ( widget_intersect ( &(state->boxes[i]->widget), xbe->x, xbe->y ) ) { // Only allow items that are visible to be selected. if ( ( state->last_offset + i ) >= state->filtered_lines ) { break; @@ -979,7 +955,7 @@ static void menu_draw ( MenuState *state, cairo_t *d ) // Element width. unsigned int element_width = state->w - ( 2 * ( state->border ) ); if ( state->scrollbar != NULL ) { - element_width -= state->scrollbar->w; + element_width -= state->scrollbar->widget.w; } if ( columns > 0 ) { element_width = ( element_width - ( columns - 1 ) * config.line_margin ) / columns; @@ -1152,7 +1128,7 @@ static void menu_paste ( MenuState *state, XSelectionEvent *xse ) static void menu_resize ( MenuState *state ) { unsigned int sbw = config.line_margin + 8; - scrollbar_move ( state->scrollbar, state->w - state->border - sbw, state->top_offset ); + widget_move ( WIDGET(state->scrollbar), state->w - state->border - sbw, state->top_offset ); if ( config.sidebar_mode == TRUE ) { int width = ( state->w - ( 2 * ( state->border ) + ( num_modi - 1 ) * config.line_margin ) ) / num_modi; for ( unsigned int j = 0; j < num_modi; j++ ) { @@ -1164,8 +1140,8 @@ static void menu_resize ( MenuState *state ) } int entrybox_width = state->w - ( 2 * ( state->border ) ) - textbox_get_width ( state->prompt_tb ) - textbox_get_width ( state->case_indicator ); - textbox_moveresize ( state->text, state->text->x, state->text->y, entrybox_width, state->line_height ); - textbox_move ( state->case_indicator, state->w - state->border - textbox_get_width ( state->case_indicator ), state->border ); + textbox_moveresize ( state->text, state->text->widget.x, state->text->widget.y, entrybox_width, state->line_height ); + widget_move ( WIDGET(state->case_indicator), state->w - state->border - textbox_get_width ( state->case_indicator ), state->border ); /** * Resize in Height */ @@ -1358,7 +1334,7 @@ MenuReturn menu ( Mode *sw, char **input, char *prompt, unsigned int *selected_l state.top_offset = state.border * 1 + state.line_height + 2 + config.line_margin * 2; // Move indicator to end. - textbox_move ( state.case_indicator, state.border + textbox_get_width ( state.prompt_tb ) + entrybox_width, state.border ); + widget_move ( WIDGET(state.case_indicator), state.border + textbox_get_width ( state.prompt_tb ) + entrybox_width, state.border ); textbox_text ( state.case_indicator, get_matching_state () ); state.message_tb = NULL; @@ -1523,7 +1499,7 @@ MenuReturn menu ( Mode *sw, char **input, char *prompt, unsigned int *selected_l ; } XMotionEvent xme = ev.xmotion; - if ( xme.x >= state.scrollbar->x && xme.x < ( state.scrollbar->x + state.scrollbar->w ) ) { + if ( xme.x >= state.scrollbar->widget.x && xme.x < ( state.scrollbar->widget.x + state.scrollbar->widget.w ) ) { state.selected = scrollbar_clicked ( state.scrollbar, xme.y ); state.update = TRUE; } diff --git a/source/scrollbar.c b/source/scrollbar.c index f80ae431..35b3d3d3 100644 --- a/source/scrollbar.c +++ b/source/scrollbar.c @@ -41,10 +41,10 @@ scrollbar *scrollbar_create ( short x, short y, short w, short h ) { scrollbar *sb = g_malloc0 ( sizeof ( scrollbar ) ); - sb->x = x; - sb->y = y; - sb->w = MAX ( 1, w ); - sb->h = MAX ( 1, h ); + sb->widget.x = x; + sb->widget.y = y; + sb->widget.w = MAX ( 1, w ); + sb->widget.h = MAX ( 1, h ); sb->length = 10; sb->pos = 0; @@ -86,7 +86,7 @@ void scrollbar_draw ( scrollbar *sb, cairo_t *draw ) { if ( sb != NULL ) { // Calculate position and size. - const short bh = sb->h - 0; + const short bh = sb->widget.h - 0; float sec = ( ( bh ) / (float) sb->length ); short height = sb->pos_length * sec; short y = sb->pos * sec; @@ -99,7 +99,7 @@ void scrollbar_draw ( scrollbar *sb, cairo_t *draw ) // Redraw base window color_separator ( display, draw ); - cairo_rectangle ( draw, sb->x + config.line_margin, sb->y + y, sb->w - config.line_margin, height ); + cairo_rectangle ( draw, sb->widget.x + config.line_margin, sb->widget.y + y, sb->widget.w - config.line_margin, height ); cairo_fill ( draw ); } } @@ -107,28 +107,20 @@ void scrollbar_resize ( scrollbar *sb, int w, int h ) { if ( sb != NULL ) { if ( h > 0 ) { - sb->h = h; + sb->widget.h = h; } if ( w > 0 ) { - sb->w = w; + sb->widget.w = w; } } } -void scrollbar_move ( scrollbar *sb, int x, int y ) -{ - if ( sb != NULL ) { - sb->x = x; - sb->y = y; - } -} - unsigned int scrollbar_clicked ( scrollbar *sb, int y ) { if ( sb != NULL ) { - if ( y >= sb->y && y < ( sb->y + sb->h ) ) { - y -= sb->y; - y = MIN ( MAX ( 1, y ), sb->h - 1 ) - 1; - const short bh = sb->h - 2; + if ( y >= sb->widget.y && y < ( sb->widget.y + sb->widget.h ) ) { + y -= sb->widget.y; + y = MIN ( MAX ( 1, y ), sb->widget.h - 1 ) - 1; + const short bh = sb->widget.h - 2; float sec = ( ( bh ) / (float) sb->length ); unsigned int sel = y / sec; return MIN ( sel, sb->length - 1 ); diff --git a/source/textbox.c b/source/textbox.c index 4f808fc3..84a51133 100644 --- a/source/textbox.c +++ b/source/textbox.c @@ -67,14 +67,14 @@ textbox* textbox_create ( TextboxFlags flags, short x, short y, short w, short h tb->flags = flags; - tb->x = x; - tb->y = y; - tb->w = MAX ( 1, w ); - tb->h = MAX ( 1, h ); + tb->widget.x = x; + tb->widget.y = y; + tb->widget.w = MAX ( 1, w ); + tb->widget.h = MAX ( 1, h ); tb->changed = FALSE; - tb->main_surface = cairo_image_surface_create ( get_format (), tb->w, tb->h ); + tb->main_surface = cairo_image_surface_create ( get_format (), tb->widget.w, tb->widget.h ); tb->main_draw = cairo_create ( tb->main_surface ); tb->layout = pango_layout_new ( p_context ); textbox_font ( tb, tbft ); @@ -86,7 +86,7 @@ textbox* textbox_create ( TextboxFlags flags, short x, short y, short w, short h textbox_cursor_end ( tb ); // auto height/width modes get handled here - textbox_moveresize ( tb, tb->x, tb->y, tb->w, tb->h ); + textbox_moveresize ( tb, tb->widget.x, tb->widget.y, tb->widget.w, tb->widget.h ); return tb; } @@ -152,19 +152,12 @@ void textbox_text ( textbox *tb, const char *text ) pango_layout_set_text ( tb->layout, tb->text, strlen ( tb->text ) ); } if ( tb->flags & TB_AUTOWIDTH ) { - textbox_moveresize ( tb, tb->x, tb->y, tb->w, tb->h ); + textbox_moveresize ( tb, tb->widget.x, tb->widget.y, tb->widget.w, tb->widget.h ); } tb->cursor = MAX ( 0, MIN ( ( int ) strlen ( text ), tb->cursor ) ); } -void textbox_move ( textbox *tb, int x, int y ) -{ - if ( x != tb->x || y != tb->y ) { - tb->x = x; - tb->y = y; - } -} // within the parent handled auto width/height modes void textbox_moveresize ( textbox *tb, int x, int y, int w, int h ) { @@ -189,15 +182,15 @@ void textbox_moveresize ( textbox *tb, int x, int y, int w, int h ) h = textbox_get_height ( tb ); } - if ( x != tb->x || y != tb->y || w != tb->w || h != tb->h ) { - tb->x = x; - tb->y = y; - tb->h = MAX ( 1, h ); - tb->w = MAX ( 1, w ); + if ( x != tb->widget.x || y != tb->widget.y || w != tb->widget.w || h != tb->widget.h ) { + tb->widget.x = x; + tb->widget.y = y; + tb->widget.h = MAX ( 1, h ); + tb->widget.w = MAX ( 1, w ); } // We always want to update this - pango_layout_set_width ( tb->layout, PANGO_SCALE * ( tb->w - 2 * SIDE_MARGIN ) ); + pango_layout_set_width ( tb->layout, PANGO_SCALE * ( tb->widget.w - 2 * SIDE_MARGIN ) ); tb->update = TRUE; } @@ -234,7 +227,7 @@ static void texbox_update ( textbox *tb ) tb->main_draw = NULL; tb->main_surface = NULL; } - tb->main_surface = cairo_image_surface_create ( get_format (), tb->w, tb->h ); + tb->main_surface = cairo_image_surface_create ( get_format (), tb->widget.w, tb->widget.h ); tb->main_draw = cairo_create ( tb->main_surface ); cairo_set_operator ( tb->main_draw, CAIRO_OPERATOR_SOURCE ); @@ -272,18 +265,18 @@ static void texbox_update ( textbox *tb ) int line_width = 0; // Get actual width. pango_layout_get_pixel_size ( tb->layout, &line_width, NULL ); - x = ( tb->w - line_width - SIDE_MARGIN ); + x = ( tb->widget.w - line_width - SIDE_MARGIN ); } else if ( tb->flags & TB_CENTER ) { int tw = textbox_get_font_width ( tb ); - x = ( ( tb->w - tw - 2 * SIDE_MARGIN ) ) / 2; + x = ( ( tb->widget.w - tw - 2 * SIDE_MARGIN ) ) / 2; } short fh = textbox_get_font_height ( tb ); - if ( fh > tb->h ) { + if ( fh > tb->widget.h ) { y = 0; } else { - y = ( ( tb->h - fh ) ) / 2; + y = ( ( tb->widget.h - fh ) ) / 2; } // Set ARGB @@ -318,8 +311,8 @@ void textbox_draw ( textbox *tb, cairo_t *draw ) /* Write buffer */ - cairo_set_source_surface ( draw, tb->main_surface, tb->x, tb->y ); - cairo_rectangle ( draw, tb->x, tb->y, tb->w, tb->h ); + cairo_set_source_surface ( draw, tb->main_surface, tb->widget.x, tb->widget.y ); + cairo_rectangle ( draw, tb->widget.x, tb->widget.y, tb->widget.w, tb->widget.h ); cairo_fill ( draw ); } diff --git a/source/widget.c b/source/widget.c new file mode 100644 index 00000000..648462a5 --- /dev/null +++ b/source/widget.c @@ -0,0 +1,27 @@ +#include +#include "widget.h" + + +int widget_intersect ( const Widget *widget, int x, int y) +{ + if(widget == NULL ){ + return FALSE; + } + + if ( x >= ( widget->x ) && x < ( widget->x + widget->w ) ) { + if ( y >= ( widget->y ) && y < ( widget->y + widget->h ) ) { + return TRUE; + } + } + return FALSE; + +} + +void widget_move(Widget *widget, short x, short y) +{ + if ( widget != NULL ){ + widget->x = x; + widget->y = y; + } + +} diff --git a/test/textbox-test.c b/test/textbox-test.c index 46883fcd..47a5c83d 100644 --- a/test/textbox-test.c +++ b/test/textbox-test.c @@ -11,6 +11,7 @@ #include #include +#include #include "settings.h" static int test = 0; @@ -169,9 +170,9 @@ int main ( G_GNUC_UNUSED int argc, G_GNUC_UNUSED char **argv ) textbox_font ( box, HIGHLIGHT ); textbox_draw ( box, draw ); - textbox_move ( box, 12, 13 ); - TASSERT ( box->x == 12 ); - TASSERT ( box->y == 13 ); + widget_move ( WIDGET(box), 12, 13 ); + TASSERT ( box->widget.x == 12 ); + TASSERT ( box->widget.y == 13 ); textbox_free ( box ); textbox_cleanup ( );