Faster, smoother rendering of dialogs (use bg pixmap, no longer using expose events).

SVN revision: 21784
This commit is contained in:
Kim Woelders 2006-04-03 22:25:19 +00:00
parent 0cdff64beb
commit 14736e21c1
1 changed files with 81 additions and 127 deletions

View File

@ -183,6 +183,7 @@ struct _dialog
char *text;
int num_buttons;
Window win;
PmapMask pmm;
DButton **button;
TextClass *tclass;
ImageClass *iclass;
@ -194,6 +195,7 @@ struct _dialog
DKeyBind *keybindings;
void *data;
char redraw;
char update;
int xu1, yu1, xu2, yu2;
};
@ -299,6 +301,7 @@ DialogDestroy(Dialog * d)
if (d->keybindings)
Efree(d->keybindings);
FreePmapMask(&(d->pmm));
EDestroyWindow(d->win);
Efree(d);
@ -408,7 +411,7 @@ DialogAddButton(Dialog * d, const char *text, DialogCallbackFunc * func,
ESelectInput(db->win,
EnterWindowMask | LeaveWindowMask | ButtonPressMask |
ButtonReleaseMask | ExposureMask);
ButtonReleaseMask);
}
static void
@ -431,9 +434,6 @@ DialogDrawButton(Dialog * d __UNUSED__, DButton * db)
state = STATE_CLICKED;
}
ImageclassApply(db->iclass, db->win, db->w, db->h, 0, 0, state, 0,
ST_WIDGET);
im = NULL;
if (Conf.dialogs.button_image)
{
@ -462,6 +462,9 @@ DialogDrawButton(Dialog * d __UNUSED__, DButton * db)
EImageBorder *pad;
int h;
ImageclassApply(db->iclass, db->win, db->w, db->h, 0, 0, state,
0, ST_WIDGET);
pad = ImageclassGetPadding(ic);
h = db->h - (pad->top + pad->bottom);
TextDraw(db->tclass, db->win, 0, 0, state, db->text,
@ -474,42 +477,8 @@ DialogDrawButton(Dialog * d __UNUSED__, DButton * db)
}
else
{
TextclassApply(db->iclass, db->win, db->w, db->h, 0, 0, state, 1,
db->tclass, db->text);
}
}
static void
DialogDraw(Dialog * d)
{
if ((!d->tclass) || (!d->iclass))
return;
if (d->text)
{
TextclassApply(d->iclass, d->win, d->w, d->h, 0, 0, STATE_NORMAL, 1,
d->tclass, d->text);
}
else if (d->item)
{
DialogDrawItems(d, d->item, 0, 0, 99999, 99999);
}
}
static void
DialogDrawArea(Dialog * d, int x, int y, int w, int h)
{
if ((!d->tclass) || (!d->iclass))
return;
if (d->text)
{
TextclassApply(d->iclass, d->win, d->w, d->h, 0, 0, STATE_NORMAL, 1,
d->tclass, d->text);
}
else if (d->item)
{
DialogDrawItems(d, d->item, x, y, w, h);
ITApply(db->win, db->iclass, NULL, db->w, db->h, state, 0, 0, 0,
ST_WIDGET, db->tclass, NULL, db->text);
}
}
@ -521,13 +490,29 @@ DialogRedraw(Dialog * d)
if ((!d->tclass) || (!d->iclass))
return;
ImageclassApply(d->iclass, d->win, d->w, d->h, 0, 0, STATE_NORMAL, 0,
ST_DIALOG);
#if DEBUG_DIALOGS
Eprintf("DialogRedraw win=%#lx pmap=%#lx\n", d->win, d->pmm.pmap);
#endif
FreePmapMask(&(d->pmm));
ImageclassApplyCopy(d->iclass, d->win, d->w, d->h, 0, 0, STATE_NORMAL,
&(d->pmm), 0, ST_DIALOG);
ESetWindowBackgroundPixmap(d->win, d->pmm.pmap);
d->redraw = 1;
for (i = 0; i < d->num_buttons; i++)
DialogDrawButton(d, d->button[i]);
DialogDraw(d);
if (d->text)
{
TextclassApply(d->iclass, d->pmm.pmap, d->w, d->h, 0, 0, STATE_NORMAL,
1, d->tclass, d->text);
}
else if (d->item)
{
DialogDrawItems(d, d->item, 0, 0, 99999, 99999);
}
}
static void
@ -535,7 +520,7 @@ DialogEwinMoveResize(EWin * ewin, int resize __UNUSED__)
{
Dialog *d = ewin->data;
if (!d || Mode.mode != MODE_NONE)
if (!d || Mode.mode != MODE_NONE || !EoIsShown(ewin))
return;
if (TransparencyUpdateNeeded() || ImageclassIsTransparent(d->iclass))
@ -638,7 +623,7 @@ ShowDialog(Dialog * d)
if (!ewin)
return;
ewin->client.event_mask |= KeyPressMask | ExposureMask;
ewin->client.event_mask |= KeyPressMask;
ESelectInput(d->win, ewin->client.event_mask);
EwinMoveToDesktop(ewin, EoGetDesk(ewin));
@ -656,9 +641,9 @@ ShowDialog(Dialog * d)
ArrangeEwinCentered(ewin);
}
ShowEwin(ewin);
DialogRedraw(d);
DialogUpdate(d);
ShowEwin(ewin);
}
void
@ -1120,7 +1105,7 @@ DialogRealizeItem(Dialog * d, DItem * di)
EMapWindow(di->win);
ESelectInput(di->win,
EnterWindowMask | LeaveWindowMask | ButtonPressMask |
ButtonReleaseMask | ExposureMask);
ButtonReleaseMask);
di->w = iw;
di->h = ih;
break;
@ -1132,12 +1117,11 @@ DialogRealizeItem(Dialog * d, DItem * di)
ih += pad->top + pad->bottom;
di->win = ECreateWindow(d->win, -20, -20, 2, 2, 0);
EMapWindow(di->win);
ESelectInput(di->win, ExposureMask);
di->item.area.area_win = ECreateWindow(di->win, -20, -20, 2, 2, 0);
EMapWindow(di->item.area.area_win);
ESelectInput(di->item.area.area_win,
EnterWindowMask | LeaveWindowMask | ButtonPressMask |
ButtonReleaseMask | ExposureMask | PointerMotionMask);
ButtonReleaseMask | PointerMotionMask);
EventCallbackRegister(di->item.area.area_win, 0, DialogHandleEvents, d);
di->w = iw;
di->h = ih;
@ -1162,7 +1146,7 @@ DialogRealizeItem(Dialog * d, DItem * di)
EMapWindow(di->win);
ESelectInput(di->win,
EnterWindowMask | LeaveWindowMask | ButtonPressMask |
ButtonReleaseMask | ExposureMask);
ButtonReleaseMask);
di->w = iw;
di->h = ih;
break;
@ -1220,7 +1204,7 @@ DialogRealizeItem(Dialog * d, DItem * di)
EMapWindow(di->win);
ESelectInput(di->win,
EnterWindowMask | LeaveWindowMask | ButtonPressMask |
ButtonReleaseMask | ExposureMask);
ButtonReleaseMask);
di->w = iw;
di->h = ih;
break;
@ -1553,7 +1537,7 @@ DialogDrawItems(Dialog * d, DItem * di, int x, int y, int w, int h)
static void
DialogDrawItem(Dialog * d, DItem * di)
{
int state;
int state, x, w;
EImageBorder *pad;
if (!di->update && di->type != DITEM_TABLE)
@ -1640,6 +1624,7 @@ DialogDrawItem(Dialog * d, DItem * di)
di->item.slider.knob_w, di->item.slider.knob_h,
0, 0, state, 0, ST_WIDGET);
break;
case DITEM_BUTTON:
state = STATE_NORMAL;
if ((di->hilited) && (di->clicked))
@ -1648,15 +1633,15 @@ DialogDrawItem(Dialog * d, DItem * di)
state = STATE_HILITED;
else if (!(di->hilited) && (di->clicked))
state = STATE_CLICKED;
ImageclassApply(di->iclass, di->win, di->w, di->h, 0, 0, state, 0,
ST_WIDGET);
TextclassApply(di->iclass, di->win, di->w, di->h, 0, 0, state, 1,
di->tclass, di->text);
ITApply(di->win, di->iclass, NULL, di->w, di->h, state, 0, 0, 0,
ST_WIDGET, di->tclass, NULL, di->text);
break;
case DITEM_AREA:
ImageclassApply(di->iclass, di->win, di->w, di->h, 0, 0,
STATE_NORMAL, 0, ST_DIALOG);
break;
case DITEM_CHECKBUTTON:
state = STATE_NORMAL;
if ((di->hilited) && (di->clicked))
@ -1665,33 +1650,28 @@ DialogDrawItem(Dialog * d, DItem * di)
state = STATE_HILITED;
else if (!(di->hilited) && (di->clicked))
state = STATE_CLICKED;
if (DialogItemCheckButtonGetState(di))
ImageclassApply(di->iclass, di->item.check_button.check_win,
di->item.check_button.check_orig_w,
di->item.check_button.check_orig_h, 1, 0, state,
0, ST_WIDGET);
else
ImageclassApply(di->iclass, di->item.check_button.check_win,
di->item.check_button.check_orig_w,
di->item.check_button.check_orig_h, 0, 0, state,
0, ST_WIDGET);
EClearArea(d->win, di->x, di->y, di->w, di->h, False);
ImageclassApply(di->iclass, di->item.check_button.check_win,
di->item.check_button.check_orig_w,
di->item.check_button.check_orig_h,
DialogItemCheckButtonGetState(di), 0, state,
0, ST_WIDGET);
if (!d->redraw)
break;
pad = ImageclassGetPadding(di->iclass);
TextDraw(di->tclass, d->win, 0, 0, STATE_NORMAL, di->text,
di->x + di->item.check_button.check_orig_w +
pad->left, di->y,
di->w - di->item.check_button.check_orig_w -
pad->left, 99999, 17, TextclassGetJustification(di->tclass));
break;
x = di->x + di->item.check_button.check_orig_w + pad->left;
w = di->w - di->item.check_button.check_orig_w - pad->left;
goto draw_text;
case DITEM_TEXT:
EClearArea(d->win, di->x, di->y, di->w, di->h, False);
TextDraw(di->tclass, d->win, 0, 0, STATE_NORMAL, di->text,
di->x, di->y, di->w, 99999, 17,
TextclassGetJustification(di->tclass));
break;
case DITEM_IMAGE:
break;
if (!d->redraw)
break;
x = di->x;
w = di->w;
goto draw_text;
case DITEM_SEPARATOR:
if (!d->redraw)
break;
if (di->item.separator.horizontal)
ImageclassApply(di->iclass, di->win, di->w, di->h, 0, 0,
STATE_NORMAL, 0, ST_WIDGET);
@ -1699,6 +1679,7 @@ DialogDrawItem(Dialog * d, DItem * di)
ImageclassApply(di->iclass, di->win, di->w, di->h, 0, 0,
STATE_CLICKED, 0, ST_WIDGET);
break;
case DITEM_RADIOBUTTON:
state = STATE_NORMAL;
if ((di->hilited) && (di->clicked))
@ -1707,26 +1688,24 @@ DialogDrawItem(Dialog * d, DItem * di)
state = STATE_HILITED;
else if (!(di->hilited) && (di->clicked))
state = STATE_CLICKED;
if (di->item.radio_button.onoff)
ImageclassApply(di->iclass, di->item.radio_button.radio_win,
di->item.radio_button.radio_orig_w,
di->item.radio_button.radio_orig_h, 1, 0, state,
0, ST_WIDGET);
else
ImageclassApply(di->iclass, di->item.radio_button.radio_win,
di->item.radio_button.radio_orig_w,
di->item.radio_button.radio_orig_w, 0, 0, state,
0, ST_WIDGET);
EClearArea(d->win, di->x, di->y, di->w, di->h, False);
ImageclassApply(di->iclass, di->item.radio_button.radio_win,
di->item.radio_button.radio_orig_w,
di->item.radio_button.radio_orig_h,
di->item.radio_button.onoff, 0, state, 0, ST_WIDGET);
if (!d->redraw)
break;
pad = ImageclassGetPadding(di->iclass);
TextDraw(di->tclass, d->win, 0, 0, STATE_NORMAL, di->text,
di->x + di->item.radio_button.radio_orig_w +
pad->left, di->y,
di->w - di->item.radio_button.radio_orig_w -
pad->left, 99999, 17, TextclassGetJustification(di->tclass));
break;
x = di->x + di->item.radio_button.radio_orig_w + pad->left;
w = di->w - di->item.radio_button.radio_orig_w - pad->left;
goto draw_text;
default:
break;
draw_text:
TextDraw(di->tclass, d->pmm.pmap, 0, 0, STATE_NORMAL, di->text,
x, di->y, w, 99999, 17, TextclassGetJustification(di->tclass));
break;
}
done:
@ -1738,6 +1717,9 @@ DialogUpdate(Dialog * d)
{
if (d->item)
DialogDrawItem(d, d->item);
if (d->xu1 < d->xu2 && d->yu1 < d->yu2)
EClearArea(d->win, d->xu1, d->yu1, d->xu2 - d->xu1, d->yu2 - d->yu1,
False);
d->update = 0;
d->xu1 = d->yu1 = 99999;
d->xu2 = d->yu2 = 0;
@ -1756,6 +1738,7 @@ DialogsCheckUpdate(void)
{
if (d->update)
DialogUpdate(d);
d->redraw = 0;
}
}
@ -1832,7 +1815,7 @@ DialogItemCheckButtonSetPtr(DItem * di, char *onoff_ptr)
static int
DialogItemCheckButtonGetState(DItem * di)
{
return *(di->item.check_button.onoff_ptr);
return *(di->item.check_button.onoff_ptr) ? 1 : 0;
}
void
@ -2186,28 +2169,6 @@ DialogEventMotion(Dialog * d, XEvent * ev)
}
}
static void
DialogEventExpose(Dialog * d, XEvent * ev)
{
Window win = ev->xexpose.window;
DItem *di;
DialogDrawArea(d, ev->xexpose.x, ev->xexpose.y,
ev->xexpose.width, ev->xexpose.height);
di = DialogFindDItem(d, win);
if (!di)
return;
switch (di->type)
{
case DITEM_AREA:
if (di->func)
di->func(d, di->val, di->data);
break;
}
}
static void
DialogEventMouseDown(Dialog * d, XEvent * ev)
{
@ -2450,9 +2411,6 @@ DialogHandleEvents(XEvent * ev, void *prm)
case LeaveNotify:
DialogEventMouseOut(d, ev);
break;
case Expose:
DialogEventExpose(d, ev);
break;
}
}
@ -2473,8 +2431,6 @@ DItemHandleEvents(XEvent * ev, void *prm)
break;
case LeaveNotify:
break;
case Expose:
break;
}
}
#endif
@ -2504,8 +2460,6 @@ DButtonHandleEvents(XEvent * ev, void *prm)
case LeaveNotify:
db->hilited = 0;
break;
case Expose:
break;
default:
return;
}