Logo Search packages:      
Sourcecode: xconq version File versions  Download package

machelp.c

/* Help for the Mac interface to Xconq.
   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998 Stanley T. Shebs.

Xconq 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, or (at your option)
any later version.  See the file COPYING.  */

#include "conq.h"
#include "macconq.h"

static void insert_newlines(TEHandle te, int n);
static void create_instructions_window(void);
static void describe_menus(int arg, char *key, TextBuffer *buf);
static void describe_mouse(int arg, char *key, TextBuffer *buf);
static void describe_help(int arg, char *key, TextBuffer *buf);
static void create_help_window(void);
static void set_help_content(HelpNode *curnode);
static void adjust_help_scrollbar(void);
static pascal void help_vscroll_fn(ControlHandle control, short code);

/* Globals for the instructions window. */

WindowPtr instructionswin = nil;

TEHandle instructions_text = nil;

UserItemUPP draw_instructions_text_proc;

/* Globals for the help window. */

DialogPtr helpwin = nil;

TEHandle helptopic = nil;

TEHandle helptext = nil;

ControlHandle helpvscrollbar;

ControlActionUPP help_vscroll_proc;

/* Used in help window. */
ControlHandle topicsbutton;
ControlHandle helpbutton;
ControlHandle prevbutton;
ControlHandle nextbutton;
ControlHandle backbutton;
ControlHandle closebutton;

/* Used in instructions window. */
ControlHandle openhelpbutton;
ControlHandle closewinbutton;

static HelpNode *cur_help_node = NULL;

char *helpstring = NULL;

/* The help node that is the list of topics. */

static HelpNode *topics_help_node = NULL;

/* The help node that tells about how to use the help system. */

static HelpNode *help_help_node = NULL;

#define NODESTACKSIZE 50

HelpNode **nodestack;

int nodestackpos;

/* The instructions window. */

void
show_instructions_window()
{
      if (instructionswin == nil) {
            create_instructions_window();
            draw_instructions();
      }
      SelectTheWindow(instructionswin);
      ActivateWindow(instructionswin, true);
}

void
insert_newlines(TEHandle te, int n)
{
      int i;
      char str[20];

      str[0] = '\0';
      for (i = 0; i < n; ++i) {
#if defined(THINK_C) || defined(__MWERKS__)
            strcat(str, "\r");
#else
            strcat(str, "\n");
#endif
      }
      TEInsert(str, strlen(str), te);
}

/* The non-modal instructions dialog messed up the floating windows, 
so I have converted it into a real window instead. */

void
create_instructions_window()
{
      /* Create the window, color if possible, since images may be in color. */
      if (hasColorQD) { 
            instructionswin = GetNewCWindow(wInstructions, NULL, NULL);
      } else {
            instructionswin = GetNewWindow(wInstructions, NULL, NULL);
      }
      openhelpbutton = GetNewControl(cHelpButton, instructionswin);
      MoveControl(openhelpbutton, 175, 200);
      closewinbutton = GetNewControl(cCloseButton, instructionswin);
      MoveControl(closewinbutton, 235, 200);
      add_window_menu_item("Instructions", instructionswin);
      /* Finally make it floating. */
      MakeFloat(instructionswin);
}

/* New function, in part derived from old create_instructions_dialog. */

