mirror of
https://github.com/davatorium/rofi.git
synced 2024-11-25 13:55:34 -05:00
Make scrollbar behave better
This commit is contained in:
parent
163934fa8c
commit
fb459e1660
8 changed files with 64 additions and 51 deletions
|
@ -46,16 +46,16 @@ typedef struct
|
||||||
*/
|
*/
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
TB_AUTOHEIGHT = 1 << 0,
|
TB_AUTOHEIGHT = 1 << 0,
|
||||||
TB_AUTOWIDTH = 1 << 1,
|
TB_AUTOWIDTH = 1 << 1,
|
||||||
TB_LEFT = 1 << 16,
|
TB_LEFT = 1 << 16,
|
||||||
TB_RIGHT = 1 << 17,
|
TB_RIGHT = 1 << 17,
|
||||||
TB_CENTER = 1 << 18,
|
TB_CENTER = 1 << 18,
|
||||||
TB_EDITABLE = 1 << 19,
|
TB_EDITABLE = 1 << 19,
|
||||||
TB_MARKUP = 1 << 20,
|
TB_MARKUP = 1 << 20,
|
||||||
TB_WRAP = 1 << 21,
|
TB_WRAP = 1 << 21,
|
||||||
TB_PASSWORD = 1 << 22,
|
TB_PASSWORD = 1 << 22,
|
||||||
TB_INDICATOR = 1 << 23,
|
TB_INDICATOR = 1 << 23,
|
||||||
} TextboxFlags;
|
} TextboxFlags;
|
||||||
/**
|
/**
|
||||||
* Flags indicating current state of the textbox.
|
* Flags indicating current state of the textbox.
|
||||||
|
|
|
@ -36,7 +36,7 @@ struct _widget
|
||||||
void ( *update )( struct _widget * );
|
void ( *update )( struct _widget * );
|
||||||
|
|
||||||
/** Handle mouse motion, used for dragging */
|
/** Handle mouse motion, used for dragging */
|
||||||
gboolean (*motion_notify)( struct _widget *, xcb_motion_notify_event_t * );
|
gboolean ( *motion_notify )( struct _widget *, xcb_motion_notify_event_t * );
|
||||||
|
|
||||||
/** widget clicked callback */
|
/** widget clicked callback */
|
||||||
widget_clicked_cb clicked;
|
widget_clicked_cb clicked;
|
||||||
|
|
|
@ -198,7 +198,7 @@ static char **read_hosts_file ( char ** retv, unsigned int *length )
|
||||||
// Reading one line per time.
|
// Reading one line per time.
|
||||||
while ( getline ( &buffer, &buffer_length, fd ) > 0 ) {
|
while ( getline ( &buffer, &buffer_length, fd ) > 0 ) {
|
||||||
// Evaluate one line.
|
// Evaluate one line.
|
||||||
unsigned int index = 0, ti = 0;
|
unsigned int index = 0, ti = 0;
|
||||||
char *token = buffer;
|
char *token = buffer;
|
||||||
|
|
||||||
// Tokenize it.
|
// Tokenize it.
|
||||||
|
|
|
@ -194,7 +194,7 @@ static GRegex * create_regex ( const char *input, int case_sensitive )
|
||||||
{
|
{
|
||||||
#define R( s ) g_regex_new ( s, G_REGEX_OPTIMIZE | ( ( case_sensitive ) ? 0 : G_REGEX_CASELESS ), 0, NULL )
|
#define R( s ) g_regex_new ( s, G_REGEX_OPTIMIZE | ( ( case_sensitive ) ? 0 : G_REGEX_CASELESS ), 0, NULL )
|
||||||
GRegex * retv = NULL;
|
GRegex * retv = NULL;
|
||||||
gchar *r;
|
gchar *r;
|
||||||
switch ( config.matching_method )
|
switch ( config.matching_method )
|
||||||
{
|
{
|
||||||
case MM_GLOB:
|
case MM_GLOB:
|
||||||
|
@ -234,7 +234,7 @@ GRegex **tokenize ( const char *input, int case_sensitive )
|
||||||
}
|
}
|
||||||
|
|
||||||
char *saveptr = NULL, *token;
|
char *saveptr = NULL, *token;
|
||||||
GRegex **retv = NULL;
|
GRegex **retv = NULL;
|
||||||
if ( !config.tokenize ) {
|
if ( !config.tokenize ) {
|
||||||
retv = g_malloc0 ( sizeof ( GRegex* ) * 2 );
|
retv = g_malloc0 ( sizeof ( GRegex* ) * 2 );
|
||||||
retv[0] = (GRegex *) create_regex ( input, case_sensitive );
|
retv[0] = (GRegex *) create_regex ( input, case_sensitive );
|
||||||
|
|
|
@ -65,11 +65,11 @@
|
||||||
#include "gitconfig.h"
|
#include "gitconfig.h"
|
||||||
|
|
||||||
// Pidfile.
|
// Pidfile.
|
||||||
char *pidfile = NULL;
|
char *pidfile = NULL;
|
||||||
const char *cache_dir = NULL;
|
const char *cache_dir = NULL;
|
||||||
|
|
||||||
/** global structure holding the keyboard status */
|
/** global structure holding the keyboard status */
|
||||||
struct xkb_stuff xkb = {
|
struct xkb_stuff xkb = {
|
||||||
.xcb_connection = NULL,
|
.xcb_connection = NULL,
|
||||||
.context = NULL,
|
.context = NULL,
|
||||||
.keymap = NULL,
|
.keymap = NULL,
|
||||||
|
@ -81,23 +81,23 @@ struct xkb_stuff xkb = {
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Path to the configuration file */
|
/** Path to the configuration file */
|
||||||
char *config_path = NULL;
|
char *config_path = NULL;
|
||||||
/** Array holding all activated modi. */
|
/** Array holding all activated modi. */
|
||||||
Mode **modi = NULL;
|
Mode **modi = NULL;
|
||||||
/** Number of activated modi in #modi array */
|
/** Number of activated modi in #modi array */
|
||||||
unsigned int num_modi = 0;
|
unsigned int num_modi = 0;
|
||||||
/** Current selected mode */
|
/** Current selected mode */
|
||||||
unsigned int curr_switcher = 0;
|
unsigned int curr_switcher = 0;
|
||||||
|
|
||||||
/** Glib main loop. */
|
/** Glib main loop. */
|
||||||
GMainLoop *main_loop = NULL;
|
GMainLoop *main_loop = NULL;
|
||||||
/** GWater xcb source, signalling events from the X server */
|
/** GWater xcb source, signalling events from the X server */
|
||||||
GWaterXcbSource *main_loop_source = NULL;
|
GWaterXcbSource *main_loop_source = NULL;
|
||||||
|
|
||||||
/** Flag indicating we are in dmenu mode. */
|
/** Flag indicating we are in dmenu mode. */
|
||||||
static int dmenu_mode = FALSE;
|
static int dmenu_mode = FALSE;
|
||||||
/** Rofi's return code */
|
/** Rofi's return code */
|
||||||
int return_code = EXIT_SUCCESS;
|
int return_code = EXIT_SUCCESS;
|
||||||
|
|
||||||
void process_result ( RofiViewState *state );
|
void process_result ( RofiViewState *state );
|
||||||
|
|
||||||
|
@ -352,7 +352,7 @@ static int add_mode ( const char * token )
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif // WINDOW_MODE
|
#endif // WINDOW_MODE
|
||||||
// SSh dialog
|
// SSh dialog
|
||||||
if ( strcasecmp ( token, "ssh" ) == 0 ) {
|
if ( strcasecmp ( token, "ssh" ) == 0 ) {
|
||||||
modi[num_modi] = &ssh_mode;
|
modi[num_modi] = &ssh_mode;
|
||||||
num_modi++;
|
num_modi++;
|
||||||
|
|
|
@ -82,16 +82,29 @@ void scrollbar_set_handle_length ( scrollbar *sb, unsigned int pos_length )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 )
|
static void scrollbar_draw ( widget *wid, cairo_t *draw )
|
||||||
{
|
{
|
||||||
scrollbar *sb = (scrollbar *) wid;
|
scrollbar *sb = (scrollbar *) wid;
|
||||||
// Calculate position and size.
|
// Calculate position and size.
|
||||||
const short bh = sb->widget.h;
|
unsigned int r = ( sb->length * wid->h ) / ( (double) ( sb->length + sb->pos_length ) );
|
||||||
float sec = ( ( bh ) / (float) ( sb->length + sb->pos_length - 2 ) );
|
unsigned int handle = wid->h - r;
|
||||||
short height = sb->pos_length * sec;
|
double sec = ( ( r ) / (double) ( sb->length - 1 ) );
|
||||||
short y = sb->pos * sec;
|
unsigned int height = handle;
|
||||||
|
unsigned int y = sb->pos * sec;
|
||||||
// Set max pos.
|
// Set max pos.
|
||||||
y = MIN ( y, bh );
|
y = MIN ( y, wid->h - handle );
|
||||||
// Never go out of bar.
|
// Never go out of bar.
|
||||||
height = MAX ( 2, height );
|
height = MAX ( 2, height );
|
||||||
// Cap length;
|
// Cap length;
|
||||||
|
@ -114,13 +127,14 @@ unsigned int scrollbar_clicked ( const scrollbar *sb, int y )
|
||||||
{
|
{
|
||||||
if ( sb != NULL ) {
|
if ( sb != NULL ) {
|
||||||
if ( y >= sb->widget.y && y <= ( sb->widget.y + sb->widget.h ) ) {
|
if ( y >= sb->widget.y && y <= ( sb->widget.y + sb->widget.h ) ) {
|
||||||
const short bh = sb->widget.h;
|
unsigned int r = ( sb->length * sb->widget.h ) / ( (double) ( sb->length + sb->pos_length ) );
|
||||||
float sec = ( ( bh ) / (float) ( sb->length + sb->pos_length ) );
|
unsigned int handle = sb->widget.h - r;
|
||||||
unsigned int half_handle = MAX ( 1, sec * ( sb->pos_length / 2.0 ) );
|
double sec = ( ( r ) / (double) ( sb->length - 1 ) );
|
||||||
|
unsigned int half_handle = handle / 2;
|
||||||
y -= sb->widget.y + half_handle;
|
y -= sb->widget.y + half_handle;
|
||||||
y = MIN ( MAX ( 0, y ), sb->widget.h - 2 * half_handle );
|
y = MIN ( MAX ( 0, y ), sb->widget.h - 2 * half_handle );
|
||||||
|
|
||||||
unsigned int sel = y / sec;
|
unsigned int sel = ( ( y ) / sec );
|
||||||
return MIN ( sel, sb->length - 1 );
|
return MIN ( sel, sb->length - 1 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,7 @@
|
||||||
|
|
||||||
#include <rofi.h>
|
#include <rofi.h>
|
||||||
/** Checks if the if x and y is inside rectangle. */
|
/** Checks if the if x and y is inside rectangle. */
|
||||||
#define INTERSECT( x,y, x1, y1, w1, h1 ) ( ( ((x) >= (x1)) && ((x) < (x1+w1)) ) && ( ((y) >= (y1)) && ((y) < (y1+h1)) ) )
|
#define INTERSECT( x, y, x1, y1, w1, h1 ) ( ( ( ( x ) >= ( x1 ) ) && ( ( x ) < ( x1 + w1 ) ) ) && ( ( ( y ) >= ( y1 ) ) && ( ( y ) < ( y1 + h1 ) ) ) )
|
||||||
#include "x11-helper.h"
|
#include "x11-helper.h"
|
||||||
#include "xkb-internal.h"
|
#include "xkb-internal.h"
|
||||||
|
|
||||||
|
|
|
@ -51,25 +51,24 @@ int main ( G_GNUC_UNUSED int argc, G_GNUC_UNUSED char **argv )
|
||||||
scrollbar_set_handle_length ( sb, 0);
|
scrollbar_set_handle_length ( sb, 0);
|
||||||
TASSERTE ( sb->pos_length, 1 );
|
TASSERTE ( sb->pos_length, 1 );
|
||||||
|
|
||||||
|
|
||||||
unsigned int cl = scrollbar_clicked ( sb, 10 );
|
unsigned int cl = scrollbar_clicked ( sb, 10 );
|
||||||
TASSERTE ( cl, 900);
|
TASSERTE ( cl, 1010);
|
||||||
cl = scrollbar_clicked ( sb, 20 );
|
cl = scrollbar_clicked ( sb, 20 );
|
||||||
TASSERTE ( cl, 1900);
|
TASSERTE ( cl, 2020);
|
||||||
cl = scrollbar_clicked ( sb, 0 );
|
cl = scrollbar_clicked ( sb, 0 );
|
||||||
TASSERTE ( cl, 0);
|
TASSERTE ( cl, 0);
|
||||||
cl = scrollbar_clicked ( sb, 99 );
|
cl = scrollbar_clicked ( sb, 99 );
|
||||||
TASSERTE ( cl, 9800);
|
TASSERTE ( cl, 9999);
|
||||||
|
scrollbar_set_handle_length ( sb, 1000);
|
||||||
|
cl = scrollbar_clicked ( sb, 10 );
|
||||||
|
TASSERTE ( cl, 555);
|
||||||
|
cl = scrollbar_clicked ( sb, 20 );
|
||||||
|
TASSERTE ( cl, 1666);
|
||||||
|
cl = scrollbar_clicked ( sb, 0 );
|
||||||
|
TASSERTE ( cl, 0);
|
||||||
|
cl = scrollbar_clicked ( sb, 99 );
|
||||||
|
TASSERTE ( cl, 9999);
|
||||||
|
|
||||||
scrollbar_set_max_value ( sb, 100 );
|
|
||||||
for ( unsigned int i = 1; i < 99; i++ ){
|
|
||||||
cl = scrollbar_clicked ( sb, i );
|
|
||||||
TASSERTE ( cl, i-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
scrollbar_set_max_value ( sb, 200 );
|
|
||||||
for ( unsigned int i = 1; i < 100; i++ ){
|
|
||||||
cl = scrollbar_clicked ( sb, i );
|
|
||||||
TASSERTE ( cl, i*2-2);
|
|
||||||
}
|
|
||||||
widget_free( WIDGET (sb ) );
|
widget_free( WIDGET (sb ) );
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue