Making widget class, moving stuff around

This commit is contained in:
Dave Davenport 2016-01-09 16:22:09 +01:00
parent 06c7f30b7e
commit d7dab65e5b
15 changed files with 137 additions and 111 deletions

View file

@ -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\

View file

@ -1,20 +1,14 @@
#ifndef ROFI_MAIN_H
#define ROFI_MAIN_H
#include <X11/X.h>
#include <X11/Xlib.h>
#include <glib.h>
#include <string.h>
#include <stdlib.h>
#include "textbox.h"
#include <cairo.h>
#include <cairo-xlib.h>
#include "timings.h"
#include "keyb.h"
#include "mode.h"
/**
* @defgroup Widgets Widgets
*/
/**
* @defgroup Main Main
* @{

View file

@ -1,6 +1,7 @@
#ifndef ROFI_SCROLLBAR_H
#define ROFI_SCROLLBAR_H
#include <cairo.h>
#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

View file

@ -6,6 +6,7 @@
#include <pango/pango-fontmap.h>
#include <pango/pangocairo.h>
#include <cairo.h>
#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

47
include/widget.h Normal file
View file

@ -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

View file

@ -1,5 +1,6 @@
#ifndef X11_ROFI_HELPER_H
#define X11_ROFI_HELPER_H
#include <cairo.h>
/**
* @defgroup X11Helper X11Helper

View file

@ -36,6 +36,7 @@
#include <errno.h>
#include "rofi.h"
#include "settings.h"
#include "textbox.h"
#include "dialogs/dmenu.h"
#include "helper.h"
#include "xrmoptions.h"

View file

@ -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"

View file

@ -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"

View file

@ -1,3 +1,6 @@
#include <stdio.h>
#include <glib.h>
#include <string.h>
#include "rofi.h"
#include "xrmoptions.h"
#include "x11-helper.h"

View file

@ -52,6 +52,7 @@
#include <libsn/sn.h>
#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;
}

View file

@ -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 );

View file

@ -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 );
}

27
source/widget.c Normal file
View file

@ -0,0 +1,27 @@
#include <glib.h>
#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;
}
}

View file

@ -11,6 +11,7 @@
#include <textbox.h>
#include <rofi.h>
#include <cairo-xlib.h>
#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 ( );