void
draw_instructions()
{
      int any_instructions = FALSE;
      Obj *instructions, *rest;
      Scorekeeper *sk;
      GrafPtr oldport;
      Rect textrect;
      Rect tmprect;
      Str255 pstr;
      char *str;

      GetPort(&oldport);
      SetPort(instructionswin);

      /* Draw the game title. */
      c2p(((mainmodule && mainmodule->title) ? mainmodule->title : ""), pstr);
      TextFont(title_font_id);
      TextSize(title_font_size);
      MoveTo(15, 20);
      DrawString(pstr);
      TextFont(small_font_id);
      TextSize(small_font_size);

      /* Draw a horizontal line under the title. */
      MoveTo(0, 30);
      LineTo(instructionswin->portRect.right, 30);

      /* Draw the instructions text itself. */
      textrect = instructionswin->portRect;
      textrect.left += 15;
      textrect.right -= 15;
      textrect.top += 40;
      textrect.bottom -= 15;
      instructions_text = TENew(&textrect, &textrect);
      TESetSelect(0, 32767, instructions_text);
      TEDelete(instructions_text);

      /* (should generify, add parameter for how to line break) */
      if (mainmodule == NULL) {
            run_error("no main module?");
      }
      instructions = mainmodule->instructions;
      if (instructions != lispnil) {
            if (stringp(instructions)) {
                  str = c_string(instructions);
                  TEInsert(str, strlen(str), instructions_text);
                  any_instructions = TRUE;
            } else if (consp(instructions)) {
                for (rest = instructions; rest != lispnil; rest = cdr(rest)) {
                  if (stringp(car(rest))) {
                        str = c_string(car(rest));
                        /* An empty string is a line break. */
                        if (strlen(str) == 0) {
                              insert_newlines(instructions_text, 1);
                        } else {
                              TEInsert(str, strlen(str), instructions_text);
                        }
                        TESetSelect(32767, 32767, instructions_text);
                        /* Insert a blank between strings if none present, since they are
                           usually word breaks. */
                        if (str[strlen(str)-1] != ' ')
                          TEInsert(" ", 1, instructions_text);
                        TESetSelect(32767, 32767, instructions_text);
                  }
            }
                  any_instructions = TRUE;
          } else {
            /* error? */
          }
      }
      instructions = dside->instructions;
      if (instructions != lispnil) {
            if (stringp(instructions)) {
                  str = "To you only:";
                insert_newlines(instructions_text, 1);
                  TEInsert(str, strlen(str), instructions_text);
                  str = c_string(instructions);
                  TEInsert(str, strlen(str), instructions_text);
                  any_instructions = TRUE;
            } else if (consp(instructions)) {
                  str = "To you only:";
                  TEInsert(str, strlen(str), instructions_text);
                insert_newlines(instructions_text, 1);
                for (rest = instructions; rest != lispnil; rest = cdr(rest)) {
                  if (stringp(car(rest))) {
                        str = c_string(car(rest));
                        /* An empty string is a line break. */
                        if (strlen(str) == 0) {
                              insert_newlines(instructions_text, 1);
                        } else {
                              TEInsert(str, strlen(str), instructions_text);
                        }
                        TESetSelect(32767, 32767, instructions_text);
                        /* Insert a blank between strings if none present, since they are
                           usually word breaks. */
                        if (str[strlen(str)-1] != ' ')
                          TEInsert(" ", 1, instructions_text);
                        TESetSelect(32767, 32767, instructions_text);
                  }
            }
                  any_instructions = TRUE;
          } else {
            /* error? */
          }
      }
      /* Fall back on some general info. */
      if (!any_instructions) {
            if (mainmodule->blurb) {
                  str = mainmodule->blurb;
                  TEInsert(str, strlen(str), instructions_text);
                  insert_newlines(instructions_text, 2);
            }
            str = "(no instructions supplied)";
            TEInsert(str, strlen(str), instructions_text);
            for_all_scorekeepers(sk) {
                  /* (should add better scorekeeper descriptions) */
                  insert_newlines(instructions_text, 1);
                  str = "Scoring: ";
                  TEInsert(str, strlen(str), instructions_text);
            }
      }
      /* Draw a default line around the close button. */
      tmprect = (*closewinbutton)->contrlRect;
      PenSize(3, 3);
      InsetRect(&tmprect, -4, -4);
      FrameRoundRect(&tmprect, 16, 16);
      InsetRect(&tmprect,  4,  4);
      PenNormal();
      SetPort(oldport);
}

/* New function. */

void
activate_instructions(int activate)
{
      HiliteControl(openhelpbutton, (activate ? 0 : 255));
      HiliteControl(closewinbutton, (activate ? 0 : 255));
}

int 
do_key_down_instructions(char key)
{
      int         handled = TRUE;
      GrafPtr     oldport;

      GetPort(&oldport);
      SetPort(instructionswin);

      switch (key) {
            case 3:           /* Enter. */
            case 13:          /* Return. */
            case 27:          /* Escape. */
                  close_window(instructionswin);
                  break;
            default:
                  handled = FALSE;
                  break;
      }
      SetPort(oldport);
      return handled;
}

/* New function. Replaces hit_instructions_dialog. */

void
do_mouse_down_instructions(Point mouse, int mods)
{
      ControlHandle control;
      Handle itemhandle;
      short part;
      
      part = FindControl(mouse, instructionswin, &control);
      if (control == openhelpbutton) {
            TrackControl(control, mouse, NULL);
            close_window(instructionswin);
            show_help_window(NULL);
      }
      if (control == closewinbutton) {
            TrackControl(control, mouse, NULL);
            close_window(instructionswin);
      }
}

/* Help window. */

/* This is the top-level access to bring up the help window, can be called
   anywhere, anytime. */

void
show_help_window(HelpNode *helpnode)
{
      if (helpwin == nil) {
            create_help_window();
      }
      if (helpnode != NULL) {
            cur_help_node = helpnode;
            set_help_content(helpnode);
      }
      SelectTheWindow(helpwin);
      ActivateWindow(helpwin, true);
}

void
describe_menus(int arg, char *key, TextBuffer *buf)
{
      tbcat(buf, "File\n");
      tbcat(buf, "  The usual file operations.\n");
      tbcat(buf, "\n");
      tbcat(buf, "Edit\n");
      tbcat(buf, "  Select All selects all of your units at once.\n");
      tbcat(buf, "\n");
      tbcat(buf, "Find\n");
      tbcat(buf, "  Find Selected goes to the next map back and looks at the unit selected or viewed in the front window.\n");
      tbcat(buf, "\n");
      tbcat(buf, "Play\n");
      tbcat(buf, "  This is the main menu for unit actions.");
      tbcat(buf, "  Each item represents something that you can do to the currently selected units.\n");
      tbcat(buf, "  If an action is grayed out, then none of the selected units can do it.\n");
      tbcat(buf, "  Closeup shows details of the selected units.\n");
      tbcat(buf, "  Build brings up the construction dialog.\n");
      tbcat(buf, "Side\n");
      tbcat(buf, "  This menu is for things that affect your whole side.\n");
      tbcat(buf, "Windows\n");
      tbcat(buf, "  This menu does window control.\n");
      tbcat(buf, "View (when a map is front window)\n");
      tbcat(buf, "  Items toggle various display elements in the front map window.\n");
      tbcat(buf, "\n");
      tbcat(buf, "View (when a list is front window)\n");
      tbcat(buf, "  Items toggle various display elements in the front list window.\n");
      tbcat(buf, "\n");
}

void
describe_mouse(int arg, char *key, TextBuffer *buf)
{
      tbcat(buf, "In move-on-click mode:\n");
      tbcat(buf, "  The next unit that can do anything will be selected automatically.\n");
      tbcat(buf, "  Click once on a destination to move the selected unit there.\n");
      tbcat(buf, "\n");
      tbcat(buf, "In normal mode:\n");
      tbcat(buf, "  Click once on a unit to select it.\n");
      tbcat(buf, "  Drag to destination to move it.\n");
      tbcat(buf, "  Shift-click to select additional units.\n");
      tbcat(buf, "  Drag out rectangle to select all units inside.\n");
      tbcat(buf, "\n");
      tbcat(buf, "Command-click to moves all selected units to the clicked-on location.");
      tbcat(buf, "\n");
      tbcat(buf, "Combat is automatic if another side's unit is adjacent and clicked on.");
}

void
describe_help(int arg, char *key, TextBuffer *buf)
{
      tbcat(buf, "Xconq Help consists of a number of ``topics''.  ");
      tbcat(buf, "Topics include generic information about Xconq as ");
      tbcat(buf, "well as specific details of the game in progress.  ");
      tbcat(buf, "To navigate, click the buttons above.");
      tbcat(buf, "\n");
      tbcat(buf, "Topics: ");
      tbcat(buf, "Clicking this button shows you the list of topics.  ");
      tbcat(buf, "Clicking on a topic in the list takes you to it directly.");
      tbcat(buf, "\n");
      tbcat(buf, "Help:  ");
      tbcat(buf, "Clicking this button shows you the topic you're looking at right now.");
      tbcat(buf, "\n");
      tbcat(buf, "Next:  ");
      tbcat(buf, "Clicking this button goes to the next topic in order.");
      tbcat(buf, "\n");
      tbcat(buf, "Previous:  ");
      tbcat(buf, "Clicking this button goes to the previous topic in order.");
      tbcat(buf, "\n");
      tbcat(buf, "Back:  ");
      tbcat(buf, "Clicking this button goes to the last topic you were looking at.  ");
      tbcat(buf, "Multiple clicks take you farther and farther back.");
      tbcat(buf, "\n");
}

void
create_help_window()
{
      int h, v;
      Rect helptopicrect, destrect, viewrect, vscrollrect;

      /* Create the window, color if possible, since images may be in color. */
      if (hasColorQD) { 
            helpwin = GetNewCWindow(wHelp, NULL, NULL);
      } else {
            helpwin = GetNewWindow(wHelp, NULL, NULL);
      }
      topicsbutton = GetNewControl(cTopicsButton, helpwin);
      helpbutton = GetNewControl(cHelpButton, helpwin);
      prevbutton = GetNewControl(cPrevButton, helpwin);
      nextbutton = GetNewControl(cNextButton, helpwin);
      backbutton = GetNewControl(cBackButton, helpwin);
      closebutton = GetNewControl(cCloseButton, helpwin);

      SetPort(helpwin);
      TextFont(title_font_id);
      TextSize(title_font_size);
      SetRect(&helptopicrect, 60, 45, 220, 84); 
      helptopic = TENew(&helptopicrect, &helptopicrect);
      TextFont(small_font_id);
      TextSize(small_font_size);
      h = window_width(helpwin);  v = window_height(helpwin);
      SetRect(&viewrect, 5, 84, h - floatsbarwid, v); 
      destrect = viewrect;
      helptext = TENew(&destrect, &destrect);
      /* Set up a vertical scrollbar. */
      vscrollrect = helpwin->portRect;
      vscrollrect.top = -1;
      vscrollrect.bottom -= floatsbarwid - 1;
      vscrollrect.left = vscrollrect.right - floatsbarwid;
      vscrollrect.right += 1;
      helpvscrollbar =
            NewControl(helpwin, &vscrollrect, "\p", TRUE, 0, 0, 0, scrollBarProc, 0L);
      HiliteControl(helpvscrollbar, 0);
      /* Add the Mac-specific help nodes. */
      /* (Note that these will appear in *reverse* order from here, because each
         is being glued right after the first help node. */
      add_help_node("textual commands", describe_long_commands, 0, first_help_node);
      add_help_node("keyboard", describe_key_commands, 0, first_help_node);
      add_help_node("menus", describe_menus, 0, first_help_node);
      add_help_node("mouse", describe_mouse, 0, first_help_node);
      help_help_node = add_help_node("help", describe_help, 0, first_help_node);
      topics_help_node = add_help_node("topics", describe_topics, 0, first_help_node);
      cur_help_node = topics_help_node;
      set_help_content(cur_help_node);
      if (nodestack == NULL)
        nodestack = (HelpNode **) xmalloc(NODESTACKSIZE * sizeof(HelpNode *));
      nodestackpos = 0;
      add_window_menu_item("Help", helpwin);

      /* Finally make it floating. */
      MakeFloat(helpwin);
}

void
set_help_content(HelpNode *curnode)
{
      char *str;

      get_help_text(curnode);
      /* Set the displayed topic title. */
      TESetSelect(0, 32767, helptopic);
      TECut(helptopic);
      /* Copy in the new help topic text. */
      TESetText(curnode->key, strlen(curnode->key), helptopic);
      /* Set the displayed text. */
      str = curnode->text;

#if defined(THINK_C) || defined(__MWERKS__)

      /* Hack up newlines so that TextEdit recognizes them. */
      {
            int i, len = strlen(str);
      
            for (i = 0; i < len; ++i) {
                  if (str[i] == '\n')
                    str[i] = '\r';
            }
      }

#endif

      helpstring = str;
      /* Remove all the existing text. */
      TESetSelect(0, 32767, helptext);
      TECut(helptext);
      /* Copy in the new help text. */
      TESetText(helpstring, strlen(helpstring), helptext);
      (*helptext)->destRect = (*helptext)->viewRect;
      /* Update on the screen. */
      draw_help();
      adjust_help_scrollbar();
}

void
draw_help()
{
      Rect tmprect;
      GrafPtr oldport;

      GetPort(&oldport);
      SetPort(helpwin);
      /* Draw a horizontal line under the navigation buttons. */
      MoveTo(0, 30);
      LineTo(helpwin->portRect.right - floatsbarwid, 30);
      SetRect(&tmprect, 5, 35, 5 + 48, 35 + 48);
      /* Grow so as to erase extra junk that may have been drawn. */
      InsetRect(&tmprect, -2, -2);
      EraseRect(&tmprect);
      /* Back to intended size. */
      InsetRect(&tmprect, 2, 2);
      /* Draw a bit of graphic for some help nodes. */
      if (cur_help_node->nclass == utypenode && is_unit_type(cur_help_node->arg)) {
            draw_unit_image(helpwin, tmprect.left, tmprect.top, 44, 44,
                                    cur_help_node->arg, 0, 0, 0, 0, FALSE);
      } else if (cur_help_node->nclass == ttypenode && is_terrain_type(cur_help_node->arg)) {
            draw_terrain_sample(helpwin, tmprect, cur_help_node->arg, 5); 
      } else if (cur_help_node->nclass == mtypenode && is_material_type(cur_help_node->arg)) {
            /* (should draw material type usefully) */ 
      }
      TextFont(title_font_id);
      TextSize(title_font_size);
      TEUpdate(&(helpwin->portRect), helptopic);
      TextFont(small_font_id);
      TextSize(small_font_size);
      TEUpdate(&(helpwin->portRect), helptext);

      /* Draw a default line around the close button. */
      DrawControls(helpwin);
      tmprect = (*closebutton)->contrlRect;
      PenSize(3, 3);
      InsetRect(&tmprect, -4, -4);
      FrameRoundRect(&tmprect, 16, 16);
      InsetRect(&tmprect,  4,  4);
      PenNormal();
      SetPort(oldport);
      adjust_help_scrollbar();
}

void
adjust_help_scrollbar()
{
      int lines, newmax, value;

      lines = (*helptext)->nLines;
      newmax = lines - (((*helptext)->viewRect.bottom - (*helptext)->viewRect.top)
                               / (*helptext)->lineHeight);
      if (newmax < 0) newmax = 0;
      SetCtlMax(helpvscrollbar, newmax);
      value = ((*helptext)->viewRect.top - (*helptext)->destRect.top)
                  / (*helptext)->lineHeight;
      SetCtlValue(helpvscrollbar, value);
}

void
activate_help(int activate)
{
      HiliteControl(helpvscrollbar, (activate ? 0 : 255));
      HiliteControl(topicsbutton, (activate ? 0 : 255));
      HiliteControl(helpbutton, (activate ? 0 : 255));
      HiliteControl(prevbutton, (activate ? 0 : 255));
      HiliteControl(nextbutton, (activate ? 0 : 255));
      HiliteControl(backbutton, (activate ? 0 : 255));
      HiliteControl(closebutton, (activate ? 0 : 255));
}

static pascal void
help_vscroll_fn(ControlHandle control, short code)
{
      int oldvalue, curvalue, minvalue, maxvalue, pagesize, jump;

      curvalue = GetCtlValue(control);
      minvalue = GetCtlMin(control);
      maxvalue = GetCtlMax(control);
      pagesize = ((*helptext)->viewRect.bottom - (*helptext)->viewRect.top) /
                        (*helptext)->lineHeight;
      if (pagesize > 1) pagesize -= 1;
      switch (code) {
            case inPageDown:
                  jump = pagesize;
                  break;
            case inDownButton:
                  jump = 2;
                  break;
            case inPageUp:
                  jump = - pagesize;
                  break;
            case inUpButton:
                  jump = -2;
                  break;
            default:
                  jump = 0;
                  break;
      }
      oldvalue = curvalue;
      curvalue = max(min(curvalue + jump, maxvalue), minvalue);
      SetCtlValue(control, curvalue);
      /* Calculate the actual jump and use it to adjust the text. */
      jump = curvalue - oldvalue;
      if (jump != 0)
        TEScroll(0, - jump * (*helptext)->lineHeight, helptext);
}

int 
do_key_down_help(char key)
{
      HelpNode    *prevhelpnode = cur_help_node;
      int         i, handled = TRUE;
      GrafPtr     oldport;

      GetPort(&oldport);
      SetPort(helpwin);

      switch (key) {
            case 3:           /* Enter. */
            case 13:          /* Return. */
            case 27:          /* Escape. */
                  close_window(helpwin);
                  break;
            case 0x1F:        /* Down Arrow */
                  help_vscroll_fn(helpvscrollbar, inDownButton);
                  break;
            case 0x1E:        /* Up Arrow */
                  help_vscroll_fn(helpvscrollbar, inUpButton);
                  break;
            case 0x1C:        /* Left Arrow */
                  cur_help_node = cur_help_node->prev;
                  break;
            case 0x1D:        /* Right Arrow */
                  cur_help_node = cur_help_node->next;
                  break;
            case 0x0C:        /* Page Down */
                  help_vscroll_fn(helpvscrollbar, inPageDown);
                  break;
            case 0x0B:        /* Page Up */
                  help_vscroll_fn(helpvscrollbar, inPageUp);
                  break;
            default:
                  handled = FALSE;
                  break;
      }
      /* If we changed help nodes, get its contents and record on the node stack. */
      if (prevhelpnode != cur_help_node) {
            set_help_content(cur_help_node);
            if (nodestackpos >= NODESTACKSIZE) {
                  for (i = 1; i < NODESTACKSIZE; ++i) nodestack[i - 1] = nodestack[i];
                  nodestackpos = NODESTACKSIZE - 1;
            }
            nodestack[nodestackpos++] = prevhelpnode;
      }
      SetPort(oldport);
      return handled;
}

/* Respond to an event occurring in the help window. */

void
do_mouse_down_help(Point mouse, int mods)
{
      ControlHandle control;
      short part, value;
      int i;
      HelpNode *prevhelpnode = cur_help_node, *helpnode;

      if (help_vscroll_proc == NULL)
        help_vscroll_proc = NewControlActionProc(help_vscroll_fn);

      part = FindControl(mouse, helpwin, &control);
      if (control == topicsbutton) {
            TrackControl(control, mouse, NULL);
            cur_help_node = topics_help_node;
      } else if (control == helpbutton) {
            TrackControl(control, mouse, NULL);
            cur_help_node = help_help_node;
      } else if (control == prevbutton) {
            TrackControl(control, mouse, NULL);
            cur_help_node = cur_help_node->prev;
      } else if (control == nextbutton) {
            TrackControl(control, mouse, NULL);
            cur_help_node = cur_help_node->next;
      } else if (control == backbutton) {
            TrackControl(control, mouse, NULL);
            if (nodestackpos > 0) {
                  cur_help_node = nodestack[--nodestackpos];
            }
      } else if (control == closebutton) {
            TrackControl(control, mouse, NULL);
            close_window(helpwin);
            
      } else if (control == helpvscrollbar) {
            if (part != 0) {
                  switch (part) {
                        case inPageDown:
                        case inDownButton:
                        case inPageUp:
                        case inUpButton:
                              value = TrackControl(control, mouse, (ControlActionUPP) help_vscroll_proc);
                              break;
                        case inThumb:
                              value = GetCtlValue(control);
                              if ((part = TrackControl(control, mouse, nil)) != 0) {
                                    value -= GetCtlValue(control);
                                    if (value != 0) {
                                          TEScroll(0, value * (*helptext)->lineHeight, helptext);
                                    }
                              }
                              break;
                  }
            }
      } else if (PtInRect(mouse, &((*helptext)->viewRect))) {
            TEClick(mouse, 0, helptext);
            if (cur_help_node == topics_help_node) {
                  char strbuf[100], *cr1, *cr2;
                  int selstart = (*helptext)->selStart, selend = (*helptext)->selEnd;
                  CharsHandle chars = TEGetText(helptext);

                  if (selstart == selend) {
                        if (strchr("\r\n", *((*chars)+selstart)))
                          --selstart;
                        /* Manufacture a "selection" of the line clicked in. */
                        for (cr1 = (*chars)+selstart; cr1 != (*chars); --cr1)
                          if (strchr("\r\n", *cr1))
                            break;
                        cr2 = strchr((*chars)+selstart, '\r');
                        if (cr2 == NULL)
                          cr2 = strchr((*chars)+selstart, '\n');
                        selstart = (cr1 != NULL ? cr1 - (*chars) + 1 : 0);
                        selend = (cr2 != NULL ? cr2 - (*chars) : 0);
                        if (selstart > selend)
                          selstart = selend;
                  }
                  if (selstart != selend) {
                        strncpy(strbuf, (*chars)+selstart, selend - selstart);
                        strbuf[selend - selstart] = '\0';
                        helpnode = find_help_node(cur_help_node, strbuf);
                        if (helpnode != NULL) {
                              cur_help_node = helpnode;
                        } else {
                              beep();
                        }
                  } else {
                        beep();
                  }
            }
      }
      /* If we changed help nodes, get its contents and record on the node stack. */
      if (prevhelpnode != cur_help_node) {
            set_help_content(cur_help_node);
            if (control != backbutton) {
                  if (nodestackpos >= NODESTACKSIZE) {
                        for (i = 1; i < NODESTACKSIZE; ++i) nodestack[i - 1] = nodestack[i];
                        nodestackpos = NODESTACKSIZE - 1;
                  }
                  nodestack[nodestackpos++] = prevhelpnode;
            }
      }
}

void
grow_help(int h, int v)
{
      EraseRect(&helpwin->portRect);
      SizeWindow(helpwin, h, v, 1);
      MoveControl(helpvscrollbar, h - floatsbarwid, -1);
      SizeControl(helpvscrollbar, floatsbarwid + 1, v  - floatsbarwid + 2);
      (*helptext)->viewRect.right = h - floatsbarwid;
      (*helptext)->viewRect.bottom = v;
      (*helptext)->destRect.right = h - floatsbarwid;
      TECalText(helptext);
      InvalRect(&helpwin->portRect);
}                             

void
zoom_help(int part)
{
      int titleh, h, v;
      Rect zoomrect;
      GDHandle gd, zoomgd;

      EraseRect(&helpwin->portRect);
      if (part == inZoomOut) {
            if (hasColorQD) {
                  zoomgd = best_zoom_screen(&helpwin->portRect);
                  zoomrect = (*zoomgd)->gdRect;
                  if (zoomgd == GetMainDevice()) {
                        zoomrect.top += GetMBarHeight();
                  }
                  titleh = 20; /* (should calc) */
                  zoomrect.top += titleh;
                  InsetRect(&zoomrect, 3, 3);
            } else {
                  /* If no Color QD, then there is only the one screen. */
                  zoomrect = QD(screenBits).bounds;
                  zoomrect.top += GetMBarHeight();
                  titleh = 20; /* (should calc) */
                  zoomrect.top += titleh;
                  InsetRect(&zoomrect, 4, 4);
            }
            (*((WStateDataHandle) ((WindowPeek) helpwin)->dataHandle))->stdState = zoomrect;
      }
      ZoomWindow(helpwin, part, false);
      h = window_width(helpwin);  v = window_height(helpwin);
      MoveControl(helpvscrollbar, h - floatsbarwid, -1);
      SizeControl(helpvscrollbar, floatsbarwid + 1, v - floatsbarwid + 2);
      adjust_help_scrollbar();
      (*helptext)->viewRect.right = h - floatsbarwid;
      (*helptext)->viewRect.bottom = v;
      (*helptext)->destRect.right = h - floatsbarwid;
      TECalText(helptext);
      /* This will force a full redraw at the next update. */
      InvalRect(&helpwin->portRect);
}

Generated by  Doxygen 1.6.0   Back to index