2000-05-04 06:32:42 -04:00
|
|
|
/*
|
2001-03-12 05:33:13 -05:00
|
|
|
statusbar.c : irssi
|
2000-05-04 06:32:42 -04:00
|
|
|
|
2001-03-12 05:33:13 -05:00
|
|
|
Copyright (C) 1999-2001 Timo Sirainen
|
2000-05-04 06:32:42 -04:00
|
|
|
|
|
|
|
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
|
|
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program; if not, write to the Free Software
|
|
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "module.h"
|
|
|
|
#include "signals.h"
|
2001-10-13 12:11:13 -04:00
|
|
|
#include "expandos.h"
|
|
|
|
#include "special-vars.h"
|
2000-05-04 06:32:42 -04:00
|
|
|
|
2001-03-14 21:26:12 -05:00
|
|
|
#include "themes.h"
|
2000-05-04 06:32:42 -04:00
|
|
|
|
|
|
|
#include "statusbar.h"
|
2001-10-13 12:11:13 -04:00
|
|
|
#include "statusbar-config.h"
|
2000-05-04 06:32:42 -04:00
|
|
|
#include "gui-windows.h"
|
2001-10-13 12:11:13 -04:00
|
|
|
#include "gui-printtext.h"
|
2000-05-04 06:32:42 -04:00
|
|
|
|
2001-11-12 04:15:39 -05:00
|
|
|
void statusbar_items_init(void);
|
|
|
|
void statusbar_items_deinit(void);
|
|
|
|
|
2001-10-13 12:11:13 -04:00
|
|
|
GSList *statusbar_groups;
|
|
|
|
STATUSBAR_GROUP_REC *active_statusbar_group;
|
2001-03-14 21:26:12 -05:00
|
|
|
|
2001-10-13 12:11:13 -04:00
|
|
|
/*
|
|
|
|
sbar_item_defs: char *name => char *value
|
|
|
|
sbar_item_funcs: char *name => STATUSBAR_FUNC func
|
|
|
|
sbar_signal_items: int signal_id => GSList *(SBAR_ITEM_REC *items)
|
|
|
|
sbar_item_signals: SBAR_ITEM_REC *item => GSList *(int *signal_ids)
|
2001-10-20 15:52:07 -04:00
|
|
|
named_sbar_items: const char *name => GSList *(SBAR_ITEM_REC *items)
|
2001-10-13 12:11:13 -04:00
|
|
|
*/
|
|
|
|
static GHashTable *sbar_item_defs, *sbar_item_funcs;
|
|
|
|
static GHashTable *sbar_signal_items, *sbar_item_signals;
|
2001-10-20 15:52:07 -04:00
|
|
|
static GHashTable *named_sbar_items;
|
2001-11-18 13:06:51 -05:00
|
|
|
static int statusbar_need_recreate_items;
|
2001-10-13 12:11:13 -04:00
|
|
|
|
|
|
|
void statusbar_item_register(const char *name, const char *value,
|
|
|
|
STATUSBAR_FUNC func)
|
|
|
|
{
|
|
|
|
gpointer hkey, hvalue;
|
|
|
|
|
2001-11-18 13:06:51 -05:00
|
|
|
statusbar_need_recreate_items = TRUE;
|
2001-10-13 12:11:13 -04:00
|
|
|
if (value != NULL) {
|
|
|
|
if (g_hash_table_lookup_extended(sbar_item_defs,
|
|
|
|
name, &hkey, &hvalue)) {
|
|
|
|
g_hash_table_remove(sbar_item_defs, name);
|
|
|
|
g_free(hkey);
|
|
|
|
g_free(hvalue);
|
|
|
|
}
|
|
|
|
g_hash_table_insert(sbar_item_defs,
|
|
|
|
g_strdup(name), g_strdup(value));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (func != NULL) {
|
|
|
|
if (g_hash_table_lookup(sbar_item_funcs, name) == NULL) {
|
|
|
|
g_hash_table_insert(sbar_item_funcs,
|
|
|
|
g_strdup(name), func);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void statusbar_item_unregister(const char *name)
|
|
|
|
{
|
|
|
|
gpointer key, value;
|
|
|
|
|
2001-11-18 13:06:51 -05:00
|
|
|
statusbar_need_recreate_items = TRUE;
|
2001-10-13 12:11:13 -04:00
|
|
|
if (g_hash_table_lookup_extended(sbar_item_defs,
|
|
|
|
name, &key, &value)) {
|
|
|
|
g_hash_table_remove(sbar_item_defs, key);
|
|
|
|
g_free(key);
|
|
|
|
g_free(value);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (g_hash_table_lookup_extended(sbar_item_funcs,
|
|
|
|
name, &key, &value)) {
|
|
|
|
g_hash_table_remove(sbar_item_funcs, key);
|
|
|
|
g_free(key);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
STATUSBAR_GROUP_REC *statusbar_group_create(const char *name)
|
|
|
|
{
|
|
|
|
STATUSBAR_GROUP_REC *rec;
|
|
|
|
|
|
|
|
rec = g_new0(STATUSBAR_GROUP_REC, 1);
|
|
|
|
rec->name = g_strdup(name);
|
|
|
|
|
|
|
|
statusbar_groups = g_slist_append(statusbar_groups, rec);
|
|
|
|
return rec;
|
|
|
|
}
|
|
|
|
|
|
|
|
void statusbar_group_destroy(STATUSBAR_GROUP_REC *rec)
|
|
|
|
{
|
|
|
|
statusbar_groups = g_slist_remove(statusbar_groups, rec);
|
|
|
|
|
|
|
|
while (rec->bars != NULL)
|
|
|
|
statusbar_destroy(rec->bars->data);
|
|
|
|
while (rec->config_bars != NULL)
|
|
|
|
statusbar_config_destroy(rec, rec->config_bars->data);
|
2000-05-04 06:32:42 -04:00
|
|
|
|
2001-10-13 12:11:13 -04:00
|
|
|
g_free(rec->name);
|
|
|
|
g_free(rec);
|
|
|
|
}
|
2000-05-04 06:32:42 -04:00
|
|
|
|
2001-10-13 12:11:13 -04:00
|
|
|
STATUSBAR_GROUP_REC *statusbar_group_find(const char *name)
|
2000-05-04 06:32:42 -04:00
|
|
|
{
|
2001-10-13 12:11:13 -04:00
|
|
|
GSList *tmp;
|
|
|
|
|
|
|
|
for (tmp = statusbar_groups; tmp != NULL; tmp = tmp->next) {
|
|
|
|
STATUSBAR_GROUP_REC *rec = tmp->data;
|
|
|
|
|
|
|
|
if (strcmp(rec->name, name) == 0)
|
|
|
|
return rec;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
2000-05-04 06:32:42 -04:00
|
|
|
}
|
|
|
|
|
2001-03-12 05:33:13 -05:00
|
|
|
static int sbar_item_cmp(SBAR_ITEM_REC *item1, SBAR_ITEM_REC *item2)
|
2000-05-04 06:32:42 -04:00
|
|
|
{
|
2001-10-13 12:11:13 -04:00
|
|
|
return item1->config->priority == item2->config->priority ? 0 :
|
|
|
|
item1->config->priority < item2->config->priority ? -1 : 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int sbar_cmp_position(STATUSBAR_REC *bar1, STATUSBAR_REC *bar2)
|
|
|
|
{
|
|
|
|
return bar1->config->position < bar2->config->position ? -1 : 1;
|
2001-03-12 05:33:13 -05:00
|
|
|
}
|
2000-05-04 06:32:42 -04:00
|
|
|
|
2001-10-13 12:11:13 -04:00
|
|
|
/* Shink all items in statusbar to their minimum requested size.
|
|
|
|
The items list should be sorted by priority, highest first. */
|
2001-03-12 05:33:13 -05:00
|
|
|
static int statusbar_shrink_to_min(GSList *items, int size, int max_width)
|
|
|
|
{
|
|
|
|
GSList *tmp;
|
2000-05-04 06:32:42 -04:00
|
|
|
|
2001-03-12 05:33:13 -05:00
|
|
|
for (tmp = items; tmp != NULL; tmp = tmp->next) {
|
2000-05-04 06:32:42 -04:00
|
|
|
SBAR_ITEM_REC *rec = tmp->data;
|
|
|
|
|
2001-03-12 05:33:13 -05:00
|
|
|
size -= (rec->max_size-rec->min_size);
|
|
|
|
rec->size = rec->min_size;
|
|
|
|
|
|
|
|
if (size <= max_width) {
|
|
|
|
rec->size += max_width-size;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rec->size == 0) {
|
|
|
|
/* min_size was 0, item removed.
|
|
|
|
remove the marginal too */
|
|
|
|
size--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return size;
|
|
|
|
}
|
2000-05-04 06:32:42 -04:00
|
|
|
|
2001-10-13 12:11:13 -04:00
|
|
|
/* shink the items in statusbar, even if their size gets smaller than
|
|
|
|
their minimum requested size. The items list should be sorted by
|
|
|
|
priority, highest first. */
|
2001-03-12 05:33:13 -05:00
|
|
|
static void statusbar_shrink_forced(GSList *items, int size, int max_width)
|
|
|
|
{
|
|
|
|
GSList *tmp;
|
2001-01-31 06:23:29 -05:00
|
|
|
|
2001-03-12 05:33:13 -05:00
|
|
|
for (tmp = items; tmp != NULL; tmp = tmp->next) {
|
|
|
|
SBAR_ITEM_REC *rec = tmp->data;
|
2000-05-04 06:32:42 -04:00
|
|
|
|
2001-03-12 05:33:13 -05:00
|
|
|
if (size-rec->size > max_width) {
|
|
|
|
/* remove the whole item */
|
2001-10-13 12:11:13 -04:00
|
|
|
size -= rec->size;
|
2001-03-12 05:33:13 -05:00
|
|
|
rec->size = 0;
|
|
|
|
} else {
|
|
|
|
/* shrink the item */
|
|
|
|
rec->size -= size-max_width;
|
|
|
|
break;
|
2000-05-04 06:32:42 -04:00
|
|
|
}
|
|
|
|
}
|
2001-03-12 05:33:13 -05:00
|
|
|
}
|
2000-05-04 06:32:42 -04:00
|
|
|
|
2001-10-13 12:11:13 -04:00
|
|
|
static void statusbar_resize_items(STATUSBAR_REC *bar, int max_width)
|
2001-03-12 05:33:13 -05:00
|
|
|
{
|
|
|
|
GSList *tmp, *prior_sorted;
|
|
|
|
int width;
|
|
|
|
|
|
|
|
/* first give items their max. size */
|
|
|
|
prior_sorted = NULL;
|
2001-10-13 12:11:13 -04:00
|
|
|
width = 0;
|
2000-05-04 06:32:42 -04:00
|
|
|
for (tmp = bar->items; tmp != NULL; tmp = tmp->next) {
|
|
|
|
SBAR_ITEM_REC *rec = tmp->data;
|
|
|
|
|
2001-03-12 05:33:13 -05:00
|
|
|
rec->func(rec, TRUE);
|
|
|
|
rec->size = rec->max_size;
|
|
|
|
|
|
|
|
if (rec->size > 0) {
|
2001-10-13 12:11:13 -04:00
|
|
|
width += rec->max_size;
|
2000-05-04 06:32:42 -04:00
|
|
|
|
2001-03-12 05:33:13 -05:00
|
|
|
prior_sorted = g_slist_insert_sorted(prior_sorted, rec,
|
|
|
|
(GCompareFunc)
|
|
|
|
sbar_item_cmp);
|
|
|
|
}
|
|
|
|
}
|
2000-05-04 06:32:42 -04:00
|
|
|
|
2001-03-12 05:33:13 -05:00
|
|
|
if (width > max_width) {
|
|
|
|
/* too big, start shrinking from items with lowest priority
|
|
|
|
and shrink until everything fits or until we've shrinked
|
|
|
|
all items. */
|
|
|
|
width = statusbar_shrink_to_min(prior_sorted, width,
|
|
|
|
max_width);
|
|
|
|
if (width > max_width) {
|
|
|
|
/* still need to shrink, remove the items with lowest
|
|
|
|
priority until everything fits to screen */
|
|
|
|
statusbar_shrink_forced(prior_sorted, width,
|
|
|
|
max_width);
|
2000-05-04 06:32:42 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-03-12 05:33:13 -05:00
|
|
|
g_slist_free(prior_sorted);
|
2000-05-04 06:32:42 -04:00
|
|
|
}
|
|
|
|
|
2001-10-28 13:40:12 -05:00
|
|
|
#define SBAR_ITEM_REDRAW_NEEDED(_bar, _item, _xpos) \
|
|
|
|
(((_bar)->dirty_xpos != -1 && \
|
|
|
|
(_xpos) >= (_bar)->dirty_xpos) || \
|
|
|
|
(_item)->xpos != (_xpos) || (_item)->current_size != (_item)->size)
|
|
|
|
|
|
|
|
static void statusbar_calc_item_positions(STATUSBAR_REC *bar)
|
2000-05-04 06:32:42 -04:00
|
|
|
{
|
2001-05-11 13:35:38 -04:00
|
|
|
WINDOW_REC *old_active_win;
|
2001-11-15 13:44:58 -05:00
|
|
|
GSList *tmp, *right_items;
|
2001-03-12 05:33:13 -05:00
|
|
|
int xpos, rxpos;
|
2000-05-04 06:32:42 -04:00
|
|
|
|
2001-05-11 13:35:38 -04:00
|
|
|
old_active_win = active_win;
|
2001-10-13 12:11:13 -04:00
|
|
|
if (bar->parent_window != NULL)
|
|
|
|
active_win = bar->parent_window->active;
|
2001-05-11 13:35:38 -04:00
|
|
|
|
2001-10-28 06:30:26 -05:00
|
|
|
statusbar_resize_items(bar, term_width);
|
2000-05-04 06:32:42 -04:00
|
|
|
|
2001-10-28 13:40:12 -05:00
|
|
|
/* left-aligned items */
|
2001-10-13 12:11:13 -04:00
|
|
|
xpos = 0;
|
2001-03-12 05:33:13 -05:00
|
|
|
for (tmp = bar->items; tmp != NULL; tmp = tmp->next) {
|
|
|
|
SBAR_ITEM_REC *rec = tmp->data;
|
|
|
|
|
2001-11-17 11:39:23 -05:00
|
|
|
if (!rec->config->right_alignment &&
|
|
|
|
(rec->size > 0 || rec->current_size > 0)) {
|
2001-10-28 13:40:12 -05:00
|
|
|
if (SBAR_ITEM_REDRAW_NEEDED(bar, rec, xpos)) {
|
|
|
|
/* redraw the item */
|
|
|
|
rec->dirty = TRUE;
|
|
|
|
if (bar->dirty_xpos == -1 ||
|
|
|
|
xpos < bar->dirty_xpos) {
|
|
|
|
irssi_set_dirty();
|
|
|
|
bar->dirty = TRUE;
|
|
|
|
bar->dirty_xpos = xpos;
|
|
|
|
}
|
|
|
|
|
|
|
|
rec->xpos = xpos;
|
|
|
|
}
|
|
|
|
xpos += rec->size;
|
2001-03-12 05:33:13 -05:00
|
|
|
}
|
|
|
|
}
|
2000-05-04 06:32:42 -04:00
|
|
|
|
2001-11-15 13:44:58 -05:00
|
|
|
/* right-aligned items - first copy them to a new list backwards,
|
|
|
|
easier to draw them in right order */
|
|
|
|
right_items = NULL;
|
2001-03-12 05:33:13 -05:00
|
|
|
for (tmp = bar->items; tmp != NULL; tmp = tmp->next) {
|
|
|
|
SBAR_ITEM_REC *rec = tmp->data;
|
|
|
|
|
2001-11-15 13:44:58 -05:00
|
|
|
if (rec->config->right_alignment && rec->size > 0)
|
|
|
|
right_items = g_slist_prepend(right_items, rec);
|
|
|
|
}
|
2001-10-28 13:40:12 -05:00
|
|
|
|
2001-11-15 13:44:58 -05:00
|
|
|
rxpos = term_width;
|
|
|
|
for (tmp = right_items; tmp != NULL; tmp = tmp->next) {
|
|
|
|
SBAR_ITEM_REC *rec = tmp->data;
|
|
|
|
|
|
|
|
rxpos -= rec->size;
|
|
|
|
if (SBAR_ITEM_REDRAW_NEEDED(bar, rec, rxpos)) {
|
|
|
|
rec->dirty = TRUE;
|
|
|
|
if (bar->dirty_xpos == -1 ||
|
|
|
|
rxpos < bar->dirty_xpos) {
|
|
|
|
irssi_set_dirty();
|
|
|
|
bar->dirty = TRUE;
|
|
|
|
bar->dirty_xpos = rxpos;
|
|
|
|
}
|
|
|
|
rec->xpos = rxpos;
|
2001-03-12 05:33:13 -05:00
|
|
|
}
|
|
|
|
}
|
2001-11-15 13:44:58 -05:00
|
|
|
g_slist_free(right_items);
|
2001-05-11 13:35:38 -04:00
|
|
|
|
|
|
|
active_win = old_active_win;
|
2001-03-12 05:33:13 -05:00
|
|
|
}
|
|
|
|
|
2001-10-28 13:40:12 -05:00
|
|
|
void statusbar_redraw(STATUSBAR_REC *bar, int force)
|
2000-05-04 06:32:42 -04:00
|
|
|
{
|
2001-11-18 13:06:51 -05:00
|
|
|
if (statusbar_need_recreate_items)
|
|
|
|
return; /* don't bother yet */
|
|
|
|
|
2001-10-28 13:40:12 -05:00
|
|
|
if (bar != NULL) {
|
|
|
|
if (force) {
|
|
|
|
irssi_set_dirty();
|
|
|
|
bar->dirty = TRUE;
|
|
|
|
bar->dirty_xpos = 0;
|
2001-10-13 12:11:13 -04:00
|
|
|
}
|
2001-10-28 13:40:12 -05:00
|
|
|
statusbar_calc_item_positions(bar);
|
|
|
|
} else if (active_statusbar_group != NULL) {
|
|
|
|
g_slist_foreach(active_statusbar_group->bars,
|
|
|
|
(GFunc) statusbar_redraw,
|
|
|
|
GINT_TO_POINTER(force));
|
2000-05-04 06:32:42 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void statusbar_item_redraw(SBAR_ITEM_REC *item)
|
|
|
|
{
|
2001-08-03 22:31:36 -04:00
|
|
|
WINDOW_REC *old_active_win;
|
|
|
|
|
2000-05-04 06:32:42 -04:00
|
|
|
g_return_if_fail(item != NULL);
|
|
|
|
|
2001-08-03 22:31:36 -04:00
|
|
|
old_active_win = active_win;
|
2001-10-13 12:11:13 -04:00
|
|
|
if (item->bar->parent_window != NULL)
|
|
|
|
active_win = item->bar->parent_window->active;
|
2001-08-03 22:31:36 -04:00
|
|
|
|
2001-03-12 05:33:13 -05:00
|
|
|
item->func(item, TRUE);
|
2001-10-28 13:40:12 -05:00
|
|
|
|
|
|
|
item->dirty = TRUE;
|
|
|
|
item->bar->dirty = TRUE;
|
|
|
|
irssi_set_dirty();
|
|
|
|
|
2001-10-13 12:11:13 -04:00
|
|
|
if (item->max_size != item->size) {
|
|
|
|
/* item wants a new size - we'll need to redraw
|
|
|
|
the statusbar to see if this is allowed */
|
2001-10-28 13:40:12 -05:00
|
|
|
statusbar_redraw(item->bar, FALSE);
|
2001-03-12 05:33:13 -05:00
|
|
|
}
|
2001-08-03 22:31:36 -04:00
|
|
|
|
|
|
|
active_win = old_active_win;
|
2000-05-04 06:32:42 -04:00
|
|
|
}
|
|
|
|
|
2001-10-20 15:52:07 -04:00
|
|
|
void statusbar_items_redraw(const char *name)
|
|
|
|
{
|
|
|
|
g_slist_foreach(g_hash_table_lookup(named_sbar_items, name),
|
|
|
|
(GFunc) statusbar_item_redraw, NULL);
|
|
|
|
}
|
|
|
|
|
2001-10-14 06:45:00 -04:00
|
|
|
static void statusbars_recalc_ypos(STATUSBAR_REC *bar)
|
2001-03-14 21:26:12 -05:00
|
|
|
{
|
2001-10-13 12:11:13 -04:00
|
|
|
GSList *tmp, *bar_group;
|
|
|
|
int ypos;
|
2001-03-14 21:26:12 -05:00
|
|
|
|
2001-10-13 12:11:13 -04:00
|
|
|
/* get list of statusbars with same type and placement,
|
|
|
|
sorted by position */
|
|
|
|
bar_group = NULL;
|
|
|
|
tmp = bar->config->type == STATUSBAR_TYPE_ROOT ? bar->group->bars :
|
|
|
|
bar->parent_window->statusbars;
|
|
|
|
|
|
|
|
for (; tmp != NULL; tmp = tmp->next) {
|
|
|
|
STATUSBAR_REC *rec = tmp->data;
|
|
|
|
|
|
|
|
if (rec->config->type == bar->config->type &&
|
|
|
|
rec->config->placement == bar->config->placement) {
|
|
|
|
bar_group = g_slist_insert_sorted(bar_group, rec,
|
|
|
|
(GCompareFunc)
|
|
|
|
sbar_cmp_position);
|
2001-03-14 21:26:12 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-10-13 12:11:13 -04:00
|
|
|
if (bar_group == NULL) {
|
|
|
|
/* we just destroyed the last statusbar in this
|
|
|
|
type/placement group */
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* get the Y-position for the first statusbar */
|
|
|
|
if (bar->config->type == STATUSBAR_TYPE_ROOT) {
|
|
|
|
ypos = bar->config->placement == STATUSBAR_TOP ? 0 :
|
2001-10-28 06:30:26 -05:00
|
|
|
term_height - g_slist_length(bar_group);
|
2001-10-13 12:11:13 -04:00
|
|
|
} else {
|
|
|
|
ypos = bar->config->placement == STATUSBAR_TOP ?
|
|
|
|
bar->parent_window->first_line :
|
|
|
|
bar->parent_window->last_line -
|
|
|
|
(g_slist_length(bar_group)-1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* set the Y-positions */
|
|
|
|
while (bar_group != NULL) {
|
|
|
|
bar = bar_group->data;
|
|
|
|
|
|
|
|
if (bar->real_ypos != ypos) {
|
|
|
|
bar->real_ypos = ypos;
|
2001-10-28 13:40:12 -05:00
|
|
|
statusbar_redraw(bar, TRUE);
|
2001-10-13 12:11:13 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
ypos++;
|
|
|
|
bar_group = g_slist_remove(bar_group, bar_group->data);
|
|
|
|
}
|
2001-03-14 21:26:12 -05:00
|
|
|
}
|
|
|
|
|
2001-10-20 10:30:20 -04:00
|
|
|
static void sig_terminal_resized(void)
|
|
|
|
{
|
|
|
|
GSList *tmp;
|
|
|
|
|
|
|
|
for (tmp = active_statusbar_group->bars; tmp != NULL; tmp = tmp->next) {
|
|
|
|
STATUSBAR_REC *bar = tmp->data;
|
|
|
|
|
|
|
|
if (bar->config->type == STATUSBAR_TYPE_ROOT &&
|
|
|
|
bar->config->placement == STATUSBAR_BOTTOM) {
|
|
|
|
statusbars_recalc_ypos(bar);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void mainwindow_recalc_ypos(MAIN_WINDOW_REC *window, int placement)
|
|
|
|
{
|
|
|
|
GSList *tmp;
|
|
|
|
|
|
|
|
for (tmp = window->statusbars; tmp != NULL; tmp = tmp->next) {
|
|
|
|
STATUSBAR_REC *bar = tmp->data;
|
|
|
|
|
|
|
|
if (bar->config->placement == placement) {
|
|
|
|
statusbars_recalc_ypos(bar);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void sig_mainwindow_resized(MAIN_WINDOW_REC *window)
|
|
|
|
{
|
|
|
|
mainwindow_recalc_ypos(window, STATUSBAR_TOP);
|
|
|
|
mainwindow_recalc_ypos(window, STATUSBAR_BOTTOM);
|
|
|
|
}
|
|
|
|
|
2001-10-13 12:11:13 -04:00
|
|
|
STATUSBAR_REC *statusbar_create(STATUSBAR_GROUP_REC *group,
|
|
|
|
STATUSBAR_CONFIG_REC *config,
|
|
|
|
MAIN_WINDOW_REC *parent_window)
|
2000-05-04 06:32:42 -04:00
|
|
|
{
|
2001-10-13 12:11:13 -04:00
|
|
|
STATUSBAR_REC *bar;
|
|
|
|
THEME_REC *theme;
|
|
|
|
GSList *tmp;
|
|
|
|
char *name, *value;
|
|
|
|
|
|
|
|
g_return_val_if_fail(group != NULL, NULL);
|
|
|
|
g_return_val_if_fail(config != NULL, NULL);
|
|
|
|
g_return_val_if_fail(config->type != STATUSBAR_TYPE_WINDOW ||
|
|
|
|
parent_window != NULL, NULL);
|
|
|
|
|
|
|
|
bar = g_new0(STATUSBAR_REC, 1);
|
|
|
|
group->bars = g_slist_append(group->bars, bar);
|
|
|
|
|
|
|
|
bar->group = group;
|
|
|
|
|
|
|
|
bar->config = config;
|
|
|
|
bar->parent_window = parent_window;
|
|
|
|
|
2001-10-28 13:40:12 -05:00
|
|
|
irssi_set_dirty();
|
|
|
|
bar->dirty = TRUE;
|
|
|
|
bar->dirty_xpos = 0;
|
|
|
|
|
2001-10-20 10:30:20 -04:00
|
|
|
signal_remove("terminal resized", (SIGNAL_FUNC) sig_terminal_resized);
|
|
|
|
signal_remove("mainwindow resized", (SIGNAL_FUNC) sig_mainwindow_resized);
|
|
|
|
signal_remove("mainwindow moved", (SIGNAL_FUNC) sig_mainwindow_resized);
|
|
|
|
|
2001-10-13 12:11:13 -04:00
|
|
|
if (config->type == STATUSBAR_TYPE_ROOT) {
|
|
|
|
/* top/bottom of the screen */
|
|
|
|
mainwindows_reserve_lines(config->placement == STATUSBAR_TOP,
|
|
|
|
config->placement == STATUSBAR_BOTTOM);
|
|
|
|
theme = current_theme;
|
|
|
|
} else {
|
|
|
|
/* top/bottom of the window */
|
|
|
|
parent_window->statusbars =
|
|
|
|
g_slist_append(parent_window->statusbars, bar);
|
|
|
|
mainwindow_set_statusbar_lines(parent_window,
|
|
|
|
config->placement == STATUSBAR_TOP,
|
|
|
|
config->placement == STATUSBAR_BOTTOM);
|
|
|
|
theme = parent_window != NULL && parent_window->active != NULL &&
|
|
|
|
parent_window->active->theme != NULL ?
|
|
|
|
parent_window->active->theme : current_theme;
|
|
|
|
}
|
2000-05-04 06:32:42 -04:00
|
|
|
|
2001-10-20 10:30:20 -04:00
|
|
|
signal_add("terminal resized", (SIGNAL_FUNC) sig_terminal_resized);
|
|
|
|
signal_add("mainwindow resized", (SIGNAL_FUNC) sig_mainwindow_resized);
|
|
|
|
signal_add("mainwindow moved", (SIGNAL_FUNC) sig_mainwindow_resized);
|
|
|
|
|
2001-10-13 12:11:13 -04:00
|
|
|
/* get background color from sb_background abstract */
|
|
|
|
name = g_strdup_printf("{sb_%s_bg}", config->name);
|
|
|
|
value = theme_format_expand(theme, name);
|
|
|
|
g_free(name);
|
2000-05-04 06:32:42 -04:00
|
|
|
|
2001-10-13 12:11:13 -04:00
|
|
|
if (*value == '\0') {
|
|
|
|
/* try with the statusbar group name */
|
|
|
|
g_free(value);
|
2000-05-04 06:32:42 -04:00
|
|
|
|
2001-10-13 12:11:13 -04:00
|
|
|
name = g_strdup_printf("{sb_%s_bg}", group->name);
|
|
|
|
value = theme_format_expand(theme, name);
|
|
|
|
g_free(name);
|
2001-10-14 05:54:52 -04:00
|
|
|
|
|
|
|
if (*value == '\0') {
|
|
|
|
/* fallback to default statusbar background
|
|
|
|
(also provides backwards compatibility..) */
|
|
|
|
value = theme_format_expand(theme, "{sb_background}");
|
|
|
|
}
|
2001-10-13 12:11:13 -04:00
|
|
|
}
|
2001-03-14 21:26:12 -05:00
|
|
|
|
2001-10-13 12:11:13 -04:00
|
|
|
if (*value == '\0') {
|
|
|
|
g_free(value);
|
|
|
|
value = g_strdup("%8");
|
|
|
|
}
|
|
|
|
bar->color = g_strconcat("%n", value, NULL);
|
|
|
|
g_free(value);
|
|
|
|
|
2001-10-14 06:45:00 -04:00
|
|
|
statusbars_recalc_ypos(bar);
|
2001-10-13 12:11:13 -04:00
|
|
|
signal_emit("statusbar created", 1, bar);
|
2001-03-14 21:26:12 -05:00
|
|
|
|
2001-10-13 12:11:13 -04:00
|
|
|
/* create the items to statusbar */
|
|
|
|
for (tmp = config->items; tmp != NULL; tmp = tmp->next) {
|
|
|
|
SBAR_ITEM_CONFIG_REC *rec = tmp->data;
|
|
|
|
|
|
|
|
statusbar_item_create(bar, rec);
|
2000-05-04 06:32:42 -04:00
|
|
|
}
|
2001-10-13 12:11:13 -04:00
|
|
|
return bar;
|
|
|
|
}
|
2000-05-04 06:32:42 -04:00
|
|
|
|
2001-10-13 12:11:13 -04:00
|
|
|
void statusbar_destroy(STATUSBAR_REC *bar)
|
|
|
|
{
|
|
|
|
int top;
|
2000-05-04 06:32:42 -04:00
|
|
|
|
2001-10-13 12:11:13 -04:00
|
|
|
g_return_if_fail(bar != NULL);
|
|
|
|
|
|
|
|
bar->group->bars = g_slist_remove(bar->group->bars, bar);
|
|
|
|
if (bar->parent_window != NULL) {
|
|
|
|
bar->parent_window->statusbars =
|
|
|
|
g_slist_remove(bar->parent_window->statusbars, bar);
|
|
|
|
}
|
|
|
|
|
|
|
|
signal_emit("statusbar destroyed", 1, bar);
|
|
|
|
|
|
|
|
while (bar->items != NULL)
|
|
|
|
statusbar_item_destroy(bar->items->data);
|
|
|
|
|
|
|
|
g_free(bar->color);
|
|
|
|
|
|
|
|
if (bar->config->type != STATUSBAR_TYPE_WINDOW ||
|
|
|
|
bar->parent_window != NULL)
|
2001-10-14 06:45:00 -04:00
|
|
|
statusbars_recalc_ypos(bar);
|
2001-10-13 12:11:13 -04:00
|
|
|
|
|
|
|
top = bar->config->placement == STATUSBAR_TOP;
|
|
|
|
if (bar->config->type == STATUSBAR_TYPE_ROOT) {
|
|
|
|
/* top/bottom of the screen */
|
|
|
|
mainwindows_reserve_lines(top ? -1 : 0, !top ? -1 : 0);
|
|
|
|
} else if (bar->parent_window != NULL) {
|
|
|
|
/* top/bottom of the window */
|
|
|
|
mainwindow_set_statusbar_lines(bar->parent_window,
|
|
|
|
top ? -1 : 0, !top ? -1 : 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
g_free(bar);
|
2000-05-04 06:32:42 -04:00
|
|
|
}
|
|
|
|
|
2001-10-20 15:52:07 -04:00
|
|
|
void statusbar_recreate_items(STATUSBAR_REC *bar)
|
|
|
|
{
|
|
|
|
GSList *tmp;
|
|
|
|
|
|
|
|
/* destroy */
|
|
|
|
while (bar->items != NULL)
|
|
|
|
statusbar_item_destroy(bar->items->data);
|
|
|
|
|
|
|
|
/* create */
|
|
|
|
for (tmp = bar->config->items; tmp != NULL; tmp = tmp->next) {
|
|
|
|
SBAR_ITEM_CONFIG_REC *rec = tmp->data;
|
|
|
|
|
|
|
|
statusbar_item_create(bar, rec);
|
|
|
|
}
|
|
|
|
|
2001-10-28 13:40:12 -05:00
|
|
|
statusbar_redraw(bar, TRUE);
|
2001-10-20 15:52:07 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void statusbars_recreate_items(void)
|
|
|
|
{
|
|
|
|
if (active_statusbar_group != NULL) {
|
|
|
|
g_slist_foreach(active_statusbar_group->bars,
|
|
|
|
(GFunc) statusbar_recreate_items, NULL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-10-13 12:11:13 -04:00
|
|
|
STATUSBAR_REC *statusbar_find(STATUSBAR_GROUP_REC *group, const char *name,
|
|
|
|
MAIN_WINDOW_REC *window)
|
2000-05-04 06:32:42 -04:00
|
|
|
{
|
|
|
|
GSList *tmp;
|
|
|
|
|
2001-10-13 12:11:13 -04:00
|
|
|
for (tmp = group->bars; tmp != NULL; tmp = tmp->next) {
|
2000-05-04 06:32:42 -04:00
|
|
|
STATUSBAR_REC *rec = tmp->data;
|
|
|
|
|
2001-10-13 12:11:13 -04:00
|
|
|
if (rec->parent_window == window &&
|
|
|
|
strcmp(rec->config->name, name) == 0)
|
|
|
|
return rec;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static char *update_statusbar_bg(const char *str, const char *color)
|
|
|
|
{
|
|
|
|
GString *out;
|
|
|
|
char *ret;
|
|
|
|
|
|
|
|
out = g_string_new(color);
|
|
|
|
while (*str != '\0') {
|
|
|
|
if (*str == '%' && str[1] == 'n') {
|
|
|
|
g_string_append(out, color);
|
|
|
|
str += 2;
|
|
|
|
continue;
|
2000-05-04 06:32:42 -04:00
|
|
|
}
|
2001-10-13 12:11:13 -04:00
|
|
|
|
|
|
|
g_string_append_c(out, *str);
|
|
|
|
str++;
|
2000-05-04 06:32:42 -04:00
|
|
|
}
|
2001-10-13 12:11:13 -04:00
|
|
|
|
|
|
|
ret = out->str;
|
|
|
|
g_string_free(out, FALSE);
|
|
|
|
return ret;
|
2000-05-04 06:32:42 -04:00
|
|
|
}
|
|
|
|
|
2001-10-13 12:11:13 -04:00
|
|
|
const char *statusbar_item_get_value(SBAR_ITEM_REC *item)
|
2000-05-04 06:32:42 -04:00
|
|
|
{
|
2001-10-13 12:11:13 -04:00
|
|
|
const char *value;
|
2000-05-04 06:32:42 -04:00
|
|
|
|
2001-10-13 12:11:13 -04:00
|
|
|
value = item->config->value;
|
|
|
|
if (value == NULL) {
|
|
|
|
value = g_hash_table_lookup(sbar_item_defs,
|
|
|
|
item->config->name);
|
|
|
|
}
|
2000-05-04 06:32:42 -04:00
|
|
|
|
2001-10-13 12:11:13 -04:00
|
|
|
return value;
|
|
|
|
}
|
2000-05-04 06:32:42 -04:00
|
|
|
|
2001-10-13 12:11:13 -04:00
|
|
|
void statusbar_item_default_handler(SBAR_ITEM_REC *item, int get_size_only,
|
|
|
|
const char *str, const char *data,
|
|
|
|
int escape_vars)
|
|
|
|
{
|
|
|
|
SERVER_REC *server;
|
|
|
|
WI_ITEM_REC *wiitem;
|
|
|
|
char *tmpstr, *tmpstr2;
|
|
|
|
int len;
|
|
|
|
|
|
|
|
if (str == NULL)
|
|
|
|
str = statusbar_item_get_value(item);
|
|
|
|
if (str == NULL || *str == '\0') {
|
|
|
|
item->min_size = item->max_size = 0;
|
|
|
|
return;
|
|
|
|
}
|
2000-05-04 06:32:42 -04:00
|
|
|
|
2001-10-13 12:11:13 -04:00
|
|
|
if (active_win == NULL) {
|
|
|
|
server = NULL;
|
|
|
|
wiitem = NULL;
|
|
|
|
} else {
|
|
|
|
server = active_win->active_server;
|
|
|
|
wiitem = active_win->active;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* expand templates */
|
2001-11-15 15:02:15 -05:00
|
|
|
tmpstr = theme_format_expand_data(current_theme, &str,
|
|
|
|
'n', 'n',
|
|
|
|
NULL, NULL,
|
|
|
|
EXPAND_FLAG_ROOT |
|
|
|
|
EXPAND_FLAG_IGNORE_REPLACES |
|
|
|
|
EXPAND_FLAG_IGNORE_EMPTY);
|
|
|
|
/* expand $variables */
|
|
|
|
tmpstr2 = parse_special_string(tmpstr, server, wiitem, data, NULL,
|
|
|
|
(escape_vars ? PARSE_FLAG_ESCAPE_VARS : 0 ));
|
|
|
|
g_free(tmpstr);
|
2001-10-13 12:11:13 -04:00
|
|
|
|
|
|
|
/* remove color codes (not %formats) */
|
|
|
|
tmpstr = strip_codes(tmpstr2);
|
|
|
|
g_free(tmpstr2);
|
|
|
|
|
|
|
|
if (get_size_only) {
|
|
|
|
item->min_size = item->max_size = format_get_length(tmpstr);
|
|
|
|
} else {
|
|
|
|
if (item->size < item->min_size) {
|
|
|
|
/* they're forcing us smaller than minimum size.. */
|
|
|
|
len = format_real_length(tmpstr, item->size);
|
|
|
|
tmpstr[len] = '\0';
|
|
|
|
}
|
|
|
|
|
|
|
|
tmpstr2 = update_statusbar_bg(tmpstr, item->bar->color);
|
|
|
|
gui_printtext(item->xpos, item->bar->real_ypos, tmpstr2);
|
|
|
|
g_free(tmpstr2);
|
|
|
|
}
|
|
|
|
g_free(tmpstr);
|
|
|
|
}
|
2000-05-04 06:32:42 -04:00
|
|
|
|
2001-10-13 12:11:13 -04:00
|
|
|
static void statusbar_item_default_func(SBAR_ITEM_REC *item, int get_size_only)
|
|
|
|
{
|
|
|
|
statusbar_item_default_handler(item, get_size_only, NULL, "", TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void statusbar_update_item(void)
|
|
|
|
{
|
|
|
|
GSList *items;
|
|
|
|
|
|
|
|
items = g_hash_table_lookup(sbar_signal_items,
|
|
|
|
GINT_TO_POINTER(signal_get_emitted_id()));
|
|
|
|
while (items != NULL) {
|
|
|
|
SBAR_ITEM_REC *item = items->data;
|
|
|
|
|
|
|
|
statusbar_item_redraw(item);
|
|
|
|
items = items->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void statusbar_update_server(SERVER_REC *server)
|
|
|
|
{
|
|
|
|
SERVER_REC *item_server;
|
|
|
|
GSList *items;
|
|
|
|
|
|
|
|
items = g_hash_table_lookup(sbar_signal_items,
|
|
|
|
GINT_TO_POINTER(signal_get_emitted_id()));
|
|
|
|
while (items != NULL) {
|
|
|
|
SBAR_ITEM_REC *item = items->data;
|
|
|
|
|
|
|
|
item_server = item->bar->parent_window != NULL ?
|
|
|
|
item->bar->parent_window->active->active_server :
|
|
|
|
active_win->active_server;
|
|
|
|
|
|
|
|
if (item_server == server)
|
|
|
|
statusbar_item_redraw(item);
|
|
|
|
|
|
|
|
items = items->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void statusbar_update_window(WINDOW_REC *window)
|
|
|
|
{
|
|
|
|
WINDOW_REC *item_window;
|
|
|
|
GSList *items;
|
|
|
|
|
|
|
|
items = g_hash_table_lookup(sbar_signal_items,
|
|
|
|
GINT_TO_POINTER(signal_get_emitted_id()));
|
|
|
|
while (items != NULL) {
|
|
|
|
SBAR_ITEM_REC *item = items->data;
|
|
|
|
|
|
|
|
item_window = item->bar->parent_window != NULL ?
|
|
|
|
item->bar->parent_window->active : active_win;
|
|
|
|
|
|
|
|
if (item_window == window)
|
|
|
|
statusbar_item_redraw(item);
|
|
|
|
|
|
|
|
items = items->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void statusbar_update_window_item(WI_ITEM_REC *wiitem)
|
|
|
|
{
|
|
|
|
WI_ITEM_REC *item_wi;
|
|
|
|
GSList *items;
|
|
|
|
|
|
|
|
items = g_hash_table_lookup(sbar_signal_items,
|
|
|
|
GINT_TO_POINTER(signal_get_emitted_id()));
|
|
|
|
while (items != NULL) {
|
|
|
|
SBAR_ITEM_REC *item = items->data;
|
|
|
|
|
|
|
|
item_wi = item->bar->parent_window != NULL ?
|
|
|
|
item->bar->parent_window->active->active :
|
|
|
|
active_win->active;
|
|
|
|
|
|
|
|
if (item_wi == wiitem)
|
|
|
|
statusbar_item_redraw(item);
|
|
|
|
|
|
|
|
items = items->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void statusbar_item_default_signals(SBAR_ITEM_REC *item)
|
|
|
|
{
|
|
|
|
SIGNAL_FUNC func;
|
|
|
|
GSList *list;
|
|
|
|
const char *value;
|
|
|
|
void *signal_id;
|
|
|
|
int *signals, *pos;
|
|
|
|
|
|
|
|
value = statusbar_item_get_value(item);
|
|
|
|
if (value == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
signals = special_vars_get_signals(value);
|
|
|
|
if (signals == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
for (pos = signals; *pos != -1; pos += 2) {
|
|
|
|
/* update signal -> item mappings */
|
|
|
|
signal_id = GINT_TO_POINTER(*pos);
|
|
|
|
list = g_hash_table_lookup(sbar_signal_items, signal_id);
|
|
|
|
if (list == NULL) {
|
|
|
|
switch (pos[1]) {
|
|
|
|
case EXPANDO_ARG_NONE:
|
|
|
|
func = (SIGNAL_FUNC) statusbar_update_item;
|
|
|
|
break;
|
|
|
|
case EXPANDO_ARG_SERVER:
|
|
|
|
func = (SIGNAL_FUNC) statusbar_update_server;
|
|
|
|
break;
|
|
|
|
case EXPANDO_ARG_WINDOW:
|
|
|
|
func = (SIGNAL_FUNC) statusbar_update_window;
|
|
|
|
break;
|
|
|
|
case EXPANDO_ARG_WINDOW_ITEM:
|
|
|
|
func = (SIGNAL_FUNC) statusbar_update_window_item;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
func = NULL;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (func != NULL)
|
|
|
|
signal_add_to_id(MODULE_NAME, 1, *pos, func);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (g_slist_find(list, item) == NULL)
|
|
|
|
list = g_slist_append(list, item);
|
|
|
|
g_hash_table_insert(sbar_signal_items, signal_id, list);
|
|
|
|
|
|
|
|
/* update item -> signal mappings */
|
|
|
|
list = g_hash_table_lookup(sbar_item_signals, item);
|
|
|
|
if (g_slist_find(list, signal_id) == NULL)
|
|
|
|
list = g_slist_append(list, signal_id);
|
|
|
|
g_hash_table_insert(sbar_item_signals, item, list);
|
|
|
|
}
|
|
|
|
g_free(signals);
|
2000-05-04 06:32:42 -04:00
|
|
|
}
|
|
|
|
|
2001-03-12 05:33:13 -05:00
|
|
|
SBAR_ITEM_REC *statusbar_item_create(STATUSBAR_REC *bar,
|
2001-10-13 12:11:13 -04:00
|
|
|
SBAR_ITEM_CONFIG_REC *config)
|
2000-05-04 06:32:42 -04:00
|
|
|
{
|
|
|
|
SBAR_ITEM_REC *rec;
|
2001-10-20 15:52:07 -04:00
|
|
|
GSList *items;
|
2000-05-04 06:32:42 -04:00
|
|
|
|
|
|
|
g_return_val_if_fail(bar != NULL, NULL);
|
2001-10-13 12:11:13 -04:00
|
|
|
g_return_val_if_fail(config != NULL, NULL);
|
2000-05-04 06:32:42 -04:00
|
|
|
|
|
|
|
rec = g_new0(SBAR_ITEM_REC, 1);
|
|
|
|
bar->items = g_slist_append(bar->items, rec);
|
|
|
|
|
2001-10-13 12:11:13 -04:00
|
|
|
rec->bar = bar;
|
|
|
|
rec->config = config;
|
|
|
|
|
|
|
|
rec->func = g_hash_table_lookup(sbar_item_funcs, config->name);
|
|
|
|
if (rec->func == NULL)
|
|
|
|
rec->func = statusbar_item_default_func;
|
|
|
|
statusbar_item_default_signals(rec);
|
2000-05-04 06:32:42 -04:00
|
|
|
|
2001-10-20 15:52:07 -04:00
|
|
|
items = g_hash_table_lookup(named_sbar_items, config->name);
|
|
|
|
items = g_slist_append(items, rec);
|
|
|
|
g_hash_table_insert(named_sbar_items, config->name, items);
|
|
|
|
|
2001-10-28 13:40:12 -05:00
|
|
|
irssi_set_dirty();
|
|
|
|
rec->dirty = TRUE;
|
|
|
|
bar->dirty = TRUE;
|
|
|
|
|
2001-10-13 12:11:13 -04:00
|
|
|
signal_emit("statusbar item created", 1, rec);
|
2000-05-04 06:32:42 -04:00
|
|
|
return rec;
|
|
|
|
}
|
|
|
|
|
2001-10-13 12:11:13 -04:00
|
|
|
static void statusbar_signal_remove(int signal_id)
|
|
|
|
{
|
|
|
|
signal_remove_id(signal_id, (SIGNAL_FUNC) statusbar_update_item);
|
|
|
|
signal_remove_id(signal_id, (SIGNAL_FUNC) statusbar_update_server);
|
|
|
|
signal_remove_id(signal_id, (SIGNAL_FUNC) statusbar_update_window);
|
|
|
|
signal_remove_id(signal_id, (SIGNAL_FUNC) statusbar_update_window_item);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void statusbar_item_remove_signal(SBAR_ITEM_REC *item, int signal_id)
|
2000-05-04 06:32:42 -04:00
|
|
|
{
|
2001-10-13 12:11:13 -04:00
|
|
|
GSList *list;
|
|
|
|
|
|
|
|
/* update signal -> item hash */
|
|
|
|
list = g_hash_table_lookup(sbar_signal_items,
|
|
|
|
GINT_TO_POINTER(signal_id));
|
|
|
|
list = g_slist_remove(list, item);
|
|
|
|
if (list != NULL) {
|
|
|
|
g_hash_table_insert(sbar_signal_items,
|
|
|
|
GINT_TO_POINTER(signal_id), list);
|
|
|
|
} else {
|
|
|
|
g_hash_table_remove(sbar_signal_items,
|
|
|
|
GINT_TO_POINTER(signal_id));
|
|
|
|
statusbar_signal_remove(signal_id);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void statusbar_item_destroy(SBAR_ITEM_REC *item)
|
|
|
|
{
|
|
|
|
GSList *list;
|
|
|
|
|
2000-05-04 06:32:42 -04:00
|
|
|
g_return_if_fail(item != NULL);
|
|
|
|
|
2001-10-13 12:11:13 -04:00
|
|
|
item->bar->items = g_slist_remove(item->bar->items, item);
|
2001-10-20 15:52:07 -04:00
|
|
|
|
|
|
|
list = g_hash_table_lookup(named_sbar_items, item->config->name);
|
|
|
|
list = g_slist_remove(list, item);
|
|
|
|
if (list == NULL)
|
|
|
|
g_hash_table_remove(named_sbar_items, item->config->name);
|
|
|
|
else
|
|
|
|
g_hash_table_insert(named_sbar_items, item->config->name, list);
|
|
|
|
|
2001-10-13 12:11:13 -04:00
|
|
|
signal_emit("statusbar item destroyed", 1, item);
|
|
|
|
|
|
|
|
list = g_hash_table_lookup(sbar_item_signals, item);
|
|
|
|
g_hash_table_remove(sbar_item_signals, item);
|
|
|
|
|
|
|
|
while (list != NULL) {
|
|
|
|
statusbar_item_remove_signal(item, GPOINTER_TO_INT(list->data));
|
|
|
|
list = g_slist_remove(list, list->data);
|
|
|
|
}
|
|
|
|
|
|
|
|
g_free(item);
|
|
|
|
}
|
|
|
|
|
2001-10-28 13:40:12 -05:00
|
|
|
static void statusbar_redraw_needed_items(STATUSBAR_REC *bar)
|
|
|
|
{
|
|
|
|
WINDOW_REC *old_active_win;
|
|
|
|
GSList *tmp;
|
|
|
|
char *str;
|
|
|
|
|
|
|
|
old_active_win = active_win;
|
|
|
|
if (bar->parent_window != NULL)
|
|
|
|
active_win = bar->parent_window->active;
|
|
|
|
|
|
|
|
if (bar->dirty_xpos >= 0) {
|
|
|
|
str = g_strconcat(bar->color, "%>", NULL);
|
|
|
|
gui_printtext(bar->dirty_xpos, bar->real_ypos, str);
|
|
|
|
g_free(str);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (tmp = bar->items; tmp != NULL; tmp = tmp->next) {
|
|
|
|
SBAR_ITEM_REC *rec = tmp->data;
|
|
|
|
|
|
|
|
if (rec->dirty ||
|
|
|
|
(bar->dirty_xpos != -1 &&
|
|
|
|
rec->xpos >= bar->dirty_xpos)) {
|
|
|
|
rec->current_size = rec->size;
|
|
|
|
rec->func(rec, FALSE);
|
|
|
|
rec->dirty = FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
active_win = old_active_win;
|
|
|
|
}
|
|
|
|
|
|
|
|
void statusbar_redraw_dirty(void)
|
|
|
|
{
|
|
|
|
GSList *tmp;
|
|
|
|
|
2001-11-18 13:16:14 -05:00
|
|
|
if (statusbar_need_recreate_items) {
|
2001-11-18 13:06:51 -05:00
|
|
|
statusbar_need_recreate_items = FALSE;
|
|
|
|
statusbars_recreate_items();
|
|
|
|
}
|
|
|
|
|
2001-10-28 13:40:12 -05:00
|
|
|
for (tmp = active_statusbar_group->bars; tmp != NULL; tmp = tmp->next) {
|
|
|
|
STATUSBAR_REC *rec = tmp->data;
|
|
|
|
|
|
|
|
if (rec->dirty) {
|
|
|
|
statusbar_redraw_needed_items(rec);
|
|
|
|
rec->dirty = FALSE;
|
|
|
|
rec->dirty_xpos = -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-10-13 12:11:13 -04:00
|
|
|
#define STATUSBAR_IS_VISIBLE(bar, window) \
|
|
|
|
((bar)->visible == STATUSBAR_VISIBLE_ALWAYS || \
|
|
|
|
(active_mainwin == (window) && \
|
|
|
|
(bar)->visible == STATUSBAR_VISIBLE_ACTIVE) || \
|
|
|
|
(active_mainwin != (window) && \
|
|
|
|
(bar)->visible == STATUSBAR_VISIBLE_INACTIVE))
|
|
|
|
|
|
|
|
static void statusbars_remove_unvisible(MAIN_WINDOW_REC *window)
|
|
|
|
{
|
|
|
|
GSList *tmp, *next;
|
|
|
|
|
|
|
|
for (tmp = window->statusbars; tmp != NULL; tmp = next) {
|
|
|
|
STATUSBAR_REC *bar = tmp->data;
|
|
|
|
|
|
|
|
next = tmp->next;
|
|
|
|
if (!STATUSBAR_IS_VISIBLE(bar->config, window))
|
|
|
|
statusbar_destroy(bar);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void statusbars_add_visible(MAIN_WINDOW_REC *window)
|
|
|
|
{
|
|
|
|
STATUSBAR_GROUP_REC *group;
|
|
|
|
STATUSBAR_REC *bar;
|
|
|
|
GSList *tmp;
|
|
|
|
|
|
|
|
group = active_statusbar_group;
|
|
|
|
for (tmp = group->config_bars; tmp != NULL; tmp = tmp->next) {
|
|
|
|
STATUSBAR_CONFIG_REC *config = tmp->data;
|
|
|
|
|
|
|
|
if (config->type == STATUSBAR_TYPE_WINDOW &&
|
|
|
|
STATUSBAR_IS_VISIBLE(config, window) &&
|
|
|
|
statusbar_find(group, config->name, window) == NULL) {
|
|
|
|
bar = statusbar_create(group, config, window);
|
2001-10-28 13:40:12 -05:00
|
|
|
statusbar_redraw(bar, TRUE);
|
2001-10-13 12:11:13 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void sig_mainwindow_destroyed(MAIN_WINDOW_REC *window)
|
|
|
|
{
|
|
|
|
while (window->statusbars != NULL) {
|
|
|
|
STATUSBAR_REC *bar = window->statusbars->data;
|
|
|
|
|
|
|
|
bar->parent_window->statusbars =
|
|
|
|
g_slist_remove(bar->parent_window->statusbars, bar);
|
|
|
|
bar->parent_window = NULL;
|
|
|
|
statusbar_destroy(bar);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void sig_window_changed(void)
|
|
|
|
{
|
|
|
|
GSList *tmp;
|
2000-05-04 06:32:42 -04:00
|
|
|
|
2001-10-13 12:11:13 -04:00
|
|
|
for (tmp = mainwindows; tmp != NULL; tmp = tmp->next) {
|
|
|
|
MAIN_WINDOW_REC *rec = tmp->data;
|
|
|
|
|
|
|
|
statusbars_remove_unvisible(rec);
|
|
|
|
statusbars_add_visible(rec);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void statusbar_item_def_destroy(void *key, void *value)
|
|
|
|
{
|
|
|
|
g_free(key);
|
|
|
|
g_free(value);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void statusbar_signal_item_destroy(void *key, GSList *value)
|
|
|
|
{
|
|
|
|
while (value != NULL) {
|
|
|
|
statusbar_signal_remove(GPOINTER_TO_INT(value->data));
|
|
|
|
value->data = g_slist_remove(value, value->data);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void statusbar_item_signal_destroy(void *key, GSList *value)
|
|
|
|
{
|
|
|
|
g_slist_free(value);
|
2000-05-04 06:32:42 -04:00
|
|
|
}
|
|
|
|
|
2001-10-14 07:17:13 -04:00
|
|
|
static void sig_setup_reload(void)
|
|
|
|
{
|
|
|
|
/* statusbar-config.c recreates root statusbars,
|
|
|
|
we need to create window-statusbars */
|
|
|
|
g_slist_foreach(mainwindows, (GFunc) statusbars_add_visible, NULL);
|
|
|
|
}
|
|
|
|
|
2000-05-04 06:32:42 -04:00
|
|
|
void statusbar_init(void)
|
|
|
|
{
|
2001-11-18 13:06:51 -05:00
|
|
|
statusbar_need_recreate_items = FALSE;
|
2001-10-13 12:11:13 -04:00
|
|
|
statusbar_groups = NULL;
|
|
|
|
active_statusbar_group = NULL;
|
|
|
|
sbar_item_defs = g_hash_table_new((GHashFunc) g_str_hash,
|
2001-10-20 15:52:07 -04:00
|
|
|
(GCompareFunc) g_str_equal);
|
2001-10-13 12:11:13 -04:00
|
|
|
sbar_item_funcs = g_hash_table_new((GHashFunc) g_str_hash,
|
|
|
|
(GCompareFunc) g_str_equal);
|
|
|
|
sbar_signal_items = g_hash_table_new((GHashFunc) g_direct_hash,
|
|
|
|
(GCompareFunc) g_direct_equal);
|
|
|
|
sbar_item_signals = g_hash_table_new((GHashFunc) g_direct_hash,
|
|
|
|
(GCompareFunc) g_direct_equal);
|
2001-10-20 15:52:07 -04:00
|
|
|
named_sbar_items = g_hash_table_new((GHashFunc) g_str_hash,
|
|
|
|
(GCompareFunc) g_str_equal);
|
2000-05-04 06:32:42 -04:00
|
|
|
|
2001-10-14 06:45:00 -04:00
|
|
|
signal_add("terminal resized", (SIGNAL_FUNC) sig_terminal_resized);
|
2000-05-04 06:32:42 -04:00
|
|
|
signal_add("mainwindow resized", (SIGNAL_FUNC) sig_mainwindow_resized);
|
|
|
|
signal_add("mainwindow moved", (SIGNAL_FUNC) sig_mainwindow_resized);
|
2001-10-13 12:11:13 -04:00
|
|
|
signal_add("window changed", (SIGNAL_FUNC) sig_window_changed);
|
|
|
|
signal_add("mainwindow destroyed", (SIGNAL_FUNC) sig_mainwindow_destroyed);
|
2001-10-14 07:17:13 -04:00
|
|
|
signal_add_last("setup reread", (SIGNAL_FUNC) sig_setup_reload);
|
2001-10-20 10:30:20 -04:00
|
|
|
|
|
|
|
statusbar_items_init();
|
|
|
|
statusbar_config_init(); /* signals need to be before this call */
|
2000-05-04 06:32:42 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void statusbar_deinit(void)
|
|
|
|
{
|
2001-10-13 12:11:13 -04:00
|
|
|
while (statusbar_groups != NULL)
|
|
|
|
statusbar_group_destroy(statusbar_groups->data);
|
|
|
|
|
|
|
|
g_hash_table_foreach(sbar_item_defs,
|
|
|
|
(GHFunc) statusbar_item_def_destroy, NULL);
|
|
|
|
g_hash_table_destroy(sbar_item_defs);
|
2000-05-04 06:32:42 -04:00
|
|
|
|
2001-10-13 12:11:13 -04:00
|
|
|
g_hash_table_foreach(sbar_item_funcs, (GHFunc) g_free, NULL);
|
|
|
|
g_hash_table_destroy(sbar_item_funcs);
|
|
|
|
|
|
|
|
g_hash_table_foreach(sbar_signal_items,
|
|
|
|
(GHFunc) statusbar_signal_item_destroy, NULL);
|
|
|
|
g_hash_table_destroy(sbar_signal_items);
|
|
|
|
g_hash_table_foreach(sbar_item_signals,
|
|
|
|
(GHFunc) statusbar_item_signal_destroy, NULL);
|
|
|
|
g_hash_table_destroy(sbar_item_signals);
|
2001-10-20 15:52:07 -04:00
|
|
|
g_hash_table_destroy(named_sbar_items);
|
2000-05-04 06:32:42 -04:00
|
|
|
|
2001-10-14 06:45:00 -04:00
|
|
|
signal_remove("terminal resized", (SIGNAL_FUNC) sig_terminal_resized);
|
2000-05-04 06:32:42 -04:00
|
|
|
signal_remove("mainwindow resized", (SIGNAL_FUNC) sig_mainwindow_resized);
|
|
|
|
signal_remove("mainwindow moved", (SIGNAL_FUNC) sig_mainwindow_resized);
|
2001-10-13 12:11:13 -04:00
|
|
|
signal_remove("window changed", (SIGNAL_FUNC) sig_window_changed);
|
|
|
|
signal_remove("mainwindow destroyed", (SIGNAL_FUNC) sig_mainwindow_destroyed);
|
2001-10-14 07:17:13 -04:00
|
|
|
signal_remove("setup reread", (SIGNAL_FUNC) sig_setup_reload);
|
2001-10-13 12:11:13 -04:00
|
|
|
|
|
|
|
statusbar_items_deinit();
|
|
|
|
statusbar_config_deinit();
|
2000-05-04 06:32:42 -04:00
|
|
|
}
|