home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / i / iv26_w_3.zip / EXAMPLES / IDRAW / PANEL.C < prev    next >
C/C++ Source or Header  |  1980-01-05  |  6KB  |  193 lines

  1. /*
  2.  * Copyright (c) 1987, 1988, 1989 Stanford University
  3.  *
  4.  * Permission to use, copy, modify, distribute, and sell this software and its
  5.  * documentation for any purpose is hereby granted without fee, provided
  6.  * that the above copyright notice appear in all copies and that both that
  7.  * copyright notice and this permission notice appear in supporting
  8.  * documentation, and that the name of Stanford not be used in advertising or
  9.  * publicity pertaining to distribution of the software without specific,
  10.  * written prior permission.  Stanford makes no representations about
  11.  * the suitability of this software for any purpose.  It is provided "as is"
  12.  * without express or implied warranty.
  13.  *
  14.  * STANFORD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  15.  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
  16.  * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  17.  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
  18.  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
  19.  * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
  20.  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  21.  */
  22.  
  23. // $Header: panel.c,v 1.10 89/10/09 14:49:11 linton Exp $
  24. // implements classes Panel and PanelItem.
  25.  
  26. #include "istring.h"
  27. #include "panel.h"
  28. #include <InterViews/event.h>
  29. #include <InterViews/font.h>
  30. #include <InterViews/painter.h>
  31. #include <InterViews/sensor.h>
  32. #include <InterViews/shape.h>
  33. #include <ctype.h>
  34.  
  35. // Define the maximum value of any character.
  36.  
  37. static const int MAXCHAR = 127;
  38.  
  39. // Panel starts with no currently highlighted or stored items.
  40.  
  41. Panel::Panel () {
  42.     cur = nil;
  43.     for (int i = 0; i <= MAXCHAR; i++) {
  44.     items[i] = nil;
  45.     }
  46. }
  47.  
  48. // Enter stores an item using its associated character as its index
  49. // and tells it it can get its highlight painter from us.
  50.  
  51. void Panel::Enter (PanelItem* i, char c) {
  52.     if (c >= 0 && c <= MAXCHAR) {
  53.     items[c] = i;
  54.     }
  55.     i->SetHighlighterParent(this);
  56. }
  57.  
  58. // LookUp returns the item associated with the given character.
  59.  
  60. PanelItem* Panel::LookUp (char c) {
  61.     PanelItem* i = nil;
  62.     if (c >= 0 && c <= MAXCHAR) {
  63.     i = items[c];
  64.     }
  65.     return i;
  66. }
  67.  
  68. // SetCur sets the currently highlighted item.  The panel highlights
  69. // only one item at any time.
  70.  
  71. void Panel::SetCur (PanelItem* item) {
  72.     if (cur != nil) {
  73.     cur->Highlight(false);
  74.     }
  75.     cur = item;
  76.     if (cur != nil) {
  77.     cur->Highlight(true);
  78.     }
  79. }
  80.  
  81. // GetCur returns the currently highlighted item.
  82.  
  83. PanelItem* Panel::GetCur () {
  84.     return cur;
  85. }
  86.  
  87. // PerformCurrentFunction tells the currently highlighted item to
  88. // perform its function.
  89.  
  90. void Panel::PerformCurrentFunction (Event& e) {
  91.     if (cur != nil) {
  92.     cur->Perform(e);
  93.     }
  94. }
  95.  
  96. // PerformTemporaryFunction temporarily selects the item associated
  97. // with the given character and tells it to perform its function.
  98.  
  99. void Panel::PerformTemporaryFunction (Event& e, char c) {
  100.     PanelItem* tmp = LookUp(c);
  101.     if (tmp != nil) {
  102.     PanelItem* prev = cur;
  103.     SetCur(tmp);
  104.     tmp->Perform(e);
  105.     SetCur(prev);
  106.     }
  107. }
  108.  
  109. // PanelItem stores the panel it belongs to and its text labels.
  110.  
  111. PanelItem::PanelItem (Panel* p, const char* l, const char* k, char c) {
  112.     p->Enter(this, c);
  113.     panel = p;
  114.     name = strdup(l ? l : "");
  115.     key = strdup(k ? k : "");
  116.     input = updownEvents;
  117.     input->Reference();
  118. }
  119.  
  120. // Free storage allocated to store the text labels.
  121.  
  122. PanelItem::~PanelItem () {
  123.     delete name;
  124.     delete key;
  125. }
  126.  
  127. // Handle highlights the item if the user clicks on it or types its
  128. // associated character (mapped by the program).
  129.  
  130. void PanelItem::Handle (Event& e) {
  131.     switch (e.eventType) {
  132.     case DownEvent:
  133.     case KeyEvent:
  134.     panel->SetCur(this);
  135.     break;
  136.     default:
  137.     break;
  138.     }
  139. }
  140.  
  141. // Perform performs the item's function.
  142.  
  143. void PanelItem::Perform (Event&) {
  144.     // define it in your subclass
  145. }
  146.  
  147. // Reconfig pads the item's shape to accomodate its text labels.
  148. // Basing padding on the font in use ensures the padding will change
  149. // proportionally with changes in the font's size.
  150.  
  151. static const float WIDTHPAD = 1.5; // fraction of font->Width(EM)
  152. static const float HTPAD = 0.77;   // fraction of font->Height()
  153. static const float KEYPAD = 1./6.; // fraction of font->Width(EM)
  154. static const char* EM = "m";       // widest alphabetic character in any font
  155.  
  156. void PanelItem::Reconfig () {
  157.     Highlighter::Reconfig();
  158.     Font* font = output->GetFont();
  159.     int xpad = round(WIDTHPAD * font->Width(EM));
  160.     int ypad = round(HTPAD * font->Height());
  161.     shape->width = font->Width(name) + (2 * xpad);
  162.     shape->height = font->Height() + (2 * ypad);
  163.     shape->Rigid(2 * xpad, hfil, 2 * ypad, 0);
  164. }
  165.  
  166. // Redraw displays the text labels.
  167.  
  168. void PanelItem::Redraw (Coord l, Coord b, Coord r, Coord t) {
  169.     output->ClearRect(canvas, l, b, r, t);
  170.     output->FillBg(false);
  171.     output->Text(canvas, name, name_x, name_y);
  172.     output->Text(canvas, key, key_x, key_y);
  173.     output->FillBg(true);
  174. }
  175.  
  176. // Resize calculates the text labels' positions.  For the convenience
  177. // of subclasses which want to draw graphic labels centered in the
  178. // canvas and as large as possible while maintaining a 1:1 aspect
  179. // ratio, Resize also calculates side, offx, and offy which define the
  180. // largest possible square centered in the canvas.
  181.  
  182. void PanelItem::Resize () {
  183.     Font* font = output->GetFont();
  184.     name_x = max(0, (xmax - font->Width(name) + 1) / 2);
  185.     name_y = (ymax - font->Height() + 1) / 2;
  186.     int pad = round(KEYPAD * font->Width(EM));
  187.     key_x = xmax - font->Width(key) - pad;
  188.     key_y = pad;
  189.     side = min(xmax, ymax);
  190.     offx = (xmax - side) / 2;
  191.     offy = (ymax - side) / 2;
  192. }
  193.