widget: new widget index method
Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
parent
4508836133
commit
094d0ebc50
166
awesomerc.5.txt
166
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. \'<title/>\' 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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
69
dbus.c
69
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);
|
||||
|
|
16
structs.h
16
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 */
|
||||
|
|
108
widget.c
108
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 },
|
||||
|
|
5
widget.h
5
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;
|
||||
|
|
470
widgets/graph.c
470
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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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/> ");
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue