From 1030dc837b10a03a02a85d5504cbeec168ce49e2 Mon Sep 17 00:00:00 2001 From: Bernie Innocenti Date: Mon, 03 May 2010 21:53:47 +0000 Subject: Import XaoS r489 (trunk after version 3.5) --- (limited to 'src/ui/uihelp.c') diff --git a/src/ui/uihelp.c b/src/ui/uihelp.c new file mode 100644 index 0000000..d597e25 --- /dev/null +++ b/src/ui/uihelp.c @@ -0,0 +1,486 @@ +#include +#ifdef _plan9_ +#include +#include +#else +#ifndef NO_MALLOC_H +#include +#endif +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "uiint.h" +#define HISTORYSIZE 10 +static int historypos; +static struct xshl_line *lines; +static int helpwidth, helpheight, helpx, helpy; +static struct uih_window *helpw; +static int textheight; +static char *ui_helppage[HISTORYSIZE]; +static int ui_helppos[HISTORYSIZE]; +int helpvisible; + +static struct xshl_item *presseditem; +static struct xshl_item *selecteditem; +static int pressedline; +static int selectedline; +#define SCROOLSIZE 10 +#define XPOS(xp) (2 * BORDERWIDTH + (xp)) +#define YPOS(yp) (2*BORDERWIDTH+ (yp)-ui_helppos[historypos]+10) +#define SCROOLSTART (helpx+helpwidth-WBORDERS) +#define WBORDERS (4*BORDERWIDTH+SCROOLSIZE) +#define HBORDERS (xtextheight(uih->font)+8*BORDERHEIGHT) +#define WIDTH (uih->image->width-WBORDERS) +#define HEIGHT (uih->image->height-HBORDERS) + +static int pressedbutton = -1; +static int selectedbutton = -1; + +#define NBUTTONS 3 +CONST char *CONST names[] = { "OK", "Back", "Main" }; + +#define BUTTONSTART(i) (helpx+BORDERWIDTH+(helpwidth-2*BORDERWIDTH)/NBUTTONS*(i)) +static void ui_build_help(char *name); +static void ui_backhelp(void) +{ + historypos--; + if (historypos < 0) + historypos = HISTORYSIZE - 1; + ui_build_help(ui_helppage[historypos]); +} + +static void do_button(int i) +{ + switch (i) { + case 0: + ui_close_help(); + break; + case 1: + ui_backhelp(); + break; + case 2: + ui_help("main"); + break; + } +} + +void ui_close_help(void) +{ + if (helpw != NULL) { + xshl_free(lines); + helpvisible = 0; + uih_removew(uih, helpw); + uih->display = 1; + helpw = NULL; + } +} + +static int getwidth(void *data, int flags, CONST char *text) +{ + if (uih->image->flags & AAIMAGE) + return (xtextwidth(uih->font, text)); + return (xtextwidth(uih->font, text) - 1); +} + +static void +helpsize(struct uih_context *c, int *x, int *y, int *width, int *height, + void + *data) +{ + *x = helpx; + *y = helpy; + *width = helpwidth; + *height = helpheight; +} + +static void drawhelp(struct uih_context *c, void *data) +{ + int i = 0; + int y; + int percentx, percenty; + struct xshl_item *curritem; + uih_drawborder(uih, helpx + BORDERWIDTH, helpy + BORDERHEIGHT, + helpwidth - WBORDERS + SCROOLSIZE, + helpheight - HBORDERS, BORDER_PRESSED); + + if (ui_helppos[historypos] > textheight - helpheight / 2 + HBORDERS) + ui_helppos[historypos] = textheight - helpheight / 2 + HBORDERS; + if (ui_helppos[historypos] < 0) + ui_helppos[historypos] = 0; + + /*draw scroolbar */ + percentx = + (helpheight - HBORDERS) * ui_helppos[historypos] / textheight; + percenty = + (helpheight - HBORDERS) * (ui_helppos[historypos] + helpheight - + HBORDERS) / textheight; + if (percentx < BORDERHEIGHT) + percentx = BORDERHEIGHT; + if (percenty < BORDERHEIGHT) + percenty = BORDERHEIGHT; + if (percentx > helpheight - HBORDERS - BORDERHEIGHT) + percentx = helpheight - HBORDERS - BORDERHEIGHT; + if (percenty > helpheight - HBORDERS - BORDERHEIGHT) + percenty = helpheight - HBORDERS - BORDERHEIGHT; + uih_drawborder(uih, SCROOLSTART, helpy + BORDERHEIGHT + percentx, + SCROOLSIZE - 1, percenty - percentx, 0); + for (i = 0; i < NBUTTONS; i++) { + ui_drawbutton(names[i], pressedbutton == i, selectedbutton == i, + BUTTONSTART(i) + BORDERWIDTH, + BUTTONSTART(i + 1) - BORDERWIDTH, + helpy + helpheight - BUTTONHEIGHT - BORDERHEIGHT); + } + + + i = 0; + while (YPOS(lines[i].y) < 2 * BORDERWIDTH) { + i++; + if (lines[i].y < 0) + return; + } + while ((y = + YPOS(lines[i].y)) < + helpheight - HBORDERS - xtextheight(uih->font) + && lines[i].y >= 0) { + curritem = lines[i].first; + while (curritem != NULL) { + unsigned int bgcolor = BGCOLOR(uih); + unsigned int fgcolor = /*FGCOLOR (uih) */ LIGHTGRAYCOLOR2(uih); + int flags = 0; + int x = XPOS(curritem->x); + + if (curritem->c.flags & (XSHL_BIG | XSHL_RED)) + fgcolor = SELCOLOR(uih); + else if (curritem->c.flags & (XSHL_EMPH | XSHL_MONOSPACE)) + fgcolor = + uih->image-> + flags & AAIMAGE ? SELCOLOR(uih) : FGCOLOR(uih); + else if (curritem->c.flags & (XSHL_BLACK)) + bgcolor = fgcolor = BGCOLOR(uih), flags = TEXT_PRESSED; + else + bgcolor = fgcolor, flags |= TEXT_PRESSED; + if (uih->palette->type & BITMAPS) { + flags = TEXT_PRESSED; + fgcolor = BGCOLOR(uih); + } + if (curritem->c.linktext != NULL) { + if (uih->palette->type & BITMAPS) { + if (curritem == presseditem + || curritem == selecteditem) + fgcolor = + FGCOLOR(uih), xrectangle(uih->image, x + helpx, + y + helpy, + curritem->width, + xtextheight(uih-> + font), + BGCOLOR(uih)); + else + xhline(uih->image, x + helpx, + y + helpy + xtextheight(uih->font) - 1, + curritem->width, BGCOLOR(uih)); + } else { + if (uih->image->flags & AAIMAGE) + fgcolor = curritem == presseditem + || curritem == + selecteditem ? SELCOLOR(uih) : BGCOLOR(uih); + else { + int i; + i = strlen(curritem->c.linktext); + if (i > 3 + && !strcmp(".xaf", + curritem->c.linktext + i - 4)) + xhline(uih->image, x + helpx, + y + helpy + xtextheight(uih->font) - 1, + curritem->width, curritem == presseditem + || curritem == + selecteditem ? SELCOLOR(uih) : + SELCOLOR(uih)); + else + xhline(uih->image, x + helpx, + y + helpy + xtextheight(uih->font) - 1, + curritem->width, curritem == presseditem + || curritem == + selecteditem ? SELCOLOR(uih) : + LIGHTGRAYCOLOR2(uih)); + xhline(uih->image, x + helpx + 1, + y + helpy + xtextheight(uih->font) - 0, + curritem->width, BGCOLOR(uih)); + } + flags = 0; + bgcolor = BGCOLOR(uih); + if (fgcolor == LIGHTGRAYCOLOR2(uih)) + fgcolor = FGCOLOR(uih); + if (curritem == presseditem + || curritem == selecteditem) + fgcolor = SELCOLOR(uih); + } + } + xprint(uih->image, uih->font, x + helpx, y + helpy, + curritem->text, fgcolor, bgcolor, flags); + curritem = curritem->next; + } + i++; + } +} + +int ui_helpkeys(int key) +{ + int i; + if (helpw == NULL) + return 0; + switch (key) { + case 'h': + ui_close_help(); + ui_menu("tutor"); + return 1; + case 'm': + ui_help("main"); + return 1; + case UIKEY_DOWN: + case 'j': + ui_helppos[historypos] += 8, uih->display = 1; + presseditem = NULL; + selecteditem = NULL; + break; + case UIKEY_UP: + case 'k': + ui_helppos[historypos] -= 8, uih->display = 1; + presseditem = NULL; + selecteditem = NULL; + break; + case UIKEY_PGDOWN: + case '+': + case 'f': + case ' ': + ui_helppos[historypos] += + helpheight - HBORDERS - 32, uih->display = 1; + presseditem = NULL; + selecteditem = NULL; + break; + case UIKEY_PGUP: + case '-': + ui_helppos[historypos] -= + helpheight - HBORDERS - 32, uih->display = 1; + presseditem = NULL; + selecteditem = NULL; + break; + case 'b': + case 1: + ui_backhelp(); + break; + case UIKEY_ESC: + case 'q': + case 'c': + case 'o': + ui_close_help(); + break; + case UIKEY_TAB: + case UIKEY_RIGHT: + uih->display = 1; + if (selectedbutton < 0 || selectedbutton == NBUTTONS - 1) { + if (selecteditem == NULL) { + i = 0; + while (YPOS(lines[i].y) < 2 * BORDERWIDTH) { + i++; + if (lines[i].y < 0) + break; + } + selecteditem = lines[i].first; + } else + i = selectedline, selecteditem = selecteditem->next; + for (; + lines[i].y >= 0 + && YPOS(lines[i].y) < helpheight - HBORDERS; i++) { + selectedline = i; + while (selecteditem != NULL) { + if (selecteditem->c.linktext != NULL) { + selectedbutton = -1; + return 0; + } + selecteditem = selecteditem->next; + } + selecteditem = lines[i + 1].first; + } + selecteditem = NULL; + selectedbutton = 0; + } else + selectedbutton++; + break; + case 13: + case '\n': + if (selecteditem != NULL) { + ui_help(selecteditem->c.linktext); + return 1; + } + if (selectedbutton >= 0) + do_button(selectedbutton); + } + return 1; +} + +int ui_helpmouse(int x, int y, int buttons, int flags) +{ + static int grabbed = 0; + int atpressed = 0; + if (helpw == NULL) + return 0; + if (x < helpx || y < helpy || x > helpx + helpwidth + || y > helpy + helpheight) { + if (flags & MOUSE_PRESS) + ui_close_help(); + pressedbutton = -1; + if (pressedbutton != -1) + pressedbutton = -1, uih->display = 1; + return 1; + } else { + if (y > helpy + helpheight - BUTTONHEIGHT - 2 * BORDERHEIGHT) { + int button; + int i; + for (i = 0; i <= NBUTTONS; i++) + if (x < BUTTONSTART(i)) + break; + button = i - 1; + if (flags & MOUSE_DRAG) { + if (pressedbutton != selectedbutton + || pressedbutton != button) + pressedbutton = selectedbutton = button, uih->display = + 1; + } else { + if (pressedbutton != -1) + pressedbutton = -1, uih->display = 1; + if (flags & MOUSE_RELEASE) + do_button(button); + } + return 1; + } + if (pressedbutton != -1) + pressedbutton = -1, uih->display = 1; + if (buttons + && ((x > SCROOLSTART && y < helpy + helpheight - HBORDERS) + || grabbed)) { + /*we are in scroolbar */ + int pos = (y - helpy) * textheight / (helpheight - HBORDERS); + if (pos != ui_helppos[historypos]) + ui_helppos[historypos] = pos, uih->display = 1; + grabbed = 1; + return 1; + } else + grabbed = 0; + y -= helpy + xtextheight(uih->font); + x -= 2 * BORDERWIDTH + helpx; + pressedbutton = -1; + if (presseditem != NULL) { + if (YPOS(lines[pressedline].y) + 1 >= y + && YPOS(lines[pressedline].y) <= y + xtextheight(uih->font) + && presseditem->x <= x + && presseditem->x + presseditem->width >= x) + atpressed = 1; + } + if (flags & MOUSE_PRESS || ((flags & MOUSE_DRAG) && !atpressed)) { + int i = 0; + for (i = 0; + lines[i].y >= 0 && (YPOS(lines[i].y) + 1 <= y + || YPOS(lines[i].y) >= + y + xtextheight(uih->font)); i++); + if (lines[i].y >= 0) { + struct xshl_item *item = lines[i].first; + while (item != NULL) { + if (item->c.linktext != NULL && item->x <= x + && item->x + item->width >= x) + break; + item = item->next; + } + if (item != NULL) { + uih->display = 1; + presseditem = item; + pressedline = i; + } + } + } else if (flags & MOUSE_MOVE) { + if (!atpressed && presseditem != NULL) + uih->display = 1, presseditem = 0; + } else if ((flags & MOUSE_RELEASE)) { + if (atpressed) { + ui_help(presseditem->c.linktext); + return 1; + } + if (presseditem != NULL) + presseditem = NULL, uih->display = 1; + /*odfajruj to! */ + } + } + return 1; +} + +static void ui_build_help(char *name) +{ + int i; + int width; + if (ui_nogui) { + printf("help \"%s\"\n", name); + return; + } + if (driver->gui_driver && driver->gui_driver->help) { + driver->gui_driver->help(uih, name); + return; + } + if (helpw != NULL) + ui_close_help(); + pressedbutton = -1; + helpvisible = 1; + width = 80 * xtextwidth(uih->font, "w"); + if (width > WIDTH) + width = WIDTH; + lines = + help_make(name ? name : "main", getwidth, width - 2, + xtextheight(uih->font), xtextheight(uih->font)); + if (lines == NULL) { + lines = + help_make("main", getwidth, width - 2, xtextheight(uih->font), + xtextheight(uih->font)); + if (lines == NULL) { + helpvisible = 0; + uih_message(uih, "Help file not found"); + return; + } + } + width += WBORDERS; + uih->display = 1; + presseditem = selecteditem = NULL; + helpwidth = width; + helpx = (uih->image->width - width) / 2; + for (i = 0; lines[i].y >= 0; i++); + textheight = lines[i - 1].y + 4 * xtextheight(uih->font); + if (textheight < HEIGHT) + helpheight = textheight; + else + helpheight = HEIGHT; + helpheight += HBORDERS; + helpy = (uih->image->height - helpheight) / 2; + helpw = uih_registerw(uih, helpsize, drawhelp, 0, DRAWBORDER); +} + +void ui_help(CONST char *name) +{ + if (strlen(name) > 4 && !strcmp(name + strlen(name) - 4, ".xaf")) { + uih_playtutorial(uih, name); + if (helpw != NULL) + ui_close_help(); + /*FIXME!!!!!!! This needs to be queued! */ + return; + } + historypos++; + historypos %= HISTORYSIZE; + ui_helppage[historypos] = mystrdup(name); /* NOTE we are not freeing this memory. I believe it is not problem. */ + ui_helppos[historypos] = 0; + ui_build_help(ui_helppage[historypos]); +} -- cgit v0.9.1