mirror of
https://github.com/davatorium/rofi.git
synced 2024-11-18 13:54:36 -05:00
Add window widget, play with logic for sizing (broken)
This commit is contained in:
parent
2db879e979
commit
a2001d1b9c
10 changed files with 316 additions and 44 deletions
|
@ -31,6 +31,7 @@ rofi_SOURCES=\
|
|||
source/history.c\
|
||||
source/theme.c\
|
||||
source/widgets/box.c\
|
||||
source/widgets/window.c\
|
||||
source/widgets/widget.c\
|
||||
source/widgets/textbox.c\
|
||||
source/widgets/listview.c\
|
||||
|
@ -62,6 +63,7 @@ rofi_SOURCES=\
|
|||
include/history.h\
|
||||
include/theme.h\
|
||||
include/widgets/box.h\
|
||||
include/widgets/window.h\
|
||||
include/widgets/widget.h\
|
||||
include/widgets/widget-internal.h\
|
||||
include/widgets/textbox.h\
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#ifndef ROFI_VIEW_INTERNAL_H
|
||||
#define ROFI_VIEW_INTERNAL_H
|
||||
#include "widgets/window.h"
|
||||
#include "widgets/widget.h"
|
||||
#include "widgets/textbox.h"
|
||||
#include "widgets/separator.h"
|
||||
|
@ -24,6 +25,7 @@ struct RofiViewState
|
|||
/** Flag indicating if view needs to be refiltered. */
|
||||
int refilter;
|
||||
|
||||
window *main_window;
|
||||
/** Main #box widget holding different elements. */
|
||||
box *main_box;
|
||||
/** #box widget packing the input bar widgets. */
|
||||
|
|
|
@ -57,4 +57,13 @@ struct _widget
|
|||
|
||||
void widget_init ( widget *widget , const char *name, const char *class_name );
|
||||
void widget_set_state ( widget *widget, const char *state );
|
||||
|
||||
int widget_padding_get_left ( const widget *wid );
|
||||
int widget_padding_get_right ( const widget *wid );
|
||||
int widget_padding_get_top ( const widget *wid );
|
||||
int widget_padding_get_bottom ( const widget *wid );
|
||||
int widget_padding_get_remaining_width ( const widget *wid );
|
||||
int widget_padding_get_remaining_height ( const widget *wid );
|
||||
int widget_padding_get_padding_height ( const widget *wid );
|
||||
int widget_padding_get_padding_width ( const widget *wid );
|
||||
#endif // WIDGET_INTERNAL_H
|
||||
|
|
37
include/widgets/window.h
Normal file
37
include/widgets/window.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
#ifndef ROFI_WINDOW_H
|
||||
#define ROFI_WINDOW_H
|
||||
|
||||
#include "widget.h"
|
||||
|
||||
/**
|
||||
* @defgroup window window
|
||||
* @ingroup widget
|
||||
*
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Abstract handle to the window widget internal state.
|
||||
*/
|
||||
typedef struct _window window;
|
||||
|
||||
/**
|
||||
* @param name The name of the widget.
|
||||
* @param type The packing direction of the newly created window.
|
||||
*
|
||||
* @returns a newly created window, free with #widget_free
|
||||
*/
|
||||
window * window_create ( const char *name );
|
||||
|
||||
/**
|
||||
* @param window Handle to the window widget.
|
||||
* @param child Handle to the child widget to pack.
|
||||
*
|
||||
* Add a widget to the window.
|
||||
*/
|
||||
void window_add ( window *window, widget *child );
|
||||
|
||||
int window_get_border_width ( const window *window );
|
||||
/*@}*/
|
||||
#endif // ROFI_WINDOW_H
|
|
@ -23,7 +23,7 @@ WHITESPACE [[:space:]]
|
|||
WORD [[:alnum:]-]+
|
||||
STRING [[:print:]]+
|
||||
HEX [[:xdigit:]]
|
||||
NUMBER [[:digit:]]
|
||||
NUMBER [[:digit:]-]
|
||||
|
||||
%x PROPERTIES
|
||||
%x NAMESTR
|
||||
|
|
|
@ -298,9 +298,7 @@ static void rofi_view_window_update_size ( RofiViewState * state )
|
|||
CacheState.edit_draw = cairo_create ( CacheState.edit_surf );
|
||||
|
||||
// Should wrap main window in a widget.
|
||||
int width = state->width - 2*state->border - state->pad.left - state->pad.right;
|
||||
int height = state->height - 2*state->border - state->pad.top- state->pad.bottom;
|
||||
widget_resize ( WIDGET ( state->main_box ), width, height );
|
||||
widget_resize ( WIDGET ( state->main_window ), state->width, state->height );
|
||||
}
|
||||
|
||||
static gboolean rofi_view_reload_idle ( G_GNUC_UNUSED gpointer data )
|
||||
|
@ -388,7 +386,7 @@ void rofi_view_free ( RofiViewState *state )
|
|||
}
|
||||
// Do this here?
|
||||
// Wait for final release?
|
||||
widget_free ( WIDGET ( state->main_box ) );
|
||||
widget_free ( WIDGET ( state->main_window ) );
|
||||
widget_free ( WIDGET ( state->overlay ) );
|
||||
|
||||
g_free ( state->line_map );
|
||||
|
@ -775,7 +773,7 @@ static void update_callback ( textbox *t, unsigned int index, void *udata, TextB
|
|||
|
||||
void rofi_view_update ( RofiViewState *state )
|
||||
{
|
||||
if ( !widget_need_redraw ( WIDGET ( state->main_box ) ) && !widget_need_redraw ( WIDGET ( state->overlay ) ) ) {
|
||||
if ( !widget_need_redraw ( WIDGET ( state->main_window ) ) && !widget_need_redraw ( WIDGET ( state->overlay ) ) ) {
|
||||
return;
|
||||
}
|
||||
TICK ();
|
||||
|
@ -792,36 +790,17 @@ void rofi_view_update ( RofiViewState *state )
|
|||
}
|
||||
cairo_paint ( d );
|
||||
cairo_set_operator ( d, CAIRO_OPERATOR_OVER );
|
||||
color_background ( d );
|
||||
rofi_theme_get_color ( "@window" , "window" , NULL, "background", d );
|
||||
cairo_paint ( d );
|
||||
}
|
||||
else {
|
||||
// Paint the background.
|
||||
color_background ( d );
|
||||
rofi_theme_get_color ( "@window", "window" , NULL, "background", d );
|
||||
// Paint the background transparent.
|
||||
cairo_set_source_rgba ( d, 0,0,0,0.0);
|
||||
cairo_paint ( d );
|
||||
}
|
||||
TICK_N ( "Background" );
|
||||
color_border ( d );
|
||||
rofi_theme_get_color ( "@window", "window" , NULL, "foreground", d );
|
||||
|
||||
int bw = rofi_theme_get_integer ( "@window", "window", NULL, "border-width" , config.menu_bw);
|
||||
if ( bw > 0 ) {
|
||||
cairo_save ( d );
|
||||
cairo_set_line_width ( d, bw );
|
||||
cairo_rectangle ( d,
|
||||
bw / 2.0,
|
||||
bw / 2.0,
|
||||
state->width - bw,
|
||||
state->height - bw );
|
||||
cairo_stroke ( d );
|
||||
cairo_restore ( d );
|
||||
}
|
||||
|
||||
// Always paint as overlay over the background.
|
||||
cairo_set_operator ( d, CAIRO_OPERATOR_OVER );
|
||||
widget_draw ( WIDGET ( state->main_box ), d );
|
||||
widget_draw ( WIDGET ( state->main_window ), d );
|
||||
|
||||
if ( state->overlay ) {
|
||||
widget_draw ( WIDGET ( state->overlay ), d );
|
||||
|
@ -886,7 +865,7 @@ static void rofi_view_mouse_navigation ( RofiViewState *state, xcb_button_press_
|
|||
xcb_button_press_event_t rel = *xbe;
|
||||
rel.event_x -= state->pad.left;
|
||||
rel.event_y -= state->pad.top;
|
||||
if ( widget_clicked ( WIDGET ( state->main_box ), &rel ) ) {
|
||||
if ( widget_clicked ( WIDGET ( state->main_window ), &rel ) ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1278,9 +1257,7 @@ void rofi_view_itterrate ( RofiViewState *state, xcb_generic_event_t *ev, xkb_st
|
|||
|
||||
CacheState.edit_surf = cairo_xcb_surface_create ( xcb->connection, CacheState.edit_pixmap, visual, state->width, state->height );
|
||||
CacheState.edit_draw = cairo_create ( CacheState.edit_surf );
|
||||
int width = state->width - 2*state->border - state->pad.left - state->pad.right;
|
||||
int height = state->height - 2*state->border - state->pad.top- state->pad.bottom;
|
||||
widget_resize ( WIDGET ( state->main_box ), width, height );
|
||||
widget_resize ( WIDGET ( state->main_window ), state->width, state->height );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -1303,7 +1280,7 @@ void rofi_view_itterrate ( RofiViewState *state, xcb_generic_event_t *ev, xkb_st
|
|||
xcb_motion_notify_event_t xme = *( (xcb_motion_notify_event_t *) ev );
|
||||
xme.event_x -= state->pad.left;
|
||||
xme.event_y -= state->pad.top;
|
||||
if ( widget_motion_notify ( WIDGET ( state->main_box ), &xme ) ) {
|
||||
if ( widget_motion_notify ( WIDGET ( state->main_window ), &xme ) ) {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
@ -1377,13 +1354,33 @@ static int rofi_view_calculate_height ( RofiViewState *state )
|
|||
}
|
||||
if ( state->filtered_lines == 0 && !config.fixed_num_lines ) {
|
||||
widget_disable ( WIDGET ( state->input_bar_separator ) );
|
||||
widget_disable ( WIDGET ( state->list_view) );
|
||||
}
|
||||
else {
|
||||
widget_enable ( WIDGET ( state->input_bar_separator ) );
|
||||
widget_enable ( WIDGET ( state->list_view) );
|
||||
}
|
||||
height = listview_get_desired_height ( state->list_view );
|
||||
// Why not a factor 2 here?
|
||||
height += window_get_border_width ( state->main_window );
|
||||
height += box_get_fixed_pixels ( state->main_box );
|
||||
height += 2 * state->border +state->pad.top+state->pad.bottom;
|
||||
// How to merge this....
|
||||
int perc =0;
|
||||
widget *main_window = WIDGET ( state->main_window );
|
||||
if ( main_window->pad.top >= 0 ){
|
||||
height += main_window->pad.top;
|
||||
} else {
|
||||
perc -= main_window->pad.top;
|
||||
}
|
||||
if ( main_window->pad.bottom >= 0 ){
|
||||
height += main_window->pad.bottom;
|
||||
} else {
|
||||
perc -= main_window->pad.bottom;
|
||||
}
|
||||
if ( perc > 0){
|
||||
height = (100*height)/(100-perc);
|
||||
}
|
||||
printf("listview: %d\n", listview_get_desired_height ( state->list_view ));
|
||||
return height;
|
||||
}
|
||||
|
||||
|
@ -1438,8 +1435,6 @@ RofiViewState *rofi_view_create ( Mode *sw,
|
|||
|
||||
state->pad = (Padding){config.padding,config.padding, config.padding, config.padding, FALSE};
|
||||
state->pad = rofi_theme_get_padding ( "@window", "window", NULL, "padding", state->pad);
|
||||
//state->border = rofi_theme_get_integer ("@window", "window", NULL, "padding" , config.padding );
|
||||
state->border += rofi_theme_get_integer ("@window", "window", NULL, "border-width" , config.menu_bw);
|
||||
|
||||
// Request the lines to show.
|
||||
state->num_lines = mode_get_num_entries ( sw );
|
||||
|
@ -1449,8 +1444,9 @@ RofiViewState *rofi_view_create ( Mode *sw,
|
|||
// Get active monitor size.
|
||||
TICK_N ( "Get active monitor" );
|
||||
|
||||
state->main_window = window_create ( "window" );
|
||||
state->main_box = box_create ( "mainbox.box", BOX_VERTICAL );
|
||||
widget_move ( WIDGET ( state->main_box ), state->border+state->pad.left, state->border+state->pad.top );
|
||||
window_add ( state->main_window, WIDGET ( state->main_box ) );
|
||||
|
||||
// we need this at this point so we can get height.
|
||||
rofi_view_calculate_window_and_element_width ( state );
|
||||
|
@ -1541,7 +1537,7 @@ RofiViewState *rofi_view_create ( Mode *sw,
|
|||
|
||||
rofi_view_update ( state );
|
||||
xcb_map_window ( xcb->connection, CacheState.main_window );
|
||||
widget_queue_redraw ( WIDGET ( state->main_box ) );
|
||||
widget_queue_redraw ( WIDGET ( state->main_window ) );
|
||||
xcb_flush ( xcb->connection );
|
||||
if ( xcb->sncontext != NULL ) {
|
||||
sn_launchee_context_complete ( xcb->sncontext );
|
||||
|
@ -1557,11 +1553,12 @@ int rofi_view_error_dialog ( const char *msg, int markup )
|
|||
state->finalize = process_result;
|
||||
state->pad = (Padding){config.padding,config.padding, config.padding, config.padding, FALSE};
|
||||
state->pad = rofi_theme_get_padding ( "@window", "window", NULL, "padding", state->pad);
|
||||
// state->border = rofi_theme_get_integer ( "@window", "window", NULL, "padding" , config.padding );
|
||||
state->border += rofi_theme_get_integer ( "@window", "window", NULL, "border-width" , config.menu_bw);
|
||||
|
||||
rofi_view_calculate_window_and_element_width ( state );
|
||||
state->main_window = window_create ( "window" );
|
||||
state->main_box = box_create ( "mainbox.box", BOX_VERTICAL);
|
||||
window_add ( state->main_window, WIDGET ( state->main_box ) );
|
||||
widget_move ( WIDGET ( state->main_box ), state->border+state->pad.left, state->border+state->pad.top );
|
||||
state->text = textbox_create ( "message", ( TB_AUTOHEIGHT | TB_WRAP ) + ( ( markup ) ? TB_MARKUP : 0 ),
|
||||
NORMAL, ( msg != NULL ) ? msg : "" );
|
||||
|
@ -1579,7 +1576,7 @@ int rofi_view_error_dialog ( const char *msg, int markup )
|
|||
|
||||
// Display it.
|
||||
xcb_map_window ( xcb->connection, CacheState.main_window );
|
||||
widget_queue_redraw ( WIDGET ( state->main_box ) );
|
||||
widget_queue_redraw ( WIDGET ( state->main_window ) );
|
||||
|
||||
if ( xcb->sncontext != NULL ) {
|
||||
sn_launchee_context_complete ( xcb->sncontext );
|
||||
|
|
|
@ -75,7 +75,10 @@ static void vert_calculate_size ( box *b )
|
|||
}
|
||||
int rem_width = b->widget.w - b->widget.pad.left-b->widget.pad.right;
|
||||
int rem_height = b->widget.h - b->widget.pad.top-b->widget.pad.bottom;
|
||||
b->max_size += MAX ( 0, ( ( active_widgets - 1 ) * b->spacing ) );
|
||||
if ( active_widgets > 0 ){
|
||||
b->max_size += ( active_widgets - 1 ) * b->spacing;
|
||||
}
|
||||
printf("%d %d\n", rem_height, b->max_size);
|
||||
if ( b->max_size > rem_height ) {
|
||||
g_log ( LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Widgets to large (height) for box: %d %d", b->max_size, b->widget.h );
|
||||
return;
|
||||
|
@ -107,6 +110,7 @@ static void vert_calculate_size ( box *b )
|
|||
}
|
||||
rem -= expanding_widgets_size;
|
||||
index++;
|
||||
b->max_size += widget_padding_get_padding_height ( child);
|
||||
}
|
||||
else if ( child->end ) {
|
||||
bottom -= widget_get_height ( child );
|
||||
|
@ -122,6 +126,7 @@ static void vert_calculate_size ( box *b )
|
|||
}
|
||||
}
|
||||
}
|
||||
b->max_size += b->widget.pad.top+b->widget.pad.bottom;
|
||||
}
|
||||
static void hori_calculate_size ( box *b )
|
||||
{
|
||||
|
@ -175,6 +180,7 @@ static void hori_calculate_size ( box *b )
|
|||
}
|
||||
rem -= expanding_widgets_size;
|
||||
index++;
|
||||
b->max_size += widget_padding_get_padding_width ( child);
|
||||
}
|
||||
else if ( child->end ) {
|
||||
right -= widget_get_width ( child );
|
||||
|
@ -190,6 +196,7 @@ static void hori_calculate_size ( box *b )
|
|||
}
|
||||
}
|
||||
}
|
||||
b->max_size += b->widget.pad.left+b->widget.pad.right;
|
||||
}
|
||||
|
||||
static void box_draw ( widget *wid, cairo_t *draw )
|
||||
|
|
|
@ -248,7 +248,7 @@ 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 - lv->widget.pad.top-lv->widget.pad.bottom;
|
||||
int height = lv->widget.h - lv->widget.pad.top-lv->widget.pad.bottom;
|
||||
lv->max_rows = ( lv->spacing + height ) / ( lv->element_height + lv->spacing );
|
||||
lv->max_elements = lv->max_rows * lv->menu_columns;
|
||||
|
||||
|
@ -451,7 +451,7 @@ void listview_nav_page_next ( listview *lv )
|
|||
|
||||
unsigned int listview_get_desired_height ( listview *lv )
|
||||
{
|
||||
if ( lv == NULL ) {
|
||||
if ( lv == NULL || lv->widget.enabled == FALSE ) {
|
||||
return 0;
|
||||
}
|
||||
int h = lv->menu_lines;
|
||||
|
@ -459,7 +459,7 @@ unsigned int listview_get_desired_height ( listview *lv )
|
|||
h = MIN ( lv->menu_lines, lv->req_elements );
|
||||
}
|
||||
if ( h == 0 ) {
|
||||
return 0;
|
||||
return lv->widget.pad.top+lv->widget.pad.bottom;
|
||||
}
|
||||
return h * lv->element_height + ( h - 1 ) * lv->spacing+lv->widget.pad.top+lv->widget.pad.bottom;
|
||||
}
|
||||
|
|
|
@ -207,3 +207,61 @@ void widget_set_name ( widget *wid, const char *name )
|
|||
}
|
||||
wid->name = g_strdup ( name );
|
||||
}
|
||||
|
||||
int widget_padding_get_left ( const widget *wid )
|
||||
{
|
||||
if ( wid->pad.left < 0 ){
|
||||
return (wid->w*-wid->pad.left)/100;
|
||||
}
|
||||
return wid->pad.left;
|
||||
}
|
||||
int widget_padding_get_right ( const widget *wid )
|
||||
{
|
||||
if ( wid->pad.right < 0 ){
|
||||
return (wid->w*-wid->pad.right)/100;
|
||||
}
|
||||
return wid->pad.right;
|
||||
}
|
||||
int widget_padding_get_top ( const widget *wid )
|
||||
{
|
||||
if ( wid->pad.top < 0 ){
|
||||
return (wid->h*-wid->pad.top)/100;
|
||||
}
|
||||
return wid->pad.top;
|
||||
}
|
||||
int widget_padding_get_bottom ( const widget *wid )
|
||||
{
|
||||
if ( wid->pad.bottom < 0 ){
|
||||
return (wid->h*-wid->pad.bottom)/100;
|
||||
}
|
||||
return wid->pad.bottom;
|
||||
}
|
||||
|
||||
int widget_padding_get_remaining_width ( const widget *wid )
|
||||
{
|
||||
int width = wid->w;
|
||||
width -= widget_padding_get_left ( wid );
|
||||
width -= widget_padding_get_right ( wid );
|
||||
return width;
|
||||
}
|
||||
int widget_padding_get_remaining_height ( const widget *wid )
|
||||
{
|
||||
int height = wid->h;
|
||||
height -= widget_padding_get_top ( wid );
|
||||
height -= widget_padding_get_bottom ( wid );
|
||||
return height;
|
||||
}
|
||||
int widget_padding_get_padding_height ( const widget *wid )
|
||||
{
|
||||
int height = 0;
|
||||
height += widget_padding_get_top ( wid );
|
||||
height += widget_padding_get_bottom ( wid );
|
||||
return height;
|
||||
}
|
||||
int widget_padding_get_padding_width ( const widget *wid )
|
||||
{
|
||||
int width = 0;
|
||||
width += widget_padding_get_left ( wid );
|
||||
width += widget_padding_get_right ( wid );
|
||||
return width;
|
||||
}
|
||||
|
|
160
source/widgets/window.c
Normal file
160
source/widgets/window.c
Normal file
|
@ -0,0 +1,160 @@
|
|||
/**
|
||||
* rofi
|
||||
*
|
||||
* MIT/X11 License
|
||||
* Modified 2016 Qball Cow <qball@gmpclient.org>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include "widgets/widget.h"
|
||||
#include "widgets/widget-internal.h"
|
||||
#include "widgets/window.h"
|
||||
#include "theme.h"
|
||||
#include "settings.h"
|
||||
|
||||
#define LOG_DOMAIN "Widgets.Window"
|
||||
const char *WINDOW_CLASS_NAME = "@window";
|
||||
|
||||
/**
|
||||
* @param window Handle to the window widget.
|
||||
* @param spacing The spacing to apply.
|
||||
*
|
||||
* Set the spacing to apply between the children in pixels.
|
||||
*/
|
||||
void window_set_spacing ( window * window, unsigned int spacing );
|
||||
|
||||
struct _window
|
||||
{
|
||||
widget widget;
|
||||
widget *child;
|
||||
int border_width;
|
||||
};
|
||||
|
||||
static void window_update ( widget *wid );
|
||||
|
||||
|
||||
static void window_draw ( widget *wid, cairo_t *draw )
|
||||
{
|
||||
window *b = (window *) wid;
|
||||
|
||||
cairo_save ( draw );
|
||||
rofi_theme_get_color ( "@window", "window" , NULL, "foreground", draw );
|
||||
cairo_set_line_width ( draw, b->border_width );
|
||||
cairo_rectangle ( draw,
|
||||
b->border_width / 2.0,
|
||||
b->border_width / 2.0,
|
||||
wid->w - b->border_width,
|
||||
wid->h - b->border_width );
|
||||
cairo_stroke ( draw );
|
||||
cairo_restore ( draw );
|
||||
widget_draw ( b->child, draw );
|
||||
}
|
||||
|
||||
static void window_free ( widget *wid )
|
||||
{
|
||||
window *b = (window *) wid;
|
||||
|
||||
widget_free ( b->child );
|
||||
g_free ( b );
|
||||
}
|
||||
|
||||
void window_add ( window *window, widget *child )
|
||||
{
|
||||
if ( window == NULL ) {
|
||||
return;
|
||||
}
|
||||
window->child = child;
|
||||
child->parent = WIDGET ( window );
|
||||
widget_update ( WIDGET ( window ) );
|
||||
}
|
||||
|
||||
static void window_resize ( widget *widget, short w, short h )
|
||||
{
|
||||
window *b = (window *) widget;
|
||||
if ( b->widget.w != w || b->widget.h != h ) {
|
||||
b->widget.w = w;
|
||||
b->widget.h = h;
|
||||
widget_update ( widget );
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean window_clicked ( widget *wid, xcb_button_press_event_t *xbe, G_GNUC_UNUSED void *udata )
|
||||
{
|
||||
window *b = (window *) wid;
|
||||
if ( widget_intersect ( b->child, xbe->event_x, xbe->event_y ) ) {
|
||||
xcb_button_press_event_t rel = *xbe;
|
||||
rel.event_x -= b->child->x;
|
||||
rel.event_y -= b->child->y;
|
||||
return widget_clicked ( b->child, &rel );
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
static gboolean window_motion_notify ( widget *wid, xcb_motion_notify_event_t *xme )
|
||||
{
|
||||
window *b = (window *) wid;
|
||||
if ( widget_intersect ( b->child, xme->event_x, xme->event_y ) ) {
|
||||
xcb_motion_notify_event_t rel = *xme;
|
||||
rel.event_x -= b->child->x;
|
||||
rel.event_y -= b->child->y;
|
||||
return widget_motion_notify ( b->child, &rel );
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
window * window_create ( const char *name )
|
||||
{
|
||||
window *b = g_malloc0 ( sizeof ( window ) );
|
||||
// Initialize widget.
|
||||
widget_init ( WIDGET(b), name, WINDOW_CLASS_NAME);
|
||||
b->widget.draw = window_draw;
|
||||
b->widget.free = window_free;
|
||||
b->widget.resize = window_resize;
|
||||
b->widget.update = window_update;
|
||||
b->widget.clicked = window_clicked;
|
||||
b->widget.motion_notify = window_motion_notify;
|
||||
b->widget.enabled = TRUE;
|
||||
b->border_width = rofi_theme_get_integer (
|
||||
b->widget.class_name, b->widget.name, NULL, "border-width" , config.menu_bw);
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
static void window_update ( widget *wid )
|
||||
{
|
||||
window *b = (window *) wid;
|
||||
if ( b->child && b->child->enabled ){
|
||||
widget_resize ( WIDGET ( b->child ),
|
||||
widget_padding_get_remaining_width (WIDGET(b))-2*b->border_width,
|
||||
widget_padding_get_remaining_height (WIDGET(b))-2*b->border_width
|
||||
);
|
||||
widget_move ( WIDGET ( b->child ),
|
||||
b->border_width+widget_padding_get_left (WIDGET(b)),
|
||||
b->border_width+widget_padding_get_top (WIDGET(b))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
int window_get_border_width ( const window *window )
|
||||
{
|
||||
return window->border_width*2;
|
||||
}
|
Loading…
Reference in a new issue