diff --git a/awesomerc.5.txt b/awesomerc.5.txt index a2bcafd76..f50350800 100644 --- a/awesomerc.5.txt +++ b/awesomerc.5.txt @@ -51,172 +51,6 @@ The current list of available widget is: Each widget as its own set of properties, described below, that can bet modified with the set() method. -PROGRESSBAR -~~~~~~~~~~~ -A progressbar widget can contain several bars, so some properties need a data section, -that means a title for the bar. For example, if you want to feed data to the `memory' bar -you want to do mywidget:set("data", "memory 100"), where memory will be the data section. -Using a new data section name will automatically create a new bar. - - -The following properties require a data section before the value: - -*data*:: - Feed with data. - -*fg*:: - Foreground color. - -*fg_off*:: - Color of unfilled area of bar. - -*bg*:: - Background color (between ticks; border_padding space). - -*bordercolor*:: - Border color. - -*fg_center*:: - Foreground center color. - -*fg_end*:: - Foreground end color. - -*min_value*:: - Minimum value. This or lower values, draw a 0% bar. - -*max_value*:: - Maximum value. This or higher values, draw a 100% bar. - -*reverse*:: - True to draw reverse. - - -The following properties do not require a data section before the value and applies to all bars inside -the widget: - -*gap*:: - Gap between borders. - -*ticks_count*:: - The number of ticks. - -*ticks_gap*:: - The gap between ticks. - -*border_padding*:: - The padding inside the border. - -*border_width*:: - The border width. - -*width*:: - The widget width. - -*height*:: - The widget height. - -*vertical*:: - If \'true\', bars are vertically aligned. If \'false\', horizontally. - -GRAPH -~~~~~ -A graph widget can display several data-graphs inside its widget-border. Some -properties need a data section, that means a title for the incoming data. For -example, if you want to feed \'mymemory\' data, you want to do -mywidget:set("data", "mymemory 100"). - - -The following properties require a data section before the value: - -*data*:: - Feed with data. - -*fg*:: - Foreground color. - -*fg_center*:: - Foreground center color. - -*fg_end*:: - Foreground end color. - -*vertical_gradient*:: - If \'true\', colorgradient shall be applied vertically. - -*max_value*:: - Maximum value. Bigger values gets truncated, unless \'scale\' is true. - -*scale*:: - Scales the graph acccording to incoming values bigger than \'max_value\'. - -*draw_style*:: - \'bottom\', \'top\' or \'line\'. - - -The following properties do not require a data section before the value: - -*width*:: - The widget width. - -*height*:: - The widget height. - -*bg*:: - Background color. - -*bordercolor*:: - Border color. - -*grow*:: - \'left\' or \'right\'. E.g. \'right\' means new values get added on the right of the widget. - -TAGLIST -~~~~~~~ -A taglist widget displays available tags and their state. - -*text_normal*:: - Text to display on normal clients. \'\' substitutes the tag's title. - -*text_focus*:: - Text to display on the focused client. \'<title/>\' gets substituted by the tag's title. - -*text_urgent*:: - Text to display on urgent clients. \'<title/>\' gets substituted by the tag's title. - -*show_empty*:: - \'true\' or \'false\'. If \'false\', empty tags won't get displayed. Selected tags are always displayed so. - -TASKLIST -~~~~~~~~ -A tasklist widget displays the titles of clients according to the \'show\' setting. - -*show*:: - \'tags\', \'focus\' or \'all\'. E.g. \'tags\' shows only clients of currently selected tags. - -*text_normal*:: - Text to display on normal clients. \'<title/>\' gets substituted by the client's title. - -*text_focus*:: - Text to display on the focused client. \'<title/>\' gets substituted by the client's title. - -*text_urgent*:: - Text to display on urgent clients. \'<title/>\' gets substituted by the client's title. - -*show_icons*:: - \'true\' or \'false\'. Set to \'true\' if client's icon (if one is avaiable) shall be displayed. - - -TEXTBOX -~~~~~~~ -A textbox displays text. - -*width*:: - Width of the widget. - -*text*:: - Text to display. - SEE ALSO -------- awesome(1) awesome-client(1) diff --git a/awesomerc.lua.in b/awesomerc.lua.in index 89de83c59..14f920b74 100644 --- a/awesomerc.lua.in +++ b/awesomerc.lua.in @@ -84,24 +84,24 @@ mytaglist:mouse_add(mouse.new({}, 3, function (object, tag) tag:view(not tag:iss mytaglist:mouse_add(mouse.new({ modkey }, 3, function (object, tag) awful.client.toggletag(tag) end)) mytaglist:mouse_add(mouse.new({ }, 4, awful.tag.viewnext)) mytaglist:mouse_add(mouse.new({ }, 5, awful.tag.viewprev)) -mytaglist:set("text_focus", "<bg color='"..bg_focus.."'/> <span color='"..fg_focus.."'><title/></span> ") +mytaglist:text_set({ ["focus"] = "<bg color='"..bg_focus.."'/> <span color='"..fg_focus.."'><title/></span> " }) -- Create a tasklist widget mytasklist = widget.new({ type = "tasklist", name = "mytasklist" }) mytasklist:mouse_add(mouse.new({ }, 1, function (object, c) c:focus_set(); c:raise() end)) mytasklist:mouse_add(mouse.new({ }, 4, function () awful.client.focus(1) end)) mytasklist:mouse_add(mouse.new({ }, 5, function () awful.client.focus(-1) end)) -mytasklist:set("text_focus", "<bg color='"..bg_focus.."'/> <span color='"..fg_focus.."'><title/></span> ") +mytasklist:text_set({ ["focus"] = "<bg color='"..bg_focus.."'/> <span color='"..fg_focus.."'><title/></span> " }) -- Create a textbox widget mytextbox = widget.new({ type = "textbox", name = "mytextbox", align = "right" }) -- Set the default text in textbox -mytextbox:set("text", "<b><small> awesome " .. AWESOME_VERSION .. " </small></b>") +mytextbox:text_set("<b><small> awesome " .. AWESOME_VERSION .. " </small></b>") mypromptbox = widget.new({ type = "textbox", name = "mypromptbox", align = "left" }) -- Create an iconbox widget myiconbox = widget.new({ type = "textbox", name = "myiconbox", align = "left" }) -myiconbox:set("text", "<bg image=\"@AWESOME_ICON_PATH@/awesome16.png\" resize=\"true\"/>") +myiconbox:text_set("<bg image=\"@AWESOME_ICON_PATH@/awesome16.png\" resize=\"true\"/>") -- Create a systray mysystray = widget.new({ type = "systray", name = "mysystray", align = "right" }) @@ -115,7 +115,7 @@ for s = 1, screen.count() do mylayoutbox[s]:mouse_add(mouse.new({ }, 3, function () awful.layout.inc(layouts, -1) end)) mylayoutbox[s]:mouse_add(mouse.new({ }, 4, function () awful.layout.inc(layouts, 1) end)) mylayoutbox[s]:mouse_add(mouse.new({ }, 5, function () awful.layout.inc(layouts, -1) end)) - mylayoutbox[s]:set("text", "<bg image=\"@AWESOME_ICON_PATH@/layouts/tilew.png\" resize=\"true\"/>") + mylayoutbox[s]:text_set("<bg image=\"@AWESOME_ICON_PATH@/layouts/tilew.png\" resize=\"true\"/>") end -- Create a statusbar for each screen and add it @@ -334,7 +334,7 @@ end -- (tag switch, new client, etc) function hook_arrange(screen) local layout = awful.layout.get(screen) - mylayoutbox[screen]:set("text", "<bg image=\"@AWESOME_ICON_PATH@/layouts/" .. layout .. "w.png\" resize=\"true\"/>") + mylayoutbox[screen]:text_set("<bg image=\"@AWESOME_ICON_PATH@/layouts/" .. layout .. "w.png\" resize=\"true\"/>") -- Uncomment if you want mouse warping --[[ @@ -356,9 +356,9 @@ end -- Hook called every second function hook_timer () -- For unix time_t lovers - mytextbox:set("text", " " .. os.time() .. " time_t ") + mytextbox:text_set(" " .. os.time() .. " time_t ") -- Otherwise use: - -- mytextbox:set("text", " " .. os.date() .. " ") + -- mytextbox:text_set(" " .. os.date() .. " ") end -- Set up some hooks diff --git a/common/tokenize.gperf b/common/tokenize.gperf index 2957233b6..85d64dd54 100644 --- a/common/tokenize.gperf +++ b/common/tokenize.gperf @@ -2,60 +2,43 @@ align all auto -bg -border_padding -border_width -bordercolor +bar_data_add +bar_properties_set bottom bottomleft bottomright center color -data -draw_style -fg -fg_center -fg_end -fg_off flex focus -gap -grow -height image left line -max_value -min_value mouse_add mouse_remove name_get name_set on +plot_data_add +plot_properties_set +properties_set resize -reverse right -scale -set shadow shadow_offset show -show_empty -show_icons +show_set +showempty_set +showicons_set tags text -text_focus -text_normal -text_urgent -ticks_count -ticks_gap +text_set top topleft topright true -vertical -vertical_gradient visible_get visible_set width +width_set yes diff --git a/dbus.c b/dbus.c index 3fb383700..d12295472 100644 --- a/dbus.c +++ b/dbus.c @@ -35,71 +35,6 @@ static DBusError err; static DBusConnection *dbus_connection = NULL; ev_io dbusio = { .fd = -1 }; -/** Check a dbus object path format and its number of element. - * \param path The path. - * \param nelem The number of element it should have. - * \return true if the path is ok, false otherwise. - */ -static bool -a_dbus_path_check(char **path, int nelem) -{ - int i; - - for(i = 0; path[i]; i++); - if(i != nelem) - return false; - - return (!a_strcmp(path[0], "org")&& !a_strcmp(path[1], "awesome")); -} - -/** Process widget.set method call. - * \param req The dbus message. - */ -static void -a_dbus_process_widget_set(DBusMessage *req) -{ - char *arg, **path; - int i; - DBusMessageIter iter; - widget_t *widget; - widget_tell_status_t status; - - if(!dbus_message_get_path_decomposed(req, &path) - || !a_dbus_path_check(path, 6) - || a_strcmp(path[2], "widget") - || a_strcmp(path[4], "property")) - { - warn("invalid object path."); - dbus_error_free(&err); - return; - } - - if(!dbus_message_iter_init(req, &iter)) - { - warn("message has no argument: %s", err.message); - dbus_error_free(&err); - return; - } - else if(DBUS_TYPE_STRING != dbus_message_iter_get_arg_type(&iter)) - { - warn("argument must be a string"); - dbus_error_free(&err); - return; - } - else - dbus_message_iter_get_basic(&iter, &arg); - - if(!(widget = widget_getbyname(path[3]))) - return warn("no such widget: %s.", path[3]); - - status = widget->tell(widget, path[5], arg); - widget_tell_managestatus(widget, status, path[5]); - - for(i = 0; path[i]; i++) - p_delete(&path[i]); - p_delete(&path); -} - static void a_dbus_process_requests(EV_P_ ev_io *w, int revents) { @@ -117,9 +52,7 @@ a_dbus_process_requests(EV_P_ ev_io *w, int revents) break; - if(dbus_message_is_method_call(msg, "org.awesome.widget", "set")) - a_dbus_process_widget_set(msg); - else if(dbus_message_is_signal(msg, DBUS_INTERFACE_LOCAL, "Disconnected")) + if(dbus_message_is_signal(msg, DBUS_INTERFACE_LOCAL, "Disconnected")) { a_dbus_cleanup(); dbus_message_unref(msg); diff --git a/structs.h b/structs.h index 96bd1f6f4..e1f7d2080 100644 --- a/structs.h +++ b/structs.h @@ -69,18 +69,6 @@ typedef widget_t *(widget_constructor_t)(alignment_t); typedef void (widget_destructor_t)(widget_t *); typedef struct awesome_t awesome_t; -/** Widget tell status code */ -typedef enum -{ - WIDGET_NOERROR = 0, - WIDGET_ERROR, - WIDGET_ERROR_NOVALUE, - WIDGET_ERROR_CUSTOM, - WIDGET_ERROR_FORMAT_FONT, - WIDGET_ERROR_FORMAT_COLOR, - WIDGET_ERROR_FORMAT_SECTION -} widget_tell_status_t; - /** Mouse buttons bindings */ struct button_t { @@ -112,8 +100,8 @@ struct widget_t widget_destructor_t *destructor; /** Draw function */ int (*draw)(draw_context_t *, int, widget_node_t *, int, int, void *); - /** Update function */ - widget_tell_status_t (*tell)(widget_t *, const char *, const char *); + /** Index function */ + int (*index)(lua_State *); /** ButtonPressedEvent handler */ void (*button_press)(widget_node_t *, xcb_button_press_event_t *, int, void *, awesome_type_t); /** Alignement */ diff --git a/widget.c b/widget.c index a18a8727e..34c3efe97 100644 --- a/widget.c +++ b/widget.c @@ -2,7 +2,6 @@ * widget.c - widget managing * * Copyright © 2007-2008 Julien Danjou <julien@danjou.info> - * Copyright © 2007 Aldo Cortesi <aldo@nullcube.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -58,26 +57,6 @@ widget_calculate_offset(int barwidth, int widgetwidth, int offset, int alignment return barwidth - offset - widgetwidth; } -/** Find a widget on a screen by its name. - * \param name The widget name. - * \return A widget pointer. - */ -widget_t * -widget_getbyname(const char *name) -{ - widget_node_t *widget; - statusbar_t *sb; - int screen; - - for(screen = 0; screen < globalconf.screens_info->nscreen; screen++) - for(sb = globalconf.screens[screen].statusbar; sb; sb = sb->next) - for(widget = sb->widgets; widget; widget = widget->next) - if(!a_strcmp(name, widget->widget->name)) - return widget->widget; - - return NULL; -} - /** Common function for button press event on widget. * It will look into configuration to find the callback function to call. * \param w The widget node. @@ -103,22 +82,6 @@ widget_common_button_press(widget_node_t *w, } } -/** Common tell function for widget, which only warn user that widget - * cannot be told anything. - * \param widget The widget. - * \param property Unused argument. - * \param new_value Unused argument. - * \return The status of the command, which is always an error in this case. - */ -static widget_tell_status_t -widget_common_tell(widget_t *widget, - const char *property __attribute__ ((unused)), - const char *new_value __attribute__ ((unused))) -{ - warn("%s widget does not accept commands.", widget->name); - return WIDGET_ERROR_CUSTOM; -} - /** Render a list of widgets. * \param wnode The list of widgets. * \param ctx The draw context where to render. @@ -238,7 +201,6 @@ void widget_common_new(widget_t *widget) { widget->align = AlignLeft; - widget->tell = widget_common_tell; widget->button_press = widget_common_button_press; } @@ -269,7 +231,7 @@ widget_invalidate_cache(int screen, int flags) * \todo Probably needs more optimization. * \param widget The widget to look for. */ -static void +void widget_invalidate_bywidget(widget_t *widget) { int screen; @@ -371,67 +333,6 @@ luaA_widget_mouse_remove(lua_State *L) return 0; } -/** Do what should be done with a widget_tell_status_t for a widget. - * \param widget The widget. - * \param status The status returned by the tell function of the widget. - * \param property The property updated. - */ -void -widget_tell_managestatus(widget_t *widget, widget_tell_status_t status, const char *property) -{ - switch(status) - { - case WIDGET_ERROR: - warn("error changing property %s of widget %s", - property, widget->name); - break; - case WIDGET_ERROR_NOVALUE: - warn("error changing property %s of widget %s, no value given", - property, widget->name); - break; - case WIDGET_ERROR_FORMAT_FONT: - warn("error changing property %s of widget %s, must be a valid font", - property, widget->name); - break; - case WIDGET_ERROR_FORMAT_COLOR: - warn("error changing property %s of widget %s, must be a valid color", - property, widget->name); - break; - case WIDGET_ERROR_FORMAT_SECTION: - warn("error changing property %s of widget %s, section/title not found", - property, widget->name); - break; - case WIDGET_NOERROR: - widget_invalidate_bywidget(widget); - break; - case WIDGET_ERROR_CUSTOM: - break; - } -} - -/** Set a widget property. Each widget type has its own set of property. - * \param L The Lua VM state. - * - * \luastack - * \lvalue A widget. - * \lparam The property name. - * \lparam The property value. - */ -static int -luaA_widget_set(lua_State *L) -{ - widget_t **widget = luaA_checkudata(L, 1, "widget"); - const char *property, *value; - widget_tell_status_t status; - - property = luaL_checkstring(L, 2); - value = luaL_checkstring(L, 3); - - status = (*widget)->tell(*widget, property, value); - widget_tell_managestatus(*widget, status, property); - return 0; -} - /** Convert a widget into a printable string. * \param L The Lua VM state. * @@ -513,6 +414,7 @@ luaA_widget_visible_get(lua_State *L) static int luaA_widget_index(lua_State *L) { + widget_t **widget = luaA_checkudata(L, 1, "widget"); size_t len; const char *str = luaL_checklstring(L, 2, &len); @@ -524,9 +426,6 @@ luaA_widget_index(lua_State *L) case A_TK_MOUSE_REMOVE: lua_pushcfunction(L, luaA_widget_mouse_remove); return 1; - case A_TK_SET: - lua_pushcfunction(L, luaA_widget_set); - return 1; case A_TK_NAME_SET: lua_pushcfunction(L, luaA_widget_name_set); return 1; @@ -540,6 +439,8 @@ luaA_widget_index(lua_State *L) lua_pushcfunction(L, luaA_widget_visible_get); return 1; default: + if((*widget)->index) + return (*widget)->index(L); return 0; } } @@ -553,7 +454,6 @@ const struct luaL_reg awesome_widget_meta[] = { { "mouse_add", luaA_widget_mouse_add }, { "mouse_remove", luaA_widget_mouse_remove }, - { "set", luaA_widget_set }, { "name_set", luaA_widget_name_set }, { "name_get", luaA_widget_name_get }, { "visible_set", luaA_widget_visible_set }, diff --git a/widget.h b/widget.h index 3b538abc9..d5f993f50 100644 --- a/widget.h +++ b/widget.h @@ -2,7 +2,6 @@ * widget.h - widget managing header * * Copyright © 2007-2008 Julien Danjou <julien@danjou.info> - * Copyright © 2007 Aldo Cortesi <aldo@nullcube.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -33,12 +32,12 @@ void widget_invalidate_cache(int, int); int widget_calculate_offset(int, int, int, int); void widget_common_new(widget_t *); -widget_t * widget_getbyname(const char *); -void widget_tell_managestatus(widget_t *, widget_tell_status_t, const char *); void widget_render(widget_node_t *, draw_context_t *, xcb_gcontext_t, xcb_drawable_t, int, position_t, int, int, void *); int luaA_widget_userdata_new(lua_State *, widget_t *); +void widget_invalidate_bywidget(widget_t *); + widget_constructor_t taglist_new; widget_constructor_t textbox_new; widget_constructor_t progressbar_new; diff --git a/widgets/graph.c b/widgets/graph.c index 1d6c69938..13b612295 100644 --- a/widgets/graph.c +++ b/widgets/graph.c @@ -34,13 +34,14 @@ typedef enum Bottom_Style = 0, Top_Style, Line_Style -} draw_style_t; +} plot_style_t; -typedef struct graph_t graph_t; +typedef struct plot_t plot_t; -struct graph_t +/** The plot data structure. */ +struct plot_t { - /** Grapht title of the data sections */ + /** Grapht title of the plot sections */ char *title; /** Represents a full graph */ float max_value; @@ -55,7 +56,7 @@ struct graph_t /** Pointer to current maximum value itself */ float current_max; /** Draw style of according index */ - draw_style_t draw_style; + plot_style_t draw_style; /** Keeps the calculated values (line-length); */ int *lines; /** Actual values */ @@ -69,11 +70,11 @@ struct graph_t /** Create a vertical color gradient */ bool vertical_gradient; /** Next and previous graph */ - graph_t *next, *prev; + plot_t *next, *prev; }; static void -graph_delete(graph_t **g) +plot_delete(plot_t **g) { p_delete(&(*g)->title); p_delete(&(*g)->lines); @@ -83,7 +84,7 @@ graph_delete(graph_t **g) p_delete(g); } -DO_SLIST(graph_t, graph, graph_delete) +DO_SLIST(plot_t, plot, plot_delete) typedef struct { @@ -106,12 +107,11 @@ typedef struct /** Preparation/tmp array for draw_graph(); */ int *draw_to; /** Graph list */ - graph_t *graphs; + plot_t *plots; } graph_data_t; -/* the same as the progressbar_pcolor_set may use a common function */ static void -graph_pcolor_set(xcolor_t **ppcolor, char *new_color) +plot_pcolor_set(xcolor_t **ppcolor, const char *new_color) { bool flag = false; if(!*ppcolor) @@ -126,22 +126,26 @@ graph_pcolor_set(xcolor_t **ppcolor, char *new_color) p_delete(ppcolor); } -static graph_t * -graph_data_add(graph_data_t *d, const char *new_data_title) +/** Add a plot to a graph. + * \param d The graph private data. + * \param title The plot title. + * \return A new plot. + */ +static plot_t * +graph_plot_add(graph_data_t *d, const char *title) { - graph_t *graph = p_new(graph_t, 1); + plot_t *plot = p_new(plot_t, 1); - /* memory (re-)allocating + initialising */ - graph->values = p_new(float, d->size); - graph->lines = p_new(int, d->size); - graph->max_value = 100.0; - graph->title = a_strdup(new_data_title); - graph->color_start = globalconf.colors.fg; - graph->vertical_gradient = true; + plot->title = a_strdup(title); + plot->values = p_new(float, d->size); + plot->lines = p_new(int, d->size); + plot->max_value = 100.0; + plot->color_start = globalconf.colors.fg; + plot->vertical_gradient = true; - graph_list_append(&d->graphs, graph); + plot_list_append(&d->plots, plot); - return graph; + return plot; } static int @@ -155,9 +159,9 @@ graph_draw(draw_context_t *ctx, int margin_top, y; graph_data_t *d = w->widget->data; area_t rectangle, pattern_area; - graph_t *graph; + plot_t *plot; - if(!d->graphs) + if(!d->plots) return 0; w->area.x = widget_calculate_offset(ctx->width, @@ -165,7 +169,7 @@ graph_draw(draw_context_t *ctx, w->widget->align); w->area.y = 0; - /* box = the graph inside the rectangle */ + /* box = the plot inside the rectangle */ if(!d->box_height) d->box_height = round(ctx->height * d->height) - 2; @@ -178,7 +182,7 @@ graph_draw(draw_context_t *ctx, rectangle.height = d->box_height; draw_rectangle(ctx, rectangle, 1.0, true, d->bg); - /* for graph drawing */ + /* for plot drawing */ rectangle.y = margin_top + d->box_height + 1; /* bottom left corner as starting point */ rectangle.width = d->size; /* rectangle.height is not used */ @@ -190,12 +194,12 @@ graph_draw(draw_context_t *ctx, else pattern_area.x = rectangle.x; - for(graph = d->graphs; graph; graph = graph->next) - switch(graph->draw_style) + for(plot = d->plots; plot; plot = plot->next) + switch(plot->draw_style) { case Top_Style: pattern_area.y = rectangle.y - rectangle.height; - if(graph->vertical_gradient) + if(plot->vertical_gradient) { pattern_area.width = 0; pattern_area.height = rectangle.height; @@ -203,25 +207,25 @@ graph_draw(draw_context_t *ctx, else { pattern_area.height = 0; - + if(d->grow == Right) pattern_area.width = - rectangle.width; else pattern_area.width = rectangle.width; } - + for(y = 0; y < d->size; y++) { /* reverse values (because drawing from top) */ d->draw_from[y] = d->box_height; /* i.e. no smaller value -> from top of box */ - d->draw_to[y] = d->box_height - graph->lines[y]; /* i.e. on full graph -> 0 = bottom */ + d->draw_to[y] = d->box_height - plot->lines[y]; /* i.e. on full plot -> 0 = bottom */ } - draw_graph(ctx, rectangle , d->draw_from, d->draw_to, graph->index, d->grow, pattern_area, - &graph->color_start, graph->pcolor_center, graph->pcolor_end); + draw_graph(ctx, rectangle , d->draw_from, d->draw_to, plot->index, d->grow, pattern_area, + &plot->color_start, plot->pcolor_center, plot->pcolor_end); break; case Bottom_Style: pattern_area.y = rectangle.y; - if(graph->vertical_gradient) + if(plot->vertical_gradient) { pattern_area.width = 0; pattern_area.height = - rectangle.height; @@ -229,20 +233,20 @@ graph_draw(draw_context_t *ctx, else { pattern_area.height = 0; - + if(d->grow == Right) pattern_area.width = - rectangle.width; else pattern_area.width = rectangle.width; } - + p_clear(d->draw_from, d->size); - draw_graph(ctx, rectangle, d->draw_from, graph->lines, graph->index, d->grow, pattern_area, - &graph->color_start, graph->pcolor_center, graph->pcolor_end); + draw_graph(ctx, rectangle, d->draw_from, plot->lines, plot->index, d->grow, pattern_area, + &plot->color_start, plot->pcolor_center, plot->pcolor_end); break; case Line_Style: pattern_area.y = rectangle.y; - if(graph->vertical_gradient) + if(plot->vertical_gradient) { pattern_area.width = 0; pattern_area.height = -rectangle.height; @@ -255,9 +259,9 @@ graph_draw(draw_context_t *ctx, else pattern_area.width = rectangle.width; } - - draw_graph_line(ctx, rectangle, graph->lines, graph->index, d->grow, pattern_area, - &graph->color_start, graph->pcolor_center, graph->pcolor_end); + + draw_graph_line(ctx, rectangle, plot->lines, plot->index, d->grow, pattern_area, + &plot->color_start, plot->pcolor_center, plot->pcolor_end); break; } @@ -273,191 +277,249 @@ graph_draw(draw_context_t *ctx, return w->area.width; } -static widget_tell_status_t -graph_tell(widget_t *widget, const char *property, const char *new_value) +/** Set various graph general properties. + * \param L The Lua VM state. + * \return The number of elements pushed on stack. + * \lstack + * \lvalue A widget. + * \lparam A table with various properties set. + */ +static int +luaA_graph_properties_set(lua_State *L) { - graph_data_t *d = widget->data; - graph_t *graph; - int i; - float value; - char *title, *setting; - char *new_val; - awesome_token_t prop = a_tokenize(property, -1); + widget_t **widget = luaA_checkudata(L, 1, "widget"); + graph_data_t *d = (*widget)->data; + plot_t *plot; + int width; + const char *buf; + size_t len; + position_t pos; - if(!new_value) - return WIDGET_ERROR_NOVALUE; + luaA_checktable(L, 2); - switch (prop) { - default: - return WIDGET_ERROR; + d->height = luaA_getopt_number(L, 2, "height", d->height); - case A_TK_HEIGHT: - d->height = atof(new_value); - return WIDGET_NOERROR; - case A_TK_WIDTH: - d->width = atoi(new_value); + width = luaA_getopt_number(L, 2, "width", d->width); + if(width != d->width) + { + d->width = width; d->size = d->width - 2; - /* re-allocate/initialise necessary values */ - for(graph = d->graphs; graph; graph = graph->next) + for(plot = d->plots; plot; plot = plot->next) { - p_realloc(&graph->values, d->size); - p_realloc(&graph->lines, d->size); - p_clear(graph->values, d->size); - p_clear(graph->lines, d->size); - graph->index = 0; - graph->current_max = 0; - graph->max_index = 0; + p_realloc(&plot->values, d->size); + p_realloc(&plot->lines, d->size); + p_clear(plot->values, d->size); + p_clear(plot->lines, d->size); + plot->index = 0; + plot->current_max = 0; + plot->max_index = 0; } - return WIDGET_NOERROR; - case A_TK_BG: - if(!xcolor_new(globalconf.connection, - globalconf.default_screen, - new_value, &d->bg)) - return WIDGET_ERROR_FORMAT_COLOR; - return WIDGET_NOERROR; - case A_TK_BORDERCOLOR: - if(!xcolor_new(globalconf.connection, - globalconf.default_screen, - new_value, &d->bordercolor)) - return WIDGET_ERROR_FORMAT_COLOR; - return WIDGET_NOERROR; - case A_TK_GROW: - switch((d->grow = position_fromstr(new_value, -1))) + } + + if((buf = luaA_getopt_string(L, 2, "bg", NULL))) + xcolor_new(globalconf.connection, globalconf.default_screen, buf, &d->bg); + if((buf = luaA_getopt_string(L, 2, "bordercolor", NULL))) + xcolor_new(globalconf.connection, globalconf.default_screen, buf, &d->bordercolor); + + if((buf = luaA_getopt_lstring(L, 2, "grow", NULL, &len))) + switch((pos = position_fromstr(buf, len))) { case Left: case Right: - return WIDGET_NOERROR; - default: - warn("error changing property %s of widget %s, must be 'left' or 'right'", - property, widget->name); - return WIDGET_ERROR_CUSTOM; - } - case A_TK_DATA: - case A_TK_FG: - case A_TK_FG_CENTER: - case A_TK_FG_END: - case A_TK_VERTICAL_GRADIENT: - case A_TK_SCALE: - case A_TK_MAX_VALUE: - case A_TK_DRAW_STYLE: - /* check if this section is defined already */ - new_val = a_strdup(new_value); - title = strtok(new_val, " "); - if(!(setting = strtok(NULL, " "))) - { - p_delete(&new_val); - return WIDGET_ERROR_NOVALUE; - } - for(graph = d->graphs; graph; graph = graph->next) - if(!a_strcmp(title, graph->title)) - break; - /* no section found -> create one */ - if(!graph) - graph = graph_data_add(d, title); - break; - } - - switch (prop) { - case A_TK_DATA: - /* assign incoming value */ - value = MAX(atof(setting), 0); - - if(++graph->index >= d->size) /* cycle inside the array */ - graph->index = 0; - - if(graph->scale) /* scale option is true */ - { - graph->values[graph->index] = value; - - if(value > graph->current_max) /* a new maximum value found */ - { - graph->max_index = graph->index; - graph->current_max = value; - - /* recalculate */ - for (i = 0; i < d->size; i++) - graph->lines[i] = round(graph->values[i] * d->box_height / graph->current_max); - } - /* old max_index reached + current_max > normal, re-check/generate */ - else if(graph->max_index == graph->index - && graph->current_max > graph->max_value) - { - /* find the new max */ - for(i = 0; i < d->size; i++) - if(graph->values[i] > graph->values[graph->max_index]) - graph->max_index = i; - - graph->current_max = MAX(graph->values[graph->max_index], graph->max_value); - - /* recalculate */ - for(i = 0; i < d->size; i++) - graph->lines[i] = round(graph->values[i] * d->box_height / graph->current_max); - } - else - graph->lines[graph->index] = round(value * d->box_height / graph->current_max); - } - else /* scale option is false - limit to d->box_height */ - { - if(value < graph->max_value) - graph->lines[graph->index] = round(value * d->box_height / graph->max_value); - else - graph->lines[graph->index] = d->box_height; - } - break; - case A_TK_FG: - xcolor_new(globalconf.connection, globalconf.default_screen, setting, &graph->color_start); - break; - case A_TK_FG_CENTER: - graph_pcolor_set(&graph->pcolor_center, setting); - break; - case A_TK_FG_END: - graph_pcolor_set(&graph->pcolor_end, setting); - break; - case A_TK_VERTICAL_GRADIENT: - graph->vertical_gradient = a_strtobool(setting, -1); - break; - case A_TK_SCALE: - graph->scale = a_strtobool(setting, -1); - break; - case A_TK_MAX_VALUE: - graph->max_value = atof(setting); - graph->current_max = graph->max_value; - break; - case A_TK_DRAW_STYLE: - switch (a_tokenize(setting, -1)) { - case A_TK_BOTTOM: - graph->draw_style = Bottom_Style; - break; - case A_TK_LINE: - graph->draw_style = Line_Style; - break; - case A_TK_TOP: - graph->draw_style = Top_Style; + d->grow = pos; break; default: - warn("'error changing property %s of widget %s, must be 'bottom', 'top' or 'line'", - property, widget->name); break; } - break; - default: - break; - } - p_delete(&new_val); - return WIDGET_NOERROR; + + widget_invalidate_bywidget(*widget); + + return 0; } +/** Set various plot graph properties. + * \param L The Lua VM state. + * \return The number of elements pushed on stack. + * \lstack + * \lvalue A widget. + * \lparam A plot name. + * \lparam A table with various properties set. + */ +static int +luaA_graph_plot_properties_set(lua_State *L) +{ + widget_t **widget = luaA_checkudata(L, 1, "widget"); + graph_data_t *d = (*widget)->data; + float max_value; + const char *title, *buf; + size_t len; + plot_t *plot; + + title = luaL_checkstring(L, 2); + luaA_checktable(L, 3); + + for(plot = d->plots; plot; plot = plot->next) + if(!a_strcmp(title, plot->title)) + break; + /* no plot found -> create one */ + if(!plot) + plot = graph_plot_add(d, title); + + if((buf = luaA_getopt_string(L, 3, "fg", NULL))) + xcolor_new(globalconf.connection, globalconf.default_screen, buf, &plot->color_start); + if((buf = luaA_getopt_string(L, 3, "fg_center", NULL))) + plot_pcolor_set(&plot->pcolor_center, buf); + if((buf = luaA_getopt_string(L, 3, "fg_end", NULL))) + plot_pcolor_set(&plot->pcolor_end, buf); + + plot->vertical_gradient = luaA_getopt_boolean(L, 3, "vertical_gradient", plot->vertical_gradient); + plot->scale = luaA_getopt_boolean(L, 3, "scale", plot->scale); + + max_value = luaA_getopt_number(L, 3, "max_value", plot->max_value); + if(max_value != plot->max_value) + plot->max_value = plot->current_max = max_value; + + if((buf = luaA_getopt_lstring(L, 3, "style", NULL, &len))) + switch (a_tokenize(buf, len)) + { + case A_TK_BOTTOM: + plot->draw_style = Bottom_Style; + break; + case A_TK_LINE: + plot->draw_style = Line_Style; + break; + case A_TK_TOP: + plot->draw_style = Top_Style; + break; + default: + break; + } + + widget_invalidate_bywidget(*widget); + + return 0; +} + +/** Add data to a plot. + * \param l The Lua VM state. + * \return The number of elements pushed on stack. + * \lstack + * \lvalue A widget. + * \lparam A plot name. + * \lparam A data value. + */ +static int +luaA_graph_plot_data_add(lua_State *L) +{ + widget_t **widget = luaA_checkudata(L, 1, "widget"); + graph_data_t *d = (*widget)->data; + plot_t *plot; + const char *title = luaL_checkstring(L, 2); + float value; + int i; + + for(plot = d->plots; plot; plot = plot->next) + if(!a_strcmp(title, plot->title)) + break; + + /* no plot found -> create one */ + if(!plot) + plot = graph_plot_add(d, title); + + /* assign incoming value */ + value = MAX(luaL_checknumber(L, 3), 0); + + if(++plot->index >= d->size) /* cycle inside the array */ + plot->index = 0; + + if(plot->scale) /* scale option is true */ + { + plot->values[plot->index] = value; + + if(value > plot->current_max) /* a new maximum value found */ + { + plot->max_index = plot->index; + plot->current_max = value; + + /* recalculate */ + for (i = 0; i < d->size; i++) + plot->lines[i] = round(plot->values[i] * d->box_height / plot->current_max); + } + /* old max_index reached + current_max > normal, re-check/generate */ + else if(plot->max_index == plot->index + && plot->current_max > plot->max_value) + { + /* find the new max */ + for(i = 0; i < d->size; i++) + if(plot->values[i] > plot->values[plot->max_index]) + plot->max_index = i; + + plot->current_max = MAX(plot->values[plot->max_index], plot->max_value); + + /* recalculate */ + for(i = 0; i < d->size; i++) + plot->lines[i] = round(plot->values[i] * d->box_height / plot->current_max); + } + else + plot->lines[plot->index] = round(value * d->box_height / plot->current_max); + } + else /* scale option is false - limit to d->box_height */ + { + if(value < plot->max_value) + plot->lines[plot->index] = round(value * d->box_height / plot->max_value); + else + plot->lines[plot->index] = d->box_height; + } + + widget_invalidate_bywidget(*widget); + + return 0; +} + +/** Index function for graph widget. + * \param L The Lua VM state. + * \return The number of elements pushed on stack. + */ +static int +luaA_graph_index(lua_State *L) +{ + size_t len; + const char *attr = luaL_checklstring(L, 2, &len); + + switch(a_tokenize(attr, len)) + { + case A_TK_PROPERTIES_SET: + lua_pushcfunction(L, luaA_graph_properties_set); + return 1; + case A_TK_PLOT_PROPERTIES_SET: + lua_pushcfunction(L, luaA_graph_plot_properties_set); + return 1; + case A_TK_PLOT_DATA_ADD: + lua_pushcfunction(L, luaA_graph_plot_data_add); + return 1; + default: + return 0; + } +} + +/** Destroy definitively a graph widget. + * \param widget Who slay. + */ static void graph_destructor(widget_t *widget) { graph_data_t *d = widget->data; - graph_list_wipe(&d->graphs); + plot_list_wipe(&d->plots); p_delete(&d->draw_from); p_delete(&d->draw_to); p_delete(&d); } +/** Create a brand new graph. + * \param align The widget alignment. + * \return A graph widget. + */ widget_t * graph_new(alignment_t align) { @@ -468,7 +530,7 @@ graph_new(alignment_t align) widget_common_new(w); w->draw = graph_draw; - w->tell = graph_tell; + w->index = luaA_graph_index; w->destructor = graph_destructor; w->align = align; d = w->data = p_new(graph_data_t, 1); diff --git a/widgets/progressbar.c b/widgets/progressbar.c index 7b1b114b9..a907623b6 100644 --- a/widgets/progressbar.c +++ b/widgets/progressbar.c @@ -28,6 +28,7 @@ extern awesome_t globalconf; typedef struct bar_t bar_t; +/** Progressbar bar data structure */ struct bar_t { /** Title of the data/bar */ @@ -56,6 +57,9 @@ struct bar_t bar_t *next, *prev; }; +/** Delete a bar. + * \param bar The bar to annihilate. + */ static void bar_delete(bar_t **bar) { @@ -67,6 +71,7 @@ bar_delete(bar_t **bar) DO_SLIST(bar_t, bar, bar_delete) +/** Progressbar private data structure */ typedef struct { /** Width of the data_items */ @@ -90,7 +95,7 @@ typedef struct } progressbar_data_t; static void -progressbar_pcolor_set(xcolor_t **ppcolor, char *new_color) +progressbar_pcolor_set(xcolor_t **ppcolor, const char *new_color) { bool flag = false; if(!*ppcolor) @@ -105,13 +110,16 @@ progressbar_pcolor_set(xcolor_t **ppcolor, char *new_color) p_delete(ppcolor); } +/** Add a new bar to the progressbar private data structure. + * \param d The private data structure. + * \param title The graph title. + */ static bar_t * -progressbar_data_add(progressbar_data_t *d, const char *new_data_title) +progressbar_bar_add(progressbar_data_t *d, const char *title) { bar_t *bar = p_new(bar_t, 1); - bar->title = a_strdup(new_data_title); - + bar->title = a_strdup(title); bar->fg = globalconf.colors.fg; bar->fg_off = globalconf.colors.bg; bar->bg = globalconf.colors.bg; @@ -124,6 +132,15 @@ progressbar_data_add(progressbar_data_t *d, const char *new_data_title) return bar; } +/** Draw a progressbar. + * \param ctx The draw context. + * \param screen The screen we're drawing for. + * \param w The widget node we're drawing for. + * \param offset Offset to draw at. + * \param used Space already used. + * \param object The object pointer we're drawing onto. + * \return The width used. + */ static int progressbar_draw(draw_context_t *ctx, int screen __attribute__ ((unused)), @@ -399,132 +416,161 @@ progressbar_draw(draw_context_t *ctx, return w->area.width; } -static widget_tell_status_t -progressbar_tell(widget_t *widget, const char *property, const char *new_value) +/** Set various progressbar general properties: + * gap, ticks_count, ticks_gap, border_padding, border_width, width, height and + * vertical. + * \param L The Lua VM state. + * \return The number of elements pushed on the stack. + * \lstack + * \lvalue A widget. + * \lparam A table with keys as properties names. + */ +int +luaA_progressbar_properties_set(lua_State *L) { - progressbar_data_t *d = widget->data; - int value; - char *title, *setting; - char *new_val; - bar_t *bar; - awesome_token_t prop = a_tokenize(property, -1); + widget_t **widget = luaA_checkudata(L, 1, "widget"); + progressbar_data_t *d = (*widget)->data; - if(!new_value) - return WIDGET_ERROR_NOVALUE; + luaA_checktable(L, 2); - switch (prop) - { - case A_TK_GAP: - d->gap = atoi(new_value); - return WIDGET_NOERROR; - case A_TK_TICKS_COUNT: - d->ticks_count = atoi(new_value); - return WIDGET_NOERROR; - case A_TK_TICKS_GAP: - d->ticks_gap = atoi(new_value); - return WIDGET_NOERROR; - case A_TK_BORDER_PADDING: - d->border_padding = atoi(new_value); - return WIDGET_NOERROR; - case A_TK_BORDER_WIDTH: - d->border_width = atoi(new_value); - return WIDGET_NOERROR; - case A_TK_WIDTH: - d->width = atoi(new_value); - return WIDGET_NOERROR; - case A_TK_HEIGHT: - d->height = atof(new_value); - return WIDGET_NOERROR; - case A_TK_VERTICAL: - d->vertical = a_strtobool(new_value, -1); - return WIDGET_NOERROR; + d->gap = luaA_getopt_number(L, 2, "gap", d->gap); + d->ticks_count = luaA_getopt_number(L, 2, "ticks_count", d->ticks_count); + d->ticks_gap = luaA_getopt_number(L, 2, "ticks_gap", d->ticks_gap); + d->border_padding = luaA_getopt_number(L, 2, "border_padding", d->border_padding); + d->border_width = luaA_getopt_number(L, 2, "border_width", d->border_width); + d->width = luaA_getopt_number(L, 2, "width", d->width); + d->height = luaA_getopt_number(L, 2, "height", d->height); - /* following properties need a datasection */ - case A_TK_FG: - case A_TK_DATA: - case A_TK_FG_OFF: - case A_TK_BG: - case A_TK_BORDERCOLOR: - case A_TK_FG_CENTER: - case A_TK_FG_END: - case A_TK_MIN_VALUE: - case A_TK_MAX_VALUE: - case A_TK_REVERSE: - /* check if this section is defined already */ - new_val = a_strdup(new_value); - title = strtok(new_val, " "); - if(!(setting = strtok(NULL, " "))) - { - p_delete(&new_val); - return WIDGET_ERROR_NOVALUE; - } - for(bar = d->bars; bar; bar = bar->next) - if(!a_strcmp(title, bar->title)) - break; + d->vertical = luaA_getopt_boolean(L, 2, "vertical", d->vertical); - /* no section found -> create one */ - if(!bar) - bar = progressbar_data_add(d, title); - break; + widget_invalidate_bywidget(*widget); - default: - return WIDGET_ERROR; - } - - switch (prop) - { - case A_TK_DATA: - value = atof(setting); - bar->value = (value < bar->min_value ? bar->min_value : - (value > bar->max_value ? bar->max_value : value)); - break; - case A_TK_FG: - xcolor_new(globalconf.connection, globalconf.default_screen, setting, &bar->fg); - break; - case A_TK_BG: - xcolor_new(globalconf.connection, globalconf.default_screen, setting, &bar->bg); - break; - case A_TK_FG_OFF: - xcolor_new(globalconf.connection, globalconf.default_screen, setting, &bar->fg_off); - break; - case A_TK_BORDERCOLOR: - xcolor_new(globalconf.connection, globalconf.default_screen, setting, &bar->bordercolor); - break; - case A_TK_FG_CENTER: - progressbar_pcolor_set(&bar->pfg_center, setting); - break; - case A_TK_FG_END: - progressbar_pcolor_set(&bar->pfg_end, setting); - break; - case A_TK_MIN_VALUE: - bar->min_value = atof(setting); - /* hack to prevent max_value beeing less than min_value - * and also preventing a division by zero when both are equal */ - if(bar->max_value <= bar->min_value) - bar->max_value = bar->max_value + 0.0001; - /* force a actual value into the newly possible range */ - if(bar->value < bar->min_value) - bar->value = bar->min_value; - break; - case A_TK_MAX_VALUE: - bar->max_value = atof(setting); - if(bar->min_value >= bar->max_value) - bar->min_value = bar->max_value - 0.0001; - if(bar->value > bar->max_value) - bar->value = bar->max_value; - break; - case A_TK_REVERSE: - bar->reverse = a_strtobool(setting, -1); - break; - default: - return WIDGET_ERROR; - } - - p_delete(&new_val); - - return WIDGET_NOERROR; + return 0; } +/** Set various progressbar bars properties: + * \param L The Lua VM state. + * \return The number of elements pushed on the stack. + * \lstack + * \lvalue A widget. + * \lparam A bar name. + * \lparam A table with keys as properties names. + */ +int +luaA_progressbar_bar_properties_set(lua_State *L) +{ + widget_t **widget = luaA_checkudata(L, 1, "widget"); + const char *buf, *title = luaL_checkstring(L, 2); + bar_t *bar; + progressbar_data_t *d = (*widget)->data; + + luaA_checktable(L, 3); + + /* check if this section is defined already */ + for(bar = d->bars; bar; bar = bar->next) + if(!a_strcmp(title, bar->title)) + break; + + /* no bar found -> create one */ + if(!bar) + bar = progressbar_bar_add(d, title); + + if((buf = luaA_getopt_string(L, 3, "fg", NULL))) + xcolor_new(globalconf.connection, globalconf.default_screen, buf, &bar->fg); + if((buf = luaA_getopt_string(L, 3, "bg", NULL))) + xcolor_new(globalconf.connection, globalconf.default_screen, buf, &bar->bg); + if((buf = luaA_getopt_string(L, 3, "fg_off", NULL))) + xcolor_new(globalconf.connection, globalconf.default_screen, buf, &bar->fg_off); + if((buf = luaA_getopt_string(L, 3, "border_color", NULL))) + xcolor_new(globalconf.connection, globalconf.default_screen, buf, &bar->bordercolor); + if((buf = luaA_getopt_string(L, 3, "fg_center", NULL))) + progressbar_pcolor_set(&bar->pfg_center, buf); + if((buf = luaA_getopt_string(L, 3, "fg_end", NULL))) + progressbar_pcolor_set(&bar->pfg_end, buf); + + bar->min_value = luaA_getopt_number(L, 3, "min_value", bar->min_value); + /* hack to prevent max_value beeing less than min_value + * and also preventing a division by zero when both are equal */ + if(bar->max_value <= bar->min_value) + bar->max_value = bar->max_value + 0.0001; + /* force a actual value into the newly possible range */ + if(bar->value < bar->min_value) + bar->value = bar->min_value; + + bar->max_value = luaA_getopt_number(L, 3, "max_value", bar->max_value); + if(bar->min_value >= bar->max_value) + bar->min_value = bar->max_value - 0.0001; + if(bar->value > bar->max_value) + bar->value = bar->max_value; + + bar->reverse = luaA_getopt_boolean(L, 3, "reverse", bar->reverse); + + widget_invalidate_bywidget(*widget); + + return 0; +} + +/** Add a value to a progressbar bar. + * \param L The Lua VM state. + * \return The number of elements pushed on the stack. + * \lstack + * \lvalue A widget. + * \lparam A bar name. + * \lparam A data value. + */ +int +luaA_progressbar_bar_data_add(lua_State *L) +{ + widget_t **widget = luaA_checkudata(L, 1, "widget"); + const char *title = luaL_checkstring(L, 2); + progressbar_data_t *d = (*widget)->data; + bar_t *bar; + + /* check if this section is defined already */ + for(bar = d->bars; bar; bar = bar->next) + if(!a_strcmp(title, bar->title)) + break; + + /* no bar found -> create one */ + if(!bar) + bar = progressbar_bar_add(d, title); + + bar->value = MAX(bar->min_value, MIN(bar->max_value, luaL_checknumber(L, 3))); + + widget_invalidate_bywidget(*widget); + + return 0; +} + +/** Index function for progressbar. + * \param L The Lua VM state. + * \return The number of elements pushed on the stack. + */ +static int +luaA_progressbar_index(lua_State *L) +{ + size_t len; + const char *attr = luaL_checklstring(L, 2, &len); + + switch(a_tokenize(attr, len)) + { + case A_TK_PROPERTIES_SET: + lua_pushcfunction(L, luaA_progressbar_properties_set); + return 1; + case A_TK_BAR_PROPERTIES_SET: + lua_pushcfunction(L, luaA_progressbar_bar_properties_set); + return 1; + case A_TK_BAR_DATA_ADD: + lua_pushcfunction(L, luaA_progressbar_bar_data_add); + return 1; + default: + return 0; + } +} + +/** Destroy a progressbar. + * \param widget The widget to kill. + */ static void progressbar_destructor(widget_t *widget) { @@ -534,6 +580,10 @@ progressbar_destructor(widget_t *widget) p_delete(&d); } +/** Create a new progressbar. + * \param align Alignment of the widget. + * \return A brand new progressbar. + */ widget_t * progressbar_new(alignment_t align) { @@ -544,7 +594,7 @@ progressbar_new(alignment_t align) widget_common_new(w); w->align = align; w->draw = progressbar_draw; - w->tell = progressbar_tell; + w->index = luaA_progressbar_index; w->destructor = progressbar_destructor; d = w->data = p_new(progressbar_data_t, 1); diff --git a/widgets/taglist.c b/widgets/taglist.c index e883cd7cc..f296b128a 100644 --- a/widgets/taglist.c +++ b/widgets/taglist.c @@ -1,7 +1,7 @@ /* * taglist.c - tag list widget * - * Copyright © 2007 Aldo Cortesi <aldo@nullcube.com> + * Copyright © 2008 Julien Danjou <julien@danjou.info> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -30,6 +30,9 @@ extern awesome_t globalconf; +/** Data type used to store where we draw the taglist for a particular object. + * This is filled in the draw function, and use later when we get a click. + */ typedef struct taglist_drawn_area_t taglist_drawn_area_t; struct taglist_drawn_area_t { @@ -38,6 +41,9 @@ struct taglist_drawn_area_t taglist_drawn_area_t *next, *prev; }; +/** Delete a taglist_drawn_area_t object. + * \param a The drawn area to delete. + */ static void taglist_drawn_area_delete(taglist_drawn_area_t **a) { @@ -47,14 +53,21 @@ taglist_drawn_area_delete(taglist_drawn_area_t **a) DO_SLIST(taglist_drawn_area_t, taglist_drawn_area, taglist_drawn_area_delete); +/** Taglist widget private data */ typedef struct { char *text_normal, *text_focus, *text_urgent; bool show_empty; taglist_drawn_area_t *drawn_area; - } taglist_data_t; + +/** Called when a markup element is encountered. + * \param p The parser data. + * \param elem The element. + * \param names The element attributes names. + * \param values The element attributes values. + */ static void tag_markup_on_elem(markup_parser_data_t *p, const char *elem, const char **names, const char **values) @@ -63,7 +76,12 @@ tag_markup_on_elem(markup_parser_data_t *p, const char *elem, buffer_add_xmlescaped(&p->text, NONULL(p->priv)); } - +/** Parse a markup string. + * \param t The tag we're parsing for. + * \param str The string we're parsing. + * \param len The string length. + * \return The parsed string. + */ static char * tag_markup_parse(tag_t *t, const char *str, ssize_t len) { @@ -88,10 +106,9 @@ tag_markup_parse(tag_t *t, const char *str, ssize_t len) return ret; } -/** Check if at least one client is tagged with tag number t and is on screen - * screen - * \param t tag - * \return true or false +/** Check if at least one client is tagged with tag number t. + * \param t The tag to check. + * \return True if the tag has a client, false otherwise. */ static bool tag_isoccupied(tag_t *t) @@ -99,24 +116,33 @@ tag_isoccupied(tag_t *t) client_t *c; for(c = globalconf.clients; c; c = c->next) - if(is_client_tagged(c, t) && !c->skip) + if(!c->skip && is_client_tagged(c, t)) return true; return false; } +/** Check if a tag has at least one client with urgency hint. + * \param t The tag. + * \return True if the tag has a client with urgency set, false otherwise. + */ static bool tag_isurgent(tag_t *t) { client_t *c; for(c = globalconf.clients; c; c = c->next) - if(is_client_tagged(c, t) && c->isurgent) + if(c->isurgent && is_client_tagged(c, t)) return true; return false; } +/** Get the string to use for drawing the tag. + * \param tag The tag. + * \param data The taglist private data. + * \return The string to use. + */ static char * taglist_text_get(tag_t *tag, taglist_data_t *data) { @@ -124,10 +150,18 @@ taglist_text_get(tag_t *tag, taglist_data_t *data) return data->text_focus; else if(tag_isurgent(tag)) return data->text_urgent; - return data->text_normal; } +/** Draw a taglist. + * \param ctx The draw context. + * \param screen The screen we're drawing for. + * \param w The widget node we're drawing for. + * \param offset Offset to draw at. + * \param used Space already used. + * \param object The object pointer we're drawing onto. + * \return The width used. + */ static int taglist_draw(draw_context_t *ctx, int screen, widget_node_t *w, int offset, @@ -180,7 +214,7 @@ taglist_draw(draw_context_t *ctx, int screen, widget_node_t *w, /* Now that we have widget width we can compute widget x coordinate */ w->area.x = widget_calculate_offset(ctx->width, w->area.width, - offset, w->widget->align); + offset, w->widget->align); for(int i = 0; i < tags->len; i++) { @@ -254,34 +288,92 @@ taglist_button_press(widget_node_t *w, } } -static widget_tell_status_t -taglist_tell(widget_t *widget, const char *property, const char *new_value) +/** Set text format string in case of a tag is normal, has focused client + * or has a client with urgency hint. + * \param L The Lua VM state. + * \return The number of elements pushed on stack. + * \lstack + * \lvalue A widget. + * \lparam A table with keys to change: `normal', `focus' and `urgent'. + */ +static int +luaA_taglist_text_set(lua_State *L) { - taglist_data_t *d = widget->data; + widget_t **widget = luaA_checkudata(L, 1, "widget"); + taglist_data_t *d = (*widget)->data; + const char *buf; - switch(a_tokenize(property, -1)) + luaA_checktable(L, 2); + + if((buf = luaA_getopt_string(L, 2, "normal", NULL))) { - case A_TK_TEXT_NORMAL: p_delete(&d->text_normal); - d->text_normal = a_strdup(new_value); - break; - case A_TK_TEXT_FOCUS: - p_delete(&d->text_focus); - d->text_focus = a_strdup(new_value); - break; - case A_TK_TEXT_URGENT: - p_delete(&d->text_urgent); - d->text_urgent = a_strdup(new_value); - break; - case A_TK_SHOW_EMPTY: - d->show_empty = a_strtobool(new_value, -1); - break; - default: - return WIDGET_ERROR; + d->text_normal = a_strdup(buf); } - return WIDGET_NOERROR; + + if((buf = luaA_getopt_string(L, 2, "focus", NULL))) + { + p_delete(&d->text_focus); + d->text_focus = a_strdup(buf); + } + + if((buf = luaA_getopt_string(L, 2, "urgent", NULL))) + { + p_delete(&d->text_urgent); + d->text_urgent = a_strdup(buf); + } + + widget_invalidate_bywidget(*widget); + + return 0; } +/** Set if the taglist must show the tags which have no client. + * \param L The Lua VM state. + * \return The number of elements pushed on stack. + * \lstack + * \lvalue A widget. + * \lparam A boolean value, true to show empty tags, false otherwise. + */ +static int +luaA_taglist_showempty_set(lua_State *L) +{ + widget_t **widget = luaA_checkudata(L, 1, "widget"); + taglist_data_t *d = (*widget)->data; + + d->show_empty = luaA_checkboolean(L, 2); + + widget_invalidate_bywidget(*widget); + + return 0; +} + +/** Index function for taglist. + * \param L The Lua VM state. + * \return The number of elements pushed on stack. + */ +int +luaA_taglist_index(lua_State *L) +{ + size_t len; + const char *attr = luaL_checklstring(L, 2, &len); + + switch(a_tokenize(attr, len)) + { + case A_TK_TEXT_SET: + lua_pushcfunction(L, luaA_taglist_text_set); + return 1; + case A_TK_SHOWEMPTY_SET: + lua_pushcfunction(L, luaA_taglist_showempty_set); + return 1; + default: + return 0; + } +} + +/** Taglist destructor. + * \param widget The widget to destroy. + */ static void taglist_destructor(widget_t *widget) { @@ -294,6 +386,10 @@ taglist_destructor(widget_t *widget) p_delete(&d); } +/** Create a brand new taglist widget. + * \param align Widget alignment. + * \return A taglist widget. + */ widget_t * taglist_new(alignment_t align) { @@ -302,10 +398,10 @@ taglist_new(alignment_t align) w = p_new(widget_t, 1); widget_common_new(w); + w->index = luaA_taglist_index; w->align = align; w->draw = taglist_draw; w->button_press = taglist_button_press; - w->tell = taglist_tell; w->destructor = taglist_destructor; w->data = d = p_new(taglist_data_t, 1); diff --git a/widgets/tasklist.c b/widgets/tasklist.c index abc93f412..a225e9b12 100644 --- a/widgets/tasklist.c +++ b/widgets/tasklist.c @@ -39,6 +39,7 @@ typedef enum ShowAll, } showclient_t; +/** The tasklist private data structure. */ typedef struct { showclient_t show; @@ -46,6 +47,18 @@ typedef struct char *text_normal, *text_urgent, *text_focus; } tasklist_data_t; +struct tasklist_hook_data +{ + draw_context_t *ctx; + area_t *area; +}; + +/** Check if a client is visible according to the showclient type paramater. + * \param c The client. + * \param screen The screen number. + * \param show The show parameters. + * \return True if the client is visible, false otherwise. + */ static inline bool tasklist_isvisible(client_t *c, int screen, showclient_t show) { @@ -64,12 +77,12 @@ tasklist_isvisible(client_t *c, int screen, showclient_t show) return false; } -struct tasklist_hook_data -{ - draw_context_t *ctx; - area_t *area; -}; - +/** Called when a markup element is found. + * \param p The markup parser data. + * \param elem The element name. + * \param names The attributes names. + * \param values The attributes values. + */ static void tasklist_markup_on_elem(markup_parser_data_t *p, const char *elem, const char **names, const char **values) @@ -88,11 +101,18 @@ tasklist_markup_on_elem(markup_parser_data_t *p, const char *elem, } } - +/** Draw a tasklist widget. + * \param ctx The draw context. + * \param screen The screen number. + * \param w The widget node we are called from. + * \param offset The offset to draw at. + * \param used The already used width. + * \param p A pointer to the object we're drawing onto. + */ static int tasklist_draw(draw_context_t *ctx, int screen, widget_node_t *w, - int offset, int used, void *q __attribute__ ((unused))) + int offset, int used, void *p __attribute__ ((unused))) { client_t *c; tasklist_data_t *d = w->widget->data; @@ -139,7 +159,7 @@ tasklist_draw(draw_context_t *ctx, int screen, { static char const * const elements[] = { "bg", NULL }; struct tasklist_hook_data data = { .ctx = ctx, .area = &area }; - markup_parser_data_t p = + markup_parser_data_t pdata = { .elements = elements, .on_element = &tasklist_markup_on_elem, @@ -154,9 +174,9 @@ tasklist_draw(draw_context_t *ctx, int screen, /* Actually look for the proper background color, since * otherwise the background statusbar color is used instead */ - markup_parser_data_init(&p); - markup_parse(&p, text, a_strlen(text)); - markup_parser_data_wipe(&p); + markup_parser_data_init(&pdata); + markup_parse(&pdata, text, a_strlen(text)); + markup_parser_data_wipe(&pdata); if((image = draw_image_new(c->icon_path))) { @@ -257,50 +277,126 @@ tasklist_button_press(widget_node_t *w, } } -static widget_tell_status_t -tasklist_tell(widget_t *widget, const char *property, const char *new_value) +/** Set the tasklist show attribute. + * \param L The Lua VM state. + * \return The number of elements pushed on stack. + * \lstack + * \lvalue A widget. + * \lparam A string: tags, focus or all. + */ +static int +luaA_tasklist_show_set(lua_State *L) { - tasklist_data_t *d = widget->data; + size_t len; + widget_t **widget = luaA_checkudata(L, 1, "widget"); + tasklist_data_t *d = (*widget)->data; + const char *buf = luaL_checklstring(L, 2, &len); - switch(a_tokenize(property, -1)) + switch(a_tokenize(buf, len)) { - case A_TK_TEXT_NORMAL: - p_delete(&d->text_normal); - d->text_normal = a_strdup(new_value); + case A_TK_TAGS: + d->show = ShowTags; break; - case A_TK_TEXT_FOCUS: - p_delete(&d->text_focus); - d->text_focus = a_strdup(new_value); + case A_TK_FOCUS: + d->show = ShowFocus; break; - case A_TK_TEXT_URGENT: - p_delete(&d->text_urgent); - d->text_urgent = a_strdup(new_value); - break; - case A_TK_SHOW_ICONS: - d->show_icons = a_strtobool(new_value, -1); - break; - case A_TK_SHOW: - switch(a_tokenize(new_value, -1)) - { - case A_TK_TAGS: - d->show = ShowTags; - break; - case A_TK_FOCUS: - d->show = ShowFocus; - break; - case A_TK_ALL: - d->show = ShowAll; - break; - default: - return WIDGET_ERROR; - } + case A_TK_ALL: + d->show = ShowAll; break; default: - return WIDGET_ERROR; + break; } - return WIDGET_NOERROR; + + widget_invalidate_bywidget(*widget); + + return 0; } +/** Select if icons must be shown. + * \param L The Lua VM state. + * \return The number of elements pushed on stack. + * \luastack + * \lvalue A widget. + * \lparam A boolean, true to see icons, false otherwise. + */ +static int +luaA_tasklist_showicons_set(lua_State *L) +{ + widget_t **widget = luaA_checkudata(L, 1, "widget"); + tasklist_data_t *d = (*widget)->data; + + d->show_icons = luaA_checkboolean(L, 2); + + return 0; +} + +/** Set text format string in case of a client is either normal, focused or has + * urgency hint. + * \param L The Lua VM state. + * \return The number of elements pushed on stack. + * \lstack + * \lvalue A widget. + * \lparam A table with keys to change: `normal', `focus' and `urgent'. + */ +static int +luaA_tasklist_text_set(lua_State *L) +{ + widget_t **widget = luaA_checkudata(L, 1, "widget"); + tasklist_data_t *d = (*widget)->data; + const char *buf; + + luaA_checktable(L, 2); + + if((buf = luaA_getopt_string(L, 2, "normal", NULL))) + { + p_delete(&d->text_normal); + d->text_normal = a_strdup(buf); + } + + if((buf = luaA_getopt_string(L, 2, "focus", NULL))) + { + p_delete(&d->text_focus); + d->text_focus = a_strdup(buf); + } + + if((buf = luaA_getopt_string(L, 2, "urgent", NULL))) + { + p_delete(&d->text_urgent); + d->text_urgent = a_strdup(buf); + } + + widget_invalidate_bywidget(*widget); + + return 0; +} + +/** Index function for tasklist widget. + * \lparam L The Lua VM state. + * \return The number of elements pushed on stack. + */ +static int +luaA_tasklist_index(lua_State *L) +{ + size_t len; + const char *attr = luaL_checklstring(L, 2, &len); + + switch(a_tokenize(attr, len)) + { + case A_TK_TEXT_SET: + lua_pushcfunction(L, luaA_tasklist_text_set); + return 1; + case A_TK_SHOWICONS_SET: + lua_pushcfunction(L, luaA_tasklist_showicons_set); + case A_TK_SHOW_SET: + lua_pushcfunction(L, luaA_tasklist_show_set); + default: + return 0; + } +} + +/** Destructor for the tasklist widget. + * \param widget The widget to destroy. + */ static void tasklist_destructor(widget_t *widget) { @@ -312,6 +408,10 @@ tasklist_destructor(widget_t *widget) p_delete(&d); } +/** Create a new widget tasklist. + * \param align The widget alignment, which is flex anyway. + * \return A brand new tasklist widget. + */ widget_t * tasklist_new(alignment_t align __attribute__ ((unused))) { @@ -323,8 +423,8 @@ tasklist_new(alignment_t align __attribute__ ((unused))) w->draw = tasklist_draw; w->button_press = tasklist_button_press; w->align = AlignFlex; + w->index = luaA_tasklist_index; w->data = d = p_new(tasklist_data_t, 1); - w->tell = tasklist_tell; w->destructor = tasklist_destructor; d->text_normal = a_strdup(" <title/> "); diff --git a/widgets/textbox.c b/widgets/textbox.c index 731454e4e..dd0a853bf 100644 --- a/widgets/textbox.c +++ b/widgets/textbox.c @@ -2,7 +2,6 @@ * textbox.c - text box widget * * Copyright © 2007-2008 Julien Danjou <julien@danjou.info> - * Copyright © 2007 Aldo Cortesi <aldo@nullcube.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -28,12 +27,24 @@ extern awesome_t globalconf; +/** The textbox private data structure */ typedef struct { + /** Textbox text */ char *text; + /** Textbox width */ int width; } textbox_data_t; +/** Draw a textbox widget. + * \param ctx The draw context. + * \param screen The screen. + * \param w The widget node we are linked from. + * \param offset Offset to draw at. + * \param used The size used on the element. + * \param p A pointer to the object we're draw onto. + * \return The width used. + */ static int textbox_draw(draw_context_t *ctx, int screen __attribute__ ((unused)), widget_node_t *w, @@ -72,27 +83,9 @@ textbox_draw(draw_context_t *ctx, int screen __attribute__ ((unused)), return w->area.width; } -static widget_tell_status_t -textbox_tell(widget_t *widget, const char *property, const char *new_value) -{ - textbox_data_t *d = widget->data; - - switch(a_tokenize(property, -1)) - { - case A_TK_TEXT: - p_delete(&d->text); - a_iso2utf8(new_value, &d->text); - break; - case A_TK_WIDTH: - d->width = atoi(new_value); - break; - default: - return WIDGET_ERROR; - } - - return WIDGET_NOERROR; -} - +/** Delete a textbox widget. + * \param w The widget to destroy. + */ static void textbox_destructor(widget_t *w) { @@ -101,6 +94,77 @@ textbox_destructor(widget_t *w) p_delete(&d); } +/** Set the text of a textbox. + * \param L The Lua VM state. + * \return The number of elements pushed on stack. + * \lstack + * \lvalue A widget. + * \lparam The text to set. + */ +static int +luaA_textbox_text_set(lua_State *L) +{ + widget_t **widget = luaA_checkudata(L, 1, "widget"); + const char *text = luaL_checkstring(L, 2); + textbox_data_t *d = (*widget)->data; + + p_delete(&d->text); + a_iso2utf8(text, &d->text); + + widget_invalidate_bywidget(*widget); + + return 0; +} + +/** Set the width of a textbox. + * \param L The Lua VM state. + * \return The number of elements pushed on stack. + * \lstack + * \lvalue A widget. + * \lparam The width to set. + */ +static int +luaA_textbox_width_set(lua_State *L) +{ + widget_t **widget = luaA_checkudata(L, 1, "widget"); + int width = luaL_checknumber(L, 2); + textbox_data_t *d = (*widget)->data; + + d->width = width; + + widget_invalidate_bywidget(*widget); + + return 0; +} + +/** The __index method for a textbox object. + * \param L The Lua VM state. + * \return The number of elements pushed on stack. + * \param The numbre of elements return on the stack. + */ +static int +luaA_textbox_index(lua_State *L) +{ + size_t len; + const char *attr = luaL_checklstring(L, 2, &len); + + switch(a_tokenize(attr, len)) + { + case A_TK_TEXT_SET: + lua_pushcfunction(L, luaA_textbox_text_set); + return 1; + case A_TK_WIDTH_SET: + lua_pushcfunction(L, luaA_textbox_width_set); + return 1; + default: + return 0; + } +} + +/** Create a new textbox widget. + * \param align Widget alignment. + * \return A brand new widget. + */ widget_t * textbox_new(alignment_t align) { @@ -111,7 +175,7 @@ textbox_new(alignment_t align) widget_common_new(w); w->align = align; w->draw = textbox_draw; - w->tell = textbox_tell; + w->index = luaA_textbox_index; w->destructor = textbox_destructor; w->data = d = p_new(textbox_data_t, 1);