Mercurial > hg > forks > yadex
view src/entry.cc @ 104:76ad709ed3c6
Cleanups.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Mon, 06 Oct 2014 05:04:24 +0300 |
parents | 2f1ecc1c5f72 |
children | 20aa5a515896 |
line wrap: on
line source
/* * entry.cc * Entry "widgets" (ahem). * AYM 1998-11-30 */ /* This file is part of Yadex. Yadex incorporates code from DEU 5.21 that was put in the public domain in 1994 by Raphaël Quinet and Brendon Wyber. The rest of Yadex is Copyright © 1997-2003 André Majorel and others. This program 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 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #include "yadex.h" #include "entry.h" #include "gfx.h" const char *strgetl(const char *&str, long &value); /* * InputInteger - display the integer input box * * FIXME *valp, minv and maxv should be changed to long. */ int InputInteger(int x0, int y0, int *valp, int minv, int maxv) { int key; int entry_out_x0; int entry_out_y0; int entry_out_x1; int entry_out_y1; int entry_text_x0; int entry_text_y0; int entry_text_x1; int entry_text_y1; const size_t boxlen = 7; // Visible width of entry box const size_t bufmaxlen = 50; // Slack enough char *buf = new char[bufmaxlen + 1]; entry_out_x0 = x0; entry_text_x0 = entry_out_x0 + HOLLOW_BORDER + NARROW_HSPACING; entry_text_x1 = entry_text_x0 + boxlen * FONTW - 1; entry_out_x1 = entry_text_x1 + HOLLOW_BORDER + NARROW_HSPACING; entry_out_y0 = y0; entry_text_y0 = entry_out_y0 + HOLLOW_BORDER + NARROW_VSPACING; entry_text_y1 = entry_text_y0 + FONTH - 1; entry_out_y1 = entry_text_y1 + HOLLOW_BORDER + NARROW_VSPACING; DrawScreenBoxHollow(entry_out_x0, entry_out_y0, entry_out_x1, entry_out_y1, BLACK); long val = *valp; sprintf(buf, "%d", *valp); // FIXME what if we were in hex ? for (bool firstkey = true;; firstkey = false) { bool ok; { const char *checkp = buf; ok = strgetl(checkp, val) == 0 && checkp == buf + strlen(buf) && val >= minv && val <= maxv; } set_colour(BLACK); DrawScreenBox(entry_text_x0, entry_text_y0, entry_text_x1, entry_text_y1); if (ok) set_colour(WHITE); else set_colour(LIGHTRED); if (strlen(buf) > boxlen) { DrawScreenText(entry_text_x0, entry_text_y0, "<%s", buf + (strlen(buf) - boxlen + 1)); } else DrawScreenString(entry_text_x0, entry_text_y0, buf); key = get_key(); if (key == YK_BACKSPACE && strlen(buf) > 0) { buf[strlen(buf) - 1] = '\0'; } else if (key == YK_RETURN && ok) { *valp = (int) val; break; // Return current value } else if (key == YK_LEFT || key == YK_RIGHT || key == YK_UP || key == YK_DOWN || key == YK_TAB || key == YK_BACKTAB) { *valp = (int) val; break; // Return current value, even if not valid } else if (key == YK_ESC) { *valp = IIV_CANCEL; // Return an out of range value break; } else if (is_ordinary(key) && strlen(buf) < bufmaxlen) { if (firstkey) { if (key == ' ') // Kludge : hit space to append to initial value continue; else *buf = '\0'; } al_sapc(buf, key, bufmaxlen); } } is.key = 0; // Shouldn't have to do that but EditorLoop() is broken delete[]buf; return key; } /* ask for an integer value and check for minimum and maximum */ int InputIntegerValue(int x0, int y0, int minv, int maxv, int defv) { int val, key; char prompt[80]; y_snprintf(prompt, sizeof prompt, "Enter a number between %d and %d:", minv, maxv); if (x0 < 0) x0 = (cfg.ScrMaxX - 25 - FONTW * strlen(prompt)) / 2; if (y0 < 0) y0 = (cfg.ScrMaxY - 55) / 2; DrawScreenBox3D(x0, y0, x0 + 25 + FONTW * strlen(prompt), y0 + 55); set_colour(WHITE); DrawScreenText(x0 + 10, y0 + 8, prompt); val = defv; while ((key = InputInteger(x0 + 10, y0 + 28, &val, minv, maxv)) != YK_RETURN && key != YK_ESC) Beep(); return val; } /* ask for a filename */ void InputFileName(int x0, int y0, const char *prompt, size_t maxlen, char *filename) { int key; size_t boxlen, l; bool firstkey; int width; int title_y0; int entry_out_x0; int entry_out_y0; int entry_out_x1; int entry_out_y1; int entry_text_x0; int entry_text_y0; int entry_text_x1; int entry_text_y1; for (l = strlen(filename) + 1; l <= maxlen; l++) filename[l] = '\0'; /* compute the width of the input box */ if (maxlen > 20) boxlen = 20; else boxlen = maxlen; width = 2 * HOLLOW_BORDER + 2 * NARROW_HSPACING + boxlen * FONTW; if ((int) (strlen(prompt) * FONTW) > width) width = strlen(prompt) * FONTW; width += 2 * BOX_BORDER + 2 * WIDE_HSPACING; if (x0 < 0) x0 = (cfg.ScrMaxX - width) / 2; if (y0 < 0) y0 = (cfg.ScrMaxY - 2 * BOX_BORDER - 2 * WIDE_VSPACING - (int) (2.5 * FONTH) - 2 * HOLLOW_BORDER - 2 * NARROW_VSPACING) / 2; /* draw the dialog box */ entry_out_x0 = x0 + BOX_BORDER + WIDE_HSPACING; entry_text_x0 = entry_out_x0 + HOLLOW_BORDER + NARROW_HSPACING; entry_text_x1 = entry_text_x0 + boxlen * FONTW - 1; entry_out_x1 = entry_text_x1 + NARROW_HSPACING + HOLLOW_BORDER; title_y0 = y0 + BOX_BORDER + WIDE_VSPACING; entry_out_y0 = title_y0 + (int) (1.5 * FONTH); entry_text_y0 = entry_out_y0 + HOLLOW_BORDER + NARROW_VSPACING; entry_text_y1 = entry_text_y0 + FONTH - 1; entry_out_y1 = entry_text_y1 + NARROW_VSPACING + HOLLOW_BORDER; DrawScreenBox3D(x0, y0, x0 + width - 1, entry_out_y1 + WIDE_VSPACING); DrawScreenBoxHollow(entry_out_x0, entry_out_y0, entry_out_x1, entry_out_y1, BLACK); set_colour(WINTITLE); DrawScreenString(entry_out_x0, title_y0, prompt); firstkey = true; for (;;) { l = strlen(filename); set_colour(BLACK); DrawScreenBox(entry_text_x0, entry_text_y0, entry_text_x1, entry_text_y1); set_colour(WHITE); if (l > boxlen) { DrawScreenText(entry_text_x0, entry_text_y0, "<%s", filename + (l - boxlen + 1)); } else DrawScreenString(entry_text_x0, entry_text_y0, filename); key = get_key(); if (firstkey && is_ordinary(key)) { for (l = 0; l <= maxlen; l++) filename[l] = '\0'; l = 0; } firstkey = false; if (l < maxlen && is_ordinary(key)) { filename[l] = key; filename[l + 1] = '\0'; } else if (l > 0 && key == YK_BACKSPACE) filename[l - 1] = '\0'; else if (key == YK_RETURN) break; /* return "filename" */ else if (key == YK_ESC) { filename[0] = '\0'; /* return an empty string */ break; } else Beep(); } is.key = 0; // Shouldn't have to do that but EditorLoop() is broken } /* * strgetl - parse a C-style signed long integer * * Parse anything that would be a legal C signed long * integer literal (L and U suffixes are not allowed). * After the function returns, <str> points on the first * character that could not be parsed. If what was parsed * constitutes a valid integer, <value> contains its value * and the return value is a null pointer. Otherwise, * <value> is undefined and the return value is a static * string describing the error. */ const char *strgetl(const char *&str, long &value) { int base = 10; int sign = 1; // Leading + or - if (*str == '-') { sign = -1; str++; } else if (*str == '+') str++; // 0- or 0x- prefix if (*str == '0' && (str[1] == 'x' || str[1] == 'X')) { base = 16; str += 2; } else if (*str == '0') base = 8; // Don't advance str, so that "0" passes the next test // Check that there is at least one digit if (hextoi(*str) < 0 || hextoi(*str) >= base) { if (base == 8) return "expected an octal digit"; else if (base == 10) return "expected a decimal digit"; else return "expected a hex digit"; } // Swallow all non-prefix digits for (value = 0; *str != '\0'; str++) { int digitval = hextoi(*str); if (digitval < 0 || digitval >= base) return 0; value = base * value + sign * digitval; } return 0; }