⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gntbox.c

📁 Linux下的多协议即时通讯程序源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "gntbox.h"#include "gntutils.h"#include <string.h>enum{	SIGS = 1,};static GntWidgetClass *parent_class = NULL;static GntWidget * find_focusable_widget(GntBox *box);static voidadd_to_focus(gpointer value, gpointer data){	GntBox *box = GNT_BOX(data);	GntWidget *w = GNT_WIDGET(value);	if (GNT_IS_BOX(w))		g_list_foreach(GNT_BOX(w)->list, add_to_focus, box);	else if (GNT_WIDGET_IS_FLAG_SET(w, GNT_WIDGET_CAN_TAKE_FOCUS))		box->focus = g_list_append(box->focus, w);}static voidget_title_thingies(GntBox *box, char *title, int *p, int *r){	GntWidget *widget = GNT_WIDGET(box);	int len;	char *end = (char*)gnt_util_onscreen_width_to_pointer(title, widget->priv.width - 4, &len);		if (p)		*p = (widget->priv.width - len) / 2;	if (r)		*r = (widget->priv.width + len) / 2;	*end = '\0';}static voidgnt_box_draw(GntWidget *widget){	GntBox *box = GNT_BOX(widget);	if (box->focus == NULL && widget->parent == NULL)		g_list_foreach(box->list, add_to_focus, box);	g_list_foreach(box->list, (GFunc)gnt_widget_draw, NULL);	gnt_box_sync_children(box);	if (box->title && !GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_NO_BORDER))	{		int pos, right;		char *title = g_strdup(box->title);				get_title_thingies(box, title, &pos, &right);		if (gnt_widget_has_focus(widget))			wbkgdset(widget->window, '\0' | COLOR_PAIR(GNT_COLOR_TITLE));		else			wbkgdset(widget->window, '\0' | COLOR_PAIR(GNT_COLOR_TITLE_D));		mvwaddch(widget->window, 0, pos-1, ACS_RTEE | COLOR_PAIR(GNT_COLOR_NORMAL));		mvwaddstr(widget->window, 0, pos, title);		mvwaddch(widget->window, 0, right, ACS_LTEE | COLOR_PAIR(GNT_COLOR_NORMAL));		g_free(title);	}		GNTDEBUG;}static voidreposition_children(GntWidget *widget){	GList *iter;	GntBox *box = GNT_BOX(widget);	int w, h, curx, cury, max;	gboolean has_border = FALSE;	w = h = 0;	max = 0;	curx = widget->priv.x;	cury = widget->priv.y;	if (!(GNT_WIDGET_FLAGS(widget) & GNT_WIDGET_NO_BORDER))	{		has_border = TRUE;		curx += 1;		cury += 1;	}	for (iter = box->list; iter; iter = iter->next)	{		if (GNT_WIDGET_IS_FLAG_SET(GNT_WIDGET(iter->data), GNT_WIDGET_INVISIBLE))			continue;		gnt_widget_set_position(GNT_WIDGET(iter->data), curx, cury);		gnt_widget_get_size(GNT_WIDGET(iter->data), &w, &h);		if (box->vertical)		{			if (h)			{				cury += h + box->pad;				if (max < w)					max = w;			}		}		else		{			if (w)			{				curx += w + box->pad;				if (max < h)					max = h;			}		}	}	if (has_border)	{		curx += 1;		cury += 1;		max += 2;	}	if (box->list)	{		if (box->vertical)			cury -= box->pad;		else			curx -= box->pad;	}	if (box->vertical)	{		widget->priv.width = max;		widget->priv.height = cury - widget->priv.y;	}	else	{		widget->priv.width = curx - widget->priv.x;		widget->priv.height = max;	}}static voidgnt_box_set_position(GntWidget *widget, int x, int y){	GList *iter;	int changex, changey;	changex = widget->priv.x - x;	changey = widget->priv.y - y;	for (iter = GNT_BOX(widget)->list; iter; iter = iter->next)	{		GntWidget *w = GNT_WIDGET(iter->data);		gnt_widget_set_position(w, w->priv.x - changex,				w->priv.y - changey);	}}static voidgnt_box_size_request(GntWidget *widget){	GntBox *box = GNT_BOX(widget);	GList *iter;	int maxw = 0, maxh = 0;		g_list_foreach(box->list, (GFunc)gnt_widget_size_request, NULL);	for (iter = box->list; iter; iter = iter->next)	{		int w, h;		gnt_widget_get_size(GNT_WIDGET(iter->data), &w, &h);		if (maxh < h)			maxh = h;		if (maxw < w)			maxw = w;	}	for (iter = box->list; iter; iter = iter->next)	{		int w, h;		GntWidget *wid = GNT_WIDGET(iter->data);		gnt_widget_get_size(wid, &w, &h);		if (box->homogeneous)		{			if (box->vertical)				h = maxh;			else				w = maxw;		}		if (box->fill)		{			if (box->vertical)				w = maxw;			else				h = maxh;		}		gnt_widget_set_size(wid, w, h);	}	reposition_children(widget);}static voidgnt_box_map(GntWidget *widget){	if (widget->priv.width == 0 || widget->priv.height == 0)	{		gnt_widget_size_request(widget);		find_focusable_widget(GNT_BOX(widget));	}	GNTDEBUG;}/* Ensures that the current widget can take focus */static GntWidget *find_focusable_widget(GntBox *box){	/* XXX: Make sure the widget is visible? */	if (box->focus == NULL && GNT_WIDGET(box)->parent == NULL)		g_list_foreach(box->list, add_to_focus, box);	if (box->active == NULL && box->focus)		box->active = box->focus->data;	return box->active;}static voidfind_next_focus(GntBox *box){	gpointer last = box->active;	do	{		GList *iter = g_list_find(box->focus, box->active);		if (iter && iter->next)			box->active = iter->next->data;		else if (box->focus)			box->active = box->focus->data;		if (!GNT_WIDGET_IS_FLAG_SET(box->active, GNT_WIDGET_INVISIBLE))			break;	} while (box->active != last);}static voidfind_prev_focus(GntBox *box){	gpointer last = box->active;	if (!box->focus)		return;	do	{		GList *iter = g_list_find(box->focus, box->active);		if (!iter)			box->active = box->focus->data;		else if (!iter->prev)			box->active = g_list_last(box->focus)->data;		else			box->active = iter->prev->data;		if (!GNT_WIDGET_IS_FLAG_SET(box->active, GNT_WIDGET_INVISIBLE))			break;	} while (box->active != last);}static gbooleangnt_box_key_pressed(GntWidget *widget, const char *text){	GntBox *box = GNT_BOX(widget);	GntWidget *now;	if (box->active == NULL && !find_focusable_widget(box))		return FALSE;	if (gnt_widget_key_pressed(box->active, text))		return TRUE;		now = box->active;	if (text[0] == 27)	{		if (strcmp(text, GNT_KEY_LEFT) == 0)		{			find_prev_focus(box);		}		else if (strcmp(text, GNT_KEY_RIGHT) == 0)		{			find_next_focus(box);		}	}	else if (text[0] == '\t')	{		find_next_focus(box);	}	if (now && now != box->active)	{		gnt_widget_set_focus(now, FALSE);		gnt_widget_set_focus(box->active, TRUE);		return TRUE;	}	return FALSE;}static voidgnt_box_lost_focus(GntWidget *widget){	GntWidget *w = GNT_BOX(widget)->active;	if (w)		gnt_widget_set_focus(w, FALSE);	gnt_widget_draw(widget);}static voidgnt_box_gained_focus(GntWidget *widget){	GntWidget *w = GNT_BOX(widget)->active;	if (w)		gnt_widget_set_focus(w, TRUE);	gnt_widget_draw(widget);}static voidgnt_box_destroy(GntWidget *w){	GntBox *box = GNT_BOX(w);	gnt_box_remove_all(box);	gnt_screen_release(w);}static voidgnt_box_expose(GntWidget *widget, int x, int y, int width, int height){	WINDOW *win = newwin(height, width, widget->priv.y + y, widget->priv.x + x);	copywin(widget->window, win, y, x, 0, 0, height - 1, width - 1, FALSE);	wrefresh(win);	delwin(win);}static gbooleangnt_box_confirm_size(GntWidget *widget, int width, int height){	GList *iter;	GntBox *box = GNT_BOX(widget);	int wchange, hchange;	if (!box->list)		return TRUE;	wchange = widget->priv.width - width;	hchange = widget->priv.height - height;	if (wchange == 0 && hchange == 0)		return TRUE;		/* Quit playing games */	/* XXX: Right now, I am trying to just apply all the changes to 	 * just one widget. It should be possible to distribute the	 * changes to all the widgets in the box. */	for (iter = box->list; iter; iter = iter->next)	{		GntWidget *wid = iter->data;		int w, h;		gnt_widget_get_size(wid, &w, &h);		if (gnt_widget_confirm_size(wid, w - wchange, h - hchange))		{			GList *i;			for (i = box->list; i; i = i->next)			{				int tw, th;				if (i == iter) continue;				gnt_widget_get_size(GNT_WIDGET(i->data), &tw, &th);				if (box->vertical)				{					if (!gnt_widget_confirm_size(i->data, tw - wchange, th)) {						/* If we are decreasing the size and the widget is going						 * to be too large to fit into the box, then do not allow						 * resizing. */						if (wchange > 0 && tw >= widget->priv.width)							return FALSE;					}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -