Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/src/ui/uihelp.c
diff options
context:
space:
mode:
authorBernie Innocenti <bernie@codewiz.org>2010-05-03 21:53:47 (GMT)
committer Bernie Innocenti <bernie@codewiz.org>2010-05-03 21:53:47 (GMT)
commit1030dc837b10a03a02a85d5504cbeec168ce49e2 (patch)
tree698eefa87ac437deaf36a4141b326f8ce7986692 /src/ui/uihelp.c
Import XaoS r489 (trunk after version 3.5)
Diffstat (limited to 'src/ui/uihelp.c')
-rw-r--r--src/ui/uihelp.c486
1 files changed, 486 insertions, 0 deletions
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 <config.h>
+#ifdef _plan9_
+#include <u.h>
+#include <libc.h>
+#else
+#ifndef NO_MALLOC_H
+#include <malloc.h>
+#endif
+#include <string.h>
+#endif
+
+#include <fconfig.h>
+#include <filter.h>
+#include <fractal.h>
+#include <ui_helper.h>
+#include <ui.h>
+#include <xshl.h>
+#include <xmenu.h>
+#include <grlib.h>
+#include <misc-f.h>
+#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]);
+}