Cleanup: area.h

This commit is contained in:
o9000 2015-11-18 21:57:10 +01:00
parent 5f41544089
commit c0e62e2e79
19 changed files with 502 additions and 422 deletions

View file

@ -121,7 +121,7 @@ void update_battery_tick(void* arg)
}
}
if (panel1[i].battery.area.on_screen == 1) {
panel1[i].battery.area.resize = 1;
panel1[i].battery.area.resize_needed = 1;
panel_refresh = 1;
}
}
@ -223,16 +223,16 @@ void init_battery_panel(void *p)
battery->area.parent = p;
battery->area.panel = p;
battery->area._draw_foreground = draw_battery;
battery->area.size_mode = SIZE_BY_CONTENT;
battery->area._resize = resize_battery;
battery->area.size_mode = LAYOUT_FIXED;
battery->area._resize = resize_battery;
battery->area.on_screen = 1;
battery->area.resize = 1;
battery->area.mouse_over_effect = battery_lclick_command ||
battery->area.resize_needed = 1;
battery->area.has_mouse_over_effect = battery_lclick_command ||
battery_mclick_command ||
battery_rclick_command ||
battery_uwheel_command ||
battery_dwheel_command;
battery->area.mouse_press_effect = battery->area.mouse_over_effect;
battery->area.has_mouse_press_effect = battery->area.has_mouse_over_effect;
if (battery_tooltip_enabled)
battery->area._get_tooltip_text = battery_get_tooltip;
}
@ -273,7 +273,7 @@ void draw_battery (void *obj, cairo_t *c)
pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_NONE);
pango_layout_set_text(layout, buf_bat_percentage, strlen(buf_bat_percentage));
cairo_set_source_rgba(c, battery->font.color[0], battery->font.color[1], battery->font.color[2], battery->font.alpha);
cairo_set_source_rgba(c, battery->font.rgb[0], battery->font.rgb[1], battery->font.rgb[2], battery->font.alpha);
pango_cairo_update_layout(c, layout);
draw_text(layout, c, 0, battery->bat1_posy, &battery->font, ((Panel*)battery->area.panel)->font_shadow);
@ -301,7 +301,7 @@ int resize_battery(void *obj)
int bat_time_height, bat_time_width, bat_time_height_ink;
int ret = 0;
battery->area.redraw = 1;
battery->area.redraw_needed = 1;
snprintf(buf_bat_percentage, sizeof(buf_bat_percentage), "%d%%", battery_state.percentage);
if (battery_state.state == BATTERY_FULL) {

View file

@ -111,7 +111,7 @@ void update_clocks_sec(void* arg)
int i;
if (time1_format) {
for (i=0 ; i < nb_panel ; i++)
panel1[i].clock.area.resize = 1;
panel1[i].clock.area.resize_needed = 1;
}
panel_refresh = 1;
}
@ -126,7 +126,7 @@ void update_clocks_min(void* arg)
int i;
if (time1_format) {
for (i=0 ; i < nb_panel ; i++)
panel1[i].clock.area.resize = 1;
panel1[i].clock.area.resize_needed = 1;
}
panel_refresh = 1;
}
@ -185,19 +185,19 @@ void init_clock_panel(void *p)
clock->area.bg = &g_array_index(backgrounds, Background, 0);
clock->area.parent = p;
clock->area.panel = p;
clock->area.mouse_press_effect = clock->area.mouse_over_effect = clock_lclick_command ||
clock->area.has_mouse_press_effect = clock->area.has_mouse_over_effect = clock_lclick_command ||
clock_mclick_command ||
clock_rclick_command ||
clock_uwheel_command ||
clock_dwheel_command;
clock->area._draw_foreground = draw_clock;
clock->area.size_mode = SIZE_BY_CONTENT;
clock->area._resize = resize_clock;
clock->area.size_mode = LAYOUT_FIXED;
clock->area._resize = resize_clock;
// check consistency
if (!time1_format)
return;
clock->area.resize = 1;
clock->area.resize_needed = 1;
clock->area.on_screen = 1;
if (time_tooltip_format) {
@ -222,7 +222,7 @@ void draw_clock (void *obj, cairo_t *c)
pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_NONE);
pango_layout_set_text (layout, buf_time, strlen(buf_time));
cairo_set_source_rgba (c, clock->font.color[0], clock->font.color[1], clock->font.color[2], clock->font.alpha);
cairo_set_source_rgba (c, clock->font.rgb[0], clock->font.rgb[1], clock->font.rgb[2], clock->font.alpha);
pango_cairo_update_layout (c, layout);
draw_text(layout, c, 0, clock->time1_posy, &clock->font, ((Panel*)clock->area.panel)->font_shadow);
@ -247,7 +247,7 @@ int resize_clock (void *obj)
Panel *panel = clock->area.panel;
int time_height_ink, time_height, time_width, date_height_ink, date_height, date_width, ret = 0;
clock->area.redraw = 1;
clock->area.redraw_needed = 1;
date_height = date_width = 0;
strftime(buf_time, sizeof(buf_time), time1_format, clock_gettime_for_tz(time1_timezone));
@ -265,7 +265,7 @@ int resize_clock (void *obj)
int new_size = (time_width > date_width) ? time_width : date_width;
new_size += (2*clock->area.paddingxlr) + (2*clock->area.bg->border.width);
if (new_size > clock->area.width || new_size < (clock->area.width-6)) {
// we try to limit the number of resize
// we try to limit the number of resizes
clock->area.width = new_size + 1;
clock->time1_posy = (clock->area.height - time_height) / 2;
if (time2_format) {
@ -278,7 +278,7 @@ int resize_clock (void *obj)
else {
int new_size = time_height + date_height + (2 * (clock->area.paddingxlr + clock->area.bg->border.width));
if (new_size != clock->area.height) {
// we try to limit the number of resize
// we try to limit the number of resizes
clock->area.height = new_size;
clock->time1_posy = (clock->area.height - time_height) / 2;
if (time2_format) {

View file

@ -213,17 +213,17 @@ void add_entry (char *key, char *value)
if (backgrounds->len > 0) {
Background *bg = &g_array_index(backgrounds, Background, backgrounds->len-1);
if (!read_bg_color_hover)
memcpy(&bg->back_hover, &bg->back, sizeof(Color));
memcpy(&bg->fill_color_hover, &bg->fill_color, sizeof(Color));
if (!read_border_color_hover)
memcpy(&bg->border_hover, &bg->border, sizeof(Color));
memcpy(&bg->border_color_hover, &bg->border, sizeof(Color));
if (!read_bg_color_press)
memcpy(&bg->back_pressed, &bg->back_hover, sizeof(Color));
memcpy(&bg->fill_color_pressed, &bg->fill_color_hover, sizeof(Color));
if (!read_border_color_press)
memcpy(&bg->border_pressed, &bg->border_hover, sizeof(Color));
memcpy(&bg->border_color_pressed, &bg->border_color_hover, sizeof(Color));
}
Background bg;
init_background(&bg);
bg.border.rounded = atoi(value);
bg.border.radius = atoi(value);
g_array_append_val(backgrounds, bg);
read_bg_color_hover = 0;
read_border_color_hover = 0;
@ -236,47 +236,47 @@ void add_entry (char *key, char *value)
else if (strcmp (key, "background_color") == 0) {
Background* bg = &g_array_index(backgrounds, Background, backgrounds->len-1);
extract_values(value, &value1, &value2, &value3);
get_color (value1, bg->back.color);
if (value2) bg->back.alpha = (atoi (value2) / 100.0);
else bg->back.alpha = 0.5;
get_color (value1, bg->fill_color.rgb);
if (value2) bg->fill_color.alpha = (atoi (value2) / 100.0);
else bg->fill_color.alpha = 0.5;
}
else if (strcmp (key, "border_color") == 0) {
Background* bg = &g_array_index(backgrounds, Background, backgrounds->len-1);
extract_values(value, &value1, &value2, &value3);
get_color (value1, bg->border.color);
if (value2) bg->border.alpha = (atoi (value2) / 100.0);
else bg->border.alpha = 0.5;
get_color (value1, bg->border.color.rgb);
if (value2) bg->border.color.alpha = (atoi (value2) / 100.0);
else bg->border.color.alpha = 0.5;
}
else if (strcmp (key, "background_color_hover") == 0) {
Background* bg = &g_array_index(backgrounds, Background, backgrounds->len-1);
extract_values(value, &value1, &value2, &value3);
get_color (value1, bg->back_hover.color);
if (value2) bg->back_hover.alpha = (atoi (value2) / 100.0);
else bg->back_hover.alpha = 0.5;
get_color (value1, bg->fill_color_hover.rgb);
if (value2) bg->fill_color_hover.alpha = (atoi (value2) / 100.0);
else bg->fill_color_hover.alpha = 0.5;
read_bg_color_hover = 1;
}
else if (strcmp (key, "border_color_hover") == 0) {
Background* bg = &g_array_index(backgrounds, Background, backgrounds->len-1);
extract_values(value, &value1, &value2, &value3);
get_color (value1, bg->border_hover.color);
if (value2) bg->border_hover.alpha = (atoi (value2) / 100.0);
else bg->border_hover.alpha = 0.5;
get_color (value1, bg->border_color_hover.rgb);
if (value2) bg->border_color_hover.alpha = (atoi (value2) / 100.0);
else bg->border_color_hover.alpha = 0.5;
read_border_color_hover = 1;
}
else if (strcmp (key, "background_color_pressed") == 0) {
Background* bg = &g_array_index(backgrounds, Background, backgrounds->len-1);
extract_values(value, &value1, &value2, &value3);
get_color (value1, bg->back_pressed.color);
if (value2) bg->back_pressed.alpha = (atoi (value2) / 100.0);
else bg->back_pressed.alpha = 0.5;
get_color (value1, bg->fill_color_pressed.rgb);
if (value2) bg->fill_color_pressed.alpha = (atoi (value2) / 100.0);
else bg->fill_color_pressed.alpha = 0.5;
read_bg_color_press = 1;
}
else if (strcmp (key, "border_color_pressed") == 0) {
Background* bg = &g_array_index(backgrounds, Background, backgrounds->len-1);
extract_values(value, &value1, &value2, &value3);
get_color (value1, bg->border_pressed.color);
if (value2) bg->border_pressed.alpha = (atoi (value2) / 100.0);
else bg->border_pressed.alpha = 0.5;
get_color (value1, bg->border_color_pressed.rgb);
if (value2) bg->border_color_pressed.alpha = (atoi (value2) / 100.0);
else bg->border_color_pressed.alpha = 0.5;
read_border_color_press = 1;
}
@ -471,7 +471,7 @@ void add_entry (char *key, char *value)
else if (strcmp (key, "battery_font_color") == 0) {
#ifdef ENABLE_BATTERY
extract_values(value, &value1, &value2, &value3);
get_color (value1, panel_config.battery.font.color);
get_color (value1, panel_config.battery.font.rgb);
if (value2) panel_config.battery.font.alpha = (atoi (value2) / 100.0);
else panel_config.battery.font.alpha = 0.5;
#endif
@ -542,7 +542,7 @@ void add_entry (char *key, char *value)
}
else if (strcmp (key, "clock_font_color") == 0) {
extract_values(value, &value1, &value2, &value3);
get_color (value1, panel_config.clock.font.color);
get_color (value1, panel_config.clock.font.rgb);
if (value2) panel_config.clock.font.alpha = (atoi (value2) / 100.0);
else panel_config.clock.font.alpha = 0.5;
}
@ -637,13 +637,13 @@ void add_entry (char *key, char *value)
}
else if (strcmp (key, "taskbar_name_font_color") == 0) {
extract_values(value, &value1, &value2, &value3);
get_color (value1, taskbarname_font.color);
get_color (value1, taskbarname_font.rgb);
if (value2) taskbarname_font.alpha = (atoi (value2) / 100.0);
else taskbarname_font.alpha = 0.5;
}
else if (strcmp (key, "taskbar_name_active_font_color") == 0) {
extract_values(value, &value1, &value2, &value3);
get_color (value1, taskbarname_active_font.color);
get_color (value1, taskbarname_active_font.rgb);
if (value2) taskbarname_active_font.alpha = (atoi (value2) / 100.0);
else taskbarname_active_font.alpha = 0.5;
}
@ -708,7 +708,7 @@ void add_entry (char *key, char *value)
extract_values(value, &value1, &value2, &value3);
float alpha = 1;
if (value2) alpha = (atoi (value2) / 100.0);
get_color (value1, panel_config.g_task.font[status].color);
get_color (value1, panel_config.g_task.font[status].rgb);
panel_config.g_task.font[status].alpha = alpha;
panel_config.g_task.config_font_mask |= (1<<status);
}
@ -859,7 +859,7 @@ void add_entry (char *key, char *value)
}
else if (strcmp (key, "tooltip_font_color") == 0) {
extract_values(value, &value1, &value2, &value3);
get_color(value1, g_tooltip.font_color.color);
get_color(value1, g_tooltip.font_color.rgb);
if (value2) g_tooltip.font_color.alpha = (atoi (value2) / 100.0);
else g_tooltip.font_color.alpha = 0.1;
}
@ -1039,13 +1039,13 @@ int config_read_file (const char *path)
if (backgrounds->len > 0) {
Background *bg = &g_array_index(backgrounds, Background, backgrounds->len-1);
if (!read_bg_color_hover)
memcpy(&bg->back_hover, &bg->back, sizeof(Color));
memcpy(&bg->fill_color_hover, &bg->fill_color, sizeof(Color));
if (!read_border_color_hover)
memcpy(&bg->border_hover, &bg->border, sizeof(Color));
memcpy(&bg->border_color_hover, &bg->border, sizeof(Color));
if (!read_bg_color_press)
memcpy(&bg->back_pressed, &bg->back_hover, sizeof(Color));
memcpy(&bg->fill_color_pressed, &bg->fill_color_hover, sizeof(Color));
if (!read_border_color_press)
memcpy(&bg->border_pressed, &bg->border_hover, sizeof(Color));
memcpy(&bg->border_color_pressed, &bg->border_color_hover, sizeof(Color));
}
return 1;

View file

@ -40,8 +40,8 @@ void init_freespace_panel(void *p)
freespace->area.bg = &g_array_index(backgrounds, Background, 0);
freespace->area.parent = p;
freespace->area.panel = p;
freespace->area.size_mode = SIZE_BY_CONTENT;
freespace->area.resize = 1;
freespace->area.size_mode = LAYOUT_FIXED;
freespace->area.resize_needed = 1;
freespace->area.on_screen = 1;
freespace->area._resize = resize_freespace;
}
@ -87,7 +87,7 @@ int resize_freespace(void *obj) {
freespace->area.height = size;
}
freespace->area.redraw = 1;
freespace->area.redraw_needed = 1;
panel_refresh = 1;
return 1;
}

View file

@ -92,10 +92,10 @@ void init_launcher_panel(void *p)
launcher->area.parent = p;
launcher->area.panel = p;
launcher->area._draw_foreground = NULL;
launcher->area.size_mode = SIZE_BY_CONTENT;
launcher->area.size_mode = LAYOUT_FIXED;
launcher->area._resize = resize_launcher;
launcher->area.resize = 1;
launcher->area.redraw = 1;
launcher->area.resize_needed = 1;
launcher->area.redraw_needed = 1;
if (!launcher->area.bg)
launcher->area.bg = &g_array_index(backgrounds, Background, 0);
@ -446,15 +446,14 @@ void launcher_load_icons(Launcher *launcher)
read_desktop_file(app->data, &entry);
if (entry.exec) {
LauncherIcon *launcherIcon = calloc(1, sizeof(LauncherIcon));
launcherIcon->area.parent = launcher;
launcherIcon->area.panel = launcher->area.panel;
launcherIcon->area._draw_foreground = draw_launcher_icon;
launcherIcon->area.size_mode = SIZE_BY_CONTENT;
launcherIcon->area.size_mode = LAYOUT_FIXED;
launcherIcon->area._resize = NULL;
launcherIcon->area.resize = 0;
launcherIcon->area.redraw = 1;
launcherIcon->area.mouse_over_effect = 1;
launcherIcon->area.mouse_press_effect = 1;
launcherIcon->area.resize_needed = 0;
launcherIcon->area.redraw_needed = 1;
launcherIcon->area.has_mouse_over_effect = 1;
launcherIcon->area.has_mouse_press_effect = 1;
launcherIcon->area.bg = launcher_icon_bg;
launcherIcon->area.on_screen = 1;
launcherIcon->area._on_change_layout = launcher_icon_on_change_layout;
@ -470,7 +469,7 @@ void launcher_load_icons(Launcher *launcher)
launcherIcon->icon_tooltip = entry.name ? strdup(entry.name) : strdup(entry.exec);
free_desktop_entry(&entry);
launcher->list_icons = g_slist_append(launcher->list_icons, launcherIcon);
add_area(&launcherIcon->area);
add_area(&launcherIcon->area, (Area*)launcher);
}
app = g_slist_next(app);
}

View file

@ -64,7 +64,7 @@ void xsettings_notify_cb (const char *name, XSettingsAction action, XSettingsSet
cleanup_launcher_theme(launcher);
launcher_load_themes(launcher);
launcher_load_icons(launcher);
launcher->area.resize = 1;
launcher->area.resize_needed = 1;
}
}
}

View file

@ -192,11 +192,11 @@ void init_panel()
p->area.parent = p;
p->area.panel = p;
p->area.on_screen = 1;
p->area.resize = 1;
p->area.size_mode = SIZE_BY_LAYOUT;
p->area.resize_needed = 1;
p->area.size_mode = LAYOUT_DYNAMIC;
p->area._resize = resize_panel;
init_panel_size_and_position(p);
// add childs according to panel_items
// add children according to panel_items
for (k=0 ; k < strlen(panel_items_order) ; k++) {
if (panel_items_order[k] == 'L')
init_launcher_panel(p);
@ -265,11 +265,11 @@ void init_panel_size_and_position(Panel *panel)
panel->area.height = (float)server.monitor[panel->monitor].height * panel->area.height / 100;
if (panel->area.width + panel->marginx > server.monitor[panel->monitor].width)
panel->area.width = server.monitor[panel->monitor].width - panel->marginx;
if (panel->area.bg->border.rounded > panel->area.height/2) {
if (panel->area.bg->border.radius > panel->area.height/2) {
printf("panel_background_id rounded is too big... please fix your tint2rc\n");
g_array_append_val(backgrounds, *panel->area.bg);
panel->area.bg = &g_array_index(backgrounds, Background, backgrounds->len-1);
panel->area.bg->border.rounded = panel->area.height/2;
panel->area.bg->border.radius = panel->area.height/2;
}
}
else {
@ -284,11 +284,11 @@ void init_panel_size_and_position(Panel *panel)
panel->area.width = old_panel_height;
if (panel->area.height + panel->marginy > server.monitor[panel->monitor].height)
panel->area.height = server.monitor[panel->monitor].height - panel->marginy;
if (panel->area.bg->border.rounded > panel->area.width/2) {
if (panel->area.bg->border.radius > panel->area.width/2) {
printf("panel_background_id rounded is too big... please fix your tint2rc\n");
g_array_append_val(backgrounds, *panel->area.bg);
panel->area.bg = &g_array_index(backgrounds, Background, backgrounds->len-1);
panel->area.bg->border.rounded = panel->area.width/2;
panel->area.bg->border.radius = panel->area.width/2;
}
}
@ -336,7 +336,7 @@ void init_panel_size_and_position(Panel *panel)
int resize_panel(void *obj)
{
Panel *panel = (Panel*)obj;
resize_by_layout(panel, 0);
relayout_with_constraint(&panel->area, 0);
//printf("resize_panel\n");
if (panel_mode != MULTI_DESKTOP && taskbar_enabled) {
@ -347,7 +347,7 @@ int resize_panel(void *obj)
for (i=0 ; i < panel->nb_desktop ; i++) {
panel->taskbar[i].area.width = width;
panel->taskbar[i].area.height = height;
panel->taskbar[i].area.resize = 1;
panel->taskbar[i].area.resize_needed = 1;
}
}
if (panel_mode == MULTI_DESKTOP && taskbar_enabled && taskbar_distribute_size) {
@ -426,7 +426,7 @@ int resize_panel(void *obj)
} else {
taskbar->area.height = actual_name_size + items / (float)total_items * total_size;
}
taskbar->area.resize = 1;
taskbar->area.resize_needed = 1;
}
}
}
@ -503,7 +503,7 @@ void set_panel_items_order(Panel *p)
for (k=0 ; k < strlen(panel_items_order) ; k++) {
if (panel_items_order[k] == 'L') {
p->area.children = g_list_append(p->area.children, &p->launcher);
p->launcher.area.resize = 1;
p->launcher.area.resize_needed = 1;
}
if (panel_items_order[k] == 'T') {
for (j=0 ; j < p->nb_desktop ; j++)
@ -522,7 +522,7 @@ void set_panel_items_order(Panel *p)
if (panel_items_order[k] == 'F')
p->area.children = g_list_append(p->area.children, &p->freespace);
}
init_rendering(&p->area, 0);
initialize_positions(&p->area, 0);
}
@ -649,7 +649,7 @@ void set_panel_background(Panel *p)
Area *a;
for (l0 = p->area.children; l0 ; l0 = l0->next) {
a = l0->data;
set_redraw(a);
schedule_redraw(a);
}
// reset task/taskbar 'state_pix'
@ -924,3 +924,9 @@ void autohide_trigger_hide(Panel* p)
change_timeout(&p->autohide_timeout, panel_autohide_hide_timeout, 0, autohide_hide, p);
}
void render_panel(Panel *panel)
{
relayout(&panel->area);
draw_tree(&panel->area);
}

View file

@ -153,6 +153,7 @@ void init_panel();
void init_panel_size_and_position(Panel *panel);
int resize_panel(void *obj);
void render_panel(Panel *panel);
void set_panel_items_order(Panel *p);
void set_panel_properties(Panel *p);

View file

@ -197,7 +197,7 @@ void *server_get_property (Window win, Atom at, Atom type, int *num_results)
result = XGetWindowProperty(server.dsp, win, at, 0, 0x7fffffff, False, type, &type_ret, &format_ret, &nitems_ret, &bafter_ret, &prop_value);
// Send back resultcount
// Send fill_color resultcount
if (num_results) *num_results = (int)nitems_ret;
if (result == Success && prop_value) return prop_value;

View file

@ -74,7 +74,7 @@ void default_systray()
systray.sort = SYSTRAY_SORT_LEFT2RIGHT;
systray.area._draw_foreground = draw_systray;
systray.area._on_change_layout = on_change_systray;
systray.area.size_mode = SIZE_BY_CONTENT;
systray.area.size_mode = LAYOUT_FIXED;
systray.area._resize = resize_systray;
systray_profile = getenv("SYSTRAY_PROFILING") != NULL;
}
@ -117,9 +117,9 @@ void init_systray_panel(void *p)
if (!systray.area.bg)
systray.area.bg = &g_array_index(backgrounds, Background, 0);
show(&systray.area);
systray.area.resize = 1;
systray.area.redraw = 1;
panel->area.resize = 1;
systray.area.resize_needed = 1;
systray.area.redraw_needed = 1;
panel->area.resize_needed = 1;
panel_refresh = 1;
refresh_systray = 1;
}
@ -615,9 +615,9 @@ gboolean add_icon(Window win)
// Resize and redraw the systray
if (systray_profile)
fprintf(stderr, BLUE "[%f] %s:%d trigger resize & redraw\n" RESET, profiling_get_time(), __FUNCTION__, __LINE__);
systray.area.resize = 1;
systray.area.redraw = 1;
panel->area.resize = 1;
systray.area.resize_needed = 1;
systray.area.redraw_needed = 1;
panel->area.resize_needed = 1;
panel_refresh = 1;
refresh_systray = 1;
return TRUE;
@ -817,9 +817,9 @@ void remove_icon(TrayWindow *traywin)
// Resize and redraw the systray
if (systray_profile)
fprintf(stderr, BLUE "[%f] %s:%d trigger resize & redraw\n" RESET, profiling_get_time(), __FUNCTION__, __LINE__);
systray.area.resize = 1;
systray.area.redraw = 1;
panel->area.resize = 1;
systray.area.resize_needed = 1;
systray.area.redraw_needed = 1;
panel->area.resize_needed = 1;
panel_refresh = 1;
refresh_systray = 1;
}
@ -906,7 +906,7 @@ void systray_reconfigure_event(TrayWindow *traywin, XEvent *e)
fprintf(stderr, RED "Detected resize loop for tray icon %lu (%s), throttling resize events\n" RESET, traywin->win, traywin->name);
}
// Delayed resize
// FIXME Normally we should force the icon to resize back to the size we resized it to when we embedded it.
// FIXME Normally we should force the icon to resize fill_color to the size we resized it to when we embedded it.
// However this triggers a resize loop in new versions of GTK, which we must avoid.
if (!traywin->resize_timeout)
traywin->resize_timeout = add_timeout(slow_resize_period, 0, systray_resize_icon, traywin, &traywin->resize_timeout);
@ -959,7 +959,7 @@ void systray_resize_request_event(TrayWindow *traywin, XEvent *e)
fprintf(stderr, RED "Detected resize loop for tray icon %lu (%s), throttling resize events\n" RESET, traywin->win, traywin->name);
}
// Delayed resize
// FIXME Normally we should force the icon to resize back to the size we resized it to when we embedded it.
// FIXME Normally we should force the icon to resize fill_color to the size we resized it to when we embedded it.
// However this triggers a resize loop in new versions of GTK, which we must avoid.
if (!traywin->resize_timeout)
traywin->resize_timeout = add_timeout(slow_resize_period, 0, systray_resize_icon, traywin, &traywin->resize_timeout);
@ -1139,9 +1139,9 @@ void systray_render_icon_composited(void* t)
// Resize and redraw the systray
if (systray_profile)
fprintf(stderr, BLUE "[%f] %s:%d trigger resize & redraw\n" RESET, profiling_get_time(), __FUNCTION__, __LINE__);
systray.area.resize = 1;
systray.area.redraw = 1;
panel->area.resize = 1;
systray.area.resize_needed = 1;
systray.area.redraw_needed = 1;
panel->area.resize_needed = 1;
panel_refresh = 1;
refresh_systray = 1;
}

View file

@ -62,8 +62,8 @@ Task *add_task (Window win)
Task new_tsk;
memset(&new_tsk, 0, sizeof(new_tsk));
new_tsk.area.mouse_over_effect = 1;
new_tsk.area.mouse_press_effect = 1;
new_tsk.area.has_mouse_over_effect = 1;
new_tsk.area.has_mouse_press_effect = 1;
new_tsk.win = win;
new_tsk.desktop = window_get_desktop (win);
new_tsk.area.panel = &panel1[monitor];
@ -94,8 +94,8 @@ Task *add_task (Window win)
new_tsk2 = calloc(1, sizeof(Task));
memcpy(&new_tsk2->area, &panel1[monitor].g_task.area, sizeof(Area));
new_tsk2->area.parent = tskbar;
new_tsk2->area.mouse_over_effect = 1;
new_tsk2->area.mouse_press_effect = 1;
new_tsk2->area.has_mouse_over_effect = 1;
new_tsk2->area.has_mouse_press_effect = 1;
new_tsk2->win = new_tsk.win;
new_tsk2->desktop = new_tsk.desktop;
new_tsk2->win_x = new_tsk.win_x;
@ -119,7 +119,7 @@ Task *add_task (Window win)
new_tsk2->icon_width = new_tsk.icon_width;
new_tsk2->icon_height = new_tsk.icon_height;
tskbar->area.children = g_list_append(tskbar->area.children, new_tsk2);
tskbar->area.resize = 1;
tskbar->area.resize_needed = 1;
g_ptr_array_add(task_group, new_tsk2);
//printf("add_task panel %d, desktop %d, task %s\n", i, j, new_tsk2->title);
}
@ -132,7 +132,7 @@ Task *add_task (Window win)
if (panel_mode == MULTI_DESKTOP) {
Panel *panel = new_tsk2->area.panel;
panel->area.resize = 1;
panel->area.resize_needed = 1;
}
if (window_is_urgent(win)) {
@ -149,7 +149,7 @@ void remove_task (Task *tsk)
if (panel_mode == MULTI_DESKTOP) {
Panel *panel = tsk->area.panel;
panel->area.resize = 1;
panel->area.resize_needed = 1;
}
Window win = tsk->win;
@ -187,7 +187,7 @@ void remove_task (Task *tsk)
if (tsk2 == task_active) task_active = 0;
if (tsk2 == task_drag) task_drag = 0;
if (g_slist_find(urgent_list, tsk2)) del_urgent(tsk2);
remove_area(tsk2);
remove_area((Area*)tsk2);
free(tsk2);
}
g_hash_table_remove(win_to_task_table, &win);
@ -555,9 +555,9 @@ void set_task_state(Task *tsk, int state)
if (!panel_config.mouse_effects) {
tsk1->area.pix = tsk1->state_pix[state];
if (!tsk1->area.pix)
tsk1->area.redraw = 1;
tsk1->area.redraw_needed = 1;
} else {
tsk1->area.redraw = 1;
tsk1->area.redraw_needed = 1;
}
if (state == TASK_ACTIVE && g_slist_find(urgent_list, tsk1))
del_urgent(tsk1);
@ -581,9 +581,9 @@ void set_task_state(Task *tsk, int state)
tsk1->area.on_screen = 1 - hide;
set_task_redraw(tsk1);
Panel *p = (Panel*)tsk->area.panel;
tsk->area.resize = 1;
p->taskbar->area.resize = 1;
p->area.resize = 1;
tsk->area.resize_needed = 1;
p->taskbar->area.resize_needed = 1;
p->area.resize_needed = 1;
}
}
panel_refresh = 1;
@ -600,7 +600,7 @@ void set_task_redraw(Task* tsk)
tsk->state_pix[k] = 0;
}
tsk->area.pix = 0;
tsk->area.redraw = 1;
tsk->area.redraw_needed = 1;
}

View file

@ -99,7 +99,7 @@ void cleanup_taskbar()
}
free_area(&tskbar->area);
// remove taskbar from the panel
remove_area(tskbar);
remove_area((Area*)tskbar);
}
if (panel->taskbar) {
free(panel->taskbar);
@ -144,22 +144,22 @@ void init_taskbar_panel(void *p)
// taskbar name
panel->g_taskbar.area_name.panel = panel;
panel->g_taskbar.area_name.size_mode = SIZE_BY_CONTENT;
panel->g_taskbar.area_name.size_mode = LAYOUT_FIXED;
panel->g_taskbar.area_name._resize = resize_taskbarname;
panel->g_taskbar.area_name._draw_foreground = draw_taskbarname;
panel->g_taskbar.area_name._on_change_layout = 0;
panel->g_taskbar.area_name.resize = 1;
panel->g_taskbar.area_name.resize_needed = 1;
panel->g_taskbar.area_name.on_screen = 1;
// taskbar
panel->g_taskbar.area.parent = panel;
panel->g_taskbar.area.panel = panel;
panel->g_taskbar.area.size_mode = SIZE_BY_LAYOUT;
panel->g_taskbar.area.size_mode = LAYOUT_DYNAMIC;
panel->g_taskbar.area.alignment = taskbar_alignment;
panel->g_taskbar.area._resize = resize_taskbar;
panel->g_taskbar.area._draw_foreground = draw_taskbar;
panel->g_taskbar.area._on_change_layout = on_change_taskbar;
panel->g_taskbar.area.resize = 1;
panel->g_taskbar.area.resize_needed = 1;
panel->g_taskbar.area.on_screen = 1;
if (panel_horizontal) {
panel->g_taskbar.area.posy = panel->area.bg->border.width + panel->area.paddingy;
@ -176,10 +176,10 @@ void init_taskbar_panel(void *p)
// task
panel->g_task.area.panel = panel;
panel->g_task.area.size_mode = SIZE_BY_LAYOUT;
panel->g_task.area.size_mode = LAYOUT_DYNAMIC;
panel->g_task.area._draw_foreground = draw_task;
panel->g_task.area._on_change_layout = on_change_task;
panel->g_task.area.resize = 1;
panel->g_task.area.resize_needed = 1;
panel->g_task.area.on_screen = 1;
if ((panel->g_task.config_asb_mask & (1<<TASK_NORMAL)) == 0) {
panel->g_task.alpha[TASK_NORMAL] = 100;
@ -223,11 +223,11 @@ void init_taskbar_panel(void *p)
for (j=0; j<TASK_STATE_COUNT; ++j) {
if (panel->g_task.background[j] == 0)
panel->g_task.background[j] = &g_array_index(backgrounds, Background, 0);
if (panel->g_task.background[j]->border.rounded > panel->g_task.area.height/2) {
if (panel->g_task.background[j]->border.radius > panel->g_task.area.height/2) {
printf("task%sbackground_id has a too large rounded value. Please fix your tint2rc\n", j==0 ? "_" : j==1 ? "_active_" : j==2 ? "_iconified_" : "_urgent_");
g_array_append_val(backgrounds, *panel->g_task.background[j]);
panel->g_task.background[j] = &g_array_index(backgrounds, Background, backgrounds->len-1);
panel->g_task.background[j]->border.rounded = panel->g_task.area.height/2;
panel->g_task.background[j]->border.radius = panel->g_task.area.height/2;
}
}
@ -334,7 +334,7 @@ int resize_taskbar(void *obj)
//printf("resize_taskbar %d %d\n", taskbar->area.posx, taskbar->area.posy);
if (panel_horizontal) {
resize_by_layout(obj, panel->g_task.maximum_width);
relayout_with_constraint(&taskbar->area, panel->g_task.maximum_width);
text_width = panel->g_task.maximum_width;
GList *l = taskbar->area.children;
@ -348,7 +348,7 @@ int resize_taskbar(void *obj)
taskbar->text_width = text_width - panel->g_task.text_posx - panel->g_task.area.bg->border.width - panel->g_task.area.paddingxlr;
}
else {
resize_by_layout(obj, panel->g_task.maximum_height);
relayout_with_constraint(&taskbar->area, panel->g_task.maximum_height);
taskbar->text_width = taskbar->area.width - (2 * panel->g_taskbar.area.paddingy) - panel->g_task.text_posx - panel->g_task.area.bg->border.width - panel->g_task.area.paddingxlr;
}
@ -367,7 +367,7 @@ void on_change_taskbar (void *obj)
tskbar->state_pix[k] = 0;
}
tskbar->area.pix = 0;
tskbar->area.redraw = 1;
tskbar->area.redraw_needed = 1;
}
@ -389,13 +389,13 @@ void set_taskbar_state(Taskbar *tskbar, int state)
}
if (tskbar->area.on_screen == 1) {
if (tskbar->state_pix[state] == 0)
tskbar->area.redraw = 1;
tskbar->area.redraw_needed = 1;
if (taskbarname_enabled) {
if (!panel_config.mouse_effects) {
if (tskbar->bar_name.state_pix[state] == 0)
tskbar->bar_name.area.redraw = 1;
tskbar->bar_name.area.redraw_needed = 1;
} else {
tskbar->bar_name.area.redraw = 1;
tskbar->bar_name.area.redraw_needed = 1;
}
}
if (panel_mode == MULTI_DESKTOP && panel1[0].g_taskbar.background[TASKBAR_NORMAL] != panel1[0].g_taskbar.background[TASKBAR_ACTIVE]) {
@ -540,9 +540,9 @@ void sort_tasks(Taskbar *taskbar)
return;
}
taskbar->area.children = g_list_sort_with_data(taskbar->area.children, (GCompareDataFunc)compare_tasks, taskbar);
taskbar->area.resize = 1;
taskbar->area.resize_needed = 1;
panel_refresh = 1;
((Panel*)taskbar->area.panel)->area.resize = 1;
((Panel*)taskbar->area.panel)->area.resize_needed = 1;
}

View file

@ -62,8 +62,8 @@ void init_taskbarname_panel(void *p)
tskbar = &panel->taskbar[j];
memcpy(&tskbar->bar_name.area, &panel->g_taskbar.area_name, sizeof(Area));
tskbar->bar_name.area.parent = tskbar;
tskbar->bar_name.area.mouse_over_effect = 1;
tskbar->bar_name.area.mouse_press_effect = 1;
tskbar->bar_name.area.has_mouse_over_effect = 1;
tskbar->bar_name.area.has_mouse_press_effect = 1;
if (j == server.desktop)
tskbar->bar_name.area.bg = panel->g_taskbar.background_name[TASKBAR_ACTIVE];
else
@ -105,7 +105,7 @@ void cleanup_taskbarname()
XFreePixmap(server.dsp, tskbar->bar_name.state_pix[k]);
tskbar->bar_name.state_pix[k] = 0;
}
remove_area(&tskbar->bar_name);
remove_area((Area*)&tskbar->bar_name);
}
}
}
@ -131,7 +131,7 @@ void draw_taskbarname (void *obj, cairo_t *c)
pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_NONE);
pango_layout_set_text (layout, taskbar_name->name, strlen(taskbar_name->name));
cairo_set_source_rgba (c, config_text->color[0], config_text->color[1], config_text->color[2], config_text->alpha);
cairo_set_source_rgba (c, config_text->rgb[0], config_text->rgb[1], config_text->rgb[2], config_text->alpha);
pango_cairo_update_layout (c, layout);
draw_text(layout, c, 0, taskbar_name->posy, config_text, ((Panel*)taskbar_name->area.panel)->font_shadow);
@ -148,7 +148,7 @@ int resize_taskbarname(void *obj)
int name_height, name_width, name_height_ink;
int ret = 0;
taskbar_name->area.redraw = 1;
taskbar_name->area.redraw_needed = 1;
get_text_size2(panel_config.taskbarname_font_desc, &name_height_ink, &name_height, &name_width, panel->area.height, panel->area.width, taskbar_name->name, strlen(taskbar_name->name),
PANGO_WRAP_WORD_CHAR,
PANGO_ELLIPSIZE_NONE);

View file

@ -354,7 +354,7 @@ void get_snapshot(const char *path)
panel->area.width = server.monitor[0].width;
panel->temp_pmap = XCreatePixmap(server.dsp, server.root_win, panel->area.width, panel->area.height, server.depth);
rendering(panel);
render_panel(panel);
Imlib_Image img = NULL;
imlib_context_set_drawable(panel->temp_pmap);
@ -545,7 +545,7 @@ void event_button_motion_notify (XEvent *e)
gpointer temp = task_iter->data;
task_iter->data = drag_iter->data;
drag_iter->data = temp;
event_taskbar->area.resize = 1;
event_taskbar->area.resize_needed = 1;
panel_refresh = 1;
task_dragged = 1;
}
@ -557,7 +557,7 @@ void event_button_motion_notify (XEvent *e)
return;
Taskbar * drag_taskbar = (Taskbar*)task_drag->area.parent;
remove_area(task_drag);
remove_area((Area*)task_drag);
if (event_taskbar->area.posx > drag_taskbar->area.posx || event_taskbar->area.posy > drag_taskbar->area.posy) {
int i = (taskbarname_enabled) ? 1 : 0;
@ -576,11 +576,11 @@ void event_button_motion_notify (XEvent *e)
sort_tasks(event_taskbar);
}
event_taskbar->area.resize = 1;
drag_taskbar->area.resize = 1;
event_taskbar->area.resize_needed = 1;
drag_taskbar->area.resize_needed = 1;
task_dragged = 1;
panel_refresh = 1;
panel->area.resize = 1;
panel->area.resize_needed = 1;
}
}
@ -714,7 +714,7 @@ void event_property_notify (XEvent *e)
if (strcmp(name, tskbar->bar_name.name) != 0) {
g_free(tskbar->bar_name.name);
tskbar->bar_name.name = name;
tskbar->bar_name.area.resize = 1;
tskbar->bar_name.area.resize_needed = 1;
}
else
g_free(name);
@ -738,7 +738,7 @@ void event_property_notify (XEvent *e)
init_taskbar_panel(&panel1[i]);
set_panel_items_order(&panel1[i]);
visible_taskbar(&panel1[i]);
panel1[i].area.resize = 1;
panel1[i].area.resize_needed = 1;
}
task_refresh_tasklist();
active_task();
@ -764,10 +764,10 @@ void event_property_notify (XEvent *e)
tsk = l->data;
if (tsk->desktop == ALLDESKTOP) {
tsk->area.on_screen = 0;
tskbar->area.resize = 1;
tskbar->area.resize_needed = 1;
panel_refresh = 1;
if (panel_mode == MULTI_DESKTOP)
panel->area.resize = 1;
panel->area.resize_needed = 1;
}
}
}
@ -778,9 +778,9 @@ void event_property_notify (XEvent *e)
tsk = l->data;
if (tsk->desktop == ALLDESKTOP) {
tsk->area.on_screen = 1;
tskbar->area.resize = 1;
tskbar->area.resize_needed = 1;
if (panel_mode == MULTI_DESKTOP)
panel->area.resize = 1;
panel->area.resize_needed = 1;
}
}
}
@ -1225,7 +1225,7 @@ start:
if (panel->temp_pmap)
XFreePixmap(server.dsp, panel->temp_pmap);
panel->temp_pmap = XCreatePixmap(server.dsp, server.root_win, panel->area.width, panel->area.height, server.depth);
rendering(panel);
render_panel(panel);
if (panel == (Panel*)systray.area.panel) {
if (refresh_systray && panel && !panel->is_hidden) {
refresh_systray = 0;

View file

@ -43,9 +43,9 @@ void default_tooltip()
// give the tooltip some reasonable default values
memset(&g_tooltip, 0, sizeof(Tooltip));
g_tooltip.font_color.color[0] = 1;
g_tooltip.font_color.color[1] = 1;
g_tooltip.font_color.color[2] = 1;
g_tooltip.font_color.rgb[0] = 1;
g_tooltip.font_color.rgb[1] = 1;
g_tooltip.font_color.rgb[2] = 1;
g_tooltip.font_color.alpha = 1;
just_shown = 0;
}
@ -217,28 +217,28 @@ void tooltip_update()
PangoLayout* layout;
cs = cairo_xlib_surface_create(server.dsp, g_tooltip.window, server.visual, width, height);
c = cairo_create(cs);
Color bc = g_tooltip.bg->back;
Color bc = g_tooltip.bg->fill_color;
Border b = g_tooltip.bg->border;
if (server.real_transparency) {
clear_pixmap(g_tooltip.window, 0, 0, width, height);
draw_rect(c, b.width, b.width, width-2*b.width, height-2*b.width, b.rounded-b.width/1.571);
cairo_set_source_rgba(c, bc.color[0], bc.color[1], bc.color[2], bc.alpha);
draw_rect(c, b.width, b.width, width-2*b.width, height-2*b.width, b.radius-b.width/1.571);
cairo_set_source_rgba(c, bc.rgb[0], bc.rgb[1], bc.rgb[2], bc.alpha);
}
else {
cairo_rectangle(c, 0., 0, width, height);
cairo_set_source_rgb(c, bc.color[0], bc.color[1], bc.color[2]);
cairo_set_source_rgb(c, bc.rgb[0], bc.rgb[1], bc.rgb[2]);
}
cairo_fill(c);
cairo_set_line_width(c, b.width);
if (server.real_transparency)
draw_rect(c, b.width/2.0, b.width/2.0, width - b.width, height - b.width, b.rounded);
draw_rect(c, b.width/2.0, b.width/2.0, width - b.width, height - b.width, b.radius);
else
cairo_rectangle(c, b.width/2.0, b.width/2.0, width-b.width, height-b.width);
cairo_set_source_rgba(c, b.color[0], b.color[1], b.color[2], b.alpha);
cairo_set_source_rgba(c, b.color.rgb[0], b.color.rgb[1], b.color.rgb[2], b.color.alpha);
cairo_stroke(c);
Color fc = g_tooltip.font_color;
cairo_set_source_rgba(c, fc.color[0], fc.color[1], fc.color[2], fc.alpha);
cairo_set_source_rgba(c, fc.rgb[0], fc.rgb[1], fc.rgb[2], fc.alpha);
layout = pango_cairo_create_layout(c);
pango_layout_set_font_description(layout, g_tooltip.font_desc);
pango_layout_set_text(layout, g_tooltip.tooltip_text, -1);

View file

@ -30,50 +30,9 @@
#include "server.h"
#include "panel.h"
/************************************************************
* !!! This design is experimental and not yet fully implemented !!!!!!!!!!!!!
*
* DATA ORGANISATION :
* Areas in tint2 are similar to widgets in a GUI.
* All graphical objects (panel, taskbar, task, systray, clock, ...) 'inherit' an abstract class 'Area'.
* This class 'Area' manage the background, border, size, position and padding.
* Area is at the begining of each object (&object == &area).
*
* tint2 define one panel per monitor. And each panel have a tree of Area.
* The root of the tree is Panel.Area. And task, clock, systray, taskbar,... are nodes.
*
* The tree give the localisation of each object :
* - tree's root is in the background while tree's leafe are foreground objects
* - position of a node/Area depend on the layout : parent's position (posx, posy), size of previous brothers and parent's padding
* - size of a node/Area depend on the content (SIZE_BY_CONTENT objects) or on the layout (SIZE_BY_LAYOUT objects)
*
* DRAWING AND LAYERING ENGINE :
* Redrawing an object (like the clock) could come from an 'external event' (date change)
* or from a 'layering event' (position change).
* The following 'drawing engine' take care of :
* - posx/posy of all Area
* - 'layering event' propagation between object
* 1) browse tree SIZE_BY_CONTENT
* - resize SIZE_BY_CONTENT node : children are resized before parent
* - if 'size' changed then 'resize = 1' on the parent
* 2) browse tree SIZE_BY_LAYOUT and POSITION
* - resize SIZE_BY_LAYOUT node : parent is resized before children
* - calculate position (posx,posy) : parent is calculated before children
* - if 'position' changed then 'redraw = 1'
* 3) browse tree REDRAW
* - redraw needed objects : parent is drawn before children
*
* CONFIGURE PANEL'S LAYOUT :
* 'panel_items' parameter (in config) define the list and the order of nodes in tree's panel.
* 'panel_items = SC' define a panel with just Systray and Clock.
* So the tree 'Panel.Area' will have 2 childs (Systray and Clock).
*
************************************************************/
Area *mouse_over_area = NULL;
void init_rendering(void *obj, int pos)
void initialize_positions(void *obj, int pos)
{
Area *a = (Area*)obj;
@ -86,58 +45,47 @@ void init_rendering(void *obj, int pos)
child->height = a->height - (2 * (a->bg->border.width + a->paddingy));
if (child->_on_change_layout)
child->_on_change_layout(child);
init_rendering(child, child->posy);
initialize_positions(child, child->posy);
}
else {
child->posx = pos + a->bg->border.width + a->paddingy;
child->width = a->width - (2 * (a->bg->border.width + a->paddingy));
if (child->_on_change_layout)
child->_on_change_layout(child);
init_rendering(child, child->posx);
initialize_positions(child, child->posx);
}
}
}
void rendering(void *obj)
void _relayout_fixed(Area *a)
{
Panel *panel = (Panel*)obj;
size_by_content(&panel->area);
size_by_layout(&panel->area, 1);
refresh(&panel->area);
}
void size_by_content (Area *a)
{
// don't resize hiden objects
if (!a->on_screen)
return;
// children node are resized before its parent
// Children are resized before the parent
GList *l;
for (l = a->children; l ; l = l->next)
size_by_content(l->data);
_relayout_fixed(l->data);
// calculate area's size
a->on_changed = 0;
if (a->resize && a->size_mode == SIZE_BY_CONTENT) {
a->resize = 0;
// Recalculate size
a->_changed = 0;
if (a->resize_needed && a->size_mode == LAYOUT_FIXED) {
a->resize_needed = 0;
if (a->_resize) {
if (a->_resize(a)) {
// 'size' changed => 'resize = 1' on the parent
((Area*)a->parent)->resize = 1;
a->on_changed = 1;
// The size hash changed => resize needed for the parent
if (a->parent)
((Area*)a->parent)->resize_needed = 1;
a->_changed = 1;
}
}
}
}
void size_by_layout (Area *a, int level)
void _relayout_dynamic(Area *a, int level)
{
// don't resize hiden objects
if (!a->on_screen)
@ -146,16 +94,16 @@ void size_by_layout (Area *a, int level)
// parent node is resized before its children
// calculate area's size
GList *l;
if (a->resize && a->size_mode == SIZE_BY_LAYOUT) {
a->resize = 0;
if (a->resize_needed && a->size_mode == LAYOUT_DYNAMIC) {
a->resize_needed = 0;
if (a->_resize) {
a->_resize(a);
// resize childs with SIZE_BY_LAYOUT
// resize children with LAYOUT_DYNAMIC
for (l = a->children; l ; l = l->next) {
Area *child = ((Area*)l->data);
if (child->size_mode == SIZE_BY_LAYOUT && child->children)
child->resize = 1;
if (child->size_mode == LAYOUT_DYNAMIC && child->children)
child->resize_needed = 1;
}
}
}
@ -174,17 +122,17 @@ void size_by_layout (Area *a, int level)
if (pos != child->posx) {
// pos changed => redraw
child->posx = pos;
child->on_changed = 1;
child->_changed = 1;
}
} else {
if (pos != child->posy) {
// pos changed => redraw
child->posy = pos;
child->on_changed = 1;
child->_changed = 1;
}
}
size_by_layout(child, level+1);
_relayout_dynamic(child, level+1);
pos += panel_horizontal ? child->width + a->paddingx : child->height + a->paddingx;
}
@ -202,17 +150,17 @@ void size_by_layout (Area *a, int level)
if (pos != child->posx) {
// pos changed => redraw
child->posx = pos;
child->on_changed = 1;
child->_changed = 1;
}
} else {
if (pos != child->posy) {
// pos changed => redraw
child->posy = pos;
child->on_changed = 1;
child->_changed = 1;
}
}
size_by_layout(child, level+1);
_relayout_dynamic(child, level+1);
pos -= a->paddingx;
}
@ -241,76 +189,77 @@ void size_by_layout (Area *a, int level)
if (pos != child->posx) {
// pos changed => redraw
child->posx = pos;
child->on_changed = 1;
child->_changed = 1;
}
} else {
if (pos != child->posy) {
// pos changed => redraw
child->posy = pos;
child->on_changed = 1;
child->_changed = 1;
}
}
size_by_layout(child, level+1);
_relayout_dynamic(child, level+1);
pos += panel_horizontal ? child->width + a->paddingx : child->height + a->paddingx;
}
}
}
if (a->on_changed) {
if (a->_changed) {
// pos/size changed
a->redraw = 1;
a->redraw_needed = 1;
if (a->_on_change_layout)
a->_on_change_layout (a);
}
}
void refresh (Area *a)
void draw_tree (Area *a)
{
// don't draw and resize hide objects
if (!a->on_screen) return;
if (!a->on_screen)
return;
// don't draw transparent objects (without foreground and without background)
if (a->redraw) {
a->redraw = 0;
if (a->redraw_needed) {
a->redraw_needed = 0;
// force redraw of child
//GList *l;
//for (l = a->children ; l ; l = l->next)
//((Area*)l->data)->redraw = 1;
//((Area*)l->data)->redraw_needed = 1;
//printf("draw area posx %d, width %d\n", a->posx, a->width);
draw(a);
}
// draw current Area
if (a->pix == 0) printf("empty area posx %d, width %d\n", a->posx, a->width);
XCopyArea (server.dsp, a->pix, ((Panel *)a->panel)->temp_pmap, server.gc, 0, 0, a->width, a->height, a->posx, a->posy);
if (a->pix == 0)
printf("empty area posx %d, width %d\n", a->posx, a->width);
XCopyArea(server.dsp, a->pix, ((Panel *)a->panel)->temp_pmap, server.gc, 0, 0, a->width, a->height, a->posx, a->posy);
// and then refresh child object
// and then draw child objects
GList *l;
for (l = a->children; l ; l = l->next)
refresh((Area*)l->data);
draw_tree((Area*)l->data);
}
int resize_by_layout(void *obj, int maximum_size)
int relayout_with_constraint(Area *a, int maximum_size)
{
Area *child, *a = (Area*)obj;
Area *child;
int size, nb_by_content=0, nb_by_layout=0;
if (panel_horizontal) {
// detect free size for SIZE_BY_LAYOUT's Area
// detect free size for LAYOUT_DYNAMIC's Area
size = a->width - (2 * (a->paddingxlr + a->bg->border.width));
GList *l;
for (l = a->children ; l ; l = l->next) {
child = (Area*)l->data;
if (child->on_screen && child->size_mode == SIZE_BY_CONTENT) {
if (child->on_screen && child->size_mode == LAYOUT_FIXED) {
size -= child->width;
nb_by_content++;
}
if (child->on_screen && child->size_mode == SIZE_BY_LAYOUT)
if (child->on_screen && child->size_mode == LAYOUT_DYNAMIC)
nb_by_layout++;
}
//printf(" resize_by_layout Deb %d, %d\n", nb_by_content, nb_by_layout);
@ -327,10 +276,10 @@ int resize_by_layout(void *obj, int maximum_size)
}
}
// resize SIZE_BY_LAYOUT objects
// resize LAYOUT_DYNAMIC objects
for (l = a->children ; l ; l = l->next) {
child = (Area*)l->data;
if (child->on_screen && child->size_mode == SIZE_BY_LAYOUT) {
if (child->on_screen && child->size_mode == LAYOUT_DYNAMIC) {
old_width = child->width;
child->width = width;
if (modulo) {
@ -338,21 +287,21 @@ int resize_by_layout(void *obj, int maximum_size)
modulo--;
}
if (child->width != old_width)
child->on_changed = 1;
child->_changed = 1;
}
}
}
else {
// detect free size for SIZE_BY_LAYOUT's Area
// detect free size for LAYOUT_DYNAMIC's Area
size = a->height - (2 * (a->paddingxlr + a->bg->border.width));
GList *l;
for (l = a->children ; l ; l = l->next) {
child = (Area*)l->data;
if (child->on_screen && child->size_mode == SIZE_BY_CONTENT) {
if (child->on_screen && child->size_mode == LAYOUT_FIXED) {
size -= child->height;
nb_by_content++;
}
if (child->on_screen && child->size_mode == SIZE_BY_LAYOUT)
if (child->on_screen && child->size_mode == LAYOUT_DYNAMIC)
nb_by_layout++;
}
if (nb_by_content+nb_by_layout)
@ -368,10 +317,10 @@ int resize_by_layout(void *obj, int maximum_size)
}
}
// resize SIZE_BY_LAYOUT objects
// resize LAYOUT_DYNAMIC objects
for (l = a->children ; l ; l = l->next) {
child = (Area*)l->data;
if (child->on_screen && child->size_mode == SIZE_BY_LAYOUT) {
if (child->on_screen && child->size_mode == LAYOUT_DYNAMIC) {
int old_height = child->height;
child->height = height;
if (modulo) {
@ -379,7 +328,7 @@ int resize_by_layout(void *obj, int maximum_size)
modulo--;
}
if (child->height != old_height)
child->on_changed = 1;
child->_changed = 1;
}
}
}
@ -387,13 +336,13 @@ int resize_by_layout(void *obj, int maximum_size)
}
void set_redraw (Area *a)
void schedule_redraw(Area *a)
{
a->redraw = 1;
a->redraw_needed = 1;
GList *l;
for (l = a->children ; l ; l = l->next)
set_redraw((Area*)l->data);
schedule_redraw((Area*)l->data);
}
void hide(Area *a)
@ -401,7 +350,8 @@ void hide(Area *a)
Area *parent = (Area*)a->parent;
a->on_screen = 0;
parent->resize = 1;
if (parent)
parent->resize_needed = 1;
if (panel_horizontal)
a->width = 0;
else
@ -413,19 +363,21 @@ void show(Area *a)
Area *parent = (Area*)a->parent;
a->on_screen = 1;
parent->resize = 1;
a->resize = 1;
if (parent)
parent->resize_needed = 1;
a->resize_needed = 1;
}
void draw (Area *a)
void draw(Area *a)
{
if (a->pix) XFreePixmap (server.dsp, a->pix);
a->pix = XCreatePixmap (server.dsp, server.root_win, a->width, a->height, server.depth);
if (a->pix)
XFreePixmap(server.dsp, a->pix);
a->pix = XCreatePixmap(server.dsp, server.root_win, a->width, a->height, server.depth);
// add layer of root pixmap (or clear pixmap if real_transparency==true)
if (server.real_transparency)
clear_pixmap(a->pix, 0 ,0, a->width, a->height);
XCopyArea (server.dsp, ((Panel *)a->panel)->temp_pmap, a->pix, server.gc, a->posx, a->posy, a->width, a->height, 0, 0);
XCopyArea(server.dsp, ((Panel *)a->panel)->temp_pmap, a->pix, server.gc, a->posx, a->posy, a->width, a->height, 0, 0);
cairo_surface_t *cs;
cairo_t *c;
@ -433,28 +385,28 @@ void draw (Area *a)
cs = cairo_xlib_surface_create (server.dsp, a->pix, server.visual, a->width, a->height);
c = cairo_create (cs);
draw_background (a, c);
draw_background(a, c);
if (a->_draw_foreground)
a->_draw_foreground(a, c);
cairo_destroy (c);
cairo_surface_destroy (cs);
cairo_destroy(c);
cairo_surface_destroy(cs);
}
void draw_background (Area *a, cairo_t *c)
{
if (a->bg->back.alpha > 0.0 ||
(panel_config.mouse_effects && (a->mouse_over_effect || a->mouse_press_effect))) {
//printf(" draw_background (%d %d) RGBA (%lf, %lf, %lf, %lf)\n", a->posx, a->posy, pix->back.color[0], pix->back.color[1], pix->back.color[2], pix->back.alpha);
if (a->bg->fill_color.alpha > 0.0 ||
(panel_config.mouse_effects && (a->has_mouse_over_effect || a->has_mouse_press_effect))) {
//printf(" draw_background (%d %d) RGBA (%lf, %lf, %lf, %lf)\n", a->posx, a->posy, pix->fill_color.rgb[0], pix->fill_color.rgb[1], pix->fill_color.rgb[2], pix->fill_color.alpha);
if (a->mouse_state == MOUSE_OVER)
cairo_set_source_rgba(c, a->bg->back_hover.color[0], a->bg->back_hover.color[1], a->bg->back_hover.color[2], a->bg->back_hover.alpha);
cairo_set_source_rgba(c, a->bg->fill_color_hover.rgb[0], a->bg->fill_color_hover.rgb[1], a->bg->fill_color_hover.rgb[2], a->bg->fill_color_hover.alpha);
else if (a->mouse_state == MOUSE_DOWN)
cairo_set_source_rgba(c, a->bg->back_pressed.color[0], a->bg->back_pressed.color[1], a->bg->back_pressed.color[2], a->bg->back_pressed.alpha);
cairo_set_source_rgba(c, a->bg->fill_color_pressed.rgb[0], a->bg->fill_color_pressed.rgb[1], a->bg->fill_color_pressed.rgb[2], a->bg->fill_color_pressed.alpha);
else
cairo_set_source_rgba(c, a->bg->back.color[0], a->bg->back.color[1], a->bg->back.color[2], a->bg->back.alpha);
draw_rect(c, a->bg->border.width, a->bg->border.width, a->width-(2.0 * a->bg->border.width), a->height-(2.0*a->bg->border.width), a->bg->border.rounded - a->bg->border.width/1.571);
cairo_set_source_rgba(c, a->bg->fill_color.rgb[0], a->bg->fill_color.rgb[1], a->bg->fill_color.rgb[2], a->bg->fill_color.alpha);
draw_rect(c, a->bg->border.width, a->bg->border.width, a->width-(2.0 * a->bg->border.width), a->height-(2.0*a->bg->border.width), a->bg->border.radius - a->bg->border.width/1.571);
cairo_fill(c);
}
@ -463,27 +415,27 @@ void draw_background (Area *a, cairo_t *c)
// draw border inside (x, y, width, height)
if (a->mouse_state == MOUSE_OVER)
cairo_set_source_rgba(c, a->bg->border_hover.color[0], a->bg->border_hover.color[1], a->bg->border_hover.color[2], a->bg->border_hover.alpha);
cairo_set_source_rgba(c, a->bg->border_color_hover.rgb[0], a->bg->border_color_hover.rgb[1], a->bg->border_color_hover.rgb[2], a->bg->border_color_hover.alpha);
else if (a->mouse_state == MOUSE_DOWN)
cairo_set_source_rgba(c, a->bg->border_pressed.color[0], a->bg->border_pressed.color[1], a->bg->border_pressed.color[2], a->bg->border_pressed.alpha);
cairo_set_source_rgba(c, a->bg->border_color_pressed.rgb[0], a->bg->border_color_pressed.rgb[1], a->bg->border_color_pressed.rgb[2], a->bg->border_color_pressed.alpha);
else
cairo_set_source_rgba(c, a->bg->border.color[0], a->bg->border.color[1], a->bg->border.color[2], a->bg->border.alpha);
draw_rect(c, a->bg->border.width/2.0, a->bg->border.width/2.0, a->width - a->bg->border.width, a->height - a->bg->border.width, a->bg->border.rounded);
cairo_set_source_rgba(c, a->bg->border.color.rgb[0], a->bg->border.color.rgb[1], a->bg->border.color.rgb[2], a->bg->border.color.alpha);
draw_rect(c, a->bg->border.width/2.0, a->bg->border.width/2.0, a->width - a->bg->border.width, a->height - a->bg->border.width, a->bg->border.radius);
cairo_stroke(c);
}
}
void remove_area (void *a)
void remove_area(Area *a)
{
Area *area = (Area*)a;
Area *parent = (Area*)area->parent;
if (parent) {
parent->children = g_list_remove(parent->children, area);
parent->resize = 1;
set_redraw(parent);
parent->resize_needed = 1;
schedule_redraw(parent);
}
if (mouse_over_area == a) {
@ -492,13 +444,15 @@ void remove_area (void *a)
}
void add_area (Area *a)
void add_area(Area *a, Area *parent)
{
Area *parent = (Area*)a->parent;
parent->children = g_list_append(parent->children, a);
set_redraw (parent);
g_assert_null(a->parent);
a->parent = parent;
if (parent) {
parent->children = g_list_append(parent->children, a);
schedule_redraw(parent);
}
}
@ -525,34 +479,6 @@ void free_area (Area *a)
}
void draw_rect(cairo_t *c, double x, double y, double w, double h, double r)
{
if (r > 0.0) {
double c1 = 0.55228475 * r;
cairo_move_to(c, x+r, y);
cairo_rel_line_to(c, w-2*r, 0);
cairo_rel_curve_to(c, c1, 0.0, r, c1, r, r);
cairo_rel_line_to(c, 0, h-2*r);
cairo_rel_curve_to(c, 0.0, c1, c1-r, r, -r, r);
cairo_rel_line_to (c, -w +2*r, 0);
cairo_rel_curve_to (c, -c1, 0, -r, -c1, -r, -r);
cairo_rel_line_to (c, 0, -h + 2 * r);
cairo_rel_curve_to (c, 0, -c1, r - c1, -r, r, -r);
}
else
cairo_rectangle(c, x, y, w, h);
}
void clear_pixmap(Pixmap p, int x, int y, int w, int h)
{
Picture pict = XRenderCreatePicture(server.dsp, p, XRenderFindVisualFormat(server.dsp, server.visual), 0, 0);
XRenderColor col = { .red=0, .green=0, .blue=0, .alpha=0 };
XRenderFillRectangle(server.dsp, PictOpSrc, pict, &col, x, y, w, h);
XRenderFreePicture(server.dsp, pict);
}
void mouse_over(Area *area, int pressed)
{
if (mouse_over_area == area && !area)
@ -561,11 +487,11 @@ void mouse_over(Area *area, int pressed)
MouseState new_state = MOUSE_NORMAL;
if (area) {
if (!pressed) {
new_state = area->mouse_over_effect ? MOUSE_OVER : MOUSE_NORMAL;
new_state = area->has_mouse_over_effect ? MOUSE_OVER : MOUSE_NORMAL;
} else {
new_state = area->mouse_press_effect
new_state = area->has_mouse_press_effect
? MOUSE_DOWN
: area->mouse_over_effect
: area->has_mouse_over_effect
? MOUSE_OVER
: MOUSE_NORMAL;
}
@ -579,7 +505,7 @@ void mouse_over(Area *area, int pressed)
mouse_over_area = area;
mouse_over_area->mouse_state = new_state;
set_redraw(mouse_over_area);
schedule_redraw(mouse_over_area);
panel_refresh = 1;
}
@ -588,7 +514,7 @@ void mouse_out()
if (!mouse_over_area)
return;
mouse_over_area->mouse_state = MOUSE_NORMAL;
set_redraw(mouse_over_area);
schedule_redraw(mouse_over_area);
panel_refresh = 1;
mouse_over_area = NULL;
}
@ -597,3 +523,9 @@ void init_background(Background *bg)
{
memset(bg, 0, sizeof(Background));
}
void relayout(Area *a)
{
_relayout_fixed(a);
_relayout_dynamic(a, 1);
}

View file

@ -1,19 +1,6 @@
/**************************************************************************
* Copyright (C) 2008 thierry lorthiois (lorthiois@bbsoft.fr)
*
* base class for all graphical objects (panel, taskbar, task, systray, clock, ...).
* Area is at the begining of each object (&object == &area).
*
* Area manage the background and border drawing, size and padding.
* Each Area has one Pixmap (pix).
*
* Area manage the tree of all objects. Parent object drawn before child object.
* panel -> taskbars -> tasks
* -> systray -> icons
* -> clock
*
* draw_foreground(obj) and resize(obj) are virtual function.
*
**************************************************************************/
#ifndef AREA_H
@ -24,129 +11,250 @@
#include <cairo.h>
#include <cairo-xlib.h>
// DATA ORGANISATION
//
// Areas in tint2 are similar to widgets in a GUI.
// All graphical objects (panel, taskbar, task, systray, clock, ...) inherit the abstract class Area.
// This class 'Area' stores data about the background, border, size, position, padding and the child areas.
// Inheritance is simulated by having an Area member as the first member of each object (thus &object == &area).
//
// tint2 uses multiple panels, one per monitor. Each panel has an area containing the children objects in a tree of
// areas. The level in the tree gives the z-order: child areas are always displayed on top of their parents.
//
//
// LAYOUT
//
// Sibling areas never overlap.
//
// The position of an Area (posx, posy) is relative to the window (i.e. absolute) and
// is computed based on a simple box model:
// * parent position + parent padding + sum of the sizes of the previous siblings and spacing
//
// The size of an Area is:
// * SIZE_BY_CONTENT objects:
// * fixed and set by the Area
// * childred are resized before the parent
// * if a child size has changed then the parent is resized
// * SIZE_BY_LAYOUT objects:
// * expandable and computed as the total size of the parent - padding -
// the size of the fixed sized siblings - spacing and divided by the number of expandable siblings
// * the parent is resized before the children
//
//
// RENDERING
//
// Redrawing an object (like the clock) could come from an 'external event' (date change)
// or from a 'layout event' (position change).
//
//
// WIDGET LIFECYCLE
//
// Each widget that occurs once per panel is defined as a struct (e.g. Clock) which is stored as a member of Panel.
// Widgets that can occur more than once should be stored as an array, still as a member of Panel.
//
// There is a special Panel instance called 'panel_config' which stores the config options and the state variables
// of the widgets (however some config options are stored as global variables by the widgets).
//
// Tint2 maintains an array of Panel instances, one for each monitor. These contain the actual Areas that are used to
// render the panels on screen, interact with user input etc.
// Each Panel is initialized as a raw copy (memcpy, see init_panel()) of panel_config.
//
// Normally, widgets should implement the following functions:
//
// * void default_widget();
//
// Called before the config is read and panel_config/panels are created.
// Afterwards, the config parsing code creates the widget/widget array in panel_config and
// populates the configuration fields.
// If the widget uses global variables to store config options or other state variables, they should be initialized
// here (e.g. with zero, NULL etc).
//
// * void init_widget();
//
// Called after the config is read and panel_config is populated, but before panels are created.
// Initializes the state of the widget in panel_config.
// If the widget uses global variables to store config options or other state variables which depend on the config
// options but not on the panel instance, they should be initialized here.
// panel_config.panel_items can be used to determine which backend items are enabled.
//
// * void init_widget_panel(void *panel);
//
// Called after each on-screen panel is created, with a pointer to the panel.
// Completes the initialization of the widget.
// At this point the widget Area has not been added yet to the GUI tree, but it will be added right afterwards.
//
// * void cleanup_widget();
//
// Called just before the panels are destroyed. Afterwards, tint2 exits or restarts and reads the config again.
// Must releases all resources.
// The widget itself should not be freed by this function, only its members or global variables that were set.
// The widget is freed by the Area tree cleanup function (remove_area).
//
// * void draw_widget(void *obj, cairo_t *c);
//
// Called on draw, obj = pointer to the widget instance from the panel that is redrawn.
// The Area's _draw_foreground member must point to this function.
//
// * int resize_widget(void *obj);
//
// Called on resize, obj = pointer to the front-end Execp item.
// Returns 1 if the new size is different than the previous size.
// The Area's _resize member must point to this function.
//
// * void widget_action(void *obj, int button);
//
// Called on mouse click event.
//
// * void widget_on_change_layout(void *obj);
//
// Implemented only to override the default layout algorithm for this widget.
// For example, if this widget is a cell in a table, its position and size should be computed here.
// The Area's _on_change_layout member must point to this function.
//
// * char* widget_get_tooltip_text(void *obj);
//
// Returns a copy of the tooltip to be displayed for this widget.
// The caller takes ownership of the pointer.
// The Area's _get_tooltip_text member must point to this function.
typedef struct
{
double color[3];
double alpha;
int width;
int rounded;
} Border;
typedef struct
{
double color[3];
typedef struct Color {
// Values are in [0, 1], with 0 meaning no intensity.
double rgb[3];
// Values are in [0, 1], with 0 meaning fully transparent, 1 meaning fully opaque.
double alpha;
} Color;
typedef struct
{
Color back;
typedef struct Border {
// It's essential that the first member is color
Color color;
// Width in pixels
int width;
// Corner radius
int radius;
} Border;
typedef struct Background {
// Normal state
Color fill_color;
Border border;
Color back_hover;
Color border_hover;
Color back_pressed;
Color border_pressed;
// On mouse hover
Color fill_color_hover;
Color border_color_hover;
// On mouse press
Color fill_color_pressed;
Color border_color_pressed;
} Background;
typedef enum Layout {
LAYOUT_DYNAMIC,
LAYOUT_FIXED
} Layout;
// way to calculate the size
// SIZE_BY_LAYOUT objects : taskbar and task
// SIZE_BY_CONTENT objects : clock, battery, launcher, systray
enum { SIZE_BY_LAYOUT, SIZE_BY_CONTENT };
enum { ALIGN_LEFT = 0, ALIGN_CENTER = 1, ALIGN_RIGHT = 2 };
typedef enum Alignment {
ALIGN_LEFT = 0,
ALIGN_CENTER = 1,
ALIGN_RIGHT = 2
} Alignment;
typedef enum {
typedef enum MouseState {
MOUSE_NORMAL = 0,
MOUSE_OVER = 1,
MOUSE_DOWN = 2
} MouseState;
typedef struct {
// coordinate relative to panel window
typedef struct Area {
// Position relative to the panel window
int posx, posy;
// width and height including border
// Size, including borders
int width, height;
Pixmap pix;
Background *bg;
// list of child : Area object
// List of children, each one a pointer to Area
GList *children;
// object visible on screen.
// An object (like systray) could be enabled but hidden (because no tray icon).
int on_screen;
// way to calculate the size (SIZE_BY_CONTENT or SIZE_BY_LAYOUT)
int size_mode;
int alignment;
// need to calculate position and width
int resize;
// need redraw Pixmap
int redraw;
// paddingxlr = horizontal padding left/right
// paddingx = horizontal padding between childs
int paddingxlr, paddingx, paddingy;
// parent Area
// Pointer to the parent Area or NULL
void *parent;
// panel
// Pointer to the Panel that contains this Area
void *panel;
int mouse_over_effect;
int mouse_press_effect;
Layout size_mode;
Alignment alignment;
gboolean has_mouse_over_effect;
gboolean has_mouse_press_effect;
// TODO padding/spacing is a clusterfuck
// paddingxlr = padding
// paddingy = vertical padding, sometimes
// paddingx = spacing
int paddingxlr, paddingx, paddingy;
MouseState mouse_state;
// Set to non-zero if the Area is visible. An object may exist but stay hidden.
gboolean on_screen;
// Set to non-zero if the size of the Area has to be recalculated.
gboolean resize_needed;
// Set to non-zero if the Area has to be redrawn.
gboolean redraw_needed;
// Set to non-zero if the position/size has changed, thus _on_change_layout needs to be called
gboolean _changed;
// This is the pixmap on which the Area is rendered. Render to it directly if needed.
Pixmap pix;
// each object can overwrite following function
// Callbacks
// Called on draw, obj = pointer to the Area
void (*_draw_foreground)(void *obj, cairo_t *c);
// update area's content and update size (width/heith).
// return '1' if size changed, '0' otherwise.
// Called on resize, obj = pointer to the Area
// Returns 1 if the new size is different than the previous size.
int (*_resize)(void *obj);
// after pos/size changed, the rendering engine will call _on_change_layout(Area*)
int on_changed;
// Implemented only to override the default layout algorithm for this widget.
// For example, if this widget is a cell in a table, its position and size should be computed here.
void (*_on_change_layout)(void *obj);
// returns allocated string, that must be free'd after usage
// Returns a copy of the tooltip to be displayed for this widget.
// The caller takes ownership of the pointer.
char* (*_get_tooltip_text)(void *obj);
} Area;
// Initializes the Background member to default values.
void init_background(Background *bg);
// on startup, initialize fixed pos/size
void init_rendering(void *obj, int pos);
// Layout
void rendering(void *obj);
void size_by_content (Area *a);
void size_by_layout (Area *a, int level);
// draw background and foreground
void refresh (Area *a);
// generic resize for SIZE_BY_LAYOUT objects
int resize_by_layout(void *obj, int maximum_size);
// Called on startup to initialize the positions of all Areas in the Area tree.
// Parameters:
// * obj: pointer to Area
// * pos: offset in pixels from left/top
void initialize_positions(void *obj, int pos);
// Relayouts the Area and its children. Normally called on the root of the tree (i.e. the Panel).
void relayout(Area *a);
// Distributes the Area's size to its children, repositioning them as needed.
// If maximum_size > 0, it is an upper limit for the child size.
int relayout_with_constraint(Area *a, int maximum_size);
// set 'redraw' on an area and childs
void set_redraw (Area *a);
// Rendering
// hide/unhide area
// Sets the redraw_needed flag on the area and its descendants
void schedule_redraw(Area *a);
// Recreates the Area pixmap and draws the background and the foreground
void draw(Area *a);
// Draws the background of the Area
void draw_background(Area *a, cairo_t *c);
// Explores the entire Area subtree (only if the on_screen flag set)
// and draws the areas with the redraw_needed flag set
void draw_tree(Area *a);
// Clears the on_screen flag, sets the size to zero and triggers a parent resize
void hide(Area *a);
// Sets the on_screen flag and triggers a parent and area resize
void show(Area *a);
// draw pixmap
void draw (Area *a);
void draw_background (Area *a, cairo_t *c);
// Area tree
void remove_area (void *a);
void add_area (Area *a);
void free_area (Area *a);
void add_area(Area *a, Area *parent);
void remove_area(Area *a);
void free_area(Area *a);
// draw rounded rectangle
void draw_rect(cairo_t *c, double x, double y, double w, double h, double r);
// clear pixmap with transparent color
void clear_pixmap(Pixmap p, int x, int y, int w, int h);
// Mouse move events
void mouse_over(Area *area, int pressed);
void mouse_out();
#endif

View file

@ -455,7 +455,7 @@ void draw_text(PangoLayout *layout, cairo_t *c, int posx, int posy, Color *color
}
}
}
cairo_set_source_rgba (c, color->color[0], color->color[1], color->color[2], color->alpha);
cairo_set_source_rgba (c, color->rgb[0], color->rgb[1], color->rgb[2], color->alpha);
pango_cairo_update_layout (c, layout);
cairo_move_to (c, posx, posy);
pango_cairo_show_layout (c, layout);
@ -524,3 +524,31 @@ Imlib_Image adjust_icon(Imlib_Image original, int alpha, int saturation, int bri
imlib_image_put_back_data(data);
return copy;
}
void draw_rect(cairo_t *c, double x, double y, double w, double h, double r)
{
if (r > 0.0) {
double c1 = 0.55228475 * r;
cairo_move_to(c, x+r, y);
cairo_rel_line_to(c, w-2*r, 0);
cairo_rel_curve_to(c, c1, 0.0, r, c1, r, r);
cairo_rel_line_to(c, 0, h-2*r);
cairo_rel_curve_to(c, 0.0, c1, c1-r, r, -r, r);
cairo_rel_line_to (c, -w +2*r, 0);
cairo_rel_curve_to (c, -c1, 0, -r, -c1, -r, -r);
cairo_rel_line_to (c, 0, -h + 2 * r);
cairo_rel_curve_to (c, 0, -c1, r - c1, -r, r, -r);
}
else
cairo_rectangle(c, x, y, w, h);
}
void clear_pixmap(Pixmap p, int x, int y, int w, int h)
{
Picture pict = XRenderCreatePicture(server.dsp, p, XRenderFindVisualFormat(server.dsp, server.visual), 0, 0);
XRenderColor col = { .red=0, .green=0, .blue=0, .alpha=0 };
XRenderFillRectangle(server.dsp, PictOpSrc, pict, &col, x, y, w, h);
XRenderFreePicture(server.dsp, pict);
}

View file

@ -78,5 +78,11 @@ Imlib_Image load_image(const char *path, int cached);
Imlib_Image adjust_icon(Imlib_Image original, int alpha, int saturation, int brightness);
// draw rounded rectangle
void draw_rect(cairo_t *c, double x, double y, double w, double h, double r);
// clear pixmap with transparent color
void clear_pixmap(Pixmap p, int x, int y, int w, int h);
#endif