File Coverage

blib/lib/Curses/Simp.pm
Criterion Covered Total %
statement 16 18 88.8
branch n/a
condition n/a
subroutine 6 6 100.0
pod n/a
total 22 24 91.6


line stmt bran cond sub pod time code
1             # 2AFBQB7: Curses::Simp by PipStuart to simplify Perl text-mode application development;
2             # Notz: Curses color names: COLOR_ BLACK,RED,GREEN,YELLOW,BLUE,MAGENTA,CYAN,WHITE
3             package Curses::Simp;
4 2     2   79793 use strict;
  2         4  
  2         124  
5 2     2   11 use vars qw( $AUTOLOAD );
  2         4  
  2         97  
6 2     2   13 use Carp;
  2         9  
  2         173  
7 2     2   2218 use Tie::Array;
  2         3113  
  2         64  
8 2     2   2190 use Math::BaseCnv qw(:all);
  2         234574  
  2         563  
9 2     2   2592 use Curses; # comment this line if you want to try 4NT rendering
  0            
  0            
10             my $curs = eval('use Curses; 1') || 0;
11             my $ptim = eval('use Time::PT; 1') || 0;
12             my $fram = eval('use Time::Frame; 1') || 0;
13             our $VERSION = '1.4.A8UG1gG'; # major . minor . PipTimeStamp
14             our $PTVR = $VERSION; $PTVR =~ s/^\d+\.\d+\.//; # strip major && minor # Please see `perldoc Time::PT` for an explanation of $PTVR.
15             my $dbug = 0; open(DBUG,'>','dbug') if($dbug); # flag for debug file logging
16             END { CScr() if($curs); close(DBUG) if($dbug); } # Auto-execute CloseScreen() on exit
17             my %SDAT = (); # potential SimpData holder for 4NT private _variables
18             my %GLBL = ( # GLOBAL CLASS VARIABLES
19             'FLAGOPEN' => 0, # flag for if a main curses screen has been opened yet
20             'FLAGU4NT' => 0, # flag for if 4NT will be used instead of Curses
21             'FLAGCOLR' => 0, # flag for whether colors have been initialized which
22             # holds the maximum number of color pairs after init
23             'TESTMAPP' => {
24             'NORMAL' => 'w', #00
25             'FILE' => 'w', #00 # normal file
26             'DIR' => 'U', #01;34 # directory
27             'LINK' => 'W', #01;37 # symbolic link
28             'FIFO' => 'y', #00;33;40 # pipe
29             'SOCK' => 'P', #01;35 # socket
30             #'DOOR' => 'P', #01;35 # door
31             'BLK' => 'Y', #01;33;40 # block device driver
32             'CHR' => 'Y', #01;33;40 # character device driver
33             'ORPHAN' => 'R', #01;31;40 # symlink to nonexistent file
34             'EXEC' => 'G', #01;32 # executable file
35             },
36             'DFLTMAPP' => {
37             qr/\.(cmd|exe|com|btm|bat)$/ => 'O',
38             qr/\.(bak)$/ => 'P',
39             qr/\.(asm|c|cpp|m|h|scm|pl|pm|py|cgi|htm|html)$/ => 'C',
40             qr/\.(tar|tgz|tbz|tbz2|arj|taz|lzh|zip|z|gz|bz|bz2|deb|rpm)$/ => 'R',
41             qr/\.(jpg|jpeg|gif|bmp|ppm|tga|xbm|xpm|tif|tiff|png|mpg|mpeg|avi|mov|gl|dl)$/ => 'p',
42             qr/\.(txt|rtf)$/ => 'W',
43             qr/\.(cfg|ini)$/ => 'Y',
44             qr/\.(ogg|mp3|s3m|mod|wav|xm|it)$/ => 'C',
45             },
46             'OVERMAPP' => { },
47             );
48             my @DISPSTAK = ( );# global stack of created Simp objects for display order
49             my @BORDSETS = ( );# array of hashes of different border char sets (see OScr())
50             my @SDLKNAMZ = ( # in advanced input mode, these SDLK names return from GetK()
51             # SDLKey ASCII value Common name
52             'SDLK_BACKSPACE', #'\b' backspace
53             'SDLK_TAB', #'\t' tab
54             'SDLK_CLEAR', # clear
55             'SDLK_RETURN', #'\r' return
56             'SDLK_PAUSE', # pause
57             'SDLK_ESCAPE', #'^[' escape
58             'SDLK_SPACE', #' ' space
59             'SDLK_EXCLAIM', #'!' exclaim
60             'SDLK_QUOTEDBL', #'"' quotedbl
61             'SDLK_HASH', #'#' hash
62             'SDLK_DOLLAR', #'$' dollar
63             'SDLK_AMPERSAND', #'&' ampersand
64             'SDLK_QUOTE', #'\'' quote
65             'SDLK_LEFTPAREN', #'(' left parenthesis
66             'SDLK_RIGHTPAREN', #')' right parenthesis
67             'SDLK_ASTERISK', #'*' asterisk
68             'SDLK_PLUS', #'+' plus sign
69             'SDLK_COMMA', #',' comma
70             'SDLK_MINUS', #'-' minus sign
71             'SDLK_PERIOD', #'.' period
72             'SDLK_SLASH', #'/' forward slash
73             'SDLK_0', #'0' 0
74             'SDLK_1', #'1' 1
75             'SDLK_2', #'2' 2
76             'SDLK_3', #'3' 3
77             'SDLK_4', #'4' 4
78             'SDLK_5', #'5' 5
79             'SDLK_6', #'6' 6
80             'SDLK_7', #'7' 7
81             'SDLK_8', #'8' 8
82             'SDLK_9', #'9' 9
83             'SDLK_COLON', #':' colon
84             'SDLK_SEMICOLON', #';' semicolon
85             'SDLK_LESS', #'<' less-than sign
86             'SDLK_EQUALS', #'=' equals sign
87             'SDLK_GREATER', #'>' greater-than sign
88             'SDLK_QUESTION', #'?' question mark
89             'SDLK_AT', #'@' at
90             'SDLK_LEFTBRACKET', #'[' left bracket
91             'SDLK_BACKSLASH', #'\' backslash
92             'SDLK_RIGHTBRACKET', #']' right bracket
93             'SDLK_CARET', #'^' caret
94             'SDLK_UNDERSCORE', #'_' underscore
95             'SDLK_BACKQUOTE', #'`' grave
96             'SDLK_TILDE', #'~' tilde
97             'SDLK_a', #'a' a
98             'SDLK_b', #'b' b
99             'SDLK_c', #'c' c
100             'SDLK_d', #'d' d
101             'SDLK_e', #'e' e
102             'SDLK_f', #'f' f
103             'SDLK_g', #'g' g
104             'SDLK_h', #'h' h
105             'SDLK_i', #'i' i
106             'SDLK_j', #'j' j
107             'SDLK_k', #'k' k
108             'SDLK_l', #'l' l
109             'SDLK_m', #'m' m
110             'SDLK_n', #'n' n
111             'SDLK_o', #'o' o
112             'SDLK_p', #'p' p
113             'SDLK_q', #'q' q
114             'SDLK_r', #'r' r
115             'SDLK_s', #'s' s
116             'SDLK_t', #'t' t
117             'SDLK_u', #'u' u
118             'SDLK_v', #'v' v
119             'SDLK_w', #'w' w
120             'SDLK_x', #'x' x
121             'SDLK_y', #'y' y
122             'SDLK_z', #'z' z
123             'SDLK_DELETE', #'^?' delete
124             'SDLK_KP0', # keypad 0
125             'SDLK_KP1', # keypad 1
126             'SDLK_KP2', # keypad 2
127             'SDLK_KP3', # keypad 3
128             'SDLK_KP4', # keypad 4
129             'SDLK_KP5', # keypad 5
130             'SDLK_KP6', # keypad 6
131             'SDLK_KP7', # keypad 7
132             'SDLK_KP8', # keypad 8
133             'SDLK_KP9', # keypad 9
134             'SDLK_KP_PERIOD', #'.' keypad period
135             'SDLK_KP_DIVIDE', #'/' keypad divide
136             'SDLK_KP_MULTIPLY', #'*' keypad multiply
137             'SDLK_KP_MINUS', #'-' keypad minus
138             'SDLK_KP_PLUS', #'+' keypad plus
139             'SDLK_KP_ENTER', #'\r' keypad enter
140             'SDLK_KP_EQUALS', #'=' keypad equals
141             'SDLK_UP', # up arrow
142             'SDLK_DOWN', # down arrow
143             'SDLK_RIGHT', # right arrow
144             'SDLK_LEFT', # left arrow
145             'SDLK_INSERT', # insert
146             'SDLK_HOME', # home
147             'SDLK_END', # end
148             'SDLK_PAGEUP', # page up
149             'SDLK_PAGEDOWN', # page down
150             'SDLK_F1', # F1
151             'SDLK_F2', # F2
152             'SDLK_F3', # F3
153             'SDLK_F4', # F4
154             'SDLK_F5', # F5
155             'SDLK_F6', # F6
156             'SDLK_F7', # F7
157             'SDLK_F8', # F8
158             'SDLK_F9', # F9
159             'SDLK_F10', # F10
160             'SDLK_F11', # F11
161             'SDLK_F12', # F12
162             'SDLK_F13', # F13
163             'SDLK_F14', # F14
164             'SDLK_F15', # F15
165             'SDLK_NUMLOCK', # numlock
166             'SDLK_CAPSLOCK', # capslock
167             'SDLK_SCROLLOCK', # scrollock
168             'SDLK_RSHIFT', # right shift
169             'SDLK_LSHIFT', # left shift
170             'SDLK_RCTRL', # right ctrl
171             'SDLK_LCTRL', # left ctrl
172             'SDLK_RALT', # right alt
173             'SDLK_LALT', # left alt
174             'SDLK_RMETA', # right meta
175             'SDLK_LMETA', # left meta
176             'SDLK_LSUPER', # left windows key
177             'SDLK_RSUPER', # right windows key
178             'SDLK_MODE', # mode shift
179             'SDLK_HELP', # help
180             'SDLK_PRINT', # print-screen
181             'SDLK_SYSREQ', # SysRq
182             'SDLK_BREAK', # break
183             'SDLK_MENU', # menu
184             'SDLK_POWER', # power
185             'SDLK_EURO', # euro
186             );
187             my %SDLKCHRM = (
188             ' ' => 'SPACE',
189             '!' => 'EXCLAIM',
190             '"' => 'QUOTEDBL',
191             '#' => 'HASH',
192             '$' => 'DOLLAR',
193             '%' => 'PERCENT',
194             '&' => 'AMPERSAND',
195             "'" => 'QUOTE',
196             '(' => 'LEFTPAREN',
197             ')' => 'RIGHTPAREN',
198             ',' => 'COMMA',
199             '*' => 'ASTERISK',
200             '+' => 'PLUS',
201             ',' => 'COMMA',
202             '-' => 'MINUS',
203             '.' => 'PERIOD',
204             '/' => 'SLASH',
205             ':' => 'COLON',
206             ';' => 'SEMICOLON',
207             '<' => 'LESS',
208             '=' => 'EQUALS',
209             '>' => 'GREATER',
210             '?' => 'QUESTION',
211             '@' => 'AT',
212             '[' => 'LEFTBRACKET',
213             '\\'=> 'BACKSLASH',
214             ']' => 'RIGHTBRACKET',
215             '^' => 'CARET',
216             '_' => 'UNDERSCORE',
217             '`' => 'BACKQUOTE',
218             '~' => 'TILDE',
219             );
220             my %SDLKCRSM = (
221             'KEY_BACKSPACE' => 'BACKSPACE',
222             'KEY_LEFT' => 'LEFT',
223             'KEY_RIGHT' => 'RIGHT',
224             'KEY_UP' => 'UP',
225             'KEY_DOWN' => 'DOWN',
226             'KEY_HOME' => 'HOME',
227             'KEY_END' => 'END',
228             'KEY_PPAGE' => 'PAGEUP',
229             'KEY_NPAGE' => 'PAGEDOWN',
230             'KEY_IC' => 'INSERT',
231             'KEY_DC' => 'DELETE',
232             'KEY_F1' => 'F1',
233             'KEY_F2' => 'F2',
234             'KEY_F3' => 'F3',
235             'KEY_F4' => 'F4',
236             'KEY_F5' => 'F5',
237             'KEY_F6' => 'F6',
238             'KEY_F7' => 'F7',
239             'KEY_F8' => 'F8',
240             'KEY_F9' => 'F9',
241             'KEY_F10' => 'F10',
242             'KEY_F11' => 'F11',
243             'KEY_F12' => 'F12',
244             'KEY_F13' => 'F13',
245             'KEY_F14' => 'F14',
246             'KEY_F15' => 'F15',
247             );
248             my %SDLKORDM = (
249             '9' => 'TAB',
250             '13' => 'RETURN',
251             '27' => 'ESCAPE',
252             );
253             my %SDLK4NTM = (
254             '@75' => 'LEFT',
255             '@77' => 'RIGHT',
256             '@72' => 'UP',
257             '@80' => 'DOWN',
258             '@71' => 'HOME',
259             '@79' => 'END',
260             '@73' => 'PAGEUP',
261             '@81' => 'PAGEDOWN',
262             '@59' => 'F1',
263             '@60' => 'F2',
264             '@61' => 'F3',
265             '@62' => 'F4',
266             '@63' => 'F5',
267             '@64' => 'F6',
268             '@65' => 'F7',
269             '@66' => 'F8',
270             '@67' => 'F9',
271             '@68' => 'F10',
272             '@133' => 'F11',
273             '@134' => 'F12',
274             );
275             my @KMODNAMZ = ( # in advanced input mode, these KMOD modifier names get set
276             # within the Simp object's '_kmod' hash after each GetK()
277             # SDL Modifier Meaning
278             'KMOD_NONE', # No modifiers applicable
279             # I don't think I can detect locks or left/right with Curses so commented
280             # 'KMOD_NUM', # Numlock is down
281             # 'KMOD_CAPS', # Capslock is down
282             # 'KMOD_LCTRL', # Left Control is down
283             # 'KMOD_RCTRL', # Right Control is down
284             # 'KMOD_RSHIFT', # Right Shift is down
285             # 'KMOD_LSHIFT', # Left Shift is down
286             # 'KMOD_RALT', # Right Alt is down
287             # 'KMOD_LALT', # Left Alt is down
288             'KMOD_CTRL', # A Control key is down
289             'KMOD_SHIFT', # A Shift key is down
290             'KMOD_ALT', # An Alt key is down
291             ); # A_BOLD attribute number
292             my @kndx = (); my @knam = (); my %knum = (); my $abld = 2097152; my $i = 0;
293             my %clet = ( 'k' => 0, 'r' => 1, 'g' => 2, 'o' => 3, # color letters map
294             'u' => 4, 'm' => 5, 't' => 6, 'y' => 3,
295             'b' => 4, 'p' => 5, 'c' => 6, 'w' => 7,
296             'K' => 8, 'R' => 9, 'G' => 10, 'O' => 3, # Orange exception
297             'U' => 12, 'M' => 13, 'T' => 14, 'Y' => 11,
298             'B' => 12, 'P' => 13, 'C' => 14, 'W' => 15,
299             'l' => 13, 'L' => 13 ); # lavender exception
300             my @telc = ( 'k', 'r', 'g', 'y', 'b', 'p', 'c', 'w' ); # core colors indexed
301             my @tel4 = ( 0 , 4 , 2 , 6 , 1 , 5 , 3 , 7 ); # 4NT colors indexed
302             # ordered attribute names array, default attribute data hash
303             my @_attrnamz = (); my %_attrdata = ();
304             my %_verbose_attrnamz = ();
305             # field data
306             push(@_attrnamz, '_wind'); $_attrdata{$_attrnamz[-1]} = 0; # CursesWindowHandle
307             $_verbose_attrnamz{$_attrnamz[-1]} = 'WindowHandle';
308             push(@_attrnamz, '_text'); $_attrdata{$_attrnamz[-1]} = []; # text data
309             $_verbose_attrnamz{$_attrnamz[-1]} = 'TextData';
310             push(@_attrnamz, '_fclr'); $_attrdata{$_attrnamz[-1]} = []; # fg color data
311             $_verbose_attrnamz{$_attrnamz[-1]} = 'ForegroundColorData';
312             push(@_attrnamz, '_bclr'); $_attrdata{$_attrnamz[-1]} = []; # bg color data
313             $_verbose_attrnamz{$_attrnamz[-1]} = 'BackgroundColorData';
314             push(@_attrnamz, '_kque'); $_attrdata{$_attrnamz[-1]} = []; # Key Queue
315             $_verbose_attrnamz{$_attrnamz[-1]} = 'KeyQueue';
316             push(@_attrnamz, '_mque'); $_attrdata{$_attrnamz[-1]} = []; # Key Mod Queue
317             $_verbose_attrnamz{$_attrnamz[-1]} = 'KeyModQueue';
318             push(@_attrnamz, '_hite'); $_attrdata{$_attrnamz[-1]} = 0; # window height
319             $_verbose_attrnamz{$_attrnamz[-1]} = 'WindowHeight';
320             push(@_attrnamz, '_widt'); $_attrdata{$_attrnamz[-1]} = 0; # window width
321             $_verbose_attrnamz{$_attrnamz[-1]} = 'WindowWidth';
322             push(@_attrnamz, '_yoff'); $_attrdata{$_attrnamz[-1]} = 0; # window y-offset
323             $_verbose_attrnamz{$_attrnamz[-1]} = 'WindowYOffset';
324             push(@_attrnamz, '_xoff'); $_attrdata{$_attrnamz[-1]} = 0; # window x-offset
325             $_verbose_attrnamz{$_attrnamz[-1]} = 'WindowXOffset';
326             push(@_attrnamz, '_ycrs'); $_attrdata{$_attrnamz[-1]} = 0; # cursor y-offset
327             $_verbose_attrnamz{$_attrnamz[-1]} = 'CursorYOffset';
328             push(@_attrnamz, '_xcrs'); $_attrdata{$_attrnamz[-1]} = 0; # cursor x-offset
329             $_verbose_attrnamz{$_attrnamz[-1]} = 'CursorXOffset';
330             push(@_attrnamz, '_btyp'); $_attrdata{$_attrnamz[-1]} = 0; # border type
331             $_verbose_attrnamz{$_attrnamz[-1]} = 'WindowBorderType';
332             push(@_attrnamz, '_brfc'); $_attrdata{$_attrnamz[-1]} = 'w';# border fore color
333             $_verbose_attrnamz{$_attrnamz[-1]} = 'WindowBorderForegroundColor';
334             push(@_attrnamz, '_brbc'); $_attrdata{$_attrnamz[-1]} = 'k';# border back color
335             $_verbose_attrnamz{$_attrnamz[-1]} = 'WindowBorderBackgroundColor';
336             push(@_attrnamz, '_titl'); $_attrdata{$_attrnamz[-1]} = ''; # window title
337             $_verbose_attrnamz{$_attrnamz[-1]} = 'WindowTitle';
338             push(@_attrnamz, '_ttfc'); $_attrdata{$_attrnamz[-1]} = 'W';# title fore color
339             $_verbose_attrnamz{$_attrnamz[-1]} = 'WindowTitleForegroundColor';
340             push(@_attrnamz, '_ttbc'); $_attrdata{$_attrnamz[-1]} = 'W';# title back color
341             $_verbose_attrnamz{$_attrnamz[-1]} = 'WindowTitleBackgroundColor';
342             push(@_attrnamz, '_dndx'); $_attrdata{$_attrnamz[-1]} = 0; # DISPSTAK index
343             $_verbose_attrnamz{$_attrnamz[-1]} = 'DisplayStackIndex';
344             # Flags, storage Values, && extended attributes
345             push(@_attrnamz, '_flagaudr'); $_attrdata{$_attrnamz[-1]} = 1; # Auto Draw()
346             $_verbose_attrnamz{$_attrnamz[-1]} = 'FlagAutoDraw';
347             push(@_attrnamz, '_flagadtf'); $_attrdata{$_attrnamz[-1]} = 1; # AD Tied FG
348             $_verbose_attrnamz{$_attrnamz[-1]} = 'FlagAutoDrawTiedForegroundData';
349             push(@_attrnamz, '_flagadtb'); $_attrdata{$_attrnamz[-1]} = 1; # AD Tied BG
350             $_verbose_attrnamz{$_attrnamz[-1]} = 'FlagAutoDrawTiedBackgroundData';
351             push(@_attrnamz, '_flagmaxi'); $_attrdata{$_attrnamz[-1]} = 1; # Maximize
352             $_verbose_attrnamz{$_attrnamz[-1]} = 'FlagMaximize';
353             push(@_attrnamz, '_flagshrk'); $_attrdata{$_attrnamz[-1]} = 1; # ShrinkToFit
354             $_verbose_attrnamz{$_attrnamz[-1]} = 'FlagShrinkToFit';
355             push(@_attrnamz, '_flagcntr'); $_attrdata{$_attrnamz[-1]} = 1; # Center
356             $_verbose_attrnamz{$_attrnamz[-1]} = 'FlagCenter';
357             push(@_attrnamz, '_flagcvis'); $_attrdata{$_attrnamz[-1]} = 0; # CursorVisible
358             $_verbose_attrnamz{$_attrnamz[-1]} = 'FlagCursorVisible';
359             push(@_attrnamz, '_flagscrl'); $_attrdata{$_attrnamz[-1]} = 0; # Scrollbar
360             $_verbose_attrnamz{$_attrnamz[-1]} = 'FlagScrollbar';
361             push(@_attrnamz, '_flagsdlk'); $_attrdata{$_attrnamz[-1]} = 0; # SDLK
362             $_verbose_attrnamz{$_attrnamz[-1]} = 'FlagSDLKey';
363             push(@_attrnamz, '_flagfram'); $_attrdata{$_attrnamz[-1]} = 0; # Time::Frame
364             $_verbose_attrnamz{$_attrnamz[-1]} = 'FlagTimeFrame';
365             push(@_attrnamz, '_flagmili'); $_attrdata{$_attrnamz[-1]} = 0; # millisecond
366             $_verbose_attrnamz{$_attrnamz[-1]} = 'FlagMillisecond';
367             push(@_attrnamz, '_flagprin'); $_attrdata{$_attrnamz[-1]} = 1; # Prnt into self
368             $_verbose_attrnamz{$_attrnamz[-1]} = 'FlagPrintInto';
369             push(@_attrnamz, '_flagclru'); $_attrdata{$_attrnamz[-1]} = 0; # Color Used?
370             $_verbose_attrnamz{$_attrnamz[-1]} = 'FlagColorUsed';
371             push(@_attrnamz, '_flaginsr'); $_attrdata{$_attrnamz[-1]} = 1; # insert mode
372             $_verbose_attrnamz{$_attrnamz[-1]} = 'FlagInsertMode';
373             push(@_attrnamz, '_flagdrop'); $_attrdata{$_attrnamz[-1]} = 0; # DropDown
374             $_verbose_attrnamz{$_attrnamz[-1]} = 'FlagDropDown';
375             push(@_attrnamz, '_flagdown'); $_attrdata{$_attrnamz[-1]} = 0; # DropIsDown
376             $_verbose_attrnamz{$_attrnamz[-1]} = 'FlagDropIsDown';
377             push(@_attrnamz, '_valulasp'); $_attrdata{$_attrnamz[-1]} = undef; # last pair
378             $_verbose_attrnamz{$_attrnamz[-1]} = 'LastPair';
379             push(@_attrnamz, '_valullsp'); $_attrdata{$_attrnamz[-1]} = undef; # llastpair
380             $_verbose_attrnamz{$_attrnamz[-1]} = 'LastLastPair';
381             push(@_attrnamz, '_valulasb'); $_attrdata{$_attrnamz[-1]} = undef; # last bold
382             $_verbose_attrnamz{$_attrnamz[-1]} = 'LastBold';
383             push(@_attrnamz, '_valullsb'); $_attrdata{$_attrnamz[-1]} = undef; # llastbold
384             $_verbose_attrnamz{$_attrnamz[-1]} = 'LastLastBold';
385             push(@_attrnamz, '_valudol8'); $_attrdata{$_attrnamz[-1]} = undef; # do late
386             $_verbose_attrnamz{$_attrnamz[-1]} = 'LateEscapedPrint';
387             # methods
388             sub DfltValu { my ($self, $attr) = @_; $_attrdata{$attr}; }
389             sub AttrNamz { @_attrnamz; } # attribute names
390             sub TIEARRAY {
391             OScr() unless($GLBL{'FLAGOPEN'}); # need Open main Screen for new Simp obj
392             my $clas = shift;
393             my $self = bless({}, $clas);
394             for my $attr ($self->AttrNamz()){
395             $self->{$attr} = $self->DfltValu($attr); # init defaults
396             }
397             for(@KMODNAMZ){ $self->{'_kmod'}->{$_} = 0; }
398             while(@_){
399             my $foun = 0;
400             my($keey, $valu)=(shift, shift);
401             for my $attr ($self->AttrNamz()){
402             if($attr =~ /$keey/i) {
403             $self->{$attr} = $valu;
404             $foun = 1;
405             }
406             }
407             unless($foun){
408             for my $attr ($self->AttrNamz()){
409             if($_verbose_attrnamz{$attr} eq $keey){ # exact match
410             $self->{$attr} = $valu;
411             $foun = 1;
412             }
413             }
414             unless($foun){
415             croak "!*EROR*! Curses::Simp::new initialization key:$keey was not recognized!\n";
416             }
417             }
418             }
419             $self->{'_flagshrk'} = 0 if($self->{'_hite'} && $self->{'_widt'});
420             $self->Updt(1);
421             if($curs){
422             $self->{'_wind'} = newwin($self->{'_hite'}, $self->{'_widt'},
423             $self->{'_yoff'}, $self->{'_xoff'});
424             unless(exists($self->{'_wind'}) && defined($self->{'_wind'})){
425             exit();
426             # croak "!*EROR*! Curses::Simp::new could not create new window with hite:$self->{'_hite'}, widt:$self->{'_widt'}, yoff:$self->{'_yoff'}, xoff:$self->{'_xoff'}!\n";
427             }
428             }
429             # newwin doesn't auto draw so if there's init _text && autodraw is on...
430             $self->TestDraw();
431             $self->Move(-1, -1) unless($self->{'_ycrs'} || $self->{'_xcrs'});
432             curs_set($self->{'_flagcvis'}) if($curs); # set cursor state
433             # add new Simp object to display order stack
434             $self->{'_dndx'} = @DISPSTAK;
435             push(@DISPSTAK, \$self);
436             return($self);
437             }
438             sub FETCH { return( $_[0]->{'_text'}->[$_[1]]); }
439             sub FETCHSIZE { return(scalar(@{$_[0]->{'_text'}}) ); }
440             sub STORE {
441             $_[0]->{'_text'}->[$_[1]] = $_[2];
442             $_[0]->TestDraw();
443             }
444             sub STORESIZE {
445             splice(@{$_[0]->{'_text'}}, $_[1], @{$_[0]->{'_text'}} - $_[1]);
446             $_[0]->TestDraw();
447             }
448             sub EXISTS { return(0) unless(defined($_[0]->{'_text'}->[$_[1]])); return(1); }
449             sub CLEAR { @{$_[0]->{'_text'}} = (); $_[0]->TestDraw(); }
450             sub PUSH { push(@{$_[0]->{'_text'}}, $_[1]); $_[0]->TestDraw(); }
451             sub POP { $_ = pop(@{$_[0]->{'_text'}}); $_[0]->TestDraw(); return($_); }
452             sub SHIFT { $_ = shift(@{$_[0]->{'_text'}}); $_[0]->TestDraw(); return($_); }
453             sub UNSHIFT { unshift(@{$_[0]->{'_text'}}, $_[1]); $_[0]->TestDraw(); }
454             sub SPLICE {
455             #open(DBUG, ">dbug"); for(0..$#_) { print DBUG "$_ : $_[$_]\n"; } close(DBUG); $_[0]->GetK(-1);
456             # $_ = splice(@{$_[0]->{'_text'}}, @_[1..$#_]); $_[0]->TestDraw(); return($_); }
457             my $self = shift;
458             my $offs = shift || 0;
459             my $leng = shift; $leng = $self->FETCHSIZE() - $offs unless(defined($leng));
460             my $retn = splice(@{$self->{'_text'}}, $offs, $leng, @_);
461             $self->TestDraw();
462             return($retn);
463             }
464             sub EXTEND { }
465             # MkMethdz creates Simp object field accessor methods with
466             # configurable handling && overrideable default operations. Beppu@CPAN.Org
467             # coded the first version of MkMethdz && taught me a new trick. =)
468             # Special Parameters:
469             # NAME => name of the method to be created
470             # ARAY => if this is true, $self->{$attr} is assumed to be
471             # an array ref, and default subcommands are installed
472             # LOOP => like ARAY above but a looping value instead
473             # ... => other method flags describing what to include in made method
474             # nmrc => sub reference for handling a numeric subcommand
475             # The rest of the parameters should be key/value pairs where:
476             # subcommand => subroutine reference
477             sub MkMethdz {
478             my %cmnd = @_;
479             my $meth = $cmnd{'NAME'} || die('NAME => required!');
480             my $aray = $cmnd{'ARAY'} || 0;
481             my $rsiz = $cmnd{'RSIZ'} || 0;
482             my $mvwn = $cmnd{'MVWN'} || 0;
483             my $mvcr = $cmnd{'MVCR'} || 0;
484             my $updt = $cmnd{'UPDT'} || 0;
485             my $crsr = $cmnd{'CRSR'} || 0;
486             my $loop = $cmnd{'LOOP'} || 0;
487             my $dstk = $cmnd{'DSTK'} || 0;
488             my $attr = '_' . lc($meth);
489             $cmnd{'asin'} ||= sub { # Dflt assign command
490             my $self = shift; my $nwvl = shift;
491             if(!$dstk || (0 <= $nwvl && $nwvl < @DISPSTAK)){
492             if($dstk && $self->{'_dndx'} != $nwvl) { # exchange displaystack indices
493             $DISPSTAK[ $nwvl ]->{'_dndx'} = $self->{'_dndx'};
494             ($DISPSTAK[$nwvl ], $DISPSTAK[$self->{'_dndx'}]) =
495             ($DISPSTAK[$self->{'_dndx'}], $DISPSTAK[$nwvl ]);
496             }
497             $self->{$attr} = $nwvl;
498             $self->{'_chgd'} = 1;#urs_set($self->{'_flagcvis'}) if($crsr && $self->{'_chgd'});
499             }
500             };
501             $cmnd{'assign'} ||= $cmnd{'asin'}; # handle normal names too =)
502             $cmnd{'blnk'} ||= sub { # Dflt blank command
503             my $self = shift;
504             $self->{$attr} = '';
505             $self->{'_chgd'} = 1;
506             };
507             $cmnd{'blank'} ||= $cmnd{'blnk'};
508             $cmnd{'togl'} ||= sub { # Dflt toggle command (for flags)
509             my $self = shift;
510             $self->{$attr} ^= 1;
511             $self->{'_chgd'} = 1;
512             };
513             $cmnd{'toggle'} ||= $cmnd{'togl'};
514             $cmnd{'true'} ||= sub { # Dflt truth command (for flags)
515             my $self = shift;
516             $self->{$attr} = 1;
517             $self->{'_chgd'} = 1;
518             };
519             $cmnd{'fals'} ||= sub { # Dflt false command (for flags)
520             my $self = shift;
521             $self->{$attr} = 0;
522             $self->{'_chgd'} = 1;
523             };
524             $cmnd{'false'} ||= $cmnd{'fals'};
525             $cmnd{'incr'} ||= sub { # Dflt increment command
526             my $self = shift; my $amnt = shift || 1;
527             if(!$dstk || $self->{'_dndx'} < $#DISPSTAK){
528             if($dstk){ # exchange display stack indices
529             ${$DISPSTAK[ $self->{'_dndx'} - 1]}->{'_dndx'}--;
530             ($DISPSTAK[$self->{'_dndx'} ], $DISPSTAK[$self->{'_dndx'} + 1]) =
531             ($DISPSTAK[$self->{'_dndx'} + 1], $DISPSTAK[$self->{'_dndx'} ]);
532             }
533             $self->{$attr} += $amnt;
534             $self->{'_chgd'} = 1;
535             }
536             };
537             $cmnd{'increase'} ||= $cmnd{'incr'};
538             $cmnd{'decr'} ||= sub { # Dflt decrement command
539             my $self = shift; my $amnt = shift || 1;
540             if(!$dstk || $self->{'_dndx'}){
541             if($dstk){ # exchange display stack indices
542             ${$DISPSTAK[ $self->{'_dndx'} - 1]}->{'_dndx'}++;
543             ($DISPSTAK[$self->{'_dndx'} ], $DISPSTAK[$self->{'_dndx'} - 1]) =
544             ($DISPSTAK[$self->{'_dndx'} - 1], $DISPSTAK[$self->{'_dndx'} ]);
545             }
546             $self->{$attr} -= $amnt;
547             $self->{'_chgd'} = 1;
548             }
549             };
550             $cmnd{'decrease'} ||= $cmnd{'decr'};
551             if($aray){ # default commands for when $self->{$attr} is an array ref
552             $cmnd{'push'} ||= sub { # Dflt push
553             my $self = shift;
554             push(@{$self->{$attr}}, shift);
555             $self->{'_chgd'} = 1;
556             };
557             $cmnd{'popp'} ||= sub { # Dflt pop
558             my $self = shift;
559             pop(@{$self->{$attr}});
560             $self->{'_chgd'} = 1;
561             };
562             $cmnd{'pop' } ||= $cmnd{'popp'};
563             $cmnd{'apnd'} ||= sub { # Dflt append to last line
564             my $self = shift;
565             if(@{$self->{$attr}}){ $self->{$attr}->[-1] .= shift; }
566             else { push(@{$self->{$attr}}, shift); }
567             $self->{'_chgd'} = 1;
568             };
569             $cmnd{'append'} ||= $cmnd{'apnd'};
570             $cmnd{'dupl'} ||= sub { # Dflt duplicate last line or some line #
571             my $self = shift; my $lndx = shift || -1;
572             if(@{$self->{$attr}}){ push(@{$self->{$attr}}, $self->{$attr}->[$lndx]); }
573             else { push(@{$self->{$attr}}, ''); }
574             $self->{'_chgd'} = 1;
575             };
576             $cmnd{'duplicate'} ||= $cmnd{'dupl'};
577             $cmnd{'size'} ||= sub { # return array size
578             my $self = shift; return(scalar(@{$self->{$attr}}));
579             };
580             $cmnd{'data'} ||= sub { # set && return whole array data
581             my $self = shift;
582             @{$self->{$attr}} = shift if(@_);
583             return(@{$self->{$attr}});
584             };
585             $cmnd{'nmrc'} ||= sub { # Dflt nmrc
586             my($self, $keey, $valu)= @_;
587             if(defined($valu)){ # value exists to be assigned
588             $self->{$attr}->[$keey] = $valu;
589             if($attr =~ /^text/i && $self->{'_flagaudr'}){
590             # new Prnt() just changing line
591             $self->Prnt('text' => $valu, 'prin' => 0,
592             'yoff' => $keey, 'xoff' => 0);
593             }else{
594             # old array element assignment with full AutoDraw
595             $self->{'_chgd'} = 1;
596             }
597             }else{ # just return array line
598             return($self->{$attr}->[$keey]);
599             }
600             };
601             $cmnd{'numeric'} ||= $cmnd{'nmrc'}; # handle normal names too =)
602             }else{
603             $cmnd{'nmrc'} ||= sub { # Dflt nmrc for non-arrays
604             my($self, $keey, $valu)= @_;
605             if(defined($valu)){
606             # hmm I don't think non-array fields will have a numeric key && a val
607             # so I don't know what to do here yet
608             }else{ # just assign the key if no defined value
609             if(!$dstk || (0 <= $keey && $keey < @DISPSTAK)) {
610             if($dstk && $self->{'_dndx'} != $keey) { # xchg displaystack indices
611             $DISPSTAK[ $keey ]->{'_dndx'} = $self->{'_dndx'};
612             ($DISPSTAK[$keey ], $DISPSTAK[$self->{'_dndx'}]) =
613             ($DISPSTAK[$self->{'_dndx'}], $DISPSTAK[$keey ]);
614             }
615             $self->{$attr} = $keey;
616             $self->{'_chgd'} = 1;
617             }
618             }
619             };
620             $cmnd{'numeric'} ||= $cmnd{'nmrc'}; # handle normal names too =)
621             }
622             if($loop){ # default commands for when $self->{$attr} is a loop
623             $cmnd{'next'} ||= sub { # Dflt next
624             my $self = shift;
625             $self->{$attr}++; # should get loop limit instead of hard @BORDSETS
626             $self->{$attr} = 0 if($self->{$attr} > @BORDSETS);
627             $self->{'_chgd'} = 1;
628             };
629             $cmnd{'prev'} ||= sub { # Dflt prev
630             my $self = shift;
631             $self->{$attr}--; # should get loop limit instead of hard @BORDSETS
632             $self->{$attr} = @BORDSETS if($self->{$attr} < 0);
633             $self->{'_chgd'} = 1;
634             };
635             $cmnd{'previous'} ||= $cmnd{'prev'}; # handle normal names too =)
636             }
637             { # block to isolate no strict where closure gets defined
638             no strict 'refs';
639             *{$meth} = sub {
640             my $self = shift; my($keey, $valu); my $foun;
641             while(@_){
642             ($keey, $valu)=(shift, shift);
643             if ( $keey =~ /\d+$/){ # call a special sub for numeric keyz
644             $cmnd{'nmrc'}->($self, $keey, $valu);
645             }elsif( defined($cmnd{$keey})){
646             $cmnd{$keey}->($self, $valu);
647             }elsif(!defined($valu)){
648             $self->{$attr} = $keey;
649             $self->{'_chgd'} = 1;
650             }elsif($keey eq lc($meth)){ # same as 'asin' with meth name instead
651             $self->{"_$keey"} = $valu;
652             }else{ # match && update any attributes accepted by new()
653             $foun = 0;
654             for my $attr ($self->AttrNamz()){
655             if ($attr =~ /$keey/i ||
656             $_verbose_attrnamz{$attr} eq $keey){ # exact match
657             $self->{$attr} = $valu;
658             $foun = 1;
659             }
660             }
661             unless($foun){
662             croak "!*EROR*! Curses::Simp::$meth key:$keey was not recognized!\n";
663             # $keey =~ s/^_*/_/; # auto-add unfound
664             # $self->{$keey} = $valu;
665             }
666             }
667             }
668             curs_set($self->{'_flagcvis'}) if($crsr);
669             ($self->{'_flagmaxi'}, $self->{'_flagshrk'}) = (0, 0) if($rsiz);
670             ($self->{'_flagmaxi'}, $self->{'_flagcntr'}) = (0, 0) if($mvwn);
671             $self->Move() if($mvcr);
672             if ($self->{'_chgd'} && $self->{'_flagaudr'}){ $self->Draw(); }
673             elsif($mvwn || $updt) { $self->Updt(); }
674             elsif($rsiz) { $self->Rsiz(); }
675             $self->{'_chgd'} = 0;
676             return($self->{$attr});
677             };
678             # also define verbose names as alternate accessor methods
679             *{$_verbose_attrnamz{$attr}} = \&{$meth};
680             # ... and if the method is a Flag accessor, provide with out /^Flag/
681             if($meth =~ /^Flag/){
682             my $flgm = $meth; $flgm =~ s/^Flag//;
683             *{$flgm} = \&{$meth};
684             }
685             }
686             }
687             MkMethdz( 'NAME' => 'Text', 'ARAY' => 1 );
688             MkMethdz( 'NAME' => 'FClr', 'ARAY' => 1 );
689             MkMethdz( 'NAME' => 'BClr', 'ARAY' => 1 );
690             MkMethdz( 'NAME' => 'KQue', 'ARAY' => 1 );
691             MkMethdz( 'NAME' => 'MQue', 'ARAY' => 1 );
692             MkMethdz( 'NAME' => 'Hite', 'RSIZ' => 1 );
693             MkMethdz( 'NAME' => 'Widt', 'RSIZ' => 1 );
694             MkMethdz( 'NAME' => 'YOff', 'MVWN' => 1 );
695             MkMethdz( 'NAME' => 'XOff', 'MVWN' => 1 );
696             MkMethdz( 'NAME' => 'YCrs', 'MVCR' => 1 );
697             MkMethdz( 'NAME' => 'XCrs', 'MVCR' => 1 );
698             MkMethdz( 'NAME' => 'BTyp', 'LOOP' => 1 );
699             MkMethdz( 'NAME' => 'BrFC', 'ARAY' => 1 );
700             MkMethdz( 'NAME' => 'BrBC', 'ARAY' => 1 );
701             MkMethdz( 'NAME' => 'Titl' );
702             MkMethdz( 'NAME' => 'TtFC', 'ARAY' => 1 );
703             MkMethdz( 'NAME' => 'TtBC', 'ARAY' => 1 );
704             MkMethdz( 'NAME' => 'DNdx', 'DSTK' => 1 );
705             MkMethdz( 'NAME' => 'FlagAuDr' );
706             MkMethdz( 'NAME' => 'FlagADTF' );
707             MkMethdz( 'NAME' => 'FlagADTB' );
708             MkMethdz( 'NAME' => 'FlagMaxi', 'UPDT' => 1 );
709             MkMethdz( 'NAME' => 'FlagShrk', 'UPDT' => 1 );
710             MkMethdz( 'NAME' => 'FlagCntr', 'UPDT' => 1 );
711             MkMethdz( 'NAME' => 'FlagCVis', 'CRSR' => 1 );
712             MkMethdz( 'NAME' => 'FlagScrl' );
713             MkMethdz( 'NAME' => 'FlagSDLK' );
714             MkMethdz( 'NAME' => 'FlagFram' );
715             MkMethdz( 'NAME' => 'FlagMili' );
716             MkMethdz( 'NAME' => 'FlagPrin' );
717             MkMethdz( 'NAME' => 'FlagClrU' );
718             MkMethdz( 'NAME' => 'FlagInsr' );
719             MkMethdz( 'NAME' => 'FlagDrop' );
720             MkMethdz( 'NAME' => 'FlagDown' );
721             sub InitPair{ return unless($curs); my($self, $fgcl, $bgcl)= @_; my($bold, $curp)=(0, 0); # internal sub to Initialize && Set Color Pairs
722             return unless(defined($fgcl) && $fgcl =~ /^([0-9a-z._ ]|-1)$/i);
723             $bgcl = 0 unless(defined($bgcl) && $bgcl ne ' '); $fgcl = 0 if($fgcl eq ' ');
724             if(!$GLBL{'FLAGCOLR'} && has_colors()){ $GLBL{'FLAGCOLR'} = COLOR_PAIRS(); # init all pairs 1st time thru
725             for( my $i=0; $i
726             for(my $j=0; $j
727             if($GLBL{'FLAGCOLR'}){
728             if($fgcl eq -1){ $curp = $self->{'_valullsp'} if(defined($self->{'_valullsp'})); $bold = $self->{'_valullsb'}; } # return to last color pair && bold values
729             else{ $fgcl = $clet{$fgcl} if(exists($clet{$fgcl})); $fgcl = dec($fgcl) % 16 if($fgcl =~ /[A-Z]/i); if($fgcl > 7 ){ $bold = 1; $fgcl -= 8; }
730             $bgcl = $clet{$bgcl} if(exists($clet{$bgcl})); $bgcl = dec($bgcl) % 8 if($bgcl =~ /[A-Z]/i); if($fgcl > 7 || $fgcl < 0){ $fgcl = 7; }
731             $bgcl = 0 unless(defined($bgcl) && $bgcl =~ /^\d+$/i); $bgcl %= 8 if($bgcl > 7); $bgcl = 0 if($bgcl < 0); $curp = $bgcl*NumC() +$fgcl+1; }
732             if(defined($self->{'_wind'})){ if(!defined($self->{'_valulasp'}) || $self->{'_valulasp'} != $curp){
733             $self->{'_wind'}->attroff(COLOR_PAIR($self->{'_valulasp'})) if(defined($self->{'_valulasp'})); $self->{'_wind'}->attron( COLOR_PAIR($curp)); }
734             if($bold){ $self->{'_wind'}->attron( $abld); }else{ $self->{'_wind'}->attroff($abld); }
735             if(!defined($self->{'_valulasp'}) || !defined($self->{'_valulasb'}) || $self->{'_valulasp'} != $curp || $self->{'_valulasb'} != $bold){
736             $self->{'_valullsp'} = $self->{'_valulasp'};$self->{'_valulasp'} = $curp;$self->{'_valullsb'} = $self->{'_valulasb'};$self->{'_valulasb'} = $bold; } }
737             } return($curp); }
738             sub BordChar{ my($self, $loca, $noip)= @_; # return characters for different border types with NoInitPair flag to keep border color the same
739             unless($noip){ my $fgcl = $self->{'_brfc'}; my $bgcl = $self->{'_brbc'}; $self->InitPair($fgcl, $bgcl) if($self->{'_flagclru'}); }
740             $self->{'_wind'}->addch( $BORDSETS[($self->{'_btyp'} - 1)]{lc($loca)} ); }
741             sub CnvAnsCC{ my $self = shift; my $acod = shift; my @alut = @telc; my $bold = 0; my($fgcl, $bgcl)=('w', 'k'); # convert ANSI Escaped Color Codes
742             $acod =~ s/(^[;0]|;$)//g; # strip all trailing or leading semicolons or zeros
743             while($acod =~ s/^(\d+);?//){
744             if ( 1 == $1 ){ $bold = 1; } # Attribute codes: 00=none 01=bold 04=underscore 05=blink 07=reverse 08=concealed
745             elsif(30 <= $1 && $1 <= 37){ $fgcl = $alut[($1 - 30)]; } # Foreground color codes: 30=black 31=red 32=green 33=yellow 34=blue 35=magenta 36=cyan 37=white
746             elsif(40 <= $1 && $1 <= 47){ $bgcl = $alut[($1 - 40)]; } # Background color codes: 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white
747             } $fgcl = uc($fgcl) if($bold); return($fgcl, $bgcl); }
748             sub ShokScrn{ my $self = shift; my($ycrs, $xcrs); my $slvl = 0; my($keey, $valu); my $foun; # shock (redraw) the entire screen && all windows in order
749             while(@_){ ($keey, $valu)=(shift, shift); $foun = 0; # load key/vals like new() # exact match ck belo
750             if(defined($valu)){ for my $attr ($self->AttrNamz()){ if($attr =~ /$keey/i || $_verbose_attrnamz{$attr} eq $keey){ $self->{$attr} = $valu; $foun = 1; } }
751             unless($foun){ if($keey =~ /slvl/i){ $slvl = $valu; }else{ croak "!*EROR*! Curses::Simp::ShokScrn key:$keey was not recognized!\n";
752             # $keey =~ s/^_*/_/; $self->{$keey} = $valu; # auto-add unfound?
753             } } }else{ $slvl = $keey; } }
754             if($slvl > 0){ if($slvl > 1){ if($slvl > 2){ clear(); } touchwin(); } refresh(); }
755             for(@DISPSTAK){ ${$_}->{'_wind'}->touchwin(); # ${$_}->Move(); # just Move()?
756             if( ${$_}->{'_valudol8'}){ ${$_}->{'_wind'}->refresh(); ${$_}->{'_wind'}->getyx( $ycrs, $xcrs );
757             print(${$_}->{'_valudol8'}); printf("\e[%d;%dH", $ycrs + 1, $xcrs);
758             if($ycrs != ${$_}->{'_ycrs'} || $xcrs != ${$_}->{'_xcrs'}){ ${$_}->{'_wind'}->move( $ycrs, $xcrs );
759             ${$_}->{'_wind'}->getyx(${$_}->{'_ycrs'}, ${$_}->{'_xcrs'});
760             if( ${$_}->{'_btyp' }){ ${$_}->{'_ycrs'}--; ${$_}->{'_xcrs'}--; } } }
761             ${$_}->{'_wind'}->refresh(); } }
762             sub KNum{ return %knum; }
763             sub CLet{ return %clet; }
764             sub OScr{ no strict 'subs'; # Open a new Curses Screen && setup all useful stuff
765             unless($GLBL{'FLAGOPEN'}){ $GLBL{'FLAGOPEN'} = 1;
766             if(!$curs && $^O eq 'MSWin32' && $ENV{'COMSPEC'} =~ /4nt\.exe$/i){ $GLBL{'FLAGU4NT'} = 1; # clear 4NT screen && get variables
767             my $data = `echos _KBHIT %_KBHIT%; &
768             echos _ROWS %_ROWS%; &
769             echos _COLUMNS %_COLUMNS%; &
770             echos _ROW %_ROW%; &
771             echos _COLUMN %_COLUMN%; &
772             echos _FG %_FG%; &
773             echos _BG %_BG%; &
774             echos _CWD %_CWD%; &
775             echos _YEAR %_YEAR%; &
776             echos _MONTH %_MONTH%; &
777             echos _DAY %_DAY%; &
778             echos _DOWI %_DOWI%; &
779             echos _HOUR %_HOUR%; &
780             echos _MINUTE %_MINUTE%; &
781             echos _SECOND %_SECOND%;`; while($data =~ s/(_[BCDFHKMRSY][ABEGIOW][ACDHLNUWY]?[IORSTU]?[HMNT]?[DEN]?S?)\s+([^;]*);//){ $SDAT{$1} = $2; }
782             return; # raw() allows ^C,^S,^Z 2simply pass thru,unlike cbreak(),but raw requirz`reset`from the cmdline,if the app crashes; napms($ms) 2nap millisecs;
783             } initscr();noecho();nonl();raw();start_color();$GLBL{'FLAGUDCL'} = eval('use_default_colors(); 1') || 0;
784             # start_color without use_default_colors was making transparent GnomeTerminal BackGround solid blacK; A7QAMqt: ... but since use_default_colors() above is
785             # not defined in some SunOS/Solaris Curses libraries, I've wrapped it in an eval to hopefully pass their CPAN tests; # below: nodelay()||timeout(-1)...
786             curs_set(0);keypad(1);meta(1);intrflush(0);notimeout(0);timeout(0);clear();move(getmaxy()-1,getmaxx()-1);refresh(); # ... for non||blocking getch()
787             @BORDSETS = ( # initscr initializes line-draw chars for my border hash
788             { 'ul' => ACS_ULCORNER, 'ur' => ACS_URCORNER,
789             'rt' => ACS_RTEE, 'lt' => ACS_LTEE,
790             'tt' => ACS_TTEE, 'bt' => ACS_BTEE,
791             'hl' => ACS_HLINE, 'vl' => ACS_VLINE,
792             'll' => ACS_LLCORNER, 'lr' => ACS_LRCORNER, },
793             { 'ul' => '+', 'rt' => '{', 'lt' => '}', 'ur' => '+', # 032:20: !"#$%&' 040:28:()*+,-./ 048:30:01234567 056:38:89:;<=>?
794             'tt' => '+', 'bt' => '+', # 064:40:@ABCDEFG 072:48:HIJKLMNO 080:50:PQRSTUVW 088:58:XYZ[\]^_
795             'll' => '+', 'hl' => '-', 'vl' => '|', 'lr' => '+', }, # 096:60:`abcdefg 104:68:hijklmno 112:70:pqrstuvw 120:78:xyz{|}~
796             { 'ul' => ' ', 'rt' => ' ', 'lt' => ' ', 'ur' => ' ', # 160:A0: ¡¢£¤¥¦§ 168:A8:¨©ª«¬­®¯ 176:B0:°±²³´µ¶· 184:B8:¸¹º»¼½¾¿
797             'tt' => ' ', 'bt' => ' ', # 192:C0:ÀÁÂÃÄÅÆÇ 200:C8:ÈÉÊËÌÍÎÏ 208:D0:ÐÑÒÓÔÕÖ× 216:D8:ØÙÚÛÜÝÞß
798             'll' => ' ', 'hl' => ' ', 'vl' => ' ', 'lr' => ' ', }, # 224:E0:àáâãäåæç 232:E8:èéêëìíîï 240:F0:ðñòóôõö÷ 248:F8:øùúûüýþÿ
799             { 'ul' => ACS_PLUS, 'ur' => ACS_PLUS,
800             'rt' => ACS_RARROW,'lt' => ACS_LARROW,
801             'tt' => ACS_UARROW,'bt' => ACS_DARROW,
802             'hl' => ACS_HLINE, 'vl' => ACS_VLINE,
803             'll' => ACS_PLUS, 'lr' => ACS_PLUS, },
804             { 'ul' => 'X', 'rt' => '[', 'lt' => ']', 'ur' => 'X',
805             'tt' => '#', 'bt' => '#',
806             'll' => 'X', 'hl' => '=', 'vl' => 'I', 'lr' => 'X', },
807             );
808             @kndx = (
809             ERR , OK , ACS_BLOCK ,
810             ACS_BOARD , ACS_BTEE , ACS_BULLET ,
811             ACS_CKBOARD , ACS_DARROW , ACS_DEGREE ,
812             ACS_DIAMOND , ACS_HLINE , ACS_LANTERN ,
813             ACS_LARROW , ACS_LLCORNER , ACS_LRCORNER ,
814             ACS_LTEE , ACS_PLMINUS , ACS_PLUS ,
815             ACS_RARROW , ACS_RTEE , ACS_S1 ,
816             ACS_S9 , ACS_TTEE , ACS_UARROW ,
817             ACS_ULCORNER , ACS_URCORNER , ACS_VLINE ,
818             A_ALTCHARSET , A_ATTRIBUTES , A_BLINK ,
819             A_BOLD , A_CHARTEXT , A_COLOR ,
820             A_DIM , A_INVIS , A_NORMAL ,
821             A_PROTECT , A_REVERSE , A_STANDOUT ,
822             A_UNDERLINE , COLOR_BLACK , COLOR_BLUE ,
823             COLOR_CYAN , COLOR_GREEN , COLOR_MAGENTA ,
824             COLOR_RED , COLOR_WHITE , COLOR_YELLOW ,
825             KEY_A1 , KEY_A3 , KEY_B2 ,
826             KEY_BACKSPACE , KEY_BEG , KEY_BREAK ,
827             KEY_BTAB , KEY_C1 , KEY_C3 ,
828             KEY_CANCEL , KEY_CATAB , KEY_CLEAR ,
829             KEY_CLOSE , KEY_COMMAND , KEY_COPY ,
830             KEY_CREATE , KEY_CTAB , KEY_DC ,
831             KEY_DL , KEY_DOWN , KEY_EIC ,
832             KEY_END , KEY_ENTER , KEY_EOL ,
833             KEY_EOS , KEY_EXIT , KEY_F0 ,
834             KEY_FIND , KEY_HELP , KEY_HOME ,
835             KEY_IC , KEY_IL , KEY_LEFT ,
836             KEY_LL , KEY_MARK , KEY_MAX ,
837             KEY_MESSAGE , KEY_MIN , KEY_MOVE ,
838             KEY_NEXT , KEY_NPAGE , KEY_OPEN ,
839             KEY_OPTIONS , KEY_PPAGE , KEY_PREVIOUS ,
840             KEY_PRINT , KEY_REDO , KEY_REFERENCE ,
841             KEY_REFRESH , KEY_REPLACE , KEY_RESET ,
842             KEY_RESTART , KEY_RESUME , KEY_RIGHT ,
843             KEY_SAVE , KEY_SBEG , KEY_SCANCEL ,
844             KEY_SCOMMAND , KEY_SCOPY , KEY_SCREATE ,
845             KEY_SDC , KEY_SDL , KEY_SELECT ,
846             KEY_SEND , KEY_SEOL , KEY_SEXIT ,
847             KEY_SF , KEY_SFIND , KEY_SHELP ,
848             KEY_SHOME , KEY_SIC , KEY_SLEFT ,
849             KEY_SMESSAGE , KEY_SMOVE , KEY_SNEXT ,
850             KEY_SOPTIONS , KEY_SPREVIOUS , KEY_SPRINT ,
851             KEY_SR , KEY_SREDO , KEY_SREPLACE ,
852             KEY_SRESET , KEY_SRIGHT , KEY_SRSUME ,
853             KEY_SSAVE , KEY_SSUSPEND , KEY_STAB ,
854             KEY_SUNDO , KEY_SUSPEND , KEY_UNDO ,
855             KEY_UP , KEY_MOUSE , BUTTON1_RELEASED ,
856             BUTTON1_PRESSED , BUTTON1_CLICKED , BUTTON1_DOUBLE_CLICKED,
857             BUTTON1_TRIPLE_CLICKED , BUTTON1_RESERVED_EVENT , BUTTON2_RELEASED ,
858             BUTTON2_PRESSED , BUTTON2_CLICKED , BUTTON2_DOUBLE_CLICKED,
859             BUTTON2_TRIPLE_CLICKED , BUTTON2_RESERVED_EVENT , BUTTON3_RELEASED ,
860             BUTTON3_PRESSED , BUTTON3_CLICKED , BUTTON3_DOUBLE_CLICKED,
861             BUTTON3_TRIPLE_CLICKED , BUTTON3_RESERVED_EVENT , BUTTON4_RELEASED ,
862             BUTTON4_PRESSED , BUTTON4_CLICKED , BUTTON4_DOUBLE_CLICKED,
863             BUTTON4_TRIPLE_CLICKED , BUTTON4_RESERVED_EVENT , BUTTON_CTRL ,
864             BUTTON_SHIFT , BUTTON_ALT , ALL_MOUSE_EVENTS ,
865             REPORT_MOUSE_POSITION , NCURSES_MOUSE_VERSION );# , E_OK ,
866             # E_SYSTEM_ERROR , E_BAD_ARGUMENT , E_POSTED ,
867             # E_CONNECTED , E_BAD_STATE , E_NO_ROOM ,
868             # E_NOT_POSTED , E_UNKNOWN_COMMAND , E_NO_MATCH ,
869             # E_NOT_SELECTABLE , E_NOT_CONNECTED , E_REQUEST_DENIED ,
870             # E_INVALID_FIELD , E_CURRENT , REQ_LEFT_ITEM ,
871             # REQ_RIGHT_ITEM , REQ_UP_ITEM , REQ_DOWN_ITEM ,
872             # REQ_SCR_ULINE , REQ_SCR_DLINE , REQ_SCR_DPAGE ,
873             # REQ_SCR_UPAGE , REQ_FIRST_ITEM , REQ_LAST_ITEM ,
874             # REQ_NEXT_ITEM , REQ_PREV_ITEM , REQ_TOGGLE_ITEM ,
875             # REQ_CLEAR_PATTERN , REQ_BACK_PATTERN , REQ_NEXT_MATCH ,
876             # REQ_PREV_MATCH , MIN_MENU_COMMAND , MAX_MENU_COMMAND ,
877             # O_ONEVALUE , O_SHOWDESC , O_ROWMAJOR ,
878             # O_IGNORECASE , O_SHOWMATCH , O_NONCYCLIC ,
879             # O_SELECTABLE , REQ_NEXT_PAGE , REQ_PREV_PAGE ,
880             # REQ_FIRST_PAGE , REQ_LAST_PAGE , REQ_NEXT_FIELD ,
881             # REQ_PREV_FIELD , REQ_FIRST_FIELD , REQ_LAST_FIELD ,
882             # REQ_SNEXT_FIELD , REQ_SPREV_FIELD , REQ_SFIRST_FIELD ,
883             # REQ_SLAST_FIELD , REQ_LEFT_FIELD , REQ_RIGHT_FIELD ,
884             # REQ_UP_FIELD , REQ_DOWN_FIELD , REQ_NEXT_CHAR ,
885             # REQ_PREV_CHAR , REQ_NEXT_LINE , REQ_PREV_LINE ,
886             # REQ_NEXT_WORD , REQ_PREV_WORD , REQ_BEG_FIELD ,
887             # REQ_END_FIELD , REQ_BEG_LINE , REQ_END_LINE ,
888             # REQ_LEFT_CHAR , REQ_RIGHT_CHAR , REQ_UP_CHAR ,
889             # REQ_DOWN_CHAR , REQ_NEW_LINE , REQ_INS_CHAR ,
890             # REQ_INS_LINE , REQ_DEL_CHAR , REQ_DEL_PREV ,
891             # REQ_DEL_LINE , REQ_DEL_WORD , REQ_CLR_EOL ,
892             # REQ_CLR_EOF , REQ_CLR_FIELD , REQ_OVL_MODE ,
893             # REQ_INS_MODE , REQ_SCR_FLINE , REQ_SCR_BLINE ,
894             # REQ_SCR_FPAGE , REQ_SCR_BPAGE , REQ_SCR_FHPAGE ,
895             # REQ_SCR_BHPAGE , REQ_SCR_FCHAR , REQ_SCR_BCHAR ,
896             # REQ_SCR_HFLINE , REQ_SCR_HBLINE , REQ_SCR_HFHALF ,
897             # REQ_SCR_HBHALF , REQ_VALIDATION , REQ_NEXT_CHOICE ,
898             # REQ_PREV_CHOICE , MIN_FORM_COMMAND , MAX_FORM_COMMAND ,
899             # NO_JUSTIFICATION , JUSTIFY_LEFT , JUSTIFY_CENTER ,
900             # JUSTIFY_RIGHT , O_VISIBLE , O_ACTIVE ,
901             # O_PUBLIC , O_EDIT , O_WRAP ,
902             # O_BLANK , O_AUTOSKIP , O_NULLOK ,
903             # O_PASSOK , O_STATIC , O_NL_OVERLOAD ,
904             # O_BS_OVERLOAD );
905             my @knam = qw(
906             ERR OK ACS_BLOCK
907             ACS_BOARD ACS_BTEE ACS_BULLET
908             ACS_CKBOARD ACS_DARROW ACS_DEGREE
909             ACS_DIAMOND ACS_HLINE ACS_LANTERN
910             ACS_LARROW ACS_LLCORNER ACS_LRCORNER
911             ACS_LTEE ACS_PLMINUS ACS_PLUS
912             ACS_RARROW ACS_RTEE ACS_S1
913             ACS_S9 ACS_TTEE ACS_UARROW
914             ACS_ULCORNER ACS_URCORNER ACS_VLINE
915             A_ALTCHARSET A_ATTRIBUTES A_BLINK
916             A_BOLD A_CHARTEXT A_COLOR
917             A_DIM A_INVIS A_NORMAL
918             A_PROTECT A_REVERSE A_STANDOUT
919             A_UNDERLINE COLOR_BLACK COLOR_BLUE
920             COLOR_CYAN COLOR_GREEN COLOR_MAGENTA
921             COLOR_RED COLOR_WHITE COLOR_YELLOW
922             KEY_A1 KEY_A3 KEY_B2
923             KEY_BACKSPACE KEY_BEG KEY_BREAK
924             KEY_BTAB KEY_C1 KEY_C3
925             KEY_CANCEL KEY_CATAB KEY_CLEAR
926             KEY_CLOSE KEY_COMMAND KEY_COPY
927             KEY_CREATE KEY_CTAB KEY_DC
928             KEY_DL KEY_DOWN KEY_EIC
929             KEY_END KEY_ENTER KEY_EOL
930             KEY_EOS KEY_EXIT KEY_F0
931             KEY_FIND KEY_HELP KEY_HOME
932             KEY_IC KEY_IL KEY_LEFT
933             KEY_LL KEY_MARK KEY_MAX
934             KEY_MESSAGE KEY_MIN KEY_MOVE
935             KEY_NEXT KEY_NPAGE KEY_OPEN
936             KEY_OPTIONS KEY_PPAGE KEY_PREVIOUS
937             KEY_PRINT KEY_REDO KEY_REFERENCE
938             KEY_REFRESH KEY_REPLACE KEY_RESET
939             KEY_RESTART KEY_RESUME KEY_RIGHT
940             KEY_SAVE KEY_SBEG KEY_SCANCEL
941             KEY_SCOMMAND KEY_SCOPY KEY_SCREATE
942             KEY_SDC KEY_SDL KEY_SELECT
943             KEY_SEND KEY_SEOL KEY_SEXIT
944             KEY_SF KEY_SFIND KEY_SHELP
945             KEY_SHOME KEY_SIC KEY_SLEFT
946             KEY_SMESSAGE KEY_SMOVE KEY_SNEXT
947             KEY_SOPTIONS KEY_SPREVIOUS KEY_SPRINT
948             KEY_SR KEY_SREDO KEY_SREPLACE
949             KEY_SRESET KEY_SRIGHT KEY_SRSUME
950             KEY_SSAVE KEY_SSUSPEND KEY_STAB
951             KEY_SUNDO KEY_SUSPEND KEY_UNDO
952             KEY_UP KEY_MOUSE BUTTON1_RELEASED
953             BUTTON1_PRESSED BUTTON1_CLICKED BUTTON1_DOUBLE_CLICKED
954             BUTTON1_TRIPLE_CLICKED BUTTON1_RESERVED_EVENT BUTTON2_RELEASED
955             BUTTON2_PRESSED BUTTON2_CLICKED BUTTON2_DOUBLE_CLICKED
956             BUTTON2_TRIPLE_CLICKED BUTTON2_RESERVED_EVENT BUTTON3_RELEASED
957             BUTTON3_PRESSED BUTTON3_CLICKED BUTTON3_DOUBLE_CLICKED
958             BUTTON3_TRIPLE_CLICKED BUTTON3_RESERVED_EVENT BUTTON4_RELEASED
959             BUTTON4_PRESSED BUTTON4_CLICKED BUTTON4_DOUBLE_CLICKED
960             BUTTON4_TRIPLE_CLICKED BUTTON4_RESERVED_EVENT BUTTON_CTRL
961             BUTTON_SHIFT BUTTON_ALT ALL_MOUSE_EVENTS
962             REPORT_MOUSE_POSITION NCURSES_MOUSE_VERSION );# E_OK
963             # E_SYSTEM_ERROR E_BAD_ARGUMENT E_POSTED
964             # E_CONNECTED E_BAD_STATE E_NO_ROOM
965             # E_NOT_POSTED E_UNKNOWN_COMMAND E_NO_MATCH
966             # E_NOT_SELECTABLE E_NOT_CONNECTED E_REQUEST_DENIED
967             # E_INVALID_FIELD E_CURRENT REQ_LEFT_ITEM
968             # REQ_RIGHT_ITEM REQ_UP_ITEM REQ_DOWN_ITEM
969             # REQ_SCR_ULINE REQ_SCR_DLINE REQ_SCR_DPAGE
970             # REQ_SCR_UPAGE REQ_FIRST_ITEM REQ_LAST_ITEM
971             # REQ_NEXT_ITEM REQ_PREV_ITEM REQ_TOGGLE_ITEM
972             # REQ_CLEAR_PATTERN REQ_BACK_PATTERN REQ_NEXT_MATCH
973             # REQ_PREV_MATCH MIN_MENU_COMMAND MAX_MENU_COMMAND
974             # O_ONEVALUE O_SHOWDESC O_ROWMAJOR
975             # O_IGNORECASE O_SHOWMATCH O_NONCYCLIC
976             # O_SELECTABLE REQ_NEXT_PAGE REQ_PREV_PAGE
977             # REQ_FIRST_PAGE REQ_LAST_PAGE REQ_NEXT_FIELD
978             # REQ_PREV_FIELD REQ_FIRST_FIELD REQ_LAST_FIELD
979             # REQ_SNEXT_FIELD REQ_SPREV_FIELD REQ_SFIRST_FIELD
980             # REQ_SLAST_FIELD REQ_LEFT_FIELD REQ_RIGHT_FIELD
981             # REQ_UP_FIELD REQ_DOWN_FIELD REQ_NEXT_CHAR
982             # REQ_PREV_CHAR REQ_NEXT_LINE REQ_PREV_LINE
983             # REQ_NEXT_WORD REQ_PREV_WORD REQ_BEG_FIELD
984             # REQ_END_FIELD REQ_BEG_LINE REQ_END_LINE
985             # REQ_LEFT_CHAR REQ_RIGHT_CHAR REQ_UP_CHAR
986             # REQ_DOWN_CHAR REQ_NEW_LINE REQ_INS_CHAR
987             # REQ_INS_LINE REQ_DEL_CHAR REQ_DEL_PREV
988             # REQ_DEL_LINE REQ_DEL_WORD REQ_CLR_EOL
989             # REQ_CLR_EOF REQ_CLR_FIELD REQ_OVL_MODE
990             # REQ_INS_MODE REQ_SCR_FLINE REQ_SCR_BLINE
991             # REQ_SCR_FPAGE REQ_SCR_BPAGE REQ_SCR_FHPAGE
992             # REQ_SCR_BHPAGE REQ_SCR_FCHAR REQ_SCR_BCHAR
993             # REQ_SCR_HFLINE REQ_SCR_HBLINE REQ_SCR_HFHALF
994             # REQ_SCR_HBHALF REQ_VALIDATION REQ_NEXT_CHOICE
995             # REQ_PREV_CHOICE MIN_FORM_COMMAND MAX_FORM_COMMAND
996             # NO_JUSTIFICATION JUSTIFY_LEFT JUSTIFY_CENTER
997             # JUSTIFY_RIGHT O_VISIBLE O_ACTIVE
998             # O_PUBLIC O_EDIT O_WRAP
999             # O_BLANK O_AUTOSKIP O_NULLOK
1000             # O_PASSOK O_STATIC O_NL_OVERLOAD
1001             # O_BS_OVERLOAD );
1002             # load $knum{CONSTANT_KEY_NUMBER_VALUE} => "CONSTANT_KEY_NAME_STRING" # not mapping -1..9since'0'..'9'are normal chrz&&GetK retnz -1 when $tmot reached
1003             for($i=0;$i<@kndx;$i++){ if(defined($knam[$i]) && $kndx[$i] =~ /../ && $kndx[$i] ne '-1'){ $knum{"$kndx[$i]"} = "$knam[$i]"; } }
1004             for($i=265;$i<=279;$i++){ $knum{"$i"} = "KEY_F" . ($i-264); } # add my own new additional key<->num mappings (i.e., 265..279 => F1..F15)
1005             for($i=0;$i<@kndx;$i++){ if(defined($knam[$i]) && $knam[$i] eq 'A_BOLD'){ # find the right value of the A_BOLD attribute so strict doesn't complain
1006             $abld = $kndx[$i] if($kndx[$i] =~ /^\d+$/); last; #$abld = 2097152;
1007             } } } return; }
1008             sub CScr{ # Close previously OpenedCursesScreen # Following are Curses funcs that might be useful to call in CloseScreen(): termname(),erasechar(),killchar()
1009             if($GLBL{'FLAGOPEN'}){ $GLBL{'FLAGOPEN'} = 0; ${$DISPSTAK[0]}->DelW() while(@DISPSTAK); return(endwin()) if($curs); } } # delete all simp objects before end
1010             sub NumC{ return(COLORS()); }
1011             # Curses::Simp object constructor as class method or copy as object method. First param can be ref to copy. Not including optional ref from copy,
1012             # default is no params to create a new empty Simp object. If params are supplied, they must be hash key => value pairs.
1013             sub new{ OScr() unless($GLBL{'FLAGOPEN'}); my($nvkr, $cork)= @_; my($keey, $valu); my $nobj = ref($nvkr); my $clas = $cork; # need Open Screen for new obj
1014             $clas = $nobj || $nvkr if(!defined($cork) || $cork !~ /::/); my $self = bless({}, $clas); # Class OR Key
1015             for my $attr ($self->AttrNamz()){ $self->{$attr} = $self->DfltValu($attr); # init defaults && copy if supposed to
1016             $self->{$attr} = $nvkr->{$attr} if($nobj); } for(@KMODNAMZ){ $self->{'_kmod'}->{$_} = 0; }
1017             if(defined($cork) && $cork !~ /::/){ $nvkr = shift if($nvkr =~ /::/); while(@_){ my $foun = 0; ($keey, $valu)=(shift, shift); # handle init params with
1018             for my $attr ($self->AttrNamz()){ if($attr =~ /$keey/i){ $self->{$attr} = $valu;$foun = 1; } } # no colons (classname)
1019             unless( $foun){ for my $attr ($self->AttrNamz()){ if($_verbose_attrnamz{$attr} eq $keey){ $self->{$attr} = $valu; $foun = 1; } } # exact match
1020             unless($foun){ croak "!*EROR*! Curses::Simp::new initialization key:$keey was not recognized!\n"; } } } }
1021             $self->{'_flagshrk'} = 0 if($self->{'_hite'} && $self->{'_widt'}); $self->Updt(1);
1022             if($curs){ $self->{'_wind'} = newwin($self->{'_hite'}, $self->{'_widt'}, $self->{'_yoff'}, $self->{'_xoff'});
1023             unless(exists($self->{'_wind'}) && defined($self->{'_wind'})){ exit;
1024             #croak "!*EROR*! Curses::Simp::new could not create window with hite:$self->{'_hite'},widt:$self->{'_widt'},yoff:$self->{'_yoff'},xoff:$self->{'_xoff'}!\n";
1025             } } $self->TestDraw(); $self->Move(-1, -1) unless($self->{'_ycrs'} || $self->{'_xcrs'}); # newwin does!autodraw so if therz init _text && autodraw is on...
1026             curs_set($self->{'_flagcvis'}) if($curs); $self->{'_dndx'} = @DISPSTAK; push(@DISPSTAK, \$self); return($self); } # set cursor state,push obj2stack,&&retn
1027             sub Prnt{ # Simp object PrintString method
1028             my $self = shift; my %parm; my($ycrs, $xcrs); my($keey, $valu);
1029             my($cnum, $delt, $chrz); my($yold, $xold); my($fgcl, $bgcl); my $foun;
1030             $parm{'nore'} = 0; # No Refresh flag init'd to false
1031             $parm{'ycrs'} = $self->{'_ycrs'};
1032             $parm{'xcrs'} = $self->{'_xcrs'};
1033             if($self->{'_btyp'}) { $parm{'ycrs'}++; $parm{'xcrs'}++; }
1034             $parm{'prin'} = $self->{'_flagprin'}; # init prin param
1035             while(@_){ ($keey, $valu)=(shift, shift); $foun = 0; if(defined($valu)){ # load params
1036             for my $attr ($self->AttrNamz()){ if($_verbose_attrnamz{$attr} eq $keey){ $attr =~ s/^_*//; $parm{$attr} = $valu; $foun = 1; } } # exact match
1037             unless($foun){ $keey =~ s/^_*//; $parm{$keey} = $valu; }
1038             }else{ $parm{'text'} = $keey; } }
1039             $chrz = ref($parm{'text'}); # if text, fclr, or bclr are arrays like new or Draw would take, join them
1040             $parm{'text'} = join("\n", @{$parm{'text'}}) if($chrz eq 'ARRAY');
1041             if(exists($parm{'fclr'})){ $self->{'_flagclru'} = 1; $chrz = ref($parm{'fclr'}); $parm{'fclr'} = join("\n", @{$parm{'fclr'}}) if($chrz eq 'ARRAY'); }
1042             if(exists($parm{'fclr'})){ $self->{'_flagclru'} = 1; $chrz = ref($parm{'bclr'}); $parm{'bclr'} = join("\n", @{$parm{'bclr'}}) if($chrz eq 'ARRAY'); }
1043             return() unless(exists($parm{'text'}) && defined($parm{'text'}) && length($parm{'text'}));
1044             ($yold, $xold)=($self->{'_ycrs'}, $self->{'_xcrs'});
1045             $parm{'ycrs'} = $parm{'ytmp'} if(exists($parm{'ytmp'}));
1046             $parm{'xcrs'} = $parm{'xtmp'} if(exists($parm{'xtmp'}));
1047             $parm{'text'} =~ s/[ ›œ]/ /g; # Prnt does not support escaped printf chars like Draw
1048             unless($curs){ system("attrib /q /e -rsh C:\\SimpDraw.bat") if(-e 'C:/SimpDraw.bat' && !-w 'C:/SimpDraw.bat');
1049             system("del /q /e C:\\SimpDraw.bat") if(-e 'C:/SimpDraw.bat' && !-w 'C:/SimpDraw.bat'); open(SCRP,'>>','C:\SimpDraw.bat'); }
1050             if($parm{'prin'}){ if($self->{'_btyp'}){ if($parm{'ycrs'}){ $parm{'ycrs'}--; }else{ $parm{'zery'} = 1; }
1051             if($parm{'xcrs'}){ $parm{'xcrs'}--; }else{ $parm{'zerx'} = 1; } }
1052             unless(@{$self->{'_text'}} > $parm{'ycrs'} && defined($self->{'_text'}->[$parm{'ycrs'}])){ $self->{'_text'}->[$parm{'ycrs'}] = ''; }
1053             if(length($self->{'_text'}->[$parm{'ycrs'}]) > $parm{'xcrs'}){substr($self->{'_text'}->[$parm{'ycrs'}],$parm{'xcrs'},length($parm{'text'}),$parm{'text'});}
1054             else{ $self->{'_text'}->[$parm{'ycrs'}] .= ' ' x ($parm{'xcrs'} - length($self->{'_text'}->[$parm{'ycrs'}])) . $parm{'text'};}
1055             if($self->{'_btyp'}){ $parm{'ycrs'}++ unless(exists($parm{'zery'})); $parm{'xcrs'}++ unless(exists($parm{'zerx'})); } }
1056             if(exists($parm{'fclr'}) || exists($parm{'bclr'})){ if($parm{'prin'}){ if($self->{'_btyp'}){ if($parm{'ycrs'}){ $parm{'ycrs'}--; }else{ $parm{'zery'} = 1; }
1057             if($parm{'xcrs'}){ $parm{'xcrs'}--; }else{ $parm{'zerx'} = 1; }}
1058             if($self->{'_btyp'}){ $parm{'ycrs'}++ unless(exists($parm{'zery'}));
1059             $parm{'xcrs'}++ unless(exists($parm{'zerx'})); }}
1060             $parm{'ycrs'} = 0 unless($parm{'ycrs'} =~ /^\d+$/); $parm{'xcrs'} = 0 unless($parm{'xcrs'} =~ /^\d+$/); $cnum = 0;
1061             while(length($parm{'text'})){ $chrz = substr($parm{'text'}, 0, 1, ''); $delt = 0;
1062             if(exists($parm{'fclr'}) && length($parm{'fclr'})){ $fgcl = substr($parm{'fclr'}, 0, 1, ''); }
1063             if(exists($parm{'bclr'}) && length($parm{'bclr'})){ $bgcl = substr($parm{'bclr'}, 0, 1, ''); } $self->InitPair($fgcl, $bgcl);
1064             while((!exists($parm{'fclr'}) || !length($parm{'fclr'}) || substr($parm{'fclr'}, 0, 1) eq $fgcl) &&
1065             (!exists($parm{'bclr'}) || !length($parm{'bclr'}) || substr($parm{'bclr'}, 0, 1) eq $bgcl) && length($parm{'text'})){ $cnum++; $delt++;
1066             substr($parm{'fclr'}, 0, 1, '') if(exists($parm{'fclr'}) && length($parm{'fclr'}));
1067             substr($parm{'bclr'}, 0, 1, '') if(exists($parm{'bclr'}) && length($parm{'bclr'})); $chrz .= substr($parm{'text'}, 0, 1, ''); }
1068             $chrz = '' unless(defined($chrz));
1069             if(exists($parm{'ycrs'}) && exists($parm{'xcrs'})){ if($curs){ $self->{'_wind'}->addstr($parm{'ycrs'}, $parm{'xcrs'} + ($cnum - $delt), $chrz); }
1070             else{ my $scrp = "\@scrput " . $parm{'ycrs'} . ' ' . $parm{'xcrs'} + ($cnum - $delt) . ' ';
1071             my $fgct = $clet{$fgcl} if(exists($clet{$fgcl}));
1072             my $bgct = $clet{$bgcl} if(exists($clet{$bgcl}));
1073             if(defined($fgct) && defined($bgct)){ if($fgct > 7){ $scrp .= $tel4[$fgct - 8] + 8; }
1074             else { $scrp .= $tel4[$fgct]; } $scrp .= ' on ';
1075             if($tel4[$bgct]){ $scrp .= "$tel4[$bgct] "; }else{ $scrp .= "0 "; }
1076             }else{ $scrp = "\@scrput " . $parm{'ycrs'} . ' ' . $parm{'xcrs'} + ($cnum - $delt) . ' '; }
1077             $scrp .= $chrz; print SCRP "$scrp\n"; } } $cnum++; }
1078             }else{ $cnum = length($parm{'text'}); if(exists($parm{'ycrs'}) && exists($parm{'xcrs'})){
1079             if($curs){ $self->{'_wind'}->addstr($parm{'ycrs'}, $parm{'xcrs'}, $parm{'text'}); }
1080             else { print SCRP "\@screen " . $parm{'ycrs'} . ' ' . $parm{'xcrs'} . ' ' . $parm{'text'} . "\n"; } } }
1081             $self->{'_wind'}->getyx($self->{'_ycrs'}, $self->{'_xcrs'}) if($curs);
1082             if($self->{'_btyp'}){ $self->{'_ycrs'}--; $self->{'_xcrs'}--; }
1083             if($curs){ if(exists($parm{'ytmp'}) || exists($parm{'xtmp'})){ $self->Move($yold, $xold); } elsif(!$parm{'nore'}){ $self->{'_wind'}->refresh(); } }
1084             else { close(SCRP); system('call C:\SimpDraw.bat'); } return($cnum); }
1085             sub Draw{ # Simp object self Drawing method
1086             my $self = shift; my($fgcl, $bgcl); my($fgct, $bgct); my($lnum, $cnum);
1087             my($keey, $valu); my($delt, $char); my($yoff, $xoff); my($ordc, $ordd);
1088             my($ltxt, $clin, $blin); my($dol8, $tndx, $foun);
1089             while(@_){ # load key/vals like new()
1090             ($keey, $valu)=(shift, shift); $foun = 0;
1091             if(defined($valu)){
1092             for my $attr ($self->AttrNamz()){
1093             if ($attr =~ /$keey/i ||
1094             $_verbose_attrnamz{$attr} eq $keey){ # exact match
1095             $self->{$attr} = $valu;
1096             $foun = 1;
1097             }
1098             }
1099             unless($foun){
1100             exit;
1101             # croak "!*EROR*! Curses::Simp::Draw key:$keey was not recognized!\n";
1102             # $keey =~ s/^_*/_/; # auto-add unfound
1103             # $self->{$keey} = $valu;
1104             }
1105             }else{
1106             my $reft = ref($keey);
1107             if($reft eq 'ARRAY'){ $self->{'_text'} = $keey ; }
1108             else { @{$self->{'_text'}} = split(/\n/, $keey); }
1109             }
1110             }
1111             $self->Updt();
1112             if($curs){ $self->{'_wind'}->move(0, 0); }
1113             else {
1114             system("attrib /q /e -rsh C:\\SimpDraw.bat") if(-e 'C:/SimpDraw.bat' && !-w 'C:/SimpDraw.bat');
1115             system("del /q /e C:\\SimpDraw.bat") if(-e 'C:/SimpDraw.bat' && !-w 'C:/SimpDraw.bat');
1116             open(SCRP, ">C:\\SimpDraw.bat"); print SCRP "\@echo off\n\@cls\n";
1117             }
1118             if($self->{'_btyp'}){
1119             $self->BordChar('ul');
1120             $tndx = int((($self->{'_widt'} - 2) - length($self->{'_titl'})) / 2);
1121             if(length($self->{'_titl'})){
1122             for(my $i=1;$i<$tndx;$i++){
1123             $self->BordChar('hl', 1);
1124             }
1125             $self->BordChar('rt', 1); $tndx++;
1126             if($self->{'_flagclru'}){
1127             $self->Prnt('text' => $self->{'_titl'}, 'ytmp' => 0, 'prin' => 0,
1128             'fclr' => $self->{'_ttfc'}, 'xtmp' => $tndx,
1129             'bclr' => $self->{'_ttbc'} );
1130             }else{
1131             $self->Prnt('text' => $self->{'_titl'}, 'ytmp' => 0, 'prin' => 0,
1132             'xtmp' => $tndx );
1133             }
1134             $tndx += length($self->{'_titl'});
1135             $self->{'_wind'}->move(0, $tndx);
1136             $self->BordChar('lt');
1137             for(my $i = 1; $i < int((($self->{'_widt'} - 1) - length($self->{'_titl'})) / 2); $i++){
1138             $self->BordChar('hl', 1);
1139             }
1140             }else{
1141             for(my $i = 0; $i < ($self->{'_widt'} - 2); $i++){
1142             $self->BordChar('hl', 1);
1143             }
1144             }
1145             if( $self->{'_flagscrl'} ||
1146             ($self->{'_flagdrop'} && !$self->{'_flagdown'})){
1147             $self->{'_wind'}->move(0, ($self->{'_widt'} - 4));
1148             $self->BordChar('tt', 1);
1149             $self->{'_wind'}->move(0, ($self->{'_widt'} - 1));
1150             }
1151             $self->BordChar('ur', 1);
1152             }
1153             for($lnum = 0; $lnum < @{$self->{'_text'}} &&
1154             ( $lnum < ($self->{'_hite'} - 2) ||
1155             ($lnum < $self->{'_hite'} && !$self->{'_btyp'})); $lnum++){
1156             $ltxt = $self->{'_text'}->[$lnum];
1157             chomp($ltxt) if(defined($ltxt));
1158             $self->BordChar('vl', 1) if($self->{'_btyp'});
1159             $self->InitPair(-1) if($self->{'_btyp'} && $self->{'_flagclru'});
1160             $ltxt = ' ' x $self->{'_widt'} unless(defined($ltxt));
1161             if (length($ltxt) > ($self->{'_widt'} - 2) && $self->{'_btyp'}){
1162             $ltxt = substr($ltxt, 0, ($self->{'_widt'} - 2));
1163             }elsif(length($ltxt) > $self->{'_widt'} ){
1164             $ltxt = substr($ltxt, 0, $self->{'_widt'} );
1165             }
1166             if((exists($self->{'_fclr'}) && $self->{'_fclr'} && @{$self->{'_fclr'}}) ||
1167             $ltxt =~ /[ ›œ]/){
1168             if($self->{'_fclr'} && defined($self->{'_fclr'}->[$lnum])){
1169             $clin = $self->{'_fclr'}->[$lnum];
1170             }
1171             if(exists($self->{'_bclr'}) && $self->{'_bclr'} && defined($self->{'_bclr'}->[$lnum])){
1172             $blin = $self->{'_bclr'}->[$lnum];
1173             }
1174             for($cnum = 0; $cnum < length($ltxt); $cnum++){
1175             if($cnum <= $self->{'_widt'}){
1176             $delt = 0;
1177             if($self->{'_fclr'} && @{$self->{'_fclr'}} && defined($self->{'_fclr'}->[$lnum]) && length($clin) >= ($cnum + 1)){
1178             $fgcl = substr($clin, $cnum, 1);
1179             $bgcl = 'k' unless(defined($bgcl) && length($bgcl));
1180             if(exists($self->{'_bclr'}) && $self->{'_bclr'} && @{$self->{'_bclr'}} && defined($self->{'_bclr'}->[$lnum]) && length($blin) >= ($cnum + 1)){
1181             $bgcl = substr($blin, $cnum, 1);
1182             }
1183             $self->InitPair($fgcl, $bgcl);
1184             $self->{'_flagclru'} = 1;
1185             }
1186             $ordc = ord(substr($ltxt, $cnum , 1));
1187             $ordd = ord(substr($ltxt, $cnum + 1, 1));
1188             while($cnum < (length($ltxt) - 1) &&
1189             $ordc > 31 && $ordc != 127 && $ordc != 155 && $ordc != 156 &&
1190             $ordd > 31 && $ordd != 127 && $ordd != 155 && $ordd != 156 &&
1191             (!defined($self->{'_fclr'}->[$lnum]) ||
1192             length($clin) < ($cnum+1) ||
1193             ($fgcl eq substr($clin, ($cnum+1), 1))) &&
1194             (!exists( $self->{'_bclr'}) ||
1195             ! $self->{'_bclr'} ||
1196             ! @{$self->{'_bclr'}} ||
1197             !defined($self->{'_bclr'}->[$lnum]) ||
1198             length($blin) < ($cnum+1) ||
1199             ($bgcl eq substr($blin, ($cnum+1), 1)))){
1200             $cnum++; $delt++;
1201             $ordc = $ordd;
1202             $ordd = ord(substr($ltxt, $cnum + 1, 1));
1203             }
1204             $char = substr($ltxt, $cnum, 1);
1205             $ordc = ord($char);
1206             if(!$delt &&
1207             ($ordc <= 31 || $ordc == 127 || $ordc == 155 || $ordc == 156)) {
1208             if($self->{'_fclr'} && @{$self->{'_fclr'}}){
1209             $fgct = $fgcl; $fgct = $clet{$fgcl} if(exists($clet{$fgcl}));
1210             $bgct = $bgcl; $bgct = $clet{$bgcl} if(exists($clet{$bgcl}));
1211             if (ord($fgct) >= ord('A')) { $delt = 1; $fgct = ((ord($fgct) - ord('A')) + 32); }
1212             elsif( $fgct >= 8 ) { $delt = 1; $fgct += 22; }
1213             else { $delt = 0; $fgct += 30; }
1214             if (ord($bgct) >= ord('A')) { $bgct = ((ord($bgct) - ord('A')) + 42); }
1215             elsif( $bgct >= 8 ) { $bgct += 32; }
1216             else { $bgct += 40; }
1217             }
1218             # fonter blanks:0,7,8, 10, 12,13,14,15, 27,155
1219             for my $tstc (0,7,8,9,10,11,12,13,14,15,24,26,27,155){
1220             $char = ' ' if($ordc == $tstc);
1221             }
1222             if($curs){ $self->{'_wind'}->addstr(' '); }
1223             else { print SCRP "\@screen $lnum 0 ^s\n"; } #+0 +0 ^s\n"; }
1224             $yoff = $self->{'_yoff'} + 1;
1225             $xoff = $self->{'_xoff'} + 1;
1226             if($self->{'_btyp'}){ $yoff++; $xoff++; }
1227             # some special chars must be printed with escapes done later (l8)
1228             if($self->{'_fclr'} && @{$self->{'_fclr'}}){
1229             $dol8 .= sprintf("\e[%d;%dH\e[%d;%d;%dm$char",
1230             ($lnum + $yoff), ($cnum + $xoff), $delt, $fgct, $bgct);
1231             }else{
1232             $dol8 .= sprintf("\e[%d;%dH\e[%dm$char",
1233             ($lnum + $yoff), ($cnum + $xoff), $delt);
1234             }
1235             }else{
1236             if($curs){
1237             $self->{'_wind'}->addstr(substr($ltxt, $cnum - $delt, $delt+1));
1238             }else{
1239             my $scrp = "\@scrput $lnum " . ($cnum - $delt) . ' ';
1240             $fgct = $fgcl; $fgct = $clet{$fgcl} if(exists($clet{$fgcl}));
1241             $bgct = $bgcl; $bgct = $clet{$bgcl} if(exists($clet{$bgcl}));
1242             if(defined($fgct) && defined($bgct)){
1243             if($fgct > 7 ){ $scrp .= $tel4[$fgct - 8] + 8; }
1244             else { $scrp .= $tel4[$fgct]; }
1245             $scrp .= ' on ';
1246             if($tel4[$bgct]){ $scrp .= "$tel4[$bgct] "; }
1247             else { $scrp .= "0 "; }
1248             }else{
1249             $scrp = "\@screen $lnum " . ($cnum - $delt) . ' ';
1250             }
1251             $scrp .= substr($ltxt, $cnum - $delt, $delt+1);
1252             print SCRP "$scrp\n";
1253             }
1254             }
1255             }
1256             }
1257             if($curs && $cnum < $self->{'_widt'}){
1258             $self->{'_wind'}->addstr(' ' x (($self->{'_widt'} - $cnum) - 2));
1259             $self->{'_wind'}->addstr(' ') unless($self->{'_btyp'} ||
1260             !defined($ltxt) ||
1261             length($ltxt) == $self->{'_widt'});
1262             }
1263             }else{ # no color
1264             if($curs){ $self->{'_wind'}->addstr($ltxt); }
1265             else { print SCRP "\@screen $lnum 0 $ltxt\n"; }
1266             if(length($ltxt) < ($self->{'_widt'} - 2)){
1267             if($curs){
1268             $self->{'_wind'}->addstr(' ' x (($self->{'_widt'} - 2) - length($ltxt)));
1269             $self->{'_wind'}->addstr(' ') unless($self->{'_btyp'});
1270             }
1271             }
1272             }
1273             $self->BordChar('vl') if($self->{'_btyp'});
1274             }
1275             # pad blank lines if height not full
1276             if(($lnum < ($self->{'_hite'} - 2)) ||
1277             ($lnum < $self->{'_hite'} && !$self->{'_btyp'})){
1278             $ltxt = ' ' x ($self->{'_widt'} - 2);
1279             $ltxt .= ' ' unless($self->{'_btyp'});
1280             while($lnum < $self->{'_hite'}){
1281             if($self->{'_btyp'}){
1282             $self->BordChar('vl', 1);
1283             $self->InitPair('k', 'k') if($self->{'_flagclru'}); # black blanks
1284             }
1285             if($curs){ $self->{'_wind'}->addstr($ltxt); }
1286             if($self->{'_btyp'}){
1287             $self->BordChar('vl');
1288             $lnum+=2 if($lnum >= ($self->{'_hite'} - 3));
1289             }
1290             $lnum++;
1291             }
1292             }
1293             if($self->{'_btyp'}){
1294             $self->BordChar('ll');
1295             $self->BordChar('hl', 1) for(2..$self->{'_widt'});
1296             $self->BordChar('lr', 1);
1297             if ($self->{'_flagdrop'} && !$self->{'_flagdown'}){
1298             $self->{'_wind'}->move(1, ($self->{'_widt'} - 4));
1299             $self->BordChar('vl', 1); $self->{'_wind'}->addstr('\/');
1300             $self->{'_wind'}->move(($self->{'_hite'} - 1), ($self->{'_widt'} - 4));
1301             $self->BordChar('bt', 1);
1302             }elsif($self->{'_flagscrl'}){
1303             $self->{'_wind'}->move(1, ($self->{'_widt'} - 4));
1304             $self->BordChar('vl', 1); $self->{'_wind'}->addstr('/\\');
1305             for(my $lndx = 2; $lndx < ($self->{'_hite'} - 2); $lndx++){
1306             $self->{'_wind'}->move($lndx, ($self->{'_widt'} - 4));
1307             $self->BordChar('vl', 1); $self->{'_wind'}->addstr('..');
1308             }
1309             $self->{'_wind'}->move(($self->{'_hite'} - 2), ($self->{'_widt'} - 4));
1310             $self->BordChar('vl', 1); $self->{'_wind'}->addstr('\/');
1311             $self->{'_wind'}->move(($self->{'_hite'} - 1), ($self->{'_widt'} - 4));
1312             $self->BordChar('bt', 1);
1313             }
1314             }
1315             unless($curs){ close(SCRP); system("call C:\\SimpDraw.bat"); }
1316             $self->{'_valudol8'} = $dol8 if(defined($dol8));
1317             $self->Move(); # replace cursor position && refresh the window
1318             return();
1319             }
1320             sub TestDraw{ # Test whether an auto-Draw() should be called
1321             $_[0]->Draw() if($_[0]->{'_text'} && @{$_[0]->{'_text'}} && $_[0]->{'_flagaudr'});
1322             }
1323             sub Wait{
1324             my $self = shift; my $wait = 0;
1325             my($keey, $valu); my $foun;
1326             while(@_){ # load key/vals like new()
1327             ($keey, $valu)=(shift, shift); $foun = 0;
1328             if(defined($valu)){
1329             for my $attr ($self->AttrNamz()){
1330             if ($attr =~ /$keey/i ||
1331             $_verbose_attrnamz{$attr} eq $keey){ # exact match
1332             $self->{$attr} = $valu;
1333             $foun = 1;
1334             }
1335             }
1336             unless($foun){
1337             if($keey =~ /wait/i){
1338             $wait = $valu;
1339             }else{
1340             croak "!*EROR*! Curses::Simp::Wait key:$keey was not recognized!\n";
1341             # $keey =~ s/^_*/_/; # auto-add unfound
1342             # $self->{$keey} = $valu;
1343             }
1344             }
1345             }else{
1346             $wait = $keey;
1347             }
1348             }
1349             if ( $self->{'_flagfram'}){ # cnv from Time::Frame to Curses ms
1350             $wait = Time::Frame->new($wait) unless(ref($wait) eq "Time::Frame");
1351             $wait = int($wait->total_frames() / 60.0 * 1000);
1352             }elsif(!$self->{'_flagmili'}){ # cnv from Dflt float seconds to Curses ms
1353             $wait = int($wait * 1000);
1354             }
1355             return(napms($wait));
1356             }
1357             sub GetK{
1358             my $self = shift; my $tmot = 0; my $tsdl = 0;
1359             my($keey, $valu); my $foun; my $char;
1360             while(@_){ # load key/vals like new()
1361             ($keey, $valu)=(shift, shift); $foun = 0;
1362             if(defined($valu)){
1363             for my $attr ($self->AttrNamz()){
1364             if ($attr =~ /$keey/i ||
1365             $_verbose_attrnamz{$attr} eq $keey){ # exact match
1366             $self->{$attr} = $valu;
1367             $foun = 1;
1368             }
1369             }
1370             unless($foun){
1371             if ($keey =~ /tmot/i || $keey eq 'Timeout'){
1372             $tmot = $valu;
1373             }elsif($keey =~ /tsdl/i || $keey eq 'TempSDLKey'){
1374             $tsdl = $valu;
1375             }else{
1376             exit;
1377             # croak "!*EROR*! Curses::Simp::GetK key:$keey was not recognized!\n";
1378             # $keey =~ s/^_*/_/; # auto-add unfound
1379             # $self->{$keey} = $valu;
1380             }
1381             }
1382             }else{
1383             $tmot = $keey;
1384             }
1385             }
1386             if($tmot ne '-1'){
1387             if ( $self->{'_flagfram'}){ # cnv from Time::Frame to Curses ms
1388             $tmot = Time::Frame->new($tmot) unless(ref($tmot) eq "Time::Frame");
1389             $tmot = int($tmot->total_frames() / 60.0 * 1000);
1390             }elsif(!$self->{'_flagmili'}){ # cnv from Dflt float seconds to Curses ms
1391             $tmot = int($tmot * 1000);
1392             }
1393             }
1394             timeout($tmot) if($curs);
1395             for(@KMODNAMZ){ $self->{'_kmod'}->{$_} = 0; } # clear keymods
1396             if($self->{'_flagsdlk'} || $tsdl){
1397             if($curs){ $char = getch(); }
1398             else {
1399             `inkey /p /x /w$tmot \%\%SimpKeey & echos \%SimpKeey > C:\\SimpKeey.txt`;
1400             open(SKEY, "; close(SKEY);
1401             $char = $SDLK4NTM{$char} if(defined($char) && exists($SDLK4NTM{$char}));
1402             }
1403             my $ordc = ord($char);
1404             $self->{'_kmod'}->{'KMOD_NONE'} = 1;
1405             if($char =~ /^[A-Z]$/) {
1406             $self->{'_kmod'}->{'KMOD_NONE'} = 0;
1407             $self->{'_kmod'}->{'KMOD_SHIFT'} = 1;
1408             $char = lc($char);
1409             }
1410             if($char ne '-1'){ # $tmot not reached
1411             if ($char =~ /^[a-z0-9]$/){
1412             $char = "SDLK_$char";
1413             }elsif(exists($SDLKCHRM{$char})){
1414             $char = "SDLK_$SDLKCHRM{$char}";
1415             }elsif(exists($knum{$char}) && exists($SDLKCRSM{$knum{$char}})){
1416             $char = "SDLK_$SDLKCRSM{$knum{$char}}";
1417             }elsif($ordc == 27){ # escape or Alt-?
1418             timeout(0);
1419             my $chr2 = getch();
1420             if(defined($chr2) && $chr2 ne '-1'){
1421             $self->{'_kmod'}->{'KMOD_NONE'} = 0;
1422             $self->{'_kmod'}->{'KMOD_ALT'} = 1;
1423             if($chr2 =~ /^[A-Z]$/){
1424             $self->{'_kmod'}->{'KMOD_SHIFT'} = 1;
1425             $char = lc($char);
1426             }
1427             if (exists($SDLKCHRM{$chr2})){
1428             $char = "SDLK_$SDLKCHRM{$chr2}";
1429             }elsif(exists($knum{$char}) && exists($SDLKCRSM{$knum{$char}})){
1430             $char = "SDLK_$SDLKCRSM{$knum{$chr2}}";
1431             }else{
1432             $char = "SDLK_$chr2";
1433             }
1434             }
1435             }elsif(exists($SDLKORDM{$ordc})){
1436             $char = "SDLK_$SDLKORDM{$ordc}";
1437             }elsif($ordc < 27){
1438             $self->{'_kmod'}->{'KMOD_NONE'} = 0;
1439             $self->{'_kmod'}->{'KMOD_CTRL'} = 1;
1440             $char = "SDLK_" . chr($ordc + 96);
1441             }
1442             }
1443             # not detected correctly yet:
1444             # 'SDLK_CLEAR', # clear
1445             # 'SDLK_PAUSE', # pause
1446             # 'SDLK_KP0', # keypad 0
1447             # 'SDLK_KP1', # keypad 1
1448             # 'SDLK_KP2', # keypad 2
1449             # 'SDLK_KP3', # keypad 3
1450             # 'SDLK_KP4', # keypad 4
1451             # 'SDLK_KP5', # keypad 5
1452             # 'SDLK_KP6', # keypad 6
1453             # 'SDLK_KP7', # keypad 7
1454             # 'SDLK_KP8', # keypad 8
1455             # 'SDLK_KP9', # keypad 9
1456             # 'SDLK_KP_PERIOD', #'.' keypad period
1457             # 'SDLK_KP_DIVIDE', #'/' keypad divide
1458             # 'SDLK_KP_MULTIPLY', #'*' keypad multiply
1459             # 'SDLK_KP_MINUS', #'-' keypad minus
1460             # 'SDLK_KP_PLUS', #'+' keypad plus
1461             # 'SDLK_KP_ENTER', #'\r' keypad enter
1462             # 'SDLK_KP_EQUALS', #'=' keypad equals
1463             # 'SDLK_NUMLOCK', # numlock
1464             # 'SDLK_CAPSLOCK', # capslock
1465             # 'SDLK_SCROLLOCK', # scrollock
1466             # 'SDLK_RSHIFT', # right shift
1467             # 'SDLK_LSHIFT', # left shift
1468             # 'SDLK_RCTRL', # right ctrl
1469             # 'SDLK_LCTRL', # left ctrl
1470             # 'SDLK_RALT', # right alt
1471             # 'SDLK_LALT', # left alt
1472             # 'SDLK_RMETA', # right meta
1473             # 'SDLK_LMETA', # left meta
1474             # 'SDLK_LSUPER', # left windows key
1475             # 'SDLK_RSUPER', # right windows key
1476             # 'SDLK_MODE', # mode shift
1477             # 'SDLK_HELP', # help
1478             # 'SDLK_PRINT', # print-screen
1479             # 'SDLK_SYSREQ', # SysRq
1480             # 'SDLK_BREAK', # break
1481             # 'SDLK_MENU', # menu
1482             # 'SDLK_POWER', # power
1483             # 'SDLK_EURO', # euro
1484             # kmods:
1485             # 'KMOD_NONE', # No modifiers applicable
1486             # 'KMOD_CTRL', # A Control key is down
1487             # 'KMOD_SHIFT', # A Shift key is down
1488             # 'KMOD_ALT', # An Alt key is down
1489             }else{
1490             if($curs){
1491             $char = getch();
1492             $char = "$knum{$char}" if(defined($char) && exists($knum{$char})); # "KEY_" names if exists
1493             }else {
1494             if($tmot == -1){ `inkey /p /x \%\%SimpKeey & echos '\%SimpKeey''\%\@ASCII[\%SimpKeey]' > C:\\SimpKeey.txt`; }
1495             else { `inkey /p /x /w$tmot \%\%SimpKeey & echos '\%SimpKeey''\%\@ASCII[\%SimpKeey]' > C:\\SimpKeey.txt`; }
1496             open(SKEY, "; close(SKEY);
1497             if(defined($char)){
1498             my $ordc;
1499             $char =~ s/^'//; $char =~ s/''(\d*)'$//; $ordc = $1;
1500             #print "\nchar:$char ordc:$ordc ord:" . ord($char) . "\n";
1501             if ($ordc ==127 ||
1502             $ordc == 8){ $char = 'KEY_BACKSPACE'; }
1503             elsif($ordc == 9){ $char = 'KEY_TAB'; }
1504             elsif($ordc == 32){ $char = '^s'; }
1505             $char = 'KEY_' . $SDLK4NTM{$char} if(defined($char) && exists($SDLK4NTM{$char}));
1506             }
1507             }
1508             }
1509             unshift(@{$self->{'_kque'}}, $char);
1510             unshift(@{$self->{'_mque'}}, { }); # save %kmod too
1511             for(@KMODNAMZ){ $self->{'_mque'}->[0]->{$_} = $self->{'_kmod'}->{$_}; }
1512             while(@{$self->{'_kque'}} > 63){ # keep up to 64 key presses && kmods
1513             pop(@{$self->{'_kque'}});
1514             pop(@{$self->{'_mque'}});
1515             }
1516             return($char);
1517             }
1518             sub KMod{ # accessor for the %{$self->{'_kmod'}} hash
1519             my $self = shift; my $kmod = 'KMOD_NONE';
1520             my($keey, $valu); my $foun;
1521             while(@_){ # load key/vals like new()
1522             ($keey, $valu)=(shift, shift); $foun = 0;
1523             if(defined($valu)){
1524             for my $attr ($self->AttrNamz()){
1525             if ($attr =~ /$keey/i ||
1526             $_verbose_attrnamz{$attr} eq $keey){ # exact match
1527             $self->{$attr} = $valu;
1528             $foun = 1;
1529             }
1530             }
1531             unless($foun){
1532             if($keey =~ /kmod/i){
1533             $kmod = $valu;
1534             }else{
1535             exit;
1536             # croak "!*EROR*! Curses::Simp::KMod key:$keey was not recognized!\n";
1537             # $keey =~ s/^_*/_/; # auto-add unfound
1538             # $self->{$keey} = $valu;
1539             }
1540             }
1541             }else{
1542             $kmod = $keey;
1543             }
1544             }
1545             for(@KMODNAMZ){
1546             if(/$kmod$/i){
1547             $valu = shift;
1548             $self->{'_kmod'}->{$_} = $valu if(defined($valu));
1549             return($self->{'_kmod'}->{$_});
1550             }
1551             }
1552             }
1553             sub GetS{ # Get a string at the cursor or pass temp y, x, and length params
1554             my $self = shift(); # maybe GetS() should update the cursor loc too?
1555             my $ycrs = shift(); $ycrs = $self->YCrs() unless(defined($ycrs));
1556             my $xcrs = shift(); $xcrs = $self->XCrs() unless(defined($xcrs));
1557             my $leng = shift();
1558             my $line = $self->{'_text'}->[$ycrs]; $line = '' unless(defined($line));
1559             if(length($line) >= $xcrs){
1560             if(defined($leng) && $leng <= (length($line) - $xcrs)){
1561             return(substr($line, $xcrs, $leng));
1562             }else{
1563             return(substr($line, $xcrs));
1564             }
1565             }
1566             }
1567             sub Move{ # update cursor position
1568             my $self = shift; my($ycrs, $xcrs)=(shift, shift); my $eflg = 0;
1569             if(defined($ycrs) && defined($xcrs)){ # (-1, -1) is a special Move exception to put cursor in lower right corner of border (if BTyp)
1570             if($ycrs == -1 && $xcrs == -1){ $eflg = 1;
1571             $ycrs = ($self->{'_hite'}-1);
1572             $xcrs = ($self->{'_widt'}-1);
1573             }
1574             }else{
1575             $ycrs = $self->{'_ycrs'} unless(defined($ycrs));
1576             $xcrs = $self->{'_xcrs'} unless(defined($xcrs));
1577             }
1578             $ycrs = 0 if($ycrs < 0);
1579             $xcrs = 0 if($xcrs < 0);
1580             if($self->{'_btyp'}){ # trap cursor inside border
1581             if (($ycrs == $self->{'_hite'}-1 &&
1582             $xcrs == $self->{'_widt'}-2) ||
1583             ($ycrs == $self->{'_hite'}-2 &&
1584             $xcrs == $self->{'_widt'}-1)){
1585             $ycrs = $self->{'_hite'}-2;
1586             $xcrs = $self->{'_widt'}-2;
1587             }elsif(!$eflg){ $ycrs++; $xcrs++;
1588             $ycrs = $self->{'_hite'}-2 if($ycrs > $self->{'_hite'}-2);
1589             $xcrs = $self->{'_widt'}-2 if($xcrs > $self->{'_widt'}-2);
1590             }
1591             }else{
1592             $ycrs = $self->{'_hite'}-1 if($ycrs > $self->{'_hite'}-1);
1593             $xcrs = $self->{'_widt'}-1 if($xcrs > $self->{'_widt'}-1);
1594             }
1595             if($curs && $self->{'_valudol8'}){
1596             $self->{'_wind'}->refresh();
1597             $self->{'_wind'}->getyx($self->{'_ycrs'}, $self->{'_xcrs'});
1598             print($self->{'_valudol8'});
1599             printf("\e[%d;%dH", $self->{'_ycrs'} + 1, $self->{'_xcrs'});
1600             }
1601             if($curs){
1602             $self->{'_wind'}->move($ycrs, $xcrs);
1603             $self->{'_wind'}->getyx($self->{'_ycrs'}, $self->{'_xcrs'});
1604             }else{
1605             system("screen $ycrs $xcrs");
1606             }
1607             if($self->{'_btyp'}){ $self->{'_ycrs'}--; $self->{'_xcrs'}--; }
1608             $self->{'_wind'}->refresh() if($curs);
1609             return($self->{'_ycrs'}, $self->{'_xcrs'});
1610             }
1611             sub Rsiz{ # update window dimensions (Resize)
1612             my $self = shift; my $hite = shift; my $widt = shift; my $eflg = 0;
1613             my ($ymax, $xmax);
1614             if(defined($hite) && defined($widt)){
1615             $hite = getmaxy() if($hite == -1);
1616             $widt = getmaxx() if($widt == -1);
1617             }else{
1618             $hite = $self->{'_hite'} unless(defined($hite));
1619             $widt = $self->{'_widt'};
1620             }
1621             $hite = 1 if($hite < 1);
1622             $widt = 1 if($widt < 1);
1623             if($self->{'_btyp'}){ # don't resize text && borders away
1624             $hite = 3 if($hite < 3);
1625             $widt = 3 if($widt < 3);
1626             $ymax = $self->{'_wind'}->getmaxy();
1627             $xmax = $self->{'_wind'}->getmaxx();
1628             if(($self->{'_ycrs'} == ($hite - 2) &&
1629             $self->{'_xcrs'} == ($widt - 3) &&
1630             $self->{'_widt'} != ($xmax )) ||
1631             ($self->{'_ycrs'} == ($hite - 3) &&
1632             $self->{'_xcrs'} == ($widt - 2) &&
1633             $self->{'_hite'} != ($ymax )) ||
1634             ($self->{'_ycrs'} == ($hite - 1) &&
1635             $self->{'_xcrs'} == ($widt - 2)) ||
1636             ($self->{'_ycrs'} == ($hite - 2) &&
1637             $self->{'_xcrs'} == ($widt - 1))){
1638             $eflg = 1;
1639             }
1640             }
1641             $self->{'_wind'}->resize($hite, $widt);
1642             $self->{'_wind'}->refresh();
1643             $self->ShokScrn();
1644             $self->{'_wind'}->getmaxyx($self->{'_hite'}, $self->{'_widt'});
1645             $self->Move(-1, -1) if($eflg);
1646             return($self->{'_hite'}, $self->{'_widt'});
1647             }
1648             sub Updt{ # update a Simp object's dimensions (resize && mvwin)
1649             my $self = shift; my $noch = 0; # No Changes flag
1650             my($keey, $valu); my $foun;
1651             while(@_){ # load key/vals like new()
1652             ($keey, $valu)=(shift, shift); $foun = 0;
1653             if(defined($valu)){
1654             for my $attr ($self->AttrNamz()){
1655             if ($attr =~ /$keey/i ||
1656             $_verbose_attrnamz{$attr} eq $keey){ # exact match
1657             $self->{$attr} = $valu;
1658             $foun = 1;
1659             }
1660             }
1661             unless($foun){
1662             if($keey =~ /noch/i){
1663             $noch = $valu;
1664             }else{
1665             croak "!*EROR*! Curses::Simp::Updt key:$keey was not recognized!\n";
1666             # $keey =~ s/^_*/_/; # auto-add unfound
1667             # $self->{$keey} = $valu;
1668             }
1669             }
1670             }else{
1671             $noch = $keey;
1672             }
1673             }
1674             my($hite, $widt)=($self->{'_hite'}, $self->{'_widt'});
1675             my($yoff, $xoff)=($self->{'_yoff'}, $self->{'_xoff'});
1676             if($curs){
1677             $self->{'_wind'}->getmaxyx($hite, $widt) unless($noch);
1678             $self->{'_wind'}->getbegyx($yoff, $xoff) unless($noch);
1679             }
1680             if(length($self->{'_titl'})){
1681             # if there's a window title, there must be a border to hold it
1682             $self->{'_btyp'} = 1 unless($self->{'_btyp'});
1683             # if titl+bord > Widt, trunc titl to Widt - 4 to fit screen
1684             if(length($self->{'_titl'}) > (getmaxx() - 4)){
1685             $self->{'_titl'} = substr($self->{'_titl'}, 0, (getmaxx() - 4));
1686             }
1687             }
1688             if($self->{'_flagmaxi'}){ # maximize
1689             if($curs){
1690             $self->{'_widt'} = getmaxx();
1691             $self->{'_hite'} = getmaxy();
1692             }elsif($GLBL{'FLAGU4NT'}){
1693             $self->{'_widt'} = $SDAT{'_COLUMNS'};
1694             $self->{'_hite'} = $SDAT{'_ROWS'};
1695             }
1696             $self->{'_yoff'} = 0;
1697             $self->{'_xoff'} = 0;
1698             }else{
1699             if($self->{'_flagshrk'}){ # shrink to (hite, wider of titl+bord || text)
1700             if($self->{'_text'} && @{$self->{'_text'}}){
1701             $self->{'_hite'} = @{$self->{'_text'}};
1702             $self->{'_hite'} += 2 if($self->{'_btyp'});
1703             }
1704             if($curs){
1705             $self->{'_hite'} = getmaxy() if($self->{'_hite'} > getmaxy());
1706             }elsif($GLBL{'FLAGU4NT'}){
1707             $self->{'_hite'} = $SDAT{'_ROWS'} if($self->{'_hite'} > $SDAT{'_ROWS'});
1708             }
1709             $self->{'_widt'} = 1;
1710             $self->{'_widt'} += (1 + length($self->{'_titl'})) if(length($self->{'_titl'}));
1711             if($self->{'_text'} && @{$self->{'_text'}}){
1712             for(@{$self->{'_text'}}){
1713             $self->{'_widt'} = length($_) if($self->{'_widt'} < length($_));
1714             }
1715             $self->{'_widt'} += 2 if($self->{'_btyp'});
1716             }
1717             if($curs){
1718             $self->{'_widt'} = getmaxx() if($self->{'_widt'} > getmaxx());
1719             }elsif($GLBL{'FLAGU4NT'}){
1720             $self->{'_widt'} = $SDAT{'_COLUMNS'} if($self->{'_widt'} > $SDAT{'_COLUMNS'});
1721             }
1722             }
1723             if($self->{'_flagcntr'}){ # set yoff,xoff so window is centered
1724             if($curs){
1725             $self->{'_yoff'} = int((getmaxy() - $self->{'_hite'}) / 2);
1726             $self->{'_xoff'} = int((getmaxx() - $self->{'_widt'}) / 2);
1727             }elsif($GLBL{'FLAGU4NT'}){
1728             $self->{'_yoff'} = int(($SDAT{'_ROWS'} - $self->{'_hite'}) / 2);
1729             $self->{'_xoff'} = int(($SDAT{'_COLUMNS'} - $self->{'_widt'}) / 2);
1730             }
1731             }
1732             }
1733             $self->{'_yoff'} = 0 if($self->{'_yoff'} < 0);
1734             $self->{'_xoff'} = 0 if($self->{'_xoff'} < 0);
1735             unless($noch){ # the window has been created so it's ok to change it
1736             $noch = 1; # reappropriate NoChanges flag to designate whether changed
1737             if( $hite != $self->{'_hite'} || $widt != $self->{'_widt'}){
1738             $self->Rsiz();
1739             # $self->{'_wind'}->resize($self->{'_hite'}, $self->{'_widt'});
1740             if($hite > $self->{'_hite'} || $widt > $self->{'_widt'}){
1741             $self->ShokScrn(2); # Clear/Refresh main screen because window shrank
1742             }
1743             $noch = 0;
1744             }
1745             if($yoff != $self->{'_yoff'} || $xoff != $self->{'_xoff'}) {
1746             $self->{'_wind'}->mvwin( $self->{'_yoff'}, $self->{'_xoff'}) if($curs);
1747             $self->ShokScrn(2); # Clear/Refresh main screen because window moved
1748             $noch = 0;
1749             }
1750             }
1751             return(!$noch); # return flag telling whether self resized or moved
1752             }
1753             # Mesg() is a special Curses::Simp object constructor which creates a
1754             # completely temporary Message window.
1755             # If params are supplied, they must be hash key => value pairs.
1756             sub Mesg{
1757             my $main = shift; my($keey, $valu); my $char = -1;
1758             my $self = bless({}, ref($main));
1759             for my $attr ($self->AttrNamz()){
1760             $self->{$attr} = $self->DfltValu($attr); # init defaults
1761             }
1762             # special Mesg window defaults
1763             $self->{'_flagmaxi'} = 0; # not maximized
1764             $self->{'_flagcvis'} = 0; # don't show cursor
1765             $self->{'_flagclru'} = $main->{'_flagclru'}; # inherit ColorUsed flag
1766             $self->{'_mesg'} = '';#EROR!';
1767             $self->{'_text'} = [ ];
1768             if($self->{'_flagclru'}){
1769             $self->{'_fclr'} = [ 'C' ];
1770             $self->{'_bclr'} = [ 'u' ];
1771             }
1772             $self->{'_titl'} = 'Message:';
1773             $self->{'_ttfc'} = 'G';
1774             $self->{'_ttbc'} = 'k';
1775             $self->{'_flagprsk'} = 1;
1776             $self->{'_pres'} = 'Press A Key...';
1777             $self->{'_prfc'} = 'Y';
1778             $self->{'_prbc'} = 'r';
1779             $self->{'_wait'} = 0;
1780             $self->{'_type'} = ''; # type can be set to special message types
1781             # like 'help' or 'info'
1782             $self->{'_stat'} = 0; # checkbox status
1783             $self->{'_elmo'} = ''; # special field to make this Mesg an ELeMent Of
1784             for(@KMODNAMZ){ $self->{'_kmod'}->{$_} = 0; }
1785             # there were init params with no colon (classname)
1786             while(@_){
1787             ($keey, $valu)=(shift, shift);
1788             if(defined($valu)){
1789             if($keey =~ /^(mesg|pres|wait|type|stat|elmo|flagprsk)$/){
1790             $self->{"_$keey"} = $valu;
1791             }else{
1792             for my $attr ($self->AttrNamz()){
1793             $self->{$attr} = $valu if($attr =~ /$keey/i);
1794             }
1795             }
1796             }else{
1797             $self->{'_mesg'} = $keey;
1798             }
1799             }
1800             unless(@{$self->{'_text'}}){
1801             @{$self->{'_text'}} = split(/\n/, $self->{'_mesg'});
1802             }
1803             if($self->{'_type'}){
1804             $self->{'_titl'} = '' if($self->{'_titl'} eq 'Message:');
1805             if ($self->{'_type'} =~ /^(help|info)$/ && $self->{'_flagclru'}){
1806             if($self->{'_text'}->[0] =~ /^(\s*)(\w+)(\s*)(v\d+\.)(\d+\.\S{7})(\s*-\s*)((written|hacked|coded|made)?\s*by\s*)(.+)$/i){
1807             my %mtch = ();
1808             $mtch{'1'} = $1 if(defined($1));
1809             $mtch{'2'} = $2 if(defined($2));
1810             $mtch{'3'} = $3 if(defined($3));
1811             $mtch{'4'} = $4 if(defined($4));
1812             $mtch{'5'} = $5 if(defined($5));
1813             $mtch{'6'} = $6 if(defined($6));
1814             $mtch{'7'} = $7 if(defined($7));
1815             $mtch{'9'} = $9 if(defined($9));
1816             $self->{'_fclr'}->[0] = '';
1817             $self->{'_bclr'}->[0] = '';
1818             $self->{'_fclr'}->[0] .= ' ' x length($mtch{'1'}) if(exists($mtch{'1'}));
1819             $self->{'_bclr'}->[0] .= 'u' x length($mtch{'1'}) if(exists($mtch{'1'}));
1820             $self->{'_fclr'}->[0] .= 'G' x length($mtch{'2'});
1821             $self->{'_bclr'}->[0] .= 'u' x length($mtch{'2'});
1822             $self->{'_fclr'}->[0] .= ' ' x length($mtch{'3'}) if(exists($mtch{'3'}));
1823             $self->{'_bclr'}->[0] .= 'u' x length($mtch{'3'}) if(exists($mtch{'3'}));
1824             $self->{'_fclr'}->[0] .= 'W' . 'Y' x (length($mtch{'4'}) - 2) . 'W';
1825             $self->{'_bclr'}->[0] .= 'u' . 'u' x (length($mtch{'4'}) - 2) . 'u';
1826             $self->{'_fclr'}->[0] .= 'C' x (length($mtch{'5'}) - 8) . 'W';
1827             $self->{'_bclr'}->[0] .= 'u' x (length($mtch{'5'}) - 8) . 'u';
1828             if($ptim){
1829             $self->{'_fclr'}->[0] .= 'ROYGCUP'; # was Time::PT::ptcc()
1830             $self->{'_bclr'}->[0] .= 'bbbbbbb'; # was Time::PT::ptcc()
1831             }else {
1832             $self->{'_fclr'}->[0] .= 'GGGGGGG';
1833             $self->{'_bclr'}->[0] .= 'uuuuuuu';
1834             }
1835             $self->{'_fclr'}->[0] .= 'U' x length($mtch{'6'});
1836             $self->{'_bclr'}->[0] .= 'u' x length($mtch{'6'});
1837             $self->{'_fclr'}->[0] .= 'W' x length($mtch{'7'});
1838             $self->{'_bclr'}->[0] .= 'u' x length($mtch{'7'});
1839             if ($mtch{'9'} =~ /^([^<]+)<([^@]+)@([^.]+)\.([^>]+)>/){
1840             $mtch{'91'} = $1;
1841             $mtch{'92'} = $2;
1842             $mtch{'93'} = $3;
1843             $mtch{'94'} = $4;
1844             $self->{'_fclr'}->[0] .= 'C' x length($mtch{'91'}) . 'W';
1845             $self->{'_bclr'}->[0] .= 'u' x length($mtch{'91'}) . 'u';
1846             $self->{'_fclr'}->[0] .= 'G' x length($mtch{'92'}) . 'W';
1847             $self->{'_bclr'}->[0] .= 'u' x length($mtch{'92'}) . 'u';
1848             $self->{'_fclr'}->[0] .= 'Y' x length($mtch{'93'}) . 'W';
1849             $self->{'_bclr'}->[0] .= 'u' x length($mtch{'93'}) . 'u';
1850             $self->{'_fclr'}->[0] .= 'C' x length($mtch{'94'}) . 'W';
1851             $self->{'_bclr'}->[0] .= 'u' x length($mtch{'94'}) . 'u';
1852             }elsif($mtch{'9'} =~ /^([^@]+)@([^.]+)\.(\S+)/){
1853             $mtch{'91'} = $1;
1854             $mtch{'92'} = $2;
1855             $mtch{'93'} = $3;
1856             $self->{'_fclr'}->[0] .= 'G' x length($mtch{'91'}) . 'W';
1857             $self->{'_bclr'}->[0] .= 'u' x length($mtch{'91'}) . 'u';
1858             $self->{'_fclr'}->[0] .= 'Y' x length($mtch{'92'}) . 'W';
1859             $self->{'_bclr'}->[0] .= 'u' x length($mtch{'92'}) . 'u';
1860             $self->{'_fclr'}->[0] .= 'C' x length($mtch{'93'});
1861             $self->{'_bclr'}->[0] .= 'u' x length($mtch{'93'});
1862             }
1863             if ($self->{'_type'} eq 'help'){
1864             $self->{'_titl'} = "$mtch{'2'} Help Text:" unless($self->{'_titl'});
1865             $self->{'_fclr'}->[1] = 'W';
1866             $self->{'_bclr'}->[1] = 'u';
1867             $self->{'_text'}->[1] = ' ' unless(length($self->{'_text'}->[1]));
1868             }elsif($self->{'_type'} eq 'info'){
1869             $self->{'_titl'} = "$mtch{'2'} Info Text:" unless($self->{'_titl'});
1870             $self->{'_fclr'}->[1] = 'C';
1871             $self->{'_bclr'}->[1] = 'u';
1872             $self->{'_text'}->[1] = ' ' unless(length($self->{'_text'}->[1]));
1873             }
1874             }
1875             }elsif($self->{'_type'} =~ /^(butn|ckbx)$/){
1876             $self->{'_flagprsk'} = 0;
1877             $self->{'_flagcntr'} = 0;
1878             $self->{'_flagsdlk'} = 1;
1879             if ($self->{'_type'} eq 'butn'){
1880             my $widt = 3;
1881             if($self->{'_titl'}){
1882             $self->{'_btyp'} = 1 unless($self->{'_btyp'});
1883             }else{
1884             for(@{$self->{'_text'}}){
1885             $widt = (length($_) + 2) if($widt < (length($_) + 2));
1886             }
1887             $self->{'_widt'} = $widt unless($self->{'_widt'});
1888             }
1889             }elsif($self->{'_type'} eq 'ckbx'){
1890             my $ndnt;
1891             $self->{'_onbx'} = '[X] - ' unless(exists($self->{'_onbx'}));
1892             unless(exists($self->{'_ofbx'})){
1893             $self->{'_ofbx'} = $self->{'_onbx'};
1894             $self->{'_ofbx'} =~ s/^(.)./$1 /;
1895             }
1896             $ndnt = ' ' x length($self->{'_ofbx'});
1897             for(@{$self->{'_text'}}){
1898             $_ =~ s/^/$ndnt/;
1899             }
1900             if($self->{'_stat'}){
1901             $self->{'_text'}->[0] =~ s/^$ndnt/$self->{'_onbx'}/;
1902             }else{
1903             $self->{'_text'}->[0] =~ s/^$ndnt/$self->{'_ofbx'}/;
1904             }
1905             if($self->{'_flagclru'}){
1906             $self->{'_fclr'}->[0] = 'c';
1907             $self->{'_bclr'}->[0] = 'k';
1908             }
1909             }
1910             }
1911             }
1912             if($self->{'_flagprsk'}){
1913             if(length($self->{'_pres'})){
1914             if($self->{'_flagclru'}){
1915             $self->{'_fclr'}->[@{$self->{'_text'}}] = $self->{'_prfc'};
1916             $self->{'_bclr'}->[@{$self->{'_text'}}] = $self->{'_prbc'};
1917             }
1918             my $wdst = 0;
1919             $wdst = length($self->{'_titl'}) + 2;
1920             if(@{$self->{'_text'}}){ # center press string
1921             for(@{$self->{'_text'}}){
1922             $wdst = length($_) if($wdst < length($_));
1923             }
1924             }
1925             if($wdst > length($self->{'_pres'})){
1926             $self->{'_pres'} = ' ' x int(($wdst - length($self->{'_pres'})) / 2) . $self->{'_pres'};
1927             }
1928             push(@{$self->{'_text'}}, $self->{'_pres'});
1929             }
1930             }
1931             $self->{'_flagshrk'} = 0 if($self->{'_hite'} && $self->{'_widt'});
1932             $self->Updt(1);
1933             $self->{'_wind'} = newwin($self->{'_hite'}, $self->{'_widt'},
1934             $self->{'_yoff'}, $self->{'_xoff'});
1935             unless(exists($self->{'_wind'}) && defined($self->{'_wind'})){
1936             exit;
1937             # croak "!*EROR*! Curses::Simp::Mesg could not create new window with hite:$self->{'_hite'}, widt:$self->{'_widt'}, yoff:$self->{'_yoff'}, xoff:$self->{'_xoff'}!\n";
1938             }
1939             $self->FlagCVis(); # set cursor visibility to new object state
1940             $self->TestDraw();
1941             if ($self->{'_flagprsk'}){
1942             if($self->{'_wait'}) { $char = $self->GetK($self->{'_wait'}); }
1943             else { $char = $self->GetK(-1); }
1944             $char = '#' . $char if($self->{'_kmod'}->{'KMOD_SHIFT'});
1945             $char = '^' . $char if($self->{'_kmod'}->{'KMOD_CTRL' });
1946             $char = '@' . $char if($self->{'_kmod'}->{'KMOD_ALT' });
1947             }elsif($self->{'_wait'}){
1948             $self->Wait($self->{'_wait'});
1949             }
1950             $self->{'_dndx'} = @DISPSTAK; # add object to display order stack
1951             push(@DISPSTAK, \$self);
1952             if($self->{'_type'} =~ /^(butn|ckbx)$/){
1953             return($self); # special types Button && CheckBox persist
1954             }else{
1955             $self->DelW();
1956             $main->ShokScrn(2);# redraw rest
1957             $main->FlagCVis(); # reset cursor visibility to calling object state
1958             return($char); # return character pressed to dismiss Mesg (if any)
1959             }
1960             }
1961             # Prmt() is a special Curses::Simp object constructor which creates a
1962             # completely temporary Prompt window.
1963             # If params are supplied, they must be hash key => value pairs.
1964             sub Prmt{
1965             my $main = shift; my($keey, $valu); my $char; my $tchr; my $data;
1966             my $self = bless({}, ref($main)); my $twid; my $indx;
1967             for my $attr ($self->AttrNamz()){
1968             $self->{$attr} = $self->DfltValu($attr); # init defaults
1969             }
1970             # special Prmt window defaults
1971             $self->{'_flagsdlk'} = 1; # get SDLKeys
1972             $self->{'_flagmaxi'} = 0; # not maximized
1973             $self->{'_flagcvis'} = 1; # show cursor
1974             $self->{'_flagedit'} = 1; # editable
1975             $self->{'_flagescx'} = 0; # Escape key eXits
1976             $self->{'_flagclru'} = $main->{'_flagclru'}; # inherit ColorUsed flag
1977             $self->{'_widt'} = getmaxx() - 4; # but almost full screen wide
1978             $self->{'_hite'} = 3; # && start 1 text line high
1979             # $self->{'_dref'} = \$data; # default text data ref !exist at start
1980             $self->{'_dtxt'} = '';
1981             $self->{'_text'} = [ ];
1982             $self->{'_dtfc'} = 'G';
1983             $self->{'_dtbc'} = 'u';
1984             if($self->{'_flagclru'}){
1985             $self->{'_fclr'} = [ $self->{'_dtfc'} ];
1986             $self->{'_bclr'} = [ $self->{'_dtbc'} ];
1987             }
1988             $self->{'_titl'} = 'Enter Text:';
1989             $self->{'_ttfc'} = 'C';
1990             $self->{'_ttbc'} = 'k';
1991             $self->{'_hifc'} = 'W';
1992             $self->{'_hibc'} = 'g';
1993             $self->{'_curs'} = 0; # special prompt cursor index
1994             $self->{'_sscr'} = 0; # special prompt side-scrolling index
1995             $self->{'_type'} = 'prmt'; # type can be set to special prompt types
1996             # like 'drop', 'cbls', or 'rdls'
1997             $self->{'_lndx'} = 0; # special line index for drop down types
1998             $self->{'_elmo'} = ''; # special field to make this Prmt an ELeMent Of
1999             for(@KMODNAMZ){ $self->{'_kmod'}->{$_} = 0; }
2000             # there were init params with no colon (classname)
2001             while(@_){
2002             ($keey, $valu)=(shift, shift);
2003             if(defined($valu)) {
2004             if($keey =~ /^(dref|dtxt|type|lndx|elmo|flagedit|flagescx)$/){
2005             $self->{"_$keey"} = $valu;
2006             }else{
2007             for my $attr ($self->AttrNamz()){
2008             $self->{$attr} = $valu if($attr =~ /$keey/i);
2009             }
2010             }
2011             }else{
2012             $self->{'_dref'} = $keey;
2013             }
2014             }
2015             if (exists($self->{'_dref'})){
2016             $self->{'_dtxt'} = ${$self->{'_dref'}};
2017             }elsif(exists($self->{'_text'}) && @{$self->{'_text'}}){
2018             $self->{'_dtxt'} = $self->{'_text'}->[0];
2019             if($self->{'_flagclru'}){
2020             for($indx = 1; $indx < @{$self->{'_text'}}; $indx++){
2021             $self->{'_fclr'}->[$indx] = $self->{'_dtfc'} unless($self->{'_fclr'}->[$indx]);
2022             $self->{'_bclr'}->[$indx] = $self->{'_dtbc'} unless($self->{'_bclr'}->[$indx]);
2023             }
2024             }
2025             }
2026             $self->{'_data'} = $self->{'_dtxt'};
2027             if($self->{'_type'} eq 'drop'){
2028             $self->{'_flagdrop'} = 1;
2029             $self->{'_flagdown'} = 0;
2030             $self->{'_flagcntr'} = 0;
2031             $self->{'_lndx'} = 0 unless($self->{'_lndx'});
2032             $self->{'_hite'} = 3;
2033             if($self->{'_widt'} == (getmaxx() - 4) && @{$self->{'_text'}}){
2034             $self->{'_widt'} = 3;
2035             for(@{$self->{'_text'}}){
2036             $self->{'_widt'} = (length($_) + 6) if($self->{'_widt'} < (length($_) + 6));
2037             }
2038             $self->{'_dtxt'} = $self->{'_text'}->[$self->{'_lndx'}];
2039             $self->{'_data'} = $self->{'_dtxt'};
2040             }
2041             unshift(@{$self->{'_text'}}, $self->{'_data'});
2042             }else{
2043             $self->{'_text'}->[0] = $self->{'_data'} unless(@{$self->{'_text'}});
2044             }
2045             $self->{'_curs'} = length($self->{'_data'});
2046             if($self->{'_widt'} < length($self->{'_titl'}) + 4){
2047             $self->{'_widt'} = length($self->{'_titl'}) + 4;
2048             }
2049             $twid = $self->{'_widt'} - 2;
2050             unless($self->{'_curs'} <= $twid){ # scrolling necessary off to the left
2051             substr($self->{'_text'}->[0], 0, $twid, substr($self->{'_data'}, -$twid, $twid));
2052             }
2053             if($self->{'_flagclru'}){
2054             $self->{'_fclr'}->[0] = $self->{'_hifc'} if($self->{'_curs'});
2055             $self->{'_bclr'}->[0] = $self->{'_hibc'} if($self->{'_curs'});
2056             }
2057             $self->{'_ycrs'} = 0;
2058             $self->{'_xcrs'} = $self->{'_curs'};
2059             $self->{'_flagshrk'} = 0 if($self->{'_hite'} && $self->{'_widt'});
2060             $self->Updt(1);
2061             $self->{'_wind'} = newwin($self->{'_hite'}, $self->{'_widt'},
2062             $self->{'_yoff'}, $self->{'_xoff'});
2063             unless(exists($self->{'_wind'}) && defined($self->{'_wind'})){
2064             croak "!*EROR*! Curses::Simp::Prmt could not create new window with hite:$self->{'_hite'}, widt:$self->{'_widt'}, yoff:$self->{'_yoff'}, xoff:$self->{'_xoff'}!\n";
2065             }
2066             $self->FlagCVis(); # set cursor visibility to new object state
2067             $self->TestDraw();
2068             $self->{'_dndx'} = @DISPSTAK; # add object to display order stack
2069             push(@DISPSTAK, \$self);
2070             if($self->{'_type'} =~ /^(drop)$/){
2071             return($self); # $self must be given explicit focus via Focu()
2072             }else{
2073             $self->Focu(); # give Prompt focus (to handle GetK loops)
2074             ${$self->{'_dref'}} = $self->{'_data'} if(exists($self->{'_dref'}));
2075             $data = $self->{'_data'};
2076             $self->DelW();
2077             $main->ShokScrn(2);# redraw rest
2078             $main->FlagCVis(); # reset cursor visibility to calling object state
2079             return($data); # return updated text data
2080             }
2081             }
2082             # Focu() is a Curses::Simp method which give focus to special
2083             # typed objects like CheckBoxes or DropDownMenus.
2084             # Maybe later, it will change the border type / color of normal
2085             # Simp object windows as they gain focus.
2086             sub Focu{
2087             my $self = shift; return() unless(exists($self->{'_type'}));
2088             my $updt = shift || 0; my $char = -1; my $tchr;
2089             unless($updt) {
2090             if ($self->{'_type'} eq 'ckbx') {
2091             $self->Draw('fclr' => [ 'C' ]) if($self->{'_flagclru'});
2092             $char = $self->GetK(-1);
2093             $self->Draw('fclr' => [ 'c' ]) if($self->{'_flagclru'});
2094             if($char =~ /^SDLK_(SPACE)$/) { # checkbox toggle keys
2095             $self->{'_stat'} ^= 1; # any other key loses focus
2096             $updt = 1; # leaving ckbx state same
2097             }
2098             } elsif($self->{'_type'} =~ /^(prmt|drop)$/) { # big Prmt (drop)? focus
2099             my $cmov; my $done = 0; # input handler
2100             $self->FlagCVis(1);
2101             while(!$done) {
2102             $char = $self->GetK(-1);
2103             $tchr = $char;
2104             $tchr =~ s/SDLK_//;
2105             $done = 1 if($tchr eq 'RETURN');
2106             if($self->{'_elmo'} eq 'brws' && $self->{'_flagdrop'} &&
2107             (($tchr eq 'F1') ||
2108             ($tchr =~ /^[bcfhu]$/ && $self->{'_kmod'}->{'KMOD_CTRL'}) ||
2109             ($tchr =~ /^(ESCAPE|SPACE|TILDE|BACKQUOTE)$/ && $self->{'_flagdown'}) ||
2110             ($tchr =~ /^(UP|DOWN|LEFT|RIGHT|j|k)$/ && !$self->{'_flagdown'}) ||
2111             $tchr =~ /^(TAB)$/)) {
2112             if($self->{'_flagdrop'} && !$self->{'_flagdown'}) {
2113             $self->{'_dtxt'} = $self->{'_data'};
2114             if($self->{'_flagclru'}) {
2115             $self->{'_fclr'}->[$self->{'_lndx'}] = $self->{'_hifc'};
2116             $self->{'_bclr'}->[$self->{'_lndx'}] = $self->{'_hibc'};
2117             }
2118             }
2119             $self->{'_echg'} = 1;
2120             $done = 1;
2121             }elsif($tchr eq 'TAB'){
2122             $tchr = ' ';
2123             }
2124             $tchr = uc($tchr) if($self->{'_kmod'}->{'KMOD_SHIFT'});
2125             if($self->{'_flagdrop'} && $self->{'_flagdown'}){ # DropIsDown
2126             if($char ne 'SDLK_TAB'){
2127             if ($tchr =~ /^(RETURN|ESCAPE|SPACE|TILDE|BACKQUOTE)$/) {
2128             $self->{'_flagdown'} = 0; # Close Drop down
2129             $self->{'_dtxt'} = $self->{'_text'}->[$self->{'_lndx'}];
2130             $self->{'_data'} = $self->{'_dtxt'};
2131             unshift(@{$self->{'_text'}}, $self->{'_data'});
2132             $self->{'_hite'} = 3;
2133             if($self->{'_flagclru'}){
2134             $self->{'_fclr'}->[$self->{'_lndx'}] = $self->{'_dtfc'};
2135             $self->{'_bclr'}->[$self->{'_lndx'}] = $self->{'_dtbc'};
2136             $self->{'_fclr'}->[0] = $self->{'_hifc'};
2137             $self->{'_bclr'}->[0] = $self->{'_hibc'};
2138             }
2139             $char = -1 if($tchr eq 'RETURN');
2140             $self->{'_echg'} = 1 if($self->{'_elmo'} eq 'brws');
2141             }elsif($tchr =~ /^(UP|LEFT|k)$/){
2142             if($self->{'_lndx'}) {
2143             $self->{'_lndx'}--;
2144             $self->{'_dtxt'} = $self->{'_text'}->[$self->{'_lndx'} ];
2145             $self->{'_data'} = $self->{'_dtxt'};
2146             if($self->{'_flagclru'}){
2147             $self->{'_fclr'}->[$self->{'_lndx'} + 1] = $self->{'_dtfc'};
2148             $self->{'_bclr'}->[$self->{'_lndx'} + 1] = $self->{'_dtbc'};
2149             $self->{'_fclr'}->[$self->{'_lndx'} ] = $self->{'_hifc'};
2150             $self->{'_bclr'}->[$self->{'_lndx'} ] = $self->{'_hibc'};
2151             }
2152             $self->{'_curs'} = length($self->{'_data'});
2153             $self->{'_echg'} = 1 if($self->{'_elmo'} eq 'brws');
2154             }
2155             }elsif($tchr =~ /^(DOWN|RIGHT|j)$/){
2156             if($self->{'_lndx'} < (@{$self->{'_text'}} - 1)){
2157             $self->{'_lndx'}++;
2158             $self->{'_dtxt'} = $self->{'_text'}->[$self->{'_lndx'} ];
2159             $self->{'_data'} = $self->{'_dtxt'};
2160             if($self->{'_flagclru'}){
2161             $self->{'_fclr'}->[$self->{'_lndx'} - 1] = $self->{'_dtfc'};
2162             $self->{'_bclr'}->[$self->{'_lndx'} - 1] = $self->{'_dtbc'};
2163             $self->{'_fclr'}->[$self->{'_lndx'} ] = $self->{'_hifc'};
2164             $self->{'_bclr'}->[$self->{'_lndx'} ] = $self->{'_hibc'};
2165             }
2166             $self->{'_curs'} = length($self->{'_data'});
2167             $self->{'_echg'} = 1 if($self->{'_elmo'} eq 'brws');
2168             }
2169             }
2170             $self->{'_xcrs'} = $self->{'_curs'};
2171             $self->{'_ycrs'} = $self->{'_lndx'};
2172             $self->Draw();
2173             }
2174             }elsif( $char ne 'SDLK_RETURN' && (!$self->{'_flagdrop'} ||
2175             ( $self->{'_elmo'} eq 'brws' &&
2176             $char ne 'SDLK_TAB' && $self->{'_flagdrop'} &&
2177             ($char !~ /^SDLK_[bcfhu]$/ || !$self->{'_kmod'}->{'KMOD_CTRL'})))){
2178             $cmov = 0; # mostly regular Prmt stuff
2179             if ( $self->{'_flagdrop'} && ($tchr =~ /^(TILDE|BACKQUOTE)$/ ||
2180             ( $tchr eq 'SPACE' && (!$self->{'_flagclru'} ||
2181             ($self->{'_fclr'}->[0] eq $self->{'_hifc'} &&
2182             $self->{'_bclr'}->[0] eq $self->{'_hibc'}))))){
2183             $self->{'_flagdown'} = 1; # drop Down
2184             shift(@{$self->{'_text'}});
2185             $self->{'_hite'} = @{$self->{'_text'}} + 2;
2186             $self->{'_dtxt'} = $self->{'_text'}->[$self->{'_lndx'}];
2187             $self->{'_data'} = $self->{'_dtxt'};
2188             if($self->{'_flagclru'}){
2189             $self->{'_fclr'}->[0] = $self->{'_dtfc'};
2190             $self->{'_bclr'}->[0] = $self->{'_dtbc'};
2191             }
2192             $self->{'_curs'} = length($self->{'_data'});
2193             $self->{'_sscr'} = 0;
2194             }elsif($tchr eq 'UP' ){
2195             if($self->{'_flagdrop'} && !$self->{'_flagdown'}) {
2196             if($self->{'_lndx'}) {
2197             $self->{'_lndx'}--;
2198             $self->{'_dtxt'} = $self->{'_text'}->[$self->{'_lndx'} + 1];
2199             $self->{'_data'} = $self->{'_dtxt'};
2200             $self->{'_text'}->[0] = $self->{'_data'};
2201             if($self->{'_flagclru'}){
2202             $self->{'_fclr'}->[0] = $self->{'_hifc'};
2203             $self->{'_bclr'}->[0] = $self->{'_hibc'};
2204             }
2205             $self->{'_curs'} = length($self->{'_data'});
2206             $self->{'_echg'} = 1 if($self->{'_elmo'} eq 'brws');
2207             }
2208             }elsif($self->{'_flagedit'} && $self->{'_curs'}){ # uppercase
2209             my $temp = substr($self->{'_data'}, $self->{'_curs'}, 1);
2210             substr($self->{'_data'}, $self->{'_curs'}, 1, uc($temp));
2211             }
2212             }elsif($tchr eq 'DOWN'){
2213             if($self->{'_flagdrop'} && !$self->{'_flagdown'}){
2214             if($self->{'_lndx'} < (@{$self->{'_text'}} - 2)){
2215             $self->{'_lndx'}++;
2216             $self->{'_dtxt'} = $self->{'_text'}->[$self->{'_lndx'} + 1];
2217             $self->{'_data'} = $self->{'_dtxt'};
2218             $self->{'_text'}->[0] = $self->{'_data'};
2219             if($self->{'_flagclru'}){
2220             $self->{'_fclr'}->[0] = $self->{'_hifc'};
2221             $self->{'_bclr'}->[0] = $self->{'_hibc'};
2222             }
2223             $self->{'_curs'} = length($self->{'_data'});
2224             $self->{'_echg'} = 1 if($self->{'_elmo'} eq 'brws');
2225             }
2226             }elsif($self->{'_flagedit'} && $self->{'_curs'}){ # lowercase
2227             my $temp = substr($self->{'_data'}, $self->{'_curs'}, 1);
2228             substr($self->{'_data'}, $self->{'_curs'}, 1, lc($temp));
2229             }
2230             }elsif($self->{'_flagedit'}){
2231             if ($tchr eq 'LEFT' ) { # move cursor left
2232             if($self->{'_curs'}) {
2233             $self->{'_curs'}--;
2234             $self->{'_sscr'}-- if($self->{'_sscr'});
2235             }
2236             $cmov = 1;
2237             }elsif($tchr eq 'RIGHT'){ # move cursor right
2238             if($self->{'_curs'} < length($self->{'_data'})){
2239             $self->{'_curs'}++;
2240             }
2241             $cmov = 1;
2242             }elsif($tchr eq 'HOME' ){ # move cursor to beginning
2243             $self->{'_curs'} = 0;
2244             $self->{'_sscr'} = 0 if($self->{'_sscr'});
2245             $cmov = 1;
2246             }elsif($tchr eq 'END' ){ # move cursor to end
2247             $self->{'_curs'} = length($self->{'_data'});
2248             if(length($self->{'_data'}) < $self->{'_widt'} - 2){
2249             $self->{'_sscr'} = (length($self->{'_data'}) - $self->{'_widt'} - 2);
2250             }
2251             $cmov = 1;
2252             }elsif($tchr eq 'INSERT'){
2253             $self->FlagInsr('togl');
2254             if($self->FlagInsr){ $self->{'_titl'} =~ s/\[O\]$//; }
2255             else { $self->{'_titl'} .= '[O]';
2256             unless($self->Widt() > length($self->Titl()) + 4){
2257             $self->Widt(length($self->Titl()) + 4);
2258             $self->Draw(); # was $main
2259             }
2260             }
2261             }elsif($tchr eq 'BACKSPACE' || ord($tchr) == 127){
2262             if($self->{'_curs'}){
2263             substr($self->{'_data'}, --$self->{'_curs'}, 1, '');
2264             $self->{'_sscr'}-- if($self->{'_sscr'});
2265             }
2266             }elsif($tchr eq 'DELETE'){
2267             if($self->{'_curs'} < length($self->{'_data'})) {
2268             substr($self->{'_data'}, $self->{'_curs'}, 1, '');
2269             $self->{'_sscr'}-- if($self->{'_sscr'});
2270             }
2271             }elsif($tchr eq 'ESCAPE'){
2272             if($self->{'_flagescx'}){
2273             $self->{'_data'} = '';
2274             $self->{'_curs'} = 0;
2275             }else{
2276             if($self->{'_flagclru'}){
2277             $self->{'_fclr'}->[0] = $self->{'_hifc'};
2278             $self->{'_bclr'}->[0] = $self->{'_hibc'};
2279             }
2280             $self->{'_data'} = $self->{'_dtxt'};
2281             $self->{'_curs'} = length($self->{'_data'});
2282             $self->{'_sscr'} = 0;
2283             }
2284             }else{
2285             for(keys(%SDLKCHRM)){
2286             $tchr = $_ if($tchr eq $SDLKCHRM{$_});
2287             }
2288             if($tchr ne 'F1'){
2289             if($self->{'_flagclru'} &&
2290             $self->{'_fclr'}->[0] eq $self->{'_hifc'} &&
2291             $self->{'_bclr'}->[0] eq $self->{'_hibc'}){
2292             $self->{'_data'} = $tchr;
2293             $self->{'_curs'} = length($self->{'_data'});
2294             }else{
2295             if ($self->{'_curs'} == length($self->{'_data'})){
2296             $self->{'_data'} .= $tchr;
2297             }elsif($self->FlagInsr()){
2298             substr($self->{'_data'}, $self->{'_curs'}, 0,$tchr);
2299             }else{
2300             substr($self->{'_data'}, $self->{'_curs'},length($tchr),$tchr);
2301             }
2302             $self->{'_curs'} += length($tchr);
2303             }
2304             }
2305             }
2306             while((($self->{'_curs'} - $self->{'_sscr'}) >= ($self->{'_widt'} - 2)) ||
2307             (($self->{'_curs'} - $self->{'_sscr'}) >= ($self->{'_widt'} - 5) && $self->{'_flagdrop'} && !$self->{'_flagdown'})){
2308             $self->{'_sscr'}++;
2309             }
2310             if( $self->{'_flagclru'} &&
2311             $self->{'_fclr'}->[0] eq $self->{'_hifc'} &&
2312             $self->{'_bclr'}->[0] eq $self->{'_hibc'} &&
2313             ($self->{'_data'} ne $self->{'_dtxt'} || $cmov)){
2314             $self->{'_fclr'}->[0] = $self->{'_dtfc'};
2315             $self->{'_bclr'}->[0] = $self->{'_dtbc'};
2316             }
2317             }else{ # test !editable keys to jump in drop etc.
2318             }
2319             if($self->{'_flagdrop'} && $self->{'_flagdown'}){
2320             $self->{'_xcrs'} = $self->{'_curs'};
2321             $self->{'_ycrs'} = $self->{'_lndx'};
2322             if($self->{'_flagclru'}){
2323             $self->{'_fclr'}->[$self->{'_lndx'}] = $self->{'_hifc'};
2324             $self->{'_bclr'}->[$self->{'_lndx'}] = $self->{'_hibc'};
2325             }
2326             }else{
2327             $self->{'_xcrs'} = ($self->{'_curs'} - $self->{'_sscr'});
2328             $self->{'_text'}->[0] = $self->{'_data'};
2329             if($self->{'_sscr'}){
2330             substr($self->{'_text'}->[0], 0, $self->{'_sscr'} + 3, '...');
2331             }
2332             }
2333             $self->Draw();
2334             }
2335             }
2336             }
2337             }
2338             if($updt){
2339             if ($self->{'_type'} eq 'ckbx'){
2340             if($self->{'_stat'}) {
2341             substr($self->{'_text'}->[0], 0, length($self->{'_ofbx'}), '');
2342             $self->{'_text'}->[0] =~ s/^/$self->{'_onbx'}/;
2343             }else{
2344             substr($self->{'_text'}->[0], 0, length($self->{'_onbx'}), '');
2345             $self->{'_text'}->[0] =~ s/^/$self->{'_ofbx'}/;
2346             }
2347             }
2348             $self->Draw();
2349             }
2350             return($char);
2351             }
2352             sub BildBlox{ # a sub used by CPik to construct color blocks in @text,@[fb]clr
2353             my $self = shift;
2354             @{$self->{'_text'}} = ( );
2355             if($self->{'_flagclru'}) {
2356             @{$self->{'_fclr'}} = ( );
2357             @{$self->{'_bclr'}} = ( );
2358             }
2359             if ($self->{'_styl'} eq 'barz'){
2360             if($self->{'_flagbakg'}){
2361             for(my $cndx = 0; $cndx < @telc; $cndx++) {
2362             push(@{$self->{'_text'}}, ' ' . hex($cndx) . ' ' .
2363             $telc[$cndx] . ' ' . $self->{'_bchr'} x 63);
2364             if($self->{'_flagclru'}){
2365             if($cndx == $self->{'_hndx'}){
2366             push(@{$self->{'_fclr'}}, 'kKkk' . ' ' . $telc[$cndx] x 63);
2367             push(@{$self->{'_bclr'}}, 'wwww' . ' ' . $telc[$cndx] x 63);
2368             }else{
2369             push(@{$self->{'_fclr'}}, 'kk' . ' ' . $telc[$cndx] x 63);
2370             push(@{$self->{'_bclr'}}, 'wW' . ' ' . $telc[$cndx] x 63);
2371             }
2372             }
2373             }
2374             }
2375             if($self->{'_flagforg'}){
2376             for(my $cndx = 0; $cndx < @telc; $cndx++) {
2377             if(hex($cndx+@telc) eq 'B' || hex($cndx+@telc) eq 'C'){
2378             push(@{$self->{'_text'}}, ' ' . '!' . ' ' .
2379             uc($telc[$cndx]) . ' ' . $self->{'_bchr'} x 63);
2380             }else{
2381             push(@{$self->{'_text'}}, ' ' . hex($cndx+@telc) . ' ' .
2382             uc($telc[$cndx]) . ' ' . $self->{'_bchr'} x 63);
2383             }
2384             if($self->{'_flagclru'}){
2385             if($cndx == ($self->{'_hndx'} - 8)){
2386             push(@{$self->{'_fclr'}}, 'kKkk' . ' ' . uc($telc[$cndx]) x 63);
2387             push(@{$self->{'_bclr'}}, 'wwww' . ' ' . uc($telc[$cndx]) x 63);
2388             }else{
2389             push(@{$self->{'_fclr'}}, 'kk' . ' ' . uc($telc[$cndx]) x 63);
2390             push(@{$self->{'_bclr'}}, 'wW' . ' ' . uc($telc[$cndx]) x 63);
2391             }
2392             }
2393             }
2394             }
2395             $self->Move($self->{'_hndx'}, 0);
2396             }elsif($self->{'_styl'} eq 'blox'){
2397             if($self->{'_flagbakg'}){
2398             for(my $rowe = 0; $rowe < 7; $rowe++) {
2399             push(@{$self->{'_text'}}, ' ');
2400             if($self->{'_flagclru'}){
2401             push(@{$self->{'_fclr'}}, ' ');
2402             push(@{$self->{'_bclr'}}, ' ');
2403             }
2404             for(my $cndx=0;$cndx<@telc;$cndx++){
2405             if ($rowe < 5){
2406             $self->{'_text'}->[-1] .= $self->{'_bchr'} x 8;
2407             if($self->{'_flagclru'}){
2408             $self->{'_fclr'}->[-1] .= $telc[$cndx] x 8;
2409             $self->{'_bclr'}->[-1] .= 'b' x 8;
2410             }
2411             }elsif($rowe < 6){
2412             $self->{'_text'}->[-1] .= ' ' . hex($cndx) .
2413             ' ' . $telc[$cndx] . ' ';
2414             if($self->{'_flagclru'}){
2415             if($cndx == $self->{'_hndx'}){
2416             $self->{'_fclr'}->[-1] .= 'kkKkkkkk';
2417             $self->{'_bclr'}->[-1] .= 'wwwwwwww';
2418             }else{
2419             $self->{'_fclr'}->[-1] .= ' w ';
2420             $self->{'_bclr'}->[-1] .= ' W ';
2421             }
2422             }
2423             }
2424             }
2425             $self->{'_text'}->[-1] .= ' ';
2426             if($self->{'_flagclru'}){
2427             $self->{'_fclr'}->[-1] .= ' ';
2428             $self->{'_bclr'}->[-1] .= ' ';
2429             }
2430             }
2431             }
2432             if($self->{'_flagforg'}){
2433             for(my $rowe = 0; $rowe < 7; $rowe++){
2434             push(@{$self->{'_text'}}, ' ');
2435             if($self->{'_flagclru'}){
2436             push(@{$self->{'_fclr'}}, ' ');
2437             push(@{$self->{'_bclr'}}, ' ');
2438             }
2439             for(my $cndx=0;$cndx<@telc;$cndx++){
2440             if ($rowe < 5){
2441             $self->{'_text'}->[-1] .= $self->{'_bchr'} x 8;
2442             if($self->{'_flagclru'}){
2443             $self->{'_fclr'}->[-1] .= uc($telc[$cndx]) x 8;
2444             $self->{'_bclr'}->[-1] .= 'k' x 8;
2445             }
2446             }elsif($rowe < 6){
2447             if(hex($cndx+@telc) eq 'B' || hex($cndx+@telc) eq 'C'){
2448             $self->{'_text'}->[-1] .= ' ' . '!' .
2449             ' ' . uc($telc[$cndx]) . ' ';
2450             }else{
2451             $self->{'_text'}->[-1] .= ' ' . hex($cndx+@telc) .
2452             ' ' . uc($telc[$cndx]) . ' ';
2453             }
2454             if($self->{'_flagclru'}){
2455             if($cndx == ($self->{'_hndx'} - 8)) {
2456             $self->{'_fclr'}->[-1] .= 'bbBbbbbb';
2457             $self->{'_bclr'}->[-1] .= 'wwwwwwww';
2458             }else{
2459             $self->{'_fclr'}->[-1] .= ' w ';
2460             $self->{'_bclr'}->[-1] .= ' W ';
2461             }
2462             }
2463             }
2464             }
2465             $self->{'_text'}->[-1] .= ' ';
2466             if($self->{'_flagclru'}){
2467             $self->{'_fclr'}->[-1] .= ' ';
2468             $self->{'_bclr'}->[-1] .= ' ';
2469             }
2470             }
2471             }
2472             if($self->{'_hndx'} < 8){
2473             $self->Move( 5, (( $self->{'_hndx'} * 8) + 2));
2474             }else{
2475             $self->Move(12, ((($self->{'_hndx'} - 8) * 8) + 2));
2476             }
2477             }elsif($self->{'_styl'} eq 'squr'){
2478             if($self->{'_flagbakg'}){
2479             for(my $rowe=0;$rowe<5;$rowe++){
2480             push(@{$self->{'_text'}}, ' ');
2481             if($self->{'_flagclru'}){
2482             push(@{$self->{'_fclr'}}, ' ');
2483             push(@{$self->{'_bclr'}}, ' ');
2484             }
2485             for(my $cndx=0;$cndx
2486             if ($rowe < 3){
2487             $self->{'_text'}->[-1] .= $self->{'_bchr'} x 16;
2488             if($self->{'_flagclru'}){
2489             $self->{'_fclr'}->[-1] .= $telc[$cndx] x 16;
2490             $self->{'_bclr'}->[-1] .= 'k' x 16;
2491             }
2492             }elsif($rowe < 4){
2493             $self->{'_text'}->[-1] .= ' ' . hex($cndx) .
2494             ' ' . $telc[$cndx] . ' ';
2495             if($self->{'_flagclru'}){
2496             if($cndx == $self->{'_hndx'}){
2497             $self->{'_fclr'}->[-1] .= 'kkkkkKkkkkkkkkkk';
2498             $self->{'_bclr'}->[-1] .= 'wwwwwwwwwwwwwwww';
2499             }else{
2500             $self->{'_fclr'}->[-1] .= ' W ';
2501             $self->{'_bclr'}->[-1] .= ' w ';
2502             }
2503             }
2504             }
2505             }
2506             $self->{'_text'}->[-1] .= ' ';
2507             if($self->{'_flagclru'}){
2508             $self->{'_fclr'}->[-1] .= ' ';
2509             $self->{'_bclr'}->[-1] .= ' ';
2510             }
2511             }
2512             for(my $rowe=0;$rowe<5;$rowe++){
2513             push(@{$self->{'_text'}}, ' ');
2514             if($self->{'_flagclru'}){
2515             push(@{$self->{'_fclr'}}, ' ');
2516             push(@{$self->{'_bclr'}}, ' ');
2517             }
2518             for(my $cndx=int(@telc/2);$cndx<@telc;$cndx++){
2519             if ($rowe < 3){
2520             $self->{'_text'}->[-1] .= $self->{'_bchr'} x 16;
2521             if($self->{'_flagclru'}){
2522             $self->{'_fclr'}->[-1] .= $telc[$cndx] x 16;
2523             $self->{'_bclr'}->[-1] .= 'k' x 16;
2524             }
2525             }elsif($rowe < 4){
2526             $self->{'_text'}->[-1] .= ' ' . hex($cndx) .
2527             ' ' . $telc[$cndx] . ' ';
2528             if($self->{'_flagclru'}){
2529             if($cndx == $self->{'_hndx'}){
2530             $self->{'_fclr'}->[-1] .= 'kkkkkKkkkkkkkkkk';
2531             $self->{'_bclr'}->[-1] .= 'wwwwwwwwwwwwwwww';
2532             }else{
2533             $self->{'_fclr'}->[-1] .= ' W ';
2534             $self->{'_bclr'}->[-1] .= ' w ';
2535             }
2536             }
2537             }
2538             }
2539             $self->{'_text'}->[-1] .= ' ';
2540             if($self->{'_flagclru'}){
2541             $self->{'_fclr'}->[-1] .= ' ';
2542             $self->{'_bclr'}->[-1] .= ' ';
2543             }
2544             }
2545             }
2546             if($self->{'_flagforg'}){
2547             for(my $rowe=0;$rowe<5;$rowe++){
2548             push(@{$self->{'_text'}}, ' ');
2549             if($self->{'_flagclru'}){
2550             push(@{$self->{'_fclr'}}, ' ');
2551             push(@{$self->{'_bclr'}}, ' ');
2552             }
2553             for(my $cndx=0;$cndx
2554             if ($rowe < 3){
2555             $self->{'_text'}->[-1] .= $self->{'_bchr'} x 16;
2556             if($self->{'_flagclru'}){
2557             $self->{'_fclr'}->[-1] .= uc($telc[$cndx]) x 16;
2558             $self->{'_bclr'}->[-1] .= 'k' x 16;
2559             }
2560             }elsif($rowe < 4){
2561             if(hex($cndx+@telc) eq 'B' || hex($cndx+@telc) eq 'C'){
2562             $self->{'_text'}->[-1] .= ' ' . '!' .
2563             ' ' . uc($telc[$cndx]) . ' ';
2564             }else{
2565             $self->{'_text'}->[-1] .= ' ' . hex($cndx+@telc) .
2566             ' ' . uc($telc[$cndx]) . ' ';
2567             }
2568             if($self->{'_flagclru'}){
2569             if($cndx == ($self->{'_hndx'} - 8)){
2570             $self->{'_fclr'}->[-1] .= 'kkkkkKkkkkkkkkkk';
2571             $self->{'_bclr'}->[-1] .= 'wwwwwwwwwwwwwwww';
2572             }else{
2573             $self->{'_fclr'}->[-1] .= ' W ';
2574             $self->{'_bclr'}->[-1] .= ' w ';
2575             }
2576             }
2577             }
2578             }
2579             $self->{'_text'}->[-1] .= ' ';
2580             if($self->{'_flagclru'}){
2581             $self->{'_fclr'}->[-1] .= ' ';
2582             $self->{'_bclr'}->[-1] .= ' ';
2583             }
2584             }
2585             for(my $rowe=0;$rowe<5;$rowe++){
2586             push(@{$self->{'_text'}}, ' ');
2587             if($self->{'_flagclru'}){
2588             push(@{$self->{'_fclr'}}, ' ');
2589             push(@{$self->{'_bclr'}}, ' ');
2590             }
2591             for(my $cndx=int(@telc/2);$cndx<@telc;$cndx++){
2592             if ($rowe < 3){
2593             $self->{'_text'}->[-1] .= $self->{'_bchr'} x 16;
2594             if($self->{'_flagclru'}){
2595             $self->{'_fclr'}->[-1] .= uc($telc[$cndx]) x 16;
2596             $self->{'_bclr'}->[-1] .= 'k' x 16;
2597             }
2598             }elsif($rowe < 4){
2599             if(hex($cndx+@telc) eq 'B' || hex($cndx+@telc) eq 'C'){
2600             $self->{'_text'}->[-1] .= ' ' . '!' .
2601             ' ' . uc($telc[$cndx]) . ' ';
2602             }else{
2603             $self->{'_text'}->[-1] .= ' ' . hex($cndx+@telc) .
2604             ' ' . uc($telc[$cndx]) . ' ';
2605             }
2606             if($self->{'_flagclru'}){
2607             if($cndx == ($self->{'_hndx'} - 8)){
2608             $self->{'_fclr'}->[-1] .= 'kkkkkKkkkkkkkkkk';
2609             $self->{'_bclr'}->[-1] .= 'wwwwwwwwwwwwwwww';
2610             }else{
2611             $self->{'_fclr'}->[-1] .= ' W ';
2612             $self->{'_bclr'}->[-1] .= ' w ';
2613             }
2614             }
2615             }
2616             }
2617             $self->{'_text'}->[-1] .= ' ';
2618             if($self->{'_flagclru'}){
2619             $self->{'_fclr'}->[-1] .= ' ';
2620             $self->{'_bclr'}->[-1] .= ' ';
2621             }
2622             }
2623             }
2624             if ($self->{'_hndx'} < 4){
2625             $self->Move( 3, (( $self->{'_hndx'} * 16) + 2));
2626             }elsif($self->{'_hndx'} < 8){
2627             $self->Move( 8, ((($self->{'_hndx'} - 4) * 16) + 2));
2628             }elsif($self->{'_hndx'} < 12){
2629             $self->Move(13, ((($self->{'_hndx'} - 8) * 16) + 2));
2630             }else{
2631             $self->Move(18, ((($self->{'_hndx'} - 12) * 16) + 2));
2632             }
2633             }
2634             if($self->{'_flagprsk'}){
2635             if(length($self->{'_pres'})){
2636             if($self->{'_flagclru'}){
2637             $self->{'_fclr'}->[@{$self->{'_text'}}] = $self->{'_prfc'};
2638             $self->{'_bclr'}->[@{$self->{'_text'}}] = $self->{'_prbc'};
2639             }
2640             my $wdst = 0;
2641             $wdst = length($self->{'_titl'}) + 4;
2642             if(@{$self->{'_text'}}){ # center press string
2643             for(@{$self->{'_text'}}){
2644             $wdst = length($_) if($wdst < length($_));
2645             }
2646             }
2647             if($wdst > length($self->{'_pres'})){
2648             $self->{'_pres'} = ' ' x int(($wdst - length($self->{'_pres'}) + 1) / 2) . $self->{'_pres'} . ' ' x int(($wdst - length($self->{'_pres'}) + 1) / 2);
2649             }
2650             push(@{$self->{'_text'}}, $self->{'_pres'});
2651             }
2652             }
2653             $self->Draw();
2654             return();
2655             }
2656             # CPik() is a special Curses::Simp object constructor which creates a
2657             # Color Pick window.
2658             # If params are supplied, they must be hash key => value pairs.
2659             sub CPik{
2660             my $main = shift;my($keey,$valu);my $char;my $tchr;my $text = '';
2661             my $self = bless({}, ref($main));
2662             my $cmov;my $pick;my $done = 0;
2663             # ' ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿','ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞß',
2664             my @bchz = ( 'X', '@', '#', '$', 'Û', '²', '±', '°'); # block chars
2665             my @styz = ( 'barz', 'blox', 'squr' ); # color display styles
2666             for my $attr($self->AttrNamz()){
2667             $self->{$attr} = $self->DfltValu($attr); # init defaults
2668             }
2669             # special CPik window defaults
2670             $self->{'_flagsdlk'} = 1; # get SDLKeys
2671             $self->{'_flagmaxi'} = 0; # not maximized
2672             $self->{'_flagcvis'} = 1; # show cursor
2673             $self->{'_flagbakg'} = 1; # pick background colors
2674             $self->{'_flagforg'} = 1; # pick foreground colors
2675             $self->{'_flagclru'} = $main->{'_flagclru'}; # inherit ColorUsed flag
2676             # $self->{'_widt'} = getmaxx() - 4; # but almost full screen wide
2677             # $self->{'_hite'} = getmaxy() - 4; # && high
2678             $self->{'_text'} = [ ' ' ];
2679             $self->{'_dtfc'} = 'G';
2680             $self->{'_dtbc'} = 'u';
2681             if($self->{'_flagclru'}){
2682             $self->{'_fclr'} = [ $self->{'_dtfc'} ];
2683             $self->{'_bclr'} = [ $self->{'_dtbc'} ];
2684             }
2685             $self->{'_titl'} = 'Color Picker:';
2686             $self->{'_ttfc'} = 'ROYGUbG';
2687             $self->{'_ttbc'} = 'pgcupbu';
2688             $self->{'_flagprsk'} = 1;
2689             $self->{'_pres'} = 'Pick A Color... (Arrows+Enter, Letter, or Number)';
2690             $self->{'_prfc'} = 'Y'; # Pick message foreground Color
2691             $self->{'_prbc'} = 'k'; # Pick message background Color
2692             $self->{'_hifc'} = 'W'; # highlight foreground color
2693             $self->{'_hibc'} = 'g'; # highlight background color
2694             $self->{'_hndx'} = 7; # highlight index
2695             $self->{'_sndx'} = 0; # style index
2696             $self->{'_styl'} = 'barz';# style name
2697             $self->{'_bndx'} = 0; # block index
2698             $self->{'_bchr'} = 'X'; # block char
2699             for(@KMODNAMZ){ $self->{'_kmod'}->{$_} = 0; }
2700             # there were init params with no colon (classname)
2701             while(@_){
2702             ($keey, $valu)=(shift, shift);
2703             if(defined($valu)){
2704             if ($keey =~ /^_*....$/){
2705             $keey =~ s/^_*//;
2706             $self->{"_$keey"} = $valu;
2707             }else{
2708             for my $attr($self->AttrNamz()){
2709             $self->{$attr} = $valu if($attr =~ /$keey/i);
2710             }
2711             }
2712             }else{
2713             $self->{'_styl'} = $keey;
2714             }
2715             }
2716             $self->{'_sndx'} = $self->{'_styl'} if($self->{'_styl'} =~ /^\d+$/);
2717             $self->{'_styl'} = $styz[$self->{'_sndx'}];
2718             $self->{'_bndx'} = $self->{'_bchr'} if($self->{'_bchr'} =~ /^\d+$/);
2719             $self->{'_bchr'} = $bchz[$self->{'_bndx'}];
2720             if($self->{'_widt'} < length($self->{'_titl'}) + 4){
2721             $self->{ '_widt'} = length($self->{'_titl'}) + 4;
2722             }
2723             $self->{'_ycrs'} = $self->{'_hndx'};
2724             $self->{'_xcrs'} = 0;
2725             $self->{'_flagshrk'} = 0 if($self->{'_hite'} && $self->{'_widt'});
2726             $self->Updt(1);
2727             $self->{'_wind'} = newwin($self->{'_hite'}, $self->{'_widt'},
2728             $self->{'_yoff'}, $self->{'_xoff'});
2729             unless(exists($self->{'_wind'}) && defined($self->{'_wind'})){
2730             croak "!*EROR*! Curses::Simp::CPik could not create new window with hite:$self->{'_hite'}, widt:$self->{'_widt'}, yoff:$self->{'_yoff'}, xoff:$self->{'_xoff'}!\n";
2731             }
2732             $self->FlagCVis(); # set cursor visibility to new object state
2733             $self->BildBlox(); # build color block data into @text,@fclr,@bclr && Draw()
2734             $self->Move($self->{'_hndx'}, 0);
2735             while(!defined($char) || !$done){
2736             $char = $self->GetK(-1);
2737             if($char =~ /^SDLK_(RETURN|[0-9A-FRGYUPW])$/i){ # gonna be done
2738             $char =~ s/^SDLK_//;
2739             if ($char =~ /^[BRGYUPCW]$/i){
2740             $pick = $char;
2741             $pick = uc($pick) if($self->{'_kmod'}->{'KMOD_SHIFT'});
2742             }else{
2743             $self->{'_hndx'} = dec(uc($char)) unless($char =~ /^RETURN$/);
2744             $pick = $telc[ ($self->{'_hndx'} % 8)];
2745             $pick = uc($pick) if($self->{'_hndx'} >= 8);
2746             }
2747             $done = 1;
2748             }else{
2749             $tchr = $char;
2750             $tchr =~ s/^SDLK_//;
2751             $cmov = 0;
2752             if ($tchr eq 'PAGEUP' ){ # Page keys cycle Block Char
2753             $self->{'_bndx'}++;
2754             $self->{'_bndx'} = 0 if($self->{'_bndx'} == @bchz);
2755             }elsif($tchr eq 'PAGEDOWN'){
2756             $self->{'_bndx'} = @bchz unless($self->{'_bndx'});
2757             $self->{'_bndx'}--;
2758             }elsif($tchr eq 'END' ){ # Home/End cycles layout Style
2759             $self->{'_sndx'}++;
2760             $self->{'_sndx'} = 0 if($self->{'_sndx'} == @styz);
2761             }elsif($tchr eq 'HOME' ){
2762             $self->{'_sndx'} = @styz unless($self->{'_sndx'});
2763             $self->{'_sndx'}--;
2764             }
2765             $self->{'_bchr'} = $bchz[$self->{'_bndx'}];
2766             $self->{'_styl'} = $styz[$self->{'_sndx'}];
2767             if ($self->{'_styl'} eq 'barz'){
2768             if ($tchr eq 'LEFT' or $tchr eq 'UP' ){
2769             $self->{'_hndx'} = 16 unless($self->{'_hndx'});
2770             $self->{'_hndx'}--;
2771             }elsif($tchr eq 'RIGHT' or $tchr eq 'DOWN'){
2772             $self->{'_hndx'}++;
2773             $self->{'_hndx'} = 0 if($self->{'_hndx'} == 16);
2774             }
2775             }elsif($self->{'_styl'} eq 'blox'){
2776             if ($tchr eq 'DOWN' or $tchr eq 'UP'){
2777             $self->{'_hndx'} += 8;
2778             $self->{'_hndx'} -= 16 if($self->{'_hndx'} >= 16);
2779             }elsif($tchr eq 'LEFT' ){
2780             $self->{'_hndx'} = 16 unless($self->{'_hndx'});
2781             $self->{'_hndx'}--;
2782             }elsif($tchr eq 'RIGHT'){
2783             $self->{'_hndx'}++;
2784             $self->{'_hndx'} = 0 if($self->{'_hndx'} == 16);
2785             }
2786             }elsif($self->{'_styl'} eq 'squr'){
2787             if ($tchr eq 'UP' ){
2788             $self->{'_hndx'} -= 4;
2789             $self->{'_hndx'} += 16 if($self->{'_hndx'} < 0);
2790             }elsif($tchr eq 'DOWN' ){
2791             $self->{'_hndx'} += 4;
2792             $self->{'_hndx'} -= 16 if($self->{'_hndx'} >= 16);
2793             }elsif($tchr eq 'LEFT' ){
2794             $self->{'_hndx'} = 16 unless($self->{'_hndx'});
2795             $self->{'_hndx'}--;
2796             }elsif($tchr eq 'RIGHT'){
2797             $self->{'_hndx'}++;
2798             $self->{'_hndx'} = 0 if($self->{'_hndx'} == 16);
2799             }
2800             } $self->BildBlox();
2801             }
2802             } delwin($self->{'_wind'}); # delete the CPik window, redraw rest
2803             $main->ShokScrn(2);
2804             $main->FlagCVis(); # reset cursor visibility to calling object state
2805             return($pick); # return picked color code
2806             }
2807             sub BrwsHelp{ # BrwsHelp() just prints a help text message for Brws()
2808             my $self = shift;
2809             $self->Mesg('type' => 'help',
2810             'titl' => 'File / Directory Browser Help: (F1)',
2811             "This Browser dialog exists to make it easy to choose a file (or directory).
2812              
2813             You can between elements. Ctrl-I and TAB are interpreted as the same
2814             key by Curses so either one can be pressed to cycle forward through Browse
2815             elements. Ctrl-U cycles backwards. Ctrl-H toggles hidden files.
2816             Ctrl-F toggles file highlighting. Ctrl-C shows the configuration screen.
2817              
2818             All drop downs can be navigated with the arrow keys, typed directly into,
2819             or have their drop state toggled with the tilde '~' or backtick '`' keys.
2820              
2821             The '=C' button is supposed to look like a wrench for configuration.
2822             Pressing enter on it will bring up the Browse configuration screen.
2823             The 'md' button allows you to make a new directory in the current path.
2824             The 'Path:' drop down lets you specify which directory to apply 'Filter:'
2825             to when populating the main view box in the center.
2826             The '..' button moves path up one directory.
2827             The '??' button brings up this help text.
2828             The main view box can be navigated with the arrow keys and a file can be
2829             chosen with Enter.
2830             The 'Filename:' drop down lets you type the filename specificially or
2831             pick from recent choices.
2832             The button following 'Filename:' will likely be labeled 'Open' or
2833             'Save As' for the purpose of the Browsing. This button accepts
2834             whatever name is in the 'Filename:' drop down.
2835             The 'Filter:' drop down lets you specify what globbing should happen in
2836             'Path:' to populate the main view.
2837             The 'Cancel' button quits without making a selection.
2838             ");
2839             }
2840             # The '=C' button is supposed to look like a wrench for configuration.
2841             # Pressing enter on it will bring up the Browse configuration screen.
2842             # The 'md' button allows you to make a new directory in the current path.
2843             # The 'Path:' drop down lets you specify which directory to apply 'Filter:'
2844             # to when populating the main view box in the center.
2845             # The '..' button moves path up one directory.
2846             # The '??' button brings up this help text.
2847             # The main view box can be navigated with the arrow keys and a file can be
2848             # chosen with Enter.
2849             # The 'Filename:' drop down lets you type the filename specificially or
2850             # pick from recent choices.
2851             # The button following 'Filename:' will likely be labeled 'Open' or
2852             # 'Save As' for the purpose of the Browsing. This button accepts
2853             # whatever name is in the 'Filename:' drop down.
2854             # The 'Filter:' drop down lets you specify what globbing should happen in
2855             # 'Path:' to populate the main view.
2856             # The 'Cancel' button quits without making a selection.
2857             sub BrwsCnfg{ # BrwsCnfg() brings up a dialog of checkboxes for elements
2858             my $self = shift; my $char; my $cndx = 0;
2859             my %cdsc = ('_cnfg' => '=C - Configuration Button',
2860             '_mkdr' => 'md - Make Directory Button',
2861             '_path' => 'Path: Drop Down',
2862             '_cdup' => '.. - Change Directory Up Button',
2863             '_help' => '?? - Help Button',
2864             '_view' => 'Main View Area ',
2865             '_file' => 'Filename: Drop Down',
2866             '_open' => 'Open/SaveAs/etc. Button',
2867             '_filt' => 'Filter: Drop Down',
2868             '_cncl' => 'Cancel Button',
2869             );
2870             my $cfgb = $self->Mesg('type' => 'butn', 'titl'=>'Browser Configuration:',
2871             'hite' => $self->{'_hite'}, 'widt' => $self->{'_widt'},
2872             'yoff' => $self->{'_yoff'}, 'xoff' => $self->{'_xoff'}, 'flagsdlk' => 1,
2873             'mesg' => " Tab or Arrows go between fields, Space toggles, Enter accepts all.",
2874             );
2875             for(my $indx=0;$indx<@{$self->{'_elem'}};$indx++){ # make ckboxes
2876             $cfgb->{'_cbob'}->{ $self->{'_elem'}->[$indx] } = $cfgb->Mesg(
2877             'type' => 'ckbx',
2878             'yoff' => ($self->{'_yoff'} + ($indx * 2) + 4),
2879             'xoff' => ($self->{'_xoff'} + 4),
2880             'stat' => $self->{'_eflz'}->{ $self->{'_elem'}->[$indx] },
2881             "$cdsc{$self->{'_elem'}->[$indx]} Visible"
2882             );
2883             }
2884             while(!defined($char) || $char ne 'SDLK_RETURN'){
2885             $char = $cfgb->{'_cbob'}->{ $self->{'_elem'}->[ $cndx ] }->Focu();
2886             if ($char =~ /^SDLK_(TAB|DOWN|j)$/){
2887             $cndx++;
2888             $cndx = 0 if($cndx >= @{$self->{'_elem'}});
2889             }elsif($char =~ /^SDLK_(UP|k)$/ ||
2890             ($char eq 'SDLK_u' && $cfgb->{'_cbob'}->{ $self->{'_elem'}->[ $cndx ] }->{'_kmod'}->{'KMOD_CTRL'})){
2891             $cndx = @{$self->{'_elem'}} unless($cndx);
2892             $cndx--;
2893             }
2894             }
2895             for(my $indx=0;$indx<@{$self->{'_elem'}};$indx++){ # make ckboxes
2896             $self->{'_eflz'}->{ $self->{'_elem'}->[$indx] } =
2897             $cfgb->{'_cbob'}->{ $self->{'_elem'}->[$indx] }->{'_stat'};
2898             $cfgb->{'_cbob'}->{ $self->{'_elem'}->[$indx] }->DelW();
2899             }
2900             $cfgb->DelW();
2901             $self->BildBrws(1);
2902             return();
2903             }
2904             sub BrwsCdUp{ # BrwsCdUp() just moves the browse path up one directory
2905             my $self = shift;
2906             if($self->{'_path'} =~ s/^(.*\/).+\/?$/$1/){
2907             $self->{'_bobj'}->{'_path'}->{'_text'}->[
2908             ($self->{'_bobj'}->{'_path'}->{'_lndx'} + 1) ] = $self->{'_path'};
2909             $self->{'_bobj'}->{'_path'}->{'_dtxt'} = $self->{'_path'};
2910             $self->{'_bobj'}->{'_path'}->{'_data'} = $self->{'_path'};
2911             $self->{'_bobj'}->{'_path'}->{'_text'}->[0] = $self->{'_path'};
2912             $self->{'_bobj'}->{'_path'}->{'_curs'} = length($self->{'_path'});
2913             $self->{'_bobj'}->{'_path'}->{'_xcrs'} = length($self->{'_path'});
2914             $self->{'_bobj'}->{'_path'}->{'_echg'} = 1;
2915             }
2916             }
2917             # BildBrws() is a utility of Brws() which creates or updates all the
2918             # elements of a Browse Window.
2919             # Brws() bare-bones dialog should look something like:
2920             # +------------------------{Open File:}-------------------------------+
2921             # |+--------------------{cwd: /home/pip }----------------------------+|
2922             # ||../ ||
2923             # ||.LS_COLORS ||
2924             # ||.ssh/ ||
2925             # ||.zshrc *Highlighted line* ||
2926             # ||dvl/ ||
2927             # |+-----------------------------------------------------------------+|
2928             # |+-----------------{Filename:}--------------+--++========++--------+|
2929             # ||.zshrc |\/|| Open || Cancel ||
2930             # |+------------------------------------------+--++========++--------+|
2931             # +-------------------------------------------------------------------+
2932             # or Brws() with frills
2933             # +---------------------------{Open File:}----------------------------+
2934             # |+--++--++-----------------------{Path:}----------------+--++--++--+|
2935             # ||=C||md||/home/pip |\/||..||??||
2936             # |+--++--++----------------------------------------------+--++--++--+|
2937             # |+-----------------------------------------------------------------+|
2938             # ||../ ||
2939             # ||.LS_COLORS ||
2940             # ||.ssh/ ||
2941             # ||.zshrc *Highlighted line* ||
2942             # ||dvl/ ||
2943             # |+-----------------------------------------------------------------+|
2944             # |+----------------------{Filename:}-------------------+--++========+|
2945             # ||.zshrc |\/|| Open ||
2946             # |+----------------------------------------------------+--++========+|
2947             # |+-----------------------{Filter:}--------------------+--++--------+|
2948             # ||* (All Files) |\/|| Cancel ||
2949             # |+----------------------------------------------------+--++--------+|
2950             # +-------------------------------------------------------------------+
2951             # heh... this one is complicated enough that it should probably be
2952             # Curses::Simp::Brws.pm instead ... too bad =)
2953             # =C is configure wrench for new dialog of all toggles (&& hotkeys)
2954             # md is mkdir dialog
2955             # \/ drop down bar to show recent or common options
2956             # .. is `cd ..`
2957             # ?? is help / F1
2958             # ==== box is highlighted (Enter selects)
2959             # Ultimately, Brws() should be able to handle easy Browsing for
2960             # Files or Directories for any Open/SaveAs/etc. purposes
2961             sub BildBrws{
2962             my $self = shift; my $updt = shift || 0; my $indx;
2963             $self->FlagCVis(); # set cursor visibility to main Brws object state
2964             $self->Draw();
2965             for($indx=0;$indx<@{$self->{'_elem'}};$indx++){
2966             if(!$self->{'_eflz'}->{$self->{'_elem'}->[$self->{'_endx'}]}){
2967             $self->{'_endx'}++;
2968             $self->{'_endx'} = 0 if($self->{'_endx'} == @{$self->{'_elem'}});
2969             }
2970             } # this for && below if make sure a visible element is indexed
2971             if(!$self->{'_eflz'}->{$self->{'_elem'}->[$self->{'_endx'}]}){
2972             $self->{'_eflz'}->{$self->{'_elem'}->[$self->{'_endx'}]} = 1;
2973             }
2974             for($indx = 0; $indx < @{$self->{'_elem'}}; $indx++){
2975             my $elem = $self->{'_elem'}->[$indx];
2976             if(!$updt || $self->{'_eflz'}->{$elem}){
2977             my($yoff, $xoff)=($self->{'_yoff'} + 1, $self->{'_xoff'} + 1);
2978             my($widt, $hite)=($self->{'_widt'} - 2, $self->{'_hite'} - 2);
2979             my $type = 'butn';my $titl = '';my $btyp = 1;
2980             my $brfc = 'w';my $brbc = 'k';my $scrl = 0;
2981             my $mesg;my @text;my @fclr;my @bclr;
2982             if($self->{'_flagclru'}){ @fclr = ( 'w' ); @bclr = ( 'k' ); }
2983             if ($elem eq '_cnfg'){ # do specific settings
2984             $hite = 3; $widt = 4;
2985             $mesg = '=C';
2986             }elsif($elem eq '_mkdr'){
2987             $hite = 3; $widt = 4;
2988             $xoff += 4 if($self->{'_eflz'}->{'_cnfg'});
2989             $mesg = 'md';
2990             }elsif($elem eq '_path'){
2991             $hite = 3;
2992             if($self->{'_eflz'}->{'_cnfg'}) { $xoff += 4; $widt -= 4; }
2993             if($self->{'_eflz'}->{'_mkdr'}) { $xoff += 4; $widt -= 4; }
2994             if($self->{'_eflz'}->{'_cdup'}) { $widt -= 4; }
2995             if($self->{'_eflz'}->{'_help'}) { $widt -= 4; }
2996             $type = 'drop';
2997             $titl = 'Path:';
2998             if(exists( $self->{'_bobj'}->{'_path'})){
2999             @text = @{$self->{'_bobj'}->{'_path'}->{'_text'}};
3000             if($self->{'_flagclru'}){
3001             @fclr = @{$self->{'_bobj'}->{'_path'}->{'_fclr'}};
3002             @bclr = @{$self->{'_bobj'}->{'_path'}->{'_bclr'}};
3003             }
3004             }else{
3005             @text = ( $self->{'_path'}, '/home/', '/tmp/' );
3006             }
3007             }elsif($elem eq '_cdup'){
3008             $hite = 3;$widt = 4;
3009             $xoff = $self->{'_widt'} - 3;
3010             $xoff -= 4 if($self->{'_eflz'}->{'_help'});
3011             $mesg = '..';
3012             }elsif($elem eq '_help'){
3013             $hite = 3;$widt = 4;
3014             $xoff = $self->{'_widt'} - 3;
3015             $mesg = '??';
3016             }elsif($elem eq '_view'){
3017             my $dtdt = 0;
3018             if($self->{'_eflz'}->{'_cnfg'} ||
3019             $self->{'_eflz'}->{'_mkdr'} ||
3020             $self->{'_eflz'}->{'_path'} ||
3021             $self->{'_eflz'}->{'_cdup'} ||
3022             $self->{'_eflz'}->{'_help'}){ $yoff += 3;$hite -= 3; }
3023             if($self->{'_eflz'}->{'_file'} ||
3024             $self->{'_eflz'}->{'_open'} ||
3025             $self->{'_eflz'}->{'_cncl'}){ $hite -= 3; }
3026             if($self->{'_eflz'}->{'_filt'}){ $hite -= 3; }
3027             if(exists( $self->{'_bobj'}->{'_view'})){
3028             @text = @{$self->{'_bobj'}->{'_view'}->{'_text'}};
3029             if($self->{'_flagclru'}){
3030             @fclr = @{$self->{'_bobj'}->{'_view'}->{'_fclr'}};
3031             @bclr = @{$self->{'_bobj'}->{'_view'}->{'_bclr'}};
3032             }
3033             if($self->{'_bobj'}->{'_view'}->{'_echg'}){
3034             $self->{'_choi'} = $text[($self->{'_vndx'} - $self->{'_vscr'})];
3035             $self->{'_bobj'}->{'_file'}->{'_curs'} = length($self->{'_choi'});
3036             $self->{'_bobj'}->{'_file'}->{'_xcrs'} = length($self->{'_choi'});
3037             }
3038             }
3039             if(!$updt || $self->{'_bobj'}->{'_mkdr'}->{'_echg'} ||
3040             $self->{'_bobj'}->{'_path'}->{'_echg'} ||
3041             $self->{'_bobj'}->{'_view'}->{'_echg'} ||
3042             $self->{'_bobj'}->{'_filt'}->{'_echg'}){
3043             @text = (); if($self->{'_flagclru'}){ @fclr = ();@bclr = (); }
3044             unless($self->{'_choi'}){
3045             $self->{'_vndx'} = 0;
3046             $self->{'_choi'} = '';
3047             }
3048             unless($self->{'_flaghide'}){
3049             for(glob($self->{'_path'} . '.' . $self->{'_filt'})){
3050             $_ .= '/' if(-d $_);
3051             s/^$self->{'_path'}//;
3052             $dtdt = 1 if($_ eq '../');
3053             unless($_ eq './'){ # || /\.swp$/) # omit . && .swp
3054             push(@text, $_);
3055             if(!$self->{'_choi'}){
3056             if(-f $_){ $self->{'_choi'} = $_; }
3057             else { $self->{'_vndx'}++; }
3058             }
3059             }
3060             }
3061             }
3062             for(glob($self->{'_path'} . $self->{'_filt'})){
3063             $_ .= '/' if(-d $_);
3064             s/^$self->{'_path'}//;
3065             unless($_ eq './' || ($_ eq '../' && $dtdt)){ # omit . or 2nd ..
3066             push(@text, $_);
3067             if(!$self->{'_choi'}){
3068             if(-f $_){ $self->{'_choi'} = $_; }
3069             else { $self->{'_vndx'}++; }
3070             }
3071             }
3072             }
3073             $self->{'_vndx'} = (@text - 1) if($self->{'_vndx'} > (@text - 1));
3074             if($self->{'_flagflhi'}){
3075             my $lsfc;my $lsbc = 'k'; # need background colors for listing?
3076             for(@text){
3077             my $fulf = $self->{'_path'} . $_;
3078             $lsfc = $GLBL{'TESTMAPP'}->{'NORMAL'};
3079             if (-d $fulf){ $lsfc = $GLBL{'TESTMAPP'}->{'DIR'};
3080             }elsif(-l $fulf){ $lsfc = $GLBL{'TESTMAPP'}->{'LINK'};
3081             }elsif(-p $fulf){ $lsfc = $GLBL{'TESTMAPP'}->{'FIFO'};
3082             }elsif(-S $fulf){ $lsfc = $GLBL{'TESTMAPP'}->{'SOCK'};
3083             }elsif(-b $fulf){ $lsfc = $GLBL{'TESTMAPP'}->{'BLK'};
3084             }elsif(-c $fulf){ $lsfc = $GLBL{'TESTMAPP'}->{'CHR'};
3085             #}elsif(-O $fulf){ $lsfc = $GLBL{'TESTMAPP'}->{'ORPHAN'}; # don't know test
3086             }elsif(-x $fulf){ $lsfc = $GLBL{'TESTMAPP'}->{'EXEC'};
3087             }elsif(-f $fulf){ $lsfc = $GLBL{'TESTMAPP'}->{'FILE'};
3088             # # lsptBl02du:stripXtraDblSpcK0lMzB4NCesk8pk0lRk0dzhvbNad3d;mABpr0cS~/.lsrc wiXtra0ptz2betRgl0b&&PCREk0lRz4fyLtypzas$ENV{LsP8}?;
3089             #ub lspt{ #2du:f0ld$ENV{LsP8}n2`lspt`n2`ls`&&evN2LEUzCurzSFUCKnsteduvANSIesk8pk0dz;r3d0NCSk8pk0dzazgl0bLFUCKnmz2mkbetREsc8NCRtSKR8;add $prmz optn2~/.lsrc;
3090             # my @ldat=`ls -lF --full-time @_`;my $t0tl='0';my %lsp8;my %lspt;my($list,$prmz,$blsz,$pwnr,$grup,$fsiz,$dayt,$tyme,$tz0n,$fnam,$cmpr,$b6bs,$b6fs);
3091             # @ldat=split(/\n/,$list);$list="$Sk80;33mt$Sk81;33m0$Sk80;33mtl$Sk81;37m:$Sk81;34m$t0tl$Sk8G\n"; #fnd longSt lIn&&strip dbl-spc colMz..
3092             # my $long=0;for(@ldat){$long = length($_) if($long < length($_))};for my $cndx (1..$long){my $dspf=0;for(@ldat){$dspf=1 if(substr($_,$cndx-1,2) ne ' ');}
3093             # if(!$dspf){for(@ldat){substr($_,$cndx-1,2)=' '}}}$list.=join("\n",@ldat)."\n$list";print $list; # <- th@ shud strip' 'colMzbutEsc8pzRmisAlInNg!
3094             # no=00: NORMAL global dflt (altho idealy evrythng shud b smthng)
3095             # fi=00: FILE normal FILE
3096             # ln=01;37: LINK symbolic LINK (if set to 'target' instead of colr;code;numz,color inherits that of file symlinked to)
3097             # mh???: #ULTIHARDLINK regular file with more than one link (used2b just "HARDLINK" with 44;37 but coreutils chngd aroun 9A68d7P)
3098             # or=05;01;01;46: ORPHAN sym------link to nonexistent file
3099             # mi=05;01;01;41: MISSING && the MISSING file it points to (blinkng alert?) #.ANSI.01.30 01;30 # bright blacK
3100             # ex=01;32: EXEC file w/ EXECute permission (+x ) #.ANSI.01.31 01;31 # bright Red
3101             # su=01;37;01;42: SETUID file that is SETUID ( u+s) #.ANSI.01.32 01;32 # bright Green
3102             # sg=00;30;00;43: SETGID file that is SETGID ( g+s) #.ANSI.01.33 01;33 # bright Yellow
3103             # di=01;34: DIR DIRectory #.ANSI.01.34 01;34 # bright Blue
3104             # st=01;37;01;44: STICKY dir w/ STICKY bit set && !other-writable (+t,o-w) #.ANSI.01.35 01;35 # bright Magenta (Purple)
3105             # ow=01;34;01;42: OTHER_WRITABLE dir w/ sticky bit !set && OTHER-WRITABLE ( o+w) #.ANSI.01.36 01;36 # bright Cyan
3106             # tw=00;30;00;45: STICKY_OTHER_WRITABLE dir w/ STICKY bit set && OTHER-WRITABLE (+t,o+w) #.ANSI.01.37 01;37 # bright White zsh:'%{' ANSI '%}'
3107             # pi=00;33;00;40: FIFO pipe (First-In,First-Out) (orig bcam 40;33 with coreutils chng2 /etc/DIR_COLORS aroun 9A68d7P)
3108             # so=01;35: SOCK SOCKet
3109             # do=01;35: DOOR DOOR (not sure why this was commented out before?) I'd gues this is POSIX||BSD-centric but !in Linux FylSys?
3110             # bd=01;33;01;40: BLK BLocK device driver
3111             # cd=01;33;01;40: CHR CHaRacter device driver #*.2du=01;33:*..#add0thRlsfyLtypz,symlnx..
3112             # for(split(':',$ENV{'LS_COLORS'})){my ($g2re,$fx2e);
3113             # if (/^([^=]*[\*\+\?]+[^=]+)=0(.+)$/){($g2re,$fx2e)=($1,"$Sk8p$2m");$g2re=~s/([.])/\\$1/g;$g2re=~s/(\?|(\*|\+))/.$2/g;$lsp8{qr/^.*\s*$g2re$/}=$fx2e}
3114             # elsif( /^([^=]+)=0(.+)$/){($g2re,$fx2e)=($1,"$Sk8p$2m"); $lspt{ $g2re }=$fx2e}}
3115             # for(@ldat){if(($prmz,$blsz,$pwnr,$grup,$fsiz,$dayt,$tyme,$tz0n,$fnam)= /^(\S{10})(\s+\d+)(\s+\S+)(\s+\S+\s+)(\d+)\s+(\S{10})\s+(\S+)(\s+\S+)\s+(.*)/){
3116             # $b6bs=b64($blsz);$b6bs=' 'x(length($blsz)-length($b6bs)).$b6bs;my $b6tt=$tz0n;my $b6tz;if( $b6tt=~s/(00$|^\s+|^[-+]?0?)//g){$b6tz=$1.b64($b6tt)}
3117             # $b6fs=b64($fsiz);$b6fs=' 'x(length($fsiz)-length($b6fs)).$b6fs;my($lar0,$k0lx,$l,$k);$l=0; $b6tz=~s/^([-+]?)0?(.*)$/$Sk8W$1$Sk8G$2$Sk80;37m/;my $ttim;
3118             # $cmpr=$prmz;my @fldz=split(/-/,$dayt);$fldz[1]=~s/^0//;$fldz[1]--;my $stat="$Mon[$fldz[1]] $fldz[2] $tyme $fldz[0]"; @fldz=split(/\./,$tyme);my $tnam;
3119             # $cmpr=~s/^(d)/$Sk8B$1/;$fldz[2]= '0.'.$fldz[1];$fldz[2]*=60;$fldz[2]=int($fldz[2]);$stat=~s/\.$fldz[1]/:$fldz[2]/;my $ptim=Time::PT->new('verbose'=>$stat);
3120             # $cmpr=~s/^(-)/$Sk8W$1/;$ttim= $ptim->color('ansi').$Sk8k;$ttim.='0'x(7-int((length($ttim)-7)/8)) if(length($ttim)<(8*7 +7));s/$dayt\s+$tyme/$ttim$Sk8G/;
3121             # $cmpr=~s/rwx/${Sk8R}7/g;$cmpr=~s/-wx/$Sk80;34m3/g;$cmpr=~s/rws/$Sk81;33m7/g;$cmpr=~s/rwt/$Sk81;35m7/g;
3122             # $cmpr=~s/rw-/${Sk8C}6/g;$cmpr=~s/-w-/$Sk80;33m2/g; # stil wnt2Uz ~/.lsrc 2mABNcod prmz asumngPXX(400,644,755..[azB64?])2ovrIdfylk0lrzby.X10shn
3123             # $cmpr=~s/r-x/${Sk8M}5/g;$cmpr=~s/--x/$Sk80;32m1/g;$cmpr=~s/r-s/$Sk80;33m5/g;$cmpr=~s/r-t/$Sk80;35m5/g; #Uzr&&Grp?
3124             # $cmpr=~s/r--/${Sk8B}4/g;$cmpr=~s/---/${Sk8G}0/g ;$grup=~s/\s$//; #?prmzRblszYpwnrCgrupPfsiz?dayt?tymeGtz0n?fnam..
3125             # for my $shgl (sort keys(%lsp8)){$tnam=$fnam;if($tnam=~/$shgl/){ $k= $lsp8{$shgl};$tnam= $k.$tnam; print "tb4b:$tnam:k:$k:\n" if($Dbug); #Gl0b
3126             # $tnam=~s/^(.*?)(\s+|\e\[[^m]+m|\s(->)\s)*(.+?)((\.)([^.]+))?$/$k$1$Sk8W$3$k$4$Sk8W$6$k$7/;#$k=~s/\e\[/\\e\\[/g;
3127             # $tnam=~s/(([-._*>])+|\s+(->)\s+)/$Sk8W$2$3$k/g;$tnam=~s/([-])+/$Sk8Y$1$k/g;$tnam=~s/([_])+/$Sk8C$1$k/g; print "taft:$tnam:k:$k:\n" if($Dbug);last}}
3128             # for my $svgl (keys(%lspt)){$k=$k0lx=$lspt{$svgl};my( $bgin,$fsnm )=('', $fnam);#elsif($svgl..=~/^(\e\[[^m]+m)?(.+->.+)$/)&& -l $fsnm)){s/../$k$fsnm} #Typz
3129             # if ($svgl eq'ex'&& (($bgin,$fsnm)= $fnam=~/^(.*?)(.+?)\*+$/ )&& -x $fsnm){if(!-d $fsnm){ $fsnm=~s/\*$//;
3130             # $list.="\n:$svgl=e\$Sk8p[$lspt{$svgl}:$fsnm:e\$Sk8W:*:..G:\n" if($Dbug);$tnam=~s/^(.*?)($fsnm)(\*)*$/$1$k$2$Sk8W$3/}}
3131             # elsif($svgl eq'di'&& (($bgin,$fsnm)= $fnam=~/^(.*?)(.+?)\/*$/ )&& -d $fsnm){$tnam=~s/^(.*?)($fsnm)(\/)*$/$1$k$2$Sk8Y$3/ }}#$tnam.=$Sk8G;
3132             # s/^$prmz$blsz$pwnr$grup(.*?)$fsiz(.*?)$tz0n(.*?)$fnam(.*)/$cmpr$Sk8R$b6bs$Sk8Y$pwnr$Sk8C$grup$Sk8M$b6fs$2$b6tz$3$tnam/;#$4
3133             # if(/^.*[.-]([0-9A-Za-z._][1-9A-C][1-9A-V][0-9A-Za-x]{4})(\.\S{1,4})?/){my($ptvr,$x10n)=($1,$2);$ptim=undef;$ptim = Time::PT->new($ptvr);
3134             # $ttim=$ptim->color('ansi')."$Sk80;30m" ;$ttim.='0'x(7-int((length($ttim)-7)/8)) if(length($ttim)<(8*7 +7));s/$ptvr/$ttim$Sk8G/}}
3135             # elsif(/^total\s+(\d+)/){$t0tl=b64($1);$_=''}$list.=$_ if /\S/}@ldat=split(/\n/,$list);$list="$Sk80;33mt${Sk8Y}0$Sk80;33mtl$Sk8W:$Sk8B$t0tl$Sk8G\n";
3136             # $list.=join("\n",@ldat)."\n$list";print $list}
3137             my %CLUT =('0;30' => 'k','1;30' => 'K','0;31' => 'r','1;31' => 'R','0;32' => 'g','1;32' => 'G','0;33' => 'O','1;33' => 'Y',
3138             '0;34' => 'b','1;34' => 'B','0;35' => 'p','1;35' => 'P','0;36' => 'c','1;36' => 'C','0;37' => 'w','1;37' => 'W');
3139             for(split(':',$ENV{'LS_COLORS'})){ my($g2re,$ansn);
3140             if (/^([^=]*[\*\+\?]+[^=]+)=0(.+)$/){($g2re,$ansn)=($1,$2);$g2re=~s/([.])/\\$1/g;
3141             $g2re=~s/(\?|(\*|\+))/.$2/g;#$lsp8{qr/^.*\s*$g2re$/}=$ansn;
3142             }elsif( /^([^=]+)=0(.+)$/){($g2re,$ansn)=($1,$2); #$lspt{ $g2re }=$ansn;
3143             }$GLBL{'OVERMAPP'}->{qr/^.*\s*$g2re$/} = $CLUT{$ansn} if(exists($CLUT{$ansn}));
3144             }
3145             for my $regx(keys(%{$GLBL{'DFLTMAPP'}})){ # test defaults
3146             $lsfc = $GLBL{'DFLTMAPP'}->{$regx} if($fulf =~ /$regx/i);
3147             }
3148             for my $regx(keys(%{$GLBL{'OVERMAPP'}})){ # test overridz
3149             $lsfc = $GLBL{'OVERMAPP'}->{$regx} if($fulf =~ /$regx/i);
3150             }
3151             }
3152             if($self->{'_flagclru'}){
3153             push(@fclr, $lsfc);
3154             push(@bclr, $lsbc);
3155             }
3156             }
3157             }elsif($self->{'_flagclru'}){ # don't highlight different files
3158             for(@text){
3159             push(@fclr, 'w');
3160             push(@bclr, 'k');
3161             }
3162             }
3163             if($self->{'_vndx'} != -1){
3164             substr($bclr[$self->{'_vndx'}], 0, 1,
3165             substr( $self->{'_hibc'}, 0, 1));
3166             if($self->{'_flagclru'} && !$self->{'_flagbgho'}){ # !BkGr Hi Only
3167             substr($fclr[$self->{'_vndx'}], 0, 1, # so get foreground too
3168             substr( $self->{'_hifc'}, 0, 1));
3169             }
3170             }
3171             if($self->{'_vndx'} > ($hite - 3)){ # handle view scrolling
3172             my $vndx = $self->{'_vndx'};
3173             while($vndx-- > ($hite - 3)){
3174             push(@text, shift(@text));
3175             if($self->{'_flagclru'}) { shift(@fclr); shift(@bclr); }
3176             }
3177             $self->{'_vscr'} = ($self->{'_vndx'} - ($hite - 3));
3178             }else{
3179             $self->{'_vscr'} = 0;
3180             }
3181             }
3182             $scrl = 1 if(@text > ($hite - 2));
3183             }elsif($elem eq '_file'){
3184             $hite = 3;
3185             $yoff = $self->{'_hite'} - 2;
3186             if ($self->{'_eflz'}->{'_filt'}){ $yoff -= 3; }
3187             elsif($self->{'_eflz'}->{'_cncl'}){ $widt -= 12; }
3188             if ($self->{'_eflz'}->{'_open'}){ $widt -= 12; }
3189             $type = 'drop';
3190             $titl = 'Filename:';
3191             if(exists( $self->{'_bobj'}->{'_file'})){
3192             @text = @{$self->{'_bobj'}->{'_file'}->{'_text'}};
3193             if($self->{'_flagclru'}){
3194             @fclr = @{$self->{'_bobj'}->{'_file'}->{'_fclr'}};
3195             @bclr = @{$self->{'_bobj'}->{'_file'}->{'_bclr'}};
3196             }
3197             }
3198             if($updt || !@text){
3199             $self->{'_bobj'}->{'_file'}->{'_data'} = $self->{'_choi'};
3200             @text = ( $self->{'_choi'} );
3201             }
3202             }elsif($elem eq '_open'){
3203             $hite = 3; $widt = 12;
3204             $yoff = $self->{'_hite'} - 2;
3205             $xoff = $self->{'_widt'} - 11;
3206             if ($self->{'_eflz'}->{'_filt'}){ $yoff -= 3; }
3207             elsif($self->{'_eflz'}->{'_cncl'}){ $xoff -= 12; }
3208             $btyp = 4;
3209             $mesg = ' ' x int((10 - length($self->{'_acpt'})) / 2);
3210             $mesg .= $self->{'_acpt'}; # $mesg = ' Open ';
3211             $mesg .= ' ' x (10 - length($mesg));
3212             }elsif($elem eq '_filt'){
3213             $hite = 3;
3214             $yoff = $self->{'_hite'} - 2;
3215             if($self->{'_eflz'}->{'_cncl'}){ $widt -= 12; }
3216             $type = 'drop';
3217             $titl = 'Filter:';
3218             if(exists( $self->{'_bobj'}->{'_filt'})){
3219             @text = @{$self->{'_bobj'}->{'_filt'}->{'_text'}};
3220             if($self->{'_flagclru'}){
3221             @fclr = @{$self->{'_bobj'}->{'_filt'}->{'_fclr'}};
3222             @bclr = @{$self->{'_bobj'}->{'_filt'}->{'_bclr'}};
3223             }
3224             }else{
3225             @text = ( $self->{'_filt'}, '.*', '*.pl' );
3226             }
3227             }elsif($elem eq '_cncl'){
3228             $hite = 3; $widt = 12;
3229             $yoff = $self->{'_hite'} - 2;
3230             $xoff = $self->{'_widt'} - 11;
3231             $mesg = ' Cancel ';
3232             }
3233             if($self->{'_endx'} == $indx){
3234             $btyp = 4;
3235             $brfc = 'C';
3236             $brbc = 'u';
3237             }
3238             @text = split(/\n/, $mesg) if($mesg);
3239             if($updt && $self->{'_bobj'}->{$elem}){ # just update existing elements
3240             if($self->{'_flagclru'}){
3241             $self->{'_bobj'}->{$elem}->Draw(
3242             'hite' => $hite, 'widt' => $widt, 'yoff' => $yoff, 'xoff' => $xoff,
3243             'btyp' => $btyp, 'brfc' => $brfc, 'brbc' => $brbc,
3244             'text' => [ @text ], 'fclr' => [ @fclr ], 'bclr' => [ @bclr ],
3245             'flagscrl' => $scrl,
3246             );
3247             }else{
3248             $self->{'_bobj'}->{$elem}->Draw(
3249             'hite' => $hite, 'widt' => $widt, 'yoff' => $yoff, 'xoff' => $xoff,
3250             'btyp' => $btyp, 'brfc' => $brfc, 'brbc' => $brbc,
3251             'text' => [ @text ], 'flagscrl' => $scrl,
3252             );
3253             }
3254             }else{
3255             if ($type eq 'butn'){ # create respective elements
3256             if($self->{'_flagclru'}){
3257             $self->{'_bobj'}->{$elem} = $self->Mesg(
3258             'hite' => $hite, 'widt' => $widt,
3259             'yoff' => $yoff, 'xoff' => $xoff,
3260             'type' => $type, 'titl' => $titl,
3261             'btyp' => $btyp, 'brfc' => $brfc, 'brbc' => $brbc,
3262             'text' => [ @text ], 'fclr' => [ @fclr ], 'bclr' => [ @bclr ],
3263             'elmo' => 'brws', 'flagscrl' => $scrl,
3264             );
3265             }else{
3266             $self->{'_bobj'}->{$elem} = $self->Mesg(
3267             'hite' => $hite, 'widt' => $widt,
3268             'yoff' => $yoff, 'xoff' => $xoff,
3269             'type' => $type, 'titl' => $titl, 'btyp' => $btyp,
3270             'text' => [ @text ], 'elmo' => 'brws', 'flagscrl' => $scrl,
3271             );
3272             }
3273             }elsif($type eq 'drop'){
3274             if($self->{'_flagclru'}){
3275             $self->{'_bobj'}->{$elem} = $self->Prmt(
3276             'hite' => $hite, 'widt' => $widt,
3277             'yoff' => $yoff, 'xoff' => $xoff,
3278             'type' => $type, 'titl' => $titl,
3279             'btyp' => $btyp, 'brfc' => $brfc, 'brbc' => $brbc,
3280             'text' => [ @text ], 'fclr' => [ @fclr ], 'bclr' => [ @bclr ],
3281             'elmo' => 'brws', 'flagscrl' => $scrl,
3282             );
3283             }else{
3284             $self->{'_bobj'}->{$elem} = $self->Prmt(
3285             'hite' => $hite, 'widt' => $widt,
3286             'yoff' => $yoff, 'xoff' => $xoff,
3287             'type' => $type, 'titl' => $titl, 'btyp' => $btyp,
3288             'text' => [ @text ], 'elmo' => 'brws', 'flagscrl' => $scrl,
3289             );
3290             }
3291             }
3292             }
3293             }else{
3294             $self->{'_eflz'}->{$elem} = undef;
3295             }
3296             }
3297             # reset object changed flags
3298             $self->{'_bobj'}->{$_}->{'_echg'} = 0 for(@{$self->{'_elem'}});
3299             }
3300             # Brws() is a special Curses::Simp object constructor which creates a
3301             # file or directory Browse Window.
3302             # If params are supplied, they must be hash key => value pairs.
3303             sub Brws{
3304             my $main = shift; my($keey, $valu); my $char; my $tchr; my $choi = '';
3305             my $self = bless({}, ref($main)); my $indx; my $done = 0;
3306             for my $attr($main->AttrNamz()){
3307             $self->{$attr} = $main->DfltValu($attr); # init defaults
3308             }
3309             # special Brws window defaults
3310             $self->{'_flagsdlk'} = 1; # get SDLKeys
3311             $self->{'_flagmaxi'} = 0; # not maximized
3312             $self->{'_flagcvis'} = 0; # don't show cursor
3313             $self->{'_flagview'} = 0; # show 0=short (1=detailed) view
3314             $self->{'_flaghide'} = 0; # don't hide .files by default
3315             $self->{'_flagquik'} = 0; # don't show quick access panel
3316             $self->{'_flagsepd'} = 0; # don't show separate directory pane
3317             $self->{'_flagflhi'} = 1; # HIghlight FiLes in browser view
3318             $self->{'_flagbgho'} = 1; # BackGround Highlight Only in view
3319             $self->{'_flagclru'} = $main->{'_flagclru'}; # inherit ColorUsed flag
3320             $self->{'_widt'} = getmaxx() - 4; # but almost full screen wide
3321             $self->{'_hite'} = getmaxy() - 4; # && high
3322             $self->{'_text'} = [ ' ' ];
3323             $self->{'_dtfc'} = 'G';
3324             $self->{'_dtbc'} = 'u';
3325             if($self->{'_flagclru'}){
3326             $self->{'_fclr'} = [ $self->{'_dtfc'} ];
3327             $self->{'_bclr'} = [ $self->{'_dtbc'} ];
3328             }
3329             $self->{'_elem'} = [ '_cnfg', '_mkdr', '_path', '_cdup', '_help', # elements
3330             '_view', '_file', '_open', '_filt', '_cncl' ];
3331             $self->{'_eflz'} = { }; $self->{'_eflz'}->{$_} = 1 for(@{$self->{'_elem'}}); # initialize element visibility flags
3332             # BareBones settings below
3333             #$self->{'_eflz'}->{$_} = 0 for('_cnfg','_mkdr','_cdup','_help','_filt');
3334             $self->{'_bobj'} = { }; # Browse Objects (elements)
3335             $self->{'_brwt'} = 'File'; # Browse type ('File' or 'Dir')
3336             $self->{'_acpt'} = 'Open'; # acceptance button text like 'Open' or 'SaveAs'
3337             $self->{'_path'} = `pwd`; # default path is the current working dir
3338             chomp($self->{'_path'});
3339             $self->{'_path'} =~ s/\/*$/\//;
3340             $self->{'_btyp'} = 1; # border type
3341             $self->{'_titl'} = ''; # gets set from Browse type below
3342             $self->{'_ttfc'} = 'G';
3343             $self->{'_ttbc'} = 'u';
3344             $self->{'_hifc'} = 'W'; # HIghlight Foreground Color
3345             $self->{'_hibc'} = 'g'; # HIghlight Background Color
3346             $self->{'_hndx'} = 0; # Highlight iNDeX
3347             $self->{'_endx'} = 6; # Element iNDeX
3348             $self->{'_vndx'} = 0; # View iNDeX (choice line)
3349             $self->{'_vscr'} = 0; # View SCRolling (to get choice line in view)
3350             $self->{'_choi'} = ''; # choice (the chosen file or dir name)
3351             $self->{'_filt'} = '*'; # glob filter
3352             for(@KMODNAMZ){ $self->{'_kmod'}->{$_} = 0; }
3353             # there were init params with no colon (classname)
3354             while(@_){
3355             ($keey, $valu)=(shift, shift);
3356             if(defined($valu)){
3357             if ($keey =~ /^_*(....)?....$/){
3358             $keey =~ s/^_*//;
3359             $self->{"_$keey"} = $valu;
3360             }else{
3361             for my $attr($self->AttrNamz()){
3362             $self->{$attr} = $valu if($attr =~ /$keey/i);
3363             }
3364             }
3365             }else{
3366             $self->{'_brwt'} = $keey;
3367             }
3368             }
3369             $self->{'_titl'} = "Open $self->{'_brwt'}:" unless($self->{'_titl'});
3370             if($self->{'_widt'} < length($self->{'_titl'}) + 4) {
3371             $self->{ '_widt'} = length($self->{'_titl'}) + 4;
3372             }
3373             $self->{'_ycrs'} = $self->{'_hndx'};
3374             $self->{'_xcrs'} = 0;
3375             $self->{'_flagshrk'} = 0 if($self->{'_hite'} && $self->{'_widt'});
3376             $self->Updt(1);
3377             $self->{'_wind'} = newwin($self->{'_hite'}, $self->{'_widt'},
3378             $self->{'_yoff'}, $self->{'_xoff'});
3379             unless(exists($self->{'_wind'}) && defined($self->{'_wind'})) {
3380             croak "!*EROR*! Curses::Simp::Brws could not create new window with hite:$self->{'_hite'}, widt:$self->{'_widt'}, yoff:$self->{'_yoff'}, xoff:$self->{'_xoff'}!\n";
3381             }
3382             $self->{'_dndx'} = @DISPSTAK; # add object to display order stack
3383             push(@DISPSTAK, \$self);
3384             $self->BildBrws(); # create all element objects
3385             while(!defined($char) || !$done){
3386             my $elem = $self->{'_elem'}->[$self->{'_endx'}];
3387             my $sobj = $self->{'_bobj'}->{$elem};
3388             if($sobj->{'_type'} eq 'drop'){
3389             $char = $sobj->Focu(); %{$self->{'_kmod'}} = %{$sobj->{'_kmod'}};
3390             $sobj->FlagCVis(0);
3391             }else{
3392             $char = $self->GetK(-1);
3393             }
3394             if ($elem eq '_path'){ $self->{'_path'} = $sobj->{'_data'};
3395             $self->{'_path'} =~ s/\/*$/\//; }
3396             elsif($elem eq '_file'){ $self->{'_choi'} = $sobj->{'_data'}; }
3397             elsif($elem eq '_filt'){ $self->{'_filt'} = $sobj->{'_data'}; }
3398             if ($char eq 'SDLK_RETURN'){
3399             if ($elem eq '_cnfg'){
3400             $self->BrwsCnfg();
3401             }elsif($elem eq '_mkdr'){
3402             my $mdir = 'New_Dir';
3403             $self->Prmt('titl' => "Make Directory: $self->{'_path'} ",
3404             'flagescx' => 1, \$mdir);
3405             if(length($mdir)){
3406             $mdir = $self->{'_path'} . $mdir unless($mdir =~ /^\//);
3407             if(-d $mdir){
3408             $self->Mesg('titl' => '!EROR! - Make Directory',
3409             "Directory: \"$mdir\" already exists!");
3410             }else{
3411             mkdir("$mdir", 0700);
3412             if(-d $mdir){
3413             $self->{'_bobj'}->{'_mkdr'}->{'_echg'} = 1;
3414             }else{
3415             $self->Mesg('titl' => '!EROR! - Make Directory',
3416             "Make directory: \"$mdir\" failed!");
3417             }
3418             }
3419             }
3420             }elsif($elem eq '_path'){
3421             $self->{'_bobj'}->{'_path'}->{'_echg'} = 1;
3422             $self->{'_endx'} = 6; # return from path jumps to file bar
3423             }elsif($elem eq '_cdup'){
3424             $self->BrwsCdUp();
3425             }elsif($elem eq '_help'){
3426             $self->BrwsHelp();
3427             }elsif($elem eq '_filt'){
3428             $self->{'_bobj'}->{'_filt'}->{'_echg'} = 1;
3429             $self->{'_endx'} = 5; # return from filt jumps to view box
3430             }else{
3431             $done = 1;
3432             }
3433             }
3434             $self->BildBrws(1);
3435             if ( $char eq 'SDLK_TAB' || # Ctrl-I == Tab
3436             ($char =~ /^SDLK_(RIGHT|DOWN)$/ && $elem =~ /^_(cnfg|mkdr|cdup|help|open|cncl)$/)){
3437             $sobj->{'_brfc'} = 'w'; $sobj->{'_brbc'} = 'k';
3438             $sobj->{'_btyp'} = $self->{'_btyp'} unless($elem eq '_open');
3439             $sobj->Draw();
3440             $self->{'_endx'}++;
3441             $self->{'_endx'} = 0 if($self->{'_endx'} == @{$self->{'_elem'}});
3442             while(!$self->{'_eflz'}->{$self->{'_elem'}->[$self->{'_endx'}]}){
3443             $self->{'_endx'}++;
3444             $self->{'_endx'} = 0 if($self->{'_endx'} == @{$self->{'_elem'}});
3445             }
3446             $elem = $self->{'_elem'}->[$self->{'_endx'}];
3447             $sobj = $self->{'_bobj'}->{$elem};
3448             $sobj->{'_brfc'} = 'C'; $sobj->{'_brbc'} = 'u';
3449             $sobj->{'_btyp'} = 4;
3450             if($elem eq '_file'){
3451             $self->{'_choi'} = $sobj->{'_data'};
3452             $sobj->{'_curs'} = length($self->{'_choi'});
3453             $sobj->{'_xcrs'} = length($self->{'_choi'});
3454             }
3455             $sobj->Draw();
3456             }elsif( $char eq 'SDLK_u' && $self->{'_kmod'}->{'KMOD_CTRL'} || # Ctrl-U ~ Shift-Tab
3457             ($char =~ /^SDLK_(LEFT|UP)$/ && $elem =~ /^_(cnfg|mkdr|cdup|help|open|cncl)$/)){
3458             $sobj->{'_brfc'} = 'w'; $sobj->{'_brbc'} = 'k';
3459             $sobj->{'_btyp'} = $self->{'_btyp'} unless($elem eq '_open');
3460             $sobj->Draw();
3461             $self->{'_endx'} = @{$self->{'_elem'}} unless($self->{'_endx'});
3462             $self->{'_endx'}--;
3463             while(!$self->{'_eflz'}->{$self->{'_elem'}->[$self->{'_endx'}]}){
3464             $self->{'_endx'} = @{$self->{'_elem'}} unless($self->{'_endx'});
3465             $self->{'_endx'}--;
3466             }
3467             $elem = $self->{'_elem'}->[$self->{'_endx'}];
3468             $sobj = $self->{'_bobj'}->{$elem};
3469             $sobj->{'_brfc'} = 'C'; $sobj->{'_brbc'} = 'u';
3470             $sobj->{'_btyp'} = 4;
3471             if($elem eq '_file'){
3472             $self->{'_choi'} = $sobj->{'_data'};
3473             $sobj->{'_curs'} = length($self->{'_choi'});
3474             $sobj->{'_xcrs'} = length($self->{'_choi'});
3475             }
3476             $sobj->Draw();
3477             }elsif($char eq 'SDLK_b' && $self->{'_kmod'}->{'KMOD_CTRL'}){ # Ctrl-B toggle view background only highlighting
3478             $self->{'_flagbgho'} ^= 1;
3479             $self->{'_bobj'}->{'_filt'}->{'_echg'} = 1;
3480             $self->BildBrws(1);
3481             }elsif($char eq 'SDLK_c' && $self->{'_kmod'}->{'KMOD_CTRL'}){ # Ctrl-C bring up configuration dialog
3482             $self->BrwsCnfg();
3483             }elsif($char eq 'SDLK_f' && $self->{'_kmod'}->{'KMOD_CTRL'}){ # Ctrl-F toggle view file highlighting
3484             $self->{'_flagflhi'} ^= 1;
3485             $self->{'_bobj'}->{'_filt'}->{'_echg'} = 1;
3486             $self->BildBrws(1);
3487             }elsif($char eq 'SDLK_h' && $self->{'_kmod'}->{'KMOD_CTRL'}){ # Ctrl-H toggle hidden file globbing
3488             $self->{'_flaghide'} ^= 1;
3489             $self->{'_bobj'}->{'_filt'}->{'_echg'} = 1;
3490             $self->BildBrws(1);
3491             }elsif($char eq 'SDLK_t' && $self->{'_kmod'}->{'KMOD_CTRL'}){ # Ctrl-T chg btyps
3492             $self->{'_btyp'}++;
3493             $self->{'_btyp'} = 0 if($self->{'_btyp'} > @BORDSETS);
3494             $self->Draw();
3495             for(@{$self->{'_elem'}}){
3496             $self->{'_bobj'}->{$_}->{'_btyp'} = $self->{'_btyp'} if($_ ne $elem);
3497             $self->{'_bobj'}->{$_}->Draw();
3498             }
3499             }elsif($char eq 'SDLK_F1'){
3500             $self->BrwsHelp();
3501             }elsif($elem eq '_view'){
3502             if ($char eq 'SDLK_UP'){
3503             if($self->{'_vndx'}){
3504             $self->{'_vndx'}--;
3505             $self->{'_choi'} = $self->{'_bobj'}->{'_view'}->{'_text'}->[ $self->{'_vndx'} ];
3506             $self->{'_bobj'}->{'_view'}->{'_echg'} = 1;
3507             $self->BildBrws(1);
3508             }
3509             }elsif($char eq 'SDLK_DOWN'){
3510             if($self->{'_vndx'} < (@{$self->{'_bobj'}->{'_view'}->{'_text'}} - 1)){
3511             $self->{'_vndx'}++;
3512             $self->{'_choi'} = $self->{'_bobj'}->{'_view'}->{'_text'}->[ $self->{'_vndx'} ];
3513             $self->{'_bobj'}->{'_view'}->{'_echg'} = 1;
3514             $self->BildBrws(1);
3515             }
3516             }elsif($char eq 'SDLK_PAGEUP'){
3517             $self->{'_vndx'} -= ($self->{'_bobj'}->{'_view'}->{'_hite'} - 3);
3518             $self->{'_vndx'} = 0 if($self->{'_vndx'} < 0);
3519             $self->{'_choi'} = $self->{'_bobj'}->{'_view'}->{'_text'}->[ $self->{'_vndx'} ];
3520             $self->{'_bobj'}->{'_view'}->{'_echg'} = 1;
3521             $self->BildBrws(1);
3522             }elsif($char eq 'SDLK_PAGEDOWN'){
3523             $self->{'_vndx'} += ($self->{'_bobj'}->{'_view'}->{'_hite'} - 3);
3524             $self->{'_vndx'} = (@{$self->{'_bobj'}->{'_view'}->{'_text'}} - 1)
3525             if($self->{'_vndx'} >= @{$self->{'_bobj'}->{'_view'}->{'_text'}});
3526             $self->{'_choi'} = $self->{'_bobj'}->{'_view'}->{'_text'}->[ $self->{'_vndx'} ];
3527             $self->{'_bobj'}->{'_view'}->{'_echg'} = 1;
3528             $self->BildBrws(1);
3529             }elsif($char eq 'SDLK_LEFT'){
3530             $self->BrwsCdUp();
3531             $self->BildBrws(1);
3532             }elsif($char eq 'SDLK_RIGHT'){
3533             $choi = $self->{'_path'} . $self->{'_choi'};
3534             if(-d $choi){
3535             $choi =~ s/^(.*\/)([^\/]+\/)\.\.\/$/$1/; # handle cd..
3536             $self->{'_path'} = $choi;
3537             $self->{'_bobj'}->{'_path'}->{'_text'}->[
3538             ($self->{'_bobj'}->{'_path'}->{'_lndx'} + 1) ] = $self->{'_path'};
3539             $self->{'_bobj'}->{'_path'}->{'_dtxt'} = $self->{'_path'};
3540             $self->{'_bobj'}->{'_path'}->{'_data'} = $self->{'_path'};
3541             $self->{'_bobj'}->{'_path'}->{'_text'}->[0] = $self->{'_path'};
3542             $self->{'_bobj'}->{'_path'}->{'_curs'} = length($self->{'_path'});
3543             $self->{'_bobj'}->{'_path'}->{'_xcrs'} = length($self->{'_path'});
3544             $self->{'_bobj'}->{'_path'}->{'_echg'} = 1;
3545             $self->BildBrws(1);
3546             }
3547             }
3548             }
3549             if($done){ # clean up && save local choice so all objects can be destroyed
3550             if ($elem eq '_cncl'){ $choi = '-1'; }
3551             else { $choi = $self->{'_path'} . $self->{'_choi'};}
3552             if($self->{'_brwt'} eq 'File' && -d $choi){
3553             $choi =~ s/^(.*\/)([^\/]+\/)\.\.\/$/$1/; # handle cd..
3554             $self->{'_path'} = $choi;
3555             $self->{'_bobj'}->{'_path'}->{'_text'}->[
3556             ($self->{'_bobj'}->{'_path'}->{'_lndx'} + 1) ] = $self->{'_path'};
3557             $self->{'_bobj'}->{'_path'}->{'_dtxt'} = $self->{'_path'};
3558             $self->{'_bobj'}->{'_path'}->{'_data'} = $self->{'_path'};
3559             $self->{'_bobj'}->{'_path'}->{'_text'}->[0] = $self->{'_path'};
3560             $self->{'_bobj'}->{'_path'}->{'_curs'} = length($self->{'_path'});
3561             $self->{'_bobj'}->{'_path'}->{'_xcrs'} = length($self->{'_path'});
3562             $self->{'_bobj'}->{'_path'}->{'_echg'} = 1;
3563             $self->BildBrws(1);
3564             $done = 0; # don't accept directory when choosing file
3565             }
3566             }
3567             }
3568             $self->DelW(); # Delete Brws Window && all element windows
3569             $main->ShokScrn(2); # redraw all old stuff
3570             $main->FlagCVis(); # reset cursor visibility to calling object state
3571             return($choi); # return choice (file or dir name)
3572             }
3573             sub DESTROY{
3574             my $self = shift || return(); my $dndx = $self->{'_dndx'};
3575             my $shok = 1;
3576             $shok = 0 if(exists($self->{'_type'}) && length($self->{'_type'}));
3577             if($self->{'_wind'}){
3578             delwin($self->{'_wind'});
3579             for(++$dndx;$dndx<@DISPSTAK;$dndx++){
3580             if($DISPSTAK[$dndx] && exists(${$DISPSTAK[$dndx]}->{'_dndx'})){
3581             ${$DISPSTAK[$dndx]}->{'_dndx'}--;
3582             }
3583             }
3584             #remove deleted from displaystack
3585             splice(@DISPSTAK, $self->{'_dndx'}, 1) if($self->{'_dndx'} < @DISPSTAK);
3586             $self->ShokScrn(2) if($shok);
3587             }
3588             }
3589             # VERBOSE METHOD NAME ALIASES
3590             *AttributeNames = \&AttrNamz;
3591             *DefaultValues = \&DfltValu;
3592             *MakeMethods = \&MkMethdz;
3593             *InitializeColorPair = \&InitPair;
3594             *PrintBorderCharacter = \&BordChar;
3595             *ConvertAnsiColorCode = \&CnvAnsCC;
3596             *ShockScreen = \&ShokScrn;
3597             *KeyNumbers = \&KNum;
3598             *ColorLetters = \&CLet;
3599             *NumColors = \&NumC;
3600             *Height = \&Hite;
3601             *Width = \&Widt;
3602             *PrintString = \&Prnt;
3603             *DrawWindow = \&Draw;
3604             *WaitTime = \&Wait;
3605             *GetKey = \&GetK;
3606             *GetString = \&GetS;
3607             *MoveCursor = \&Move;
3608             *ResizeWindow = \&Rsiz;
3609             *UpdateWindow = \&Updt;
3610             *MessageWindow = \&Mesg;
3611             *PromptWindow = \&Prmt;
3612             *FocusWindow = \&Focu;
3613             *ColorPickWindow = \&CPik;
3614             *BrowseWindow = \&Brws;
3615             *DeleteWindow = \&DelW;
3616             *DelW = \&DESTROY;
3617             # allow color arrays to be tied too
3618             package Curses::Simp::FClr;
3619             sub TIEARRAY { # bless an anon array with just parent in case more to store
3620             my $clas = shift;my $prnt = shift;
3621             # carp("!*EROR*! Need additional Parent object reference parameter to tie $clas to!\n") unless(defined($prnt) && ref($prnt) eq 'Curses::Simp');
3622             exit unless(defined($prnt) && ref($prnt) eq 'Curses::Simp');
3623             my $self = bless([$prnt], $clas);
3624             $prnt->{'_flagclru'} = 1;
3625             return($self);
3626             }
3627             sub FETCH { return( $_[0]->[0]->{'_fclr'}->[$_[1]]); }
3628             sub FETCHSIZE{ return(scalar(@{$_[0]->[0]->{'_fclr'}}) ); }
3629             sub STORE {
3630             $_[0]->[0]->{'_fclr'}->[$_[1]] = $_[2];
3631             $_[0]->[0]->Curses::Simp::TestDraw() if($_[0]->[0]->{'_flagadtf'});
3632             }
3633             sub STORESIZE{
3634             splice(@{$_[0]->[0]->{'_fclr'}}, $_[1], @{$_[0]->[0]->{'_fclr'}} - $_[1]);
3635             $_[0]->[0]->Curses::Simp::TestDraw() if($_[0]->[0]->{'_flagadtf'});
3636             }
3637             sub EXISTS { return(0) unless(defined($_[0]->[0]->{'_fclr'}->[$_[1]])); return(1); }
3638             sub CLEAR { @{$_[0]->[0]->{'_fclr'}} = (); $_[0]->[0]->Curses::Simp::TestDraw() if($_[0]->[0]->{'_flagadtf'}); }
3639             sub PUSH { push(@{$_[0]->[0]->{'_fclr'}}, $_[1]); $_[0]->[0]->Curses::Simp::TestDraw() if($_[0]->[0]->{'_flagadtf'}); }
3640             sub POP { $_ = pop(@{$_[0]->[0]->{'_fclr'}}); $_[0]->[0]->Curses::Simp::TestDraw() if($_[0]->[0]->{'_flagadtf'}); return($_); }
3641             sub SHIFT { $_ = shift(@{$_[0]->[0]->{'_fclr'}}); $_[0]->[0]->Curses::Simp::TestDraw() if($_[0]->[0]->{'_flagadtf'}); return($_); }
3642             sub UNSHIFT { unshift(@{$_[0]->[0]->{'_fclr'}}, $_[1]); $_[0]->[0]->Curses::Simp::TestDraw() if($_[0]->[0]->{'_flagadtf'}); }
3643             sub SPLICE {
3644             # $_ = splice(@{$_[0]->[0]->{'_fclr'}}, @_[1..$#_]); $_[0]->[0]->Curses::Simp::TestDraw() if($_[0]->[0]->{'_flagadtf'}); return($_); }
3645             my $self = shift;
3646             my $offs = shift || 0;
3647             my $leng = shift; $leng = $self->[0]->FETCHSIZE() - $offs unless(defined($leng));
3648             my $retn = splice(@{$self->[0]->{'_fclr'}}, $offs, $leng, @_);
3649             $self->[0]->Curses::Simp::TestDraw() if($self->[0]->{'_flagadtb'});
3650             return($retn);
3651             }
3652             sub EXTEND { }
3653             package Curses::Simp::BClr;
3654             sub TIEARRAY {
3655             my $clas = shift; my $prnt = shift;
3656             # carp("!*EROR*! Need additional Parent object reference parameter to tie $clas to!\n") unless(defined($prnt) && ref($prnt) eq 'Curses::Simp');
3657             exit unless(defined($prnt) && ref($prnt) eq 'Curses::Simp');
3658             my $self = bless([$prnt], $clas);
3659             $prnt->{'_flagclru'} = 1;
3660             return($self);
3661             }
3662             sub FETCH { return( $_[0]->[0]->{'_bclr'}->[$_[1]]); }
3663             sub FETCHSIZE{ return(scalar(@{$_[0]->[0]->{'_bclr'}}) ); }
3664             sub STORE {
3665             $_[0]->[0]->{'_bclr'}->[$_[1]] = $_[2];
3666             $_[0]->[0]->Curses::Simp::TestDraw() if($_[0]->[0]->{'_flagadtb'});
3667             }
3668             sub STORESIZE{
3669             splice(@{$_[0]->[0]->{'_bclr'}}, $_[1], @{$_[0]->[0]->{'_bclr'}} - $_[1]);
3670             $_[0]->[0]->Curses::Simp::TestDraw() if($_[0]->[0]->{'_flagadtb'});
3671             }
3672             sub EXISTS { return(0) unless(defined($_[0]->[0]->{'_bclr'}->[$_[1]])); return(1); }
3673             sub CLEAR { @{$_[0]->[0]->{'_bclr'}} = (); $_[0]->[0]->Curses::Simp::TestDraw() if($_[0]->[0]->{'_flagadtb'}); }
3674             sub PUSH { push(@{$_[0]->[0]->{'_bclr'}}, $_[1]); $_[0]->[0]->Curses::Simp::TestDraw() if($_[0]->[0]->{'_flagadtb'}); }
3675             sub POP { $_ = pop(@{$_[0]->[0]->{'_bclr'}}); $_[0]->[0]->Curses::Simp::TestDraw() if($_[0]->[0]->{'_flagadtb'}); return($_); }
3676             sub SHIFT { $_ = shift(@{$_[0]->[0]->{'_bclr'}}); $_[0]->[0]->Curses::Simp::TestDraw() if($_[0]->[0]->{'_flagadtb'}); return($_); }
3677             sub UNSHIFT { unshift(@{$_[0]->[0]->{'_bclr'}}, $_[1]); $_[0]->[0]->Curses::Simp::TestDraw() if($_[0]->[0]->{'_flagadtb'}); }
3678             sub SPLICE {
3679             # $_ = splice(@{$_[0]->[0]->{'_bclr'}}, @_[1..$#_]); $_[0]->[0]->Curses::Simp::TestDraw() if($_[0]->[0]->{'_flagadtf'}); return($_); }
3680             my $self = shift;
3681             my $offs = shift || 0;
3682             my $leng = shift; $leng = $self->[0]->FETCHSIZE() - $offs unless(defined($leng));
3683             my $retn = splice(@{$self->[0]->{'_bclr'}}, $offs, $leng, @_);
3684             $self->[0]->Curses::Simp::TestDraw() if($self->[0]->{'_flagadtb'});
3685             return($retn);
3686             }
3687             sub EXTEND { }
3688             127;
3689             =head1 NAME
3690              
3691             Curses::Simp - Curses Not Quite Simple
3692              
3693             =head1 VERSION
3694              
3695             This documentation refers to version 1.4.A8UG1gG of
3696             Curses::Simp, which was released on Mon Aug 30 16:01:42:16 2010.
3697              
3698             =head1 SYNOPSIS
3699              
3700             use Curses::Simp;
3701             my @text; my $keey = '';
3702             my $simp = tie(@text, 'Curses::Simp');
3703             @text =('1337', 'nachoz', 'w/', 'cheese' x 7);
3704             while($keey ne 'x'){ # wait for 'x' to eXit
3705             $keey = $simp->GetKey(-1); # get a blocking keypress
3706             push(@text, $keey);
3707             }
3708              
3709             =head1 DESCRIPTION
3710              
3711             Curses::Simp provides a curt mechanism for updating a console screen
3712             with any Perl array (or multiple arrays to include color codes).
3713             Most key events can be obtained and tested directly. The goal
3714             was ease-of-use for the common cases first and efficient
3715             rendering second.
3716              
3717             =head1 2DU
3718              
3719             =over 2
3720              
3721             =item - mk proper scrollbars for all objects && use in Brws: view
3722              
3723             =item - Brws: mk togl to pack files left && right in view
3724              
3725             =item - mk ~/.simprc to save CPik && Brws cfg, OVERMAPP, etc.
3726              
3727             =item - CPik: rewrite BildBlox to scale style to window dims if !flagshrk
3728             && mk sure no forg or bakg works for all styles... also add
3729             options for only name or number options or common grid size defaults
3730              
3731             =item - CPik: add styles to pick fgcl,bgcl color code at once
3732              
3733             =item - 4NT: work on recognizing more keys the same as Curses (&& then SDL)
3734              
3735             =item - 4NT: write custom window support? mk Mesg at least wrap MSGBOX
3736              
3737             =item - describe Simp objects sharing apps (ptok above pmix)
3738             mk OScr read Simp apps @_ param list && auto-handle --geom wxh+x+y
3739              
3740             =item - Prmt: mk new 'cbls' type: as a ckbx list && use in BrwsCnfg
3741              
3742             =item - Prmt: mk new 'rdls' type: as a radio list w/ auto (*) -
3743              
3744             =item - Mesg: mk new 'slid' type: params for all overlay text, chars, ticks,
3745             flags, etc. && updt pmix to use... maybe register sub fields,dims...
3746              
3747             =item - Prnt: add multi-line option where text can split on /\n/ but each new
3748             line prints relative to starting xcrs
3749              
3750             =item - Prmt: add multi-line option where dtxt can split on /\n/ && ^d
3751             accepts entry instead of RETURN
3752              
3753             =item - Prnt: handle ASCII chars under 32 with escapes like Draw
3754              
3755             =item - Draw: optimize rendering
3756              
3757             =item - Prnt&&Draw: handle ASCII chars under 32 better than current escapes
3758              
3759             =item - mk 'ceol' && 'ceos' params to clear text[n] from cursor on
3760              
3761             =item - consider breaking sub (CPik|Brws|.+?) into own Curses::Simp::$1.pm
3762             instead of letting Simp.pm remain so cluttered
3763              
3764             =back
3765              
3766             if detectable:
3767              
3768             =over 4
3769              
3770             =item - handle xterm resize events
3771              
3772             =item - handle mouse input (study any existent Curses apps that use mouse
3773             input you can find ... probably in C), read man for gpm(1),
3774             sysmouse(4), && sb(4) && study aumix mouse source
3775              
3776             =item - Learn how to read a Shift-Tab key press if in any way
3777             distinguishable from Tab/Ctrl-I
3778              
3779             =item - What else does Simp need?
3780              
3781             =back
3782              
3783             =head1 WHY?
3784              
3785             Curses::Simp was created because I could hardly find documentation or
3786             examples of L usage so I fiddled until I could wrap the
3787             most important behaviors in names and enhanced functions.
3788              
3789             =head1 USAGE
3790              
3791             B - Curses::Simp object constructor
3792              
3793             new() opens a new Curses screen if one does not exist already and
3794             initializes useful default screen, color, and keys settings. The
3795             created Curses screen is automatically closed on program exit.
3796              
3797             Available object methods are described in detail below. Each of
3798             the following four letter abbreviated or verbose method names
3799             can be used as initialization parameters to new():
3800              
3801             Key or VerboseName => Default Value
3802             ----- ------------- ---------------
3803             'text' or 'TextData' => [ ]
3804             'fclr' or 'ForegroundColorData' => [ ]
3805             'bclr' or 'BackgroundColorData' => [ ]
3806             'kque' or 'KeyQueue' => [ ]
3807             'mque' or 'KeyModQueue' => [ ]
3808             'hite' or 'WindowHeight' => 0
3809             'widt' or 'WindowWidth' => 0
3810             'yoff' or 'WindowYOffset' => 0
3811             'xoff' or 'WindowXOffset' => 0
3812             'ycrs' or 'CursorYOffset' => 0
3813             'xcrs' or 'CursorXOffset' => 0
3814             'btyp' or 'WindowBorderType' => 0
3815             'brfc' or 'WindowBorderForegroundColor'=> 'w'
3816             'brbc' or 'WindowBorderBackgroundColor'=> 'k'
3817             'titl' or 'WindowTitle' => ''
3818             'ttfc' or 'WindowTitleForegroundColor' => 'W'
3819             'ttbc' or 'WindowTitleBackgroundColor' => 'k'
3820             'dndx' or 'DisplayStackIndex' => 0
3821             'flagaudr' or 'FlagAutoDraw' => 1
3822             'flagadtf' or 'FlagAutoDrawTiedForegroundData' => 1
3823             'flagadtb' or 'FlagAutoDrawTiedBackgroundData' => 1
3824             'flagmaxi' or 'FlagMaximize' => 1
3825             'flagshrk' or 'FlagShrinkToFit' => 1
3826             'flagcntr' or 'FlagCenter' => 1
3827             'flagcvis' or 'FlagCursorVisible' => 0
3828             'flagscrl' or 'FlagScrollbar' => 0
3829             'flagsdlk' or 'FlagSDLKey' => 0
3830             'flagfram' or 'FlagTimeFrame' => 0
3831             'flagmili' or 'FlagMillisecond' => 0
3832             'flagprin' or 'FlagPrintInto' => 1
3833             'flagclru' or 'FlagColorUsed' => 0
3834              
3835             An example of setting and updating 'WindowHeight':
3836              
3837             use Curses::Simp;
3838             my $simp = Curses::Simp->new( 'WindowHeight' => 7 ); # set
3839             $simp->WindowHeight( 15 ); # update
3840              
3841             See the individual sections in the L<"ACCESSOR AND FLAG METHODS">
3842             heading for more information on how to manipulate created
3843             Curses::Simp objects.
3844              
3845             Most other Curses::Simp methods also accept hash key => value pairs as
3846             parameters which loads the object fields the same way new() does
3847             before performing their operation. This gives you the ability to
3848             update many Simp fields with a call to any particular
3849             accessor method. The method name just designates where the lone
3850             value will be assigned and which field will be returned.
3851              
3852             =head2 Tied Array Interfaces
3853              
3854             Curses::Simp now supports tied array interfaces as the new preferred
3855             object construction mechanism (instead of new()). This allows
3856             more natural manipulation of screen data (i.e., both text and colors)
3857             through all of the familiar operations that can be performed on
3858             standard Perl arrays. A basic example for just text can be found in
3859             the L<"SYNOPSIS"> above.
3860              
3861             Since it's not a straightforward process to tie multiple arrays
3862             to different components of the same object (which seemed desirable
3863             for printing colors), here is an example of how it can be done:
3864              
3865             use Curses::Simp;
3866             my $keey = ''; my @text; my @fclr; my @bclr;
3867             my $simp = tie(@text, 'Curses::Simp');
3868             tie(@fclr, 'Curses::Simp::FClr', $simp);
3869             tie(@bclr, 'Curses::Simp::BClr', $simp);
3870             @text = ( '1337', 'nachoz', 'w/', 'cheese' x 7); $simp->GetK(1);
3871             push(@fclr, 'GBRG' ); $simp->GetK(1);
3872             push(@fclr, 'YWOPCY' ); $simp->GetK(1);
3873             push(@fclr, 'wK' ); $simp->GetK(1);
3874             push(@fclr, 'P' ); $simp->GetK(1);
3875             push(@bclr, 'r' ); $simp->GetK(1);
3876             push(@bclr, 'g' ); $simp->GetK(1);
3877             push(@bclr, 'c' ); $simp->GetK(1);
3878             push(@bclr, 'b' ); $simp->GetK(1);
3879              
3880             Notice the three tie() lines near the top. The second and third must
3881             provide the third parameter of the object which they also want to tie
3882             to. If this is not provided, the program will exit.
3883              
3884             The result of all this is an extremely simple way to immediately
3885             manipulate any of the text or colors displayed on the console screen.
3886              
3887             =head2 CnvAnsCC or ConvertAnsiColorCode( $AnsiColorCode )
3888              
3889             Returns the Simp form of the ANSI color code
3890             $AnsiColorCode.
3891              
3892             $AnsiColorCode may contain any of the typical ANSI attribute or
3893             color codes:
3894              
3895             Attribute codes:
3896             00=none 01=bold 04=underscore 05=blink 07=reverse 08=concealed
3897             Foreground color codes:
3898             30=black 31=red 32=green 33=yellow 34=blue 35=magenta 36=cyan 37=white
3899             Background color codes:
3900             40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white
3901              
3902             ConvertAnsiColorCode() is primarily useful as an internal function
3903             to the Curses::Simp package but I have exposed it because it could
3904             be useful elsewhere.
3905              
3906             =head2 ShokScrn or ShockScreen( [$FlagClear] )
3907              
3908             ShockScreen() forces the screen and all created Simp objects
3909             to be refreshed in order.
3910              
3911             The $FlagClear (default is false) can be provided to specify that
3912             the entire screen is to be cleared before everything refreshes.
3913             Clearing the entire screen usually isn't necessary and it slows drawing
3914             down.
3915              
3916             =head2 KNum or KeyNumbers()
3917              
3918             Returns a hash with key numbers => "names".
3919              
3920             =head2 CLet or ColorLetters()
3921              
3922             Returns a hash with color "letters" => numbers.
3923              
3924             =head2 NumC or NumColors()
3925              
3926             Returns the number of available colors
3927             (last index: NumC() - 1)
3928              
3929             =head2 Hite or Height
3930              
3931             Returns the current Simp object's window height
3932             (last index: Height() - 1)
3933              
3934             =head2 Widt or Width
3935              
3936             Returns the current Simp object's window width
3937             (last index: Width() - 1)
3938              
3939             =head2 Prnt or PrintString( $String )
3940              
3941             Prints $String at current cursor position. PrintString() can also accept
3942             a hash of parameters (e.g., PrintString('text' => $String)) where:
3943              
3944             'text' => [ "String to Print" ], # or can just be string without arrayref
3945             'fclr' => [ "ForegroundColorCodes corresponding to text" ],
3946             'bclr' => [ "BackgroundColorCodes corresponding to text" ],
3947             'ycrs' => 3, # Number to move the cursor's y to before printing
3948             'xcrs' => 7, # Number to move the cursor's x to before printing
3949             'yoff' => 15, # same as ycrs except original ycrs is restored afterwards
3950             'xoff' => 31, # same as xcrs except original xcrs is restored afterwards
3951             'prin' => 1, # flag to specify whether printed text should update the
3952             # main Text(), FClr(), and BClr() data or just print to the
3953             # screen temporarily. Default is true (i.e., Print Into all)
3954              
3955             The hash keys can also be the corresponding VerboseNames described in the
3956             new() section instead of these 4-letter abbreviated key names.
3957              
3958             PrintString() returns the number of characters printed.
3959              
3960             =head2 Draw or DrawWindow()
3961              
3962             Draws the current Simp object with the established TextData() and
3963             ColorData() functions.
3964              
3965             DrawWindow() accepts a hash of parameters like new() which will update
3966             as many attributes of the Simp object as are specified by key => value
3967             pairs.
3968              
3969             DrawWindow() returns the number of lines printed (which is normally the
3970             same as Height()).
3971              
3972             =head2 Wait or WaitTime( $Time )
3973              
3974             WaitTime() does nothing for $Time seconds.
3975              
3976             $Time can be an integer or floating point number of seconds.
3977             (e.g., WaitTime(1.27) does nothing for just over one second).
3978              
3979             WaitTime() (like GetKey()) can also use alternate waiting methods.
3980             The default $Time format is integer or floating seconds. It can
3981             also be a Time::Frame object or an integer of milliseconds.
3982             These modes can be set with the FlagTimeFrame(1) and
3983             FlagMillisecond(1) methods respectively.
3984              
3985             =head2 GetK or GetKey( [$Timeout [,$FlagSDLKey]] )
3986              
3987             Returns a keypress if one is made or -1 after waiting $Timeout seconds.
3988              
3989             $Timeout can be an integer or floating point number of seconds.
3990             (e.g., GetKey(2.55) waits for two and one-half seconds before returning -1
3991             if no key was pressed).
3992              
3993             Default behavior is to not block (i.e., GetKey(0)). Use GetKey(-1) for a
3994             blocking keypress (i.e., to wait indefinitely).
3995              
3996             GetKey() can use alternate waiting methods. The default is integer or
3997             floating seconds. It can also utilize L objects
3998             or integer milliseconds if preferred. These modes can be set with
3999             the FlagTimeFrame(1) and FlagMillisecond(1) methods respectively.
4000              
4001             Under normal mode (i.e., when $FlagSDLKey is absent or false), GetKey()
4002             returns a string describing the key pressed. This will either be a
4003             single character or the Curses name for the key if a special key was
4004             pressed. The list of special key names that can be returned from
4005             normal mode are described in the L<"CURSES KEY NOTES"> section. This
4006             means that the return value should be easy to test directly like:
4007              
4008             use Curses::Simp;
4009             my $simp = Curses::Simp->new();
4010             my $key = $simp->GetKey(-1); # get a blocking keypress
4011             if ( $key eq 'a' ) { # do 'a' stuff
4012             } elsif( $key eq 'b' ) { # do 'b' stuff
4013             } elsif( $key eq 'A' ) { # do 'A' stuff
4014             } elsif( $key eq 'B' ) { # do 'B' stuff
4015             } elsif( $key eq 'KEY_LEFT' ) { # do Left-Arrow-Key stuff
4016             } elsif( $key eq 'KEY_NPAGE') { # do PageDown stuff
4017             } elsif( $key eq 'KEY_F1' ) { # do F1 (Help) stuff
4018             } elsif(ord($key) == 9 ) { # do Tab stuff
4019             } elsif(ord($key) == 13 ) { # do Return stuff
4020             } elsif(ord($key) == 27 ) { # do Escape stuff
4021             }
4022              
4023             $FlagSDLKey is a flag (default is false) which tells GetKey() to return
4024             a verbose key string name from the list of SDLKeys in the L<"SDLKEY NOTES">
4025             section instead of the normal Curses key value or name. In SDLKey mode,
4026             GetKey() also sets flags for Shift, Control, and Alt keys which are
4027             testable through KeyMode().
4028              
4029             The $FlagSDLKey parameter sets SDLKey mode temporarily (i.e., only for a
4030             single execution of GetKey()). This mode can be turned on permanently
4031             via the FlagSDLKey(1) function.
4032              
4033             If the $Timeout for GetKey() is reached and no keypress has
4034             occurred (in either normal mode or SDLKey mode), -1 is returned.
4035              
4036             =head2 KMod or KeyMode( [$KeyName [,$NewValue]] )
4037              
4038             Returns the key mode (state) of the key mode name $KeyName. $KeyName
4039             should be one of the KMOD_ names from the bottom of the L<"SDLKEY NOTES">
4040             section.
4041              
4042             If no parameters are provided, the state of KMOD_NONE is returned.
4043              
4044             If $NewValue is provided, the state of $KeyName is set to $NewValue.
4045              
4046             =head2 GetS or GetString( [$YCursor, $XCursor[, $ResultLength]] )
4047              
4048             GetString() returns the string found from the cursor (or the specified
4049             coordinates) on to the end-of-line or to $ResultLength if provided.
4050              
4051             =head2 Move or MoveCursor( [$YCursor, $XCursor] )
4052              
4053             MoveCursor() updates the current Simp object's cursor position
4054             to the newly specified $YCursor, $XCursor.
4055              
4056             By default, the cursor is not visible but this can be changed through
4057             the FlagCursorVisible(1) function.
4058              
4059             Returns ($YCursor, $XCursor) as the coordinates of the cursor.
4060              
4061             =head2 Rsiz or ResizeWindow( $Height, $Width )
4062              
4063             ResizeWindow() updates the current Simp object's window dimensions
4064             to the newly specified $Height, $Width.
4065              
4066             Think of ResizeWindow() as an easy way to call both Height() and
4067             Width() at once.
4068              
4069             Returns ($Height, $Width) as the dimensions of the window.
4070              
4071             =head2 Mesg or MessageWindow( $Message )
4072              
4073             MessageWindow() draws a Message Window in the center of the screen to
4074             display $Message. MessageWindow() can also accept a hash of parameters
4075             (e.g., MessageWindow('mesg' => $Message)) where:
4076              
4077             'mesg' => "Message to Print",
4078             'text' => [ "same as new \@text" ],
4079             'fclr' => [ "ForegroundColorCodes corresponding to mesg or text" ],
4080             'bclr' => [ "BackgroundColorCodes corresponding to mesg or text" ],
4081             'titl' => "MessageWindow Title string",
4082             'ttfc' => "ColorCodes corresponding to titl foreground color",
4083             'ttbc' => "ColorCodes corresponding to titl background color",
4084             'flagprsk' => 1, # a flag specifying whether to "Press A Key"
4085             'pres' => "Press A Key...", # string to append if flagprsk is true
4086             'prfc' => "ColorCodes corresponding to pres foreground color",
4087             'prbc' => "ColorCodes corresponding to pres background color",
4088             'wait' => 1.0, # floating number of seconds to wait
4089             # if flagprsk is true, MessageWindow() waits this
4090             # long for a keypress before quitting
4091             # if flagprsk is false, MessageWindow() waits this
4092             # long regardless of whether keys are pressed
4093              
4094             The hash keys can also be the corresponding VerboseNames described in the
4095             new() section instead of these 4-letter abbreviated key names.
4096              
4097             Returns the value of the pressed key (if the "Press A Key" flag was true).
4098             This can be used to make simple one-character prompt windows. For example:
4099              
4100             use Curses::Simp;
4101             my $simp = Curses::Simp->new();
4102             my $answer = $simp->MessageWindow('titl' => 'Is Simp useful?',
4103             'pres' => '(Yes/No)');
4104             $simp->MessageWindow('titl' => 'Answer:', $answer);
4105              
4106             =head2 Prmt or PromptWindow( \$DefaultRef )
4107              
4108             PromptWindow() draws a Prompt Window in the center of the screen to
4109             display and update the value of $DefaultRef. \$DefaultRef should be
4110             a reference to a variable containing a string you want edited or
4111             replaced. PromptWindow() can also accept a hash of parameters
4112             (e.g., PromptWindow('dref' => \$DefaultRef)) where:
4113              
4114             'dref' => \$dref, # Default Reference to variable to be read && edited
4115             'dtxt' => "Default Text string in place of dref",
4116             'dtfc' => "ColorCodes corresponding to dref/dtxt foreground color",
4117             'dtbc' => "ColorCodes corresponding to dref/dtxt background color",
4118             'hifc' => "ColorCodes for highlighted (unedited) dref/dtxt foreground color",
4119             'hibc' => "ColorCodes for highlighted (unedited) dref/dtxt background color",
4120             'text' => [ "same as new \@text" ],
4121             'fclr' => [ "ForegroundColorCodes corresponding to text" ],
4122             'bclr' => [ "BackgroundColorCodes corresponding to text" ],
4123             'hite' => 3, # height of the prompt window (including borders)
4124             'widt' => 63, # width of the prompt window (including borders)
4125             'titl' => "PromptWindow Title string",
4126             'ttfc' => "ColorCodes corresponding to titl foreground color",
4127             'ttbc' => "ColorCodes corresponding to titl background color",
4128             'flagcvis' => 1, # a flag specifying whether the cursor should be displayed
4129              
4130             The hash keys can also be the corresponding VerboseNames described in the
4131             new() section instead of these 4-letter abbreviated key names.
4132              
4133             =head2 CPik or ColorPickWindow()
4134              
4135             ColorPickWindow() is a simple Color Picker window.
4136              
4137             It accepts arrow keys to highlight a particular color and enter to select.
4138             The letter corresponding to the color or the number of the index can also
4139             be pressed instead.
4140              
4141             Returns the letter (i.e., Color Code) of the picked color.
4142              
4143             =head2 Brws or BrowseWindow()
4144              
4145             BrowseWindow() is a simple file browser.
4146              
4147             It contains typical file browse dialog components which can be tabbed
4148             between. The tilde (~) character opens and closes drop down boxes.
4149             Enter presses highlighted buttons or selects a highlighted file.
4150             F1 brings up the BrowseWindow() help text.
4151              
4152             Returns the full filename chosen or -1 if dialog was canceled.
4153              
4154             =head2 DESTROY or DelW or DeleteWindow()
4155              
4156             DeleteWindow() deletes all the components of the created Simp object
4157             and calls ShockScreen() to cause the screen and all other created
4158             objects to be redrawn.
4159              
4160             =head1 ACCESSOR AND FLAG METHODS
4161              
4162             Simp accessor and flag object methods have related interfaces as they
4163             each access and update a single component field of Curses::Simp objects. Each
4164             one always returns the value of the field they access. Thus if you want
4165             to obtain a certain value from a Simp object, just call the accessor
4166             method with no parameters. If you provide parameters, the field will
4167             be updated and will return its new value.
4168              
4169             All of these methods accept a default parameter of their own type or
4170             a hash of operations to perform on their field.
4171              
4172             Some operations are only applicable to a subset of the methods as
4173             dictated by the field type. The available operations are:
4174              
4175             Key => Value Type
4176             NormalName (if different) ... # Purpose
4177             ----- ------------
4178             'asin' => $scalar (number|string|arrayref)
4179             'assign' # asin is context-sensitive assignment to load the field
4180             'blnk' => $ignored # blanks a string value
4181             'blank'
4182             'togl' => $ignored # toggles a flag value
4183             'toggle'
4184             'true' => $ignored # trues a flag value
4185             'fals' => $ignored # falsifies a flag value
4186             'false'
4187             'incr' => $numeric_amount
4188             'increase' # increments if no $num is provided or increases by $num
4189             'decr' => $numeric_amount
4190             'decrease' # decrements if no $num is provided or decreases by $num
4191             'nmrc' => $string
4192             'numeric'
4193             # instead of an explicit 'nmrc' hash key, this means the
4194             # key is an entirely numeric string like '1023'
4195             # so the value gets assigned to that indexed element when
4196             # the field is an array. The key is assigned directly if
4197             # the field is numeric or a string.
4198             # Array-Specific operations:
4199             'size' => $ignored # return the array size
4200             'push' => $scalar (number|string) # push new value
4201             'popp' => $ignored # pop last value
4202             'pop'
4203             'apnd' => $scalar (number|string) # append to last element
4204             'append'
4205             'dupl' => $number # duplicate last line or
4206             'duplicate' # $num line if provided
4207             'data' => $arrayref # assigns the array if
4208             # $arrayref provided &&
4209             # returns ALL array data
4210             # Loop-Specific operations:
4211             'next' => $ignored # assign to next in loop
4212             'prev' => $ignored # assign to previous in loop
4213             'previous'
4214              
4215             =head2 Array Accessors
4216              
4217             Text or TextData # update the text array
4218             FClr or ForegroundColorData # update the color array for foregrounds
4219             BClr or BackgroundColorData # update the color array for backgrounds
4220              
4221             Instead of using the above Array Accessors and Array-Specific
4222             operations, it is recommended that you employ the L<"Tied Array Interfaces">
4223             since they accomplish the goal of screen manipulation in a more
4224             Perl-friendly manner.
4225              
4226             =head3 Text or TextData
4227              
4228             =head3 FClr or ForegroundColorData
4229              
4230             =head3 BClr or BackgroundColorData
4231              
4232             =head2 Loop Accessors
4233              
4234             BTyp or WindowBorderType # loop through border types
4235              
4236             =head3 BTyp or WindowBorderType
4237              
4238             =head2 Normal Accessors
4239              
4240             Name or VerboseName # Description
4241             ---- ----------- -------------
4242             Hite or WindowHeight # window height
4243             Widt or WindowWidth # window width
4244             YOff or WindowYOffset # window y-offset position
4245             XOff or WindowXOffset # window x-offset position
4246             YCrs or CursorYOffset # window y-cursor position
4247             XCrs or CursorXOffset # window x-cursor position
4248             BrFC or WindowBorderForegroundColor # border fg color code string
4249             BrBC or WindowBorderBackgroundColor # border bg color code string
4250             Titl or WindowTitle # title string
4251             TtFC or WindowTitleForegroundColor # title fg color code string
4252             TtBC or WindowTitleBackgroundColor # title bg color code string
4253             DNdx or DisplayStackIndex # global display index
4254              
4255             =head3 Hite or WindowHeight
4256              
4257             =head3 Widt or WindowWidth
4258              
4259             =head3 YOff or WindowYOffset
4260              
4261             =head3 XOff or WindowXOffset
4262              
4263             =head3 YCrs or CursorYOffset
4264              
4265             =head3 XCrs or CursorXOffset
4266              
4267             =head3 BrFC or WindowBorderForegroundColor
4268              
4269             =head3 BrBC or WindowBorderBackgroundColor
4270              
4271             =head3 Titl or WindowTitle
4272              
4273             =head3 TtFC or WindowTitleForegroundColor
4274              
4275             =head3 TtBC or WindowTitleBackgroundColor
4276              
4277             =head3 DNdx or DisplayStackIndex
4278              
4279             =head2 Flag Accessors
4280              
4281             FlagName or VerboseFlagName Default # Description
4282             -------- --------------- ------- -------------
4283             FlagAuDr or FlagAutoDraw 1 # Automatic DrawWindow() call whenever
4284             # TextData or Color*Data is updated
4285             FlagADTF or FlagAutoDrawTiedForegroundData 1 # Automatic DrawWindow() call
4286             # for arrays tied to Curses::Simp::FClr objects when FlagAuDr is already set
4287             FlagADTB or FlagAutoDrawTiedBackgroundData 1 # Automatic DrawWindow() call
4288             # for arrays tied to Curses::Simp::BClr objects when FlagAuDr is already set
4289             FlagMaxi or FlagMaximize 1 # Maximize window
4290             FlagShrk or FlagShrinkToFit 1 # Shrink window to fit TextData
4291             FlagCntr or FlagCenter 1 # Center window within entire screen
4292             FlagCVis or FlagCursorVisible 0 # Cursor Visible
4293             FlagScrl or FlagScrollbar 0 # use Scrollbars
4294             FlagSDLK or FlagSDLKey 0 # use advanced SDLKey mode in GetKey()
4295             FlagFram or FlagTimeFrame 0 # use Time::Frame objects instead of
4296             # float seconds for timing
4297             FlagMili or FlagMillisecond 0 # use integer milliseconds instead of
4298             # float seconds for timing
4299             FlagPrin or FlagPrintInto 1 # PrintString() prints Into TextData
4300             # array. If FlagPrintInto is false, then each call to PrintString()
4301             # only writes to the screen temporarily and will be wiped the next time
4302             # the window behind it is updated.
4303             FlagClrU or FlagColorUsed 0 # ColorUsed gets set automatically
4304             # when color codes are used and determines if internal dialogs have color
4305              
4306             =head3 AuDr or FlagAuDr or FlagAutoDraw
4307              
4308             =head3 ADTF or FlagADTF or FlagAutoDrawTiedForegroundData
4309              
4310             =head3 ADTB or FlagADTB or FlagAutoDrawTiedBackgroundData
4311              
4312             =head3 Down or FlagDown or FlagDropIsDown
4313              
4314             =head3 Drop or FlagDrop or FlagDropDown
4315              
4316             =head3 Insr or FlagInsr or FlagInsertMode
4317              
4318             =head3 Maxi or FlagMaxi or FlagMaximize
4319              
4320             =head3 Shrk or FlagShrk or FlagShrinkToFit
4321              
4322             =head3 Cntr or FlagCntr or FlagCenter
4323              
4324             =head3 CVis or FlagCVis or FlagCursorVisible
4325              
4326             =head3 Scrl or FlagScrl or FlagScrollbar
4327              
4328             =head3 SDLK or FlagSDLK or FlagSDLKey
4329              
4330             =head3 Fram or FlagFram or FlagTimeFrame
4331              
4332             =head3 Mili or FlagMili or FlagMillisecond
4333              
4334             =head3 Prin or FlagPrin or FlagPrintInto
4335              
4336             =head3 ClrU or FlagClrU or FlagColorUsed
4337              
4338             =head2 Miscellaneous Accessors
4339              
4340             Name or VerboseName # Description
4341             -------- ----------------------- -------------
4342             AttrNamz or AttributeNames # list of available Simp Attributes
4343             DfltValu or DefaultValues # list of Default attribute Values
4344             KQue or KeyQueue # list of ordered unhandled Key events
4345             MQue or KeyModQueue # list of ordered unhandled modifiers
4346             Focu or FocusWindow # changes Focus to current Window
4347             Updt or UpdateWindow # Updates display of current Window
4348             CScr or CloseScreen # closes all opened Curses screens
4349             # Note: CScr() is automatically called when any Simp program exits,
4350             # so explicit calls are probably unnecessary && redundant.
4351             BordChar or PrintBorderCharacter # utility to draw Border Characters
4352             InitPair or InitializeColorPair # utility to Initialize Color Pairs
4353             MkMethdz or MakeMethods # utility to Make many Methods
4354             TestDraw # Tests whether AutoDraw is pending
4355             BildBrws # utility to Build Browse dialogs
4356             BrwsCdUp # utility to `cd ..` Browse directories
4357             BrwsHelp # utility to print Browse Help
4358              
4359             =head3 AttrNamz or AttributeNames
4360              
4361             =head3 DfltValu or DefaultValues
4362              
4363             =head3 KQue or KeyQueue
4364              
4365             =head3 MQue or KeyModQueue
4366              
4367             =head3 Focu or FocusWindow
4368              
4369             =head3 Updt or UpdateWindow
4370              
4371             =head3 CScr or CloseScreen
4372              
4373             =head3 BordChar or PrintBorderCharacter
4374              
4375             =head3 InitPair or InitializeColorPair
4376              
4377             =head3 MkMethdz or MakeMethods
4378              
4379             =head3 TestDraw
4380              
4381             =head3 BildBrws
4382              
4383             =head3 BrwsCdUp
4384              
4385             =head3 BrwsHelp
4386              
4387             =head2 Accessor and Flag Method Usage Examples
4388              
4389             #!/usr/bin/perl -w
4390             use strict;
4391             use Curses::Simp;
4392             # create new object which gets auto-drawn with init params
4393             my $simp = Curses::Simp->new('text' => [ 'hmmm', 'haha', 'whoa', 'yeah' ],
4394             'fclr' => [ 'kkkK', 'kKKw', 'KwrR', 'ROYW' ],
4395             'btyp' => 1,
4396             'maxi' => 0);
4397             $simp->GetK(-1); # wait for a key press
4398             $simp->Text('push' => 'weee'); # add more to the Text
4399             $simp->FClr('push' => 'WwKk'); # && FClr arrays
4400             $simp->Maxi('togl'); # toggle the maximize flag
4401             $simp->GetK(-1); # wait for a key press
4402             $simp->Text('2' => 'cool'); # change index two elements of Text
4403             $simp->FClr('2' => 'bBCW'); # && FClr
4404             $simp->Maxi('fals'); # falsify the maximize flag
4405             $simp->GetK(-1); # wait for a key press
4406             $simp->Text('popp'); # pop the last elements off Text
4407             $simp->FClr('popp'); # && FClr
4408             $simp->BTyp('incr'); # increment the border type
4409             $simp->GetK(-1); # wait for a key press
4410             $simp->Text('asin' => [ 'some', 'diff', 'rent', 'stuf' ]);
4411             $simp->FClr('asin' => [ 'GGYY', 'CCOO', 'BBRR', 'WWPP' ]);
4412             $simp->BTyp('incr'); # increment the border type
4413             $simp->GetK(-1); # wait for a key press before quitting
4414              
4415             =head1 CURSES KEY NOTES
4416              
4417             When the GetKey() function is in the normal default mode of input,
4418             special keypress name strings will be returned when detected. A
4419             small set of the names below are found commonly (like the arrow
4420             keys, the function keys, HOME, END, PPAGE [PageUp], NPAGE [PageDown],
4421             IC [Insert], and BACKSPACE) but they are all described here since
4422             they are supported by L and therefore could arise.
4423              
4424             The list of returnable Curses Key names are:
4425              
4426             KEY_F1 KEY_F2 KEY_F3
4427             KEY_F4 KEY_F5 KEY_F6
4428             KEY_F7 KEY_F8 KEY_F9
4429             KEY_F10 KEY_F11 KEY_F12
4430             KEY_F13 KEY_F14 KEY_F15
4431             KEY_A1 KEY_A3 KEY_B2
4432             KEY_BACKSPACE KEY_BEG KEY_BREAK
4433             KEY_BTAB KEY_C1 KEY_C3
4434             KEY_CANCEL KEY_CATAB KEY_CLEAR
4435             KEY_CLOSE KEY_COMMAND KEY_COPY
4436             KEY_CREATE KEY_CTAB KEY_DC
4437             KEY_DL KEY_DOWN KEY_EIC
4438             KEY_END KEY_ENTER KEY_EOL
4439             KEY_EOS KEY_EXIT KEY_F0
4440             KEY_FIND KEY_HELP KEY_HOME
4441             KEY_IC KEY_IL KEY_LEFT
4442             KEY_LL KEY_MARK KEY_MAX
4443             KEY_MESSAGE KEY_MIN KEY_MOVE
4444             KEY_NEXT KEY_NPAGE KEY_OPEN
4445             KEY_OPTIONS KEY_PPAGE KEY_PREVIOUS
4446             KEY_PRINT KEY_REDO KEY_REFERENCE
4447             KEY_REFRESH KEY_REPLACE KEY_RESET
4448             KEY_RESTART KEY_RESUME KEY_RIGHT
4449             KEY_SAVE KEY_SBEG KEY_SCANCEL
4450             KEY_SCOMMAND KEY_SCOPY KEY_SCREATE
4451             KEY_SDC KEY_SDL KEY_SELECT
4452             KEY_SEND KEY_SEOL KEY_SEXIT
4453             KEY_SF KEY_SFIND KEY_SHELP
4454             KEY_SHOME KEY_SIC KEY_SLEFT
4455             KEY_SMESSAGE KEY_SMOVE KEY_SNEXT
4456             KEY_SOPTIONS KEY_SPREVIOUS KEY_SPRINT
4457             KEY_SR KEY_SREDO KEY_SREPLACE
4458             KEY_SRESET KEY_SRIGHT KEY_SRSUME
4459             KEY_SSAVE KEY_SSUSPEND KEY_STAB
4460             KEY_SUNDO KEY_SUSPEND KEY_UNDO
4461             KEY_UP KEY_MOUSE
4462              
4463             =head1 SDLKEY NOTES
4464              
4465             The GetKey() function has a special advanced mode of input.
4466             Instead of returning the plain keypress (e.g., 'a'), the $FlagSDLKey
4467             parameter can be set to true for temporary SDLKey mode or with
4468             FlagSDLKey(1) for permanence so that verbose strings of SDLKey names
4469             (e.g., 'SDLK_a') will be returned.
4470              
4471             The list of returnable SDLKey names are:
4472              
4473             SDLKey ASCII value Common name
4474             ---------------- ----------- ------------
4475             'SDLK_BACKSPACE', #'\b' backspace
4476             'SDLK_TAB', #'\t' tab
4477             'SDLK_CLEAR', # clear
4478             'SDLK_RETURN', #'\r' return
4479             'SDLK_PAUSE', # pause
4480             'SDLK_ESCAPE', #'^[' escape
4481             'SDLK_SPACE', #' ' space
4482             'SDLK_EXCLAIM', #'!' exclaim
4483             'SDLK_QUOTEDBL', #'"' quotedbl
4484             'SDLK_HASH', #'#' hash
4485             'SDLK_DOLLAR', #'$' dollar
4486             'SDLK_AMPERSAND', #'&' ampersand
4487             'SDLK_QUOTE', #'\'' quote
4488             'SDLK_LEFTPAREN', #'(' left parenthesis
4489             'SDLK_RIGHTPAREN', #')' right parenthesis
4490             'SDLK_ASTERISK', #'*' asterisk
4491             'SDLK_PLUS', #'+' plus sign
4492             'SDLK_COMMA', #',' comma
4493             'SDLK_MINUS', #'-' minus sign
4494             'SDLK_PERIOD', #'.' period
4495             'SDLK_SLASH', #'/' forward slash
4496             'SDLK_0', #'0' 0
4497             'SDLK_1', #'1' 1
4498             'SDLK_2', #'2' 2
4499             'SDLK_3', #'3' 3
4500             'SDLK_4', #'4' 4
4501             'SDLK_5', #'5' 5
4502             'SDLK_6', #'6' 6
4503             'SDLK_7', #'7' 7
4504             'SDLK_8', #'8' 8
4505             'SDLK_9', #'9' 9
4506             'SDLK_COLON', #':' colon
4507             'SDLK_SEMICOLON', #';' semicolon
4508             'SDLK_LESS', #'<' less-than sign
4509             'SDLK_EQUALS', #'=' equals sign
4510             'SDLK_GREATER', #'>' greater-than sign
4511             'SDLK_QUESTION', #'?' question mark
4512             'SDLK_AT', #'@' at
4513             'SDLK_LEFTBRACKET', #'[' left bracket
4514             'SDLK_BACKSLASH', #'\' backslash
4515             'SDLK_RIGHTBRACKET', #']' right bracket
4516             'SDLK_CARET', #'^' caret
4517             'SDLK_UNDERSCORE', #'_' underscore
4518             'SDLK_BACKQUOTE', #'`' grave
4519             'SDLK_TILDE', #'~' tilde
4520             'SDLK_a', #'a' a
4521             'SDLK_b', #'b' b
4522             'SDLK_c', #'c' c
4523             'SDLK_d', #'d' d
4524             'SDLK_e', #'e' e
4525             'SDLK_f', #'f' f
4526             'SDLK_g', #'g' g
4527             'SDLK_h', #'h' h
4528             'SDLK_i', #'i' i
4529             'SDLK_j', #'j' j
4530             'SDLK_k', #'k' k
4531             'SDLK_l', #'l' l
4532             'SDLK_m', #'m' m
4533             'SDLK_n', #'n' n
4534             'SDLK_o', #'o' o
4535             'SDLK_p', #'p' p
4536             'SDLK_q', #'q' q
4537             'SDLK_r', #'r' r
4538             'SDLK_s', #'s' s
4539             'SDLK_t', #'t' t
4540             'SDLK_u', #'u' u
4541             'SDLK_v', #'v' v
4542             'SDLK_w', #'w' w
4543             'SDLK_x', #'x' x
4544             'SDLK_y', #'y' y
4545             'SDLK_z', #'z' z
4546             'SDLK_DELETE', #'^?' delete
4547             'SDLK_UP', # up arrow
4548             'SDLK_DOWN', # down arrow
4549             'SDLK_RIGHT', # right arrow
4550             'SDLK_LEFT', # left arrow
4551             'SDLK_INSERT', # insert
4552             'SDLK_HOME', # home
4553             'SDLK_END', # end
4554             'SDLK_PAGEUP', # page up
4555             'SDLK_PAGEDOWN', # page down
4556             'SDLK_F1', # F1
4557             'SDLK_F2', # F2
4558             'SDLK_F3', # F3
4559             'SDLK_F4', # F4
4560             'SDLK_F5', # F5
4561             'SDLK_F6', # F6
4562             'SDLK_F7', # F7
4563             'SDLK_F8', # F8
4564             'SDLK_F9', # F9
4565             'SDLK_F10', # F10
4566             'SDLK_F11', # F11
4567             'SDLK_F12', # F12
4568             'SDLK_F13', # F13
4569             'SDLK_F14', # F14
4570             'SDLK_F15', # F15
4571             # SDLKeys below aren't detected correctly yet
4572             'SDLK_KP0', # keypad 0
4573             'SDLK_KP1', # keypad 1
4574             'SDLK_KP2', # keypad 2
4575             'SDLK_KP3', # keypad 3
4576             'SDLK_KP4', # keypad 4
4577             'SDLK_KP5', # keypad 5
4578             'SDLK_KP6', # keypad 6
4579             'SDLK_KP7', # keypad 7
4580             'SDLK_KP8', # keypad 8
4581             'SDLK_KP9', # keypad 9
4582             'SDLK_KP_PERIOD', #'.' keypad period
4583             'SDLK_KP_DIVIDE', #'/' keypad divide
4584             'SDLK_KP_MULTIPLY', #'*' keypad multiply
4585             'SDLK_KP_MINUS', #'-' keypad minus
4586             'SDLK_KP_PLUS', #'+' keypad plus
4587             'SDLK_KP_ENTER', #'\r' keypad enter
4588             'SDLK_KP_EQUALS', #'=' keypad equals
4589             'SDLK_NUMLOCK', # numlock
4590             'SDLK_CAPSLOCK', # capslock
4591             'SDLK_SCROLLOCK', # scrollock
4592             'SDLK_RSHIFT', # right shift
4593             'SDLK_LSHIFT', # left shift
4594             'SDLK_RCTRL', # right ctrl
4595             'SDLK_LCTRL', # left ctrl
4596             'SDLK_RALT', # right alt
4597             'SDLK_LALT', # left alt
4598             'SDLK_RMETA', # right meta
4599             'SDLK_LMETA', # left meta
4600             'SDLK_LSUPER', # left windows key
4601             'SDLK_RSUPER', # right windows key
4602             'SDLK_MODE', # mode shift
4603             'SDLK_HELP', # help
4604             'SDLK_PRINT', # print-screen
4605             'SDLK_SYSREQ', # SysRq
4606             'SDLK_BREAK', # break
4607             'SDLK_MENU', # menu
4608             'SDLK_POWER', # power
4609             'SDLK_EURO', # euro
4610              
4611             SDLKey mode also sets flags in KeyMode() where:
4612              
4613             SDL Modifier Meaning
4614             -------------- ---------
4615             'KMOD_NONE', # No modifiers applicable
4616             'KMOD_CTRL', # A Control key is down
4617             'KMOD_SHIFT', # A Shift key is down
4618             'KMOD_ALT', # An Alt key is down
4619              
4620             =head1 COLOR NOTES
4621              
4622             Colors can be encoded along with each text line to be printed.
4623             PrintString() and DrawWindow() each take hash parameters where the
4624             key should be one of:
4625              
4626             'fclr' or 'ForegroundColorData'
4627             'bclr' or 'BackgroundColorData'
4628              
4629             and the value is a color code string as described below.
4630              
4631             A normal color code is simply a single character (typically just the
4632             first letter of the color name and the case [upper or lower]
4633             designates high or low intensity [i.e., Bold on or off]).
4634             The default printing mode of color codes assumes black background
4635             colors for everything when no 'ColorBackgroundData' is supplied.
4636             Sometimes Bold misbehaves. I've hardcoded the correct value of A_BOLD
4637             from my implementation of Curses as the default value which will only
4638             be overridden if A_BOLD properly returns the curses number of the
4639             attribute. Occassionally it doesn't work and I can't figure out why.
4640              
4641             =head2 Normal Color Code Reference
4642              
4643             (lower-case = dull) k(blacK), r(Red), g(Green), y(Yellow),
4644             (upper-case = bright) b(Blue), p(Purple), c(Cyan), w(White),
4645              
4646             =head2 Alternate Color Codes
4647              
4648             (lower-case = dull) o([Orange] *Yellow), m([Magenta] Purple),
4649             (upper-case = bright) u([blUe] Blue), t([Teal] Cyan),
4650              
4651             =head2 *Case-Determines-Brightness Exception
4652              
4653             There is one special exception to the Case-Determines-Brightness rule.
4654             Orange is actually Dark Yellow but it is often expected to be much
4655             brighter than any of the other dark colors. Therefore, Upper-Case 'O'
4656             breaks the "lower-case = dull, upper-case = bright" rule and is
4657             interpreted as Lower-Case 'y'. Every other color code is consistent
4658             with the rule.
4659              
4660             =head1 CHANGES
4661              
4662             Revision history for Perl extension Curses::Simp:
4663              
4664             =over 4
4665              
4666             =item - 1.4.A8UG1gG Mon Aug 30 16:01:42:16 2010
4667              
4668             * t/00podc.t should pass now that my POD is updated to cover all subs
4669              
4670             * Brws: setup to read $ENV{'LS_COLORS'} into GLBL{OVERMAPP}
4671              
4672             * fixed POD error that was failing on FreeBSD because items must follow overs
4673              
4674             * tested ACS_ borders working again, restored as dfalt, added new ARROW bordset
4675              
4676             * fixed Prmt handle Eterm BACKSPACE (ord(127)) like TTY (without ndng Ctrl-BS)
4677              
4678             * fixed FlagCVis (MkMethodz CRSR flag was accidentally set as CURS)
4679              
4680             * updated license to GPLv3 and bumped minor version for the CPAN
4681              
4682             =item - 1.2.A7DDCh3 Tue Jul 13 13:12:43:03 2010
4683              
4684             * made B == Blue && K == blacK like RGB vs. CMYK
4685              
4686             * added ColorUsed '_flagclru' tracking and test for internal dialogs
4687              
4688             * fixed up Mesg() for no press key option to force window to stay for wait
4689             && auto header color gen for my help && info pages
4690              
4691             * added flags to auto-draw tied @_fclr (FlagADTF) && @_bclr (FlagADTB)
4692              
4693             * added optional length param to GetS
4694              
4695             * added basic 4NT support by generating C:/SimpDraw.bat
4696              
4697             * added Tie::Array interfaces for @_text, @_fclr, && @_bclr
4698              
4699             * removed repeats and color code expansion && added @_bclr
4700              
4701             * updated License
4702              
4703             * added GetS() since Dan asked how
4704              
4705             =item - 1.0.4287FJQ Sun Feb 8 07:15:19:26 2004
4706              
4707             * made Brws()
4708              
4709             * added ckbx && butn types to Mesg() && drop type to Prmt() && wrote Focu()
4710             to focus new types
4711              
4712             * added info && help types to Mesg() to auto title && color those screens
4713              
4714             * added blox && squr styles to CPik && made style/blockchar increment
4715             keys (PgUp/Dn/Home/End)
4716              
4717             =item - 1.0.41V0L3a Sat Jan 31 00:21:03:36 2004
4718              
4719             * made flag accessors without ^Flag
4720              
4721             * wrote support for VerboseName hash keys
4722              
4723             * fixed ShokScrn overlap && DelW bugs
4724              
4725             * made GetK return detected KEY_ names in normal mode && added CURSES
4726             KEY MODE section to POD && made both key modes return -1 if $tmot reached
4727              
4728             * made ShokScrn not blank the screen so often
4729              
4730             * made Text('1' => 'new line') use Prnt instead of Draw for efficiency
4731              
4732             * updated POD to use VerboseNames instead of 4-letter names && erased most '&&'
4733              
4734             * made verbose accessor names like VerboseName instead of verbose_name
4735              
4736             =item - 1.0.41O4516 Sat Jan 24 04:05:01:06 2004
4737              
4738             * made all but ptok && qbix non-executable for EXE_FILES
4739              
4740             * updated POD && added Simp projects into bin/ && MANIFEST in preparation
4741             for release
4742              
4743             =item - 1.0.41O3SQK Sat Jan 24 03:28:26:20 2004
4744              
4745             * fixed weird char probs in Draw && removed weird char support from Prnt
4746              
4747             * added PrintInto '_flagprin' ability
4748              
4749             * made new Mesg, Prmt, && CPik utils
4750              
4751             * added SDLK advanced input option to GetK
4752              
4753             * setup window border char sets
4754              
4755             =item - 1.0.4140asO Sun Jan 4 00:36:54:24 2004
4756              
4757             * refined Draw() && InitPair() for objects instead of exported procedures
4758              
4759             * CHANGES section && new objects created
4760              
4761             =item - 1.0.37VG26k Thu Jul 31 16:02:06:46 2003
4762              
4763             * original version
4764              
4765             =back
4766              
4767             =head1 INSTALL
4768              
4769             Please run:
4770              
4771             `perl -MCPAN -e "install Curses::Simp"`
4772              
4773             or uncompress the package and run the standard:
4774              
4775             `perl Makefile.PL; make; make test; make install`
4776              
4777             =head1 FILES
4778              
4779             Curses::Simp requires:
4780              
4781             =over 4
4782              
4783             =item L - to allow errors to croak() from calling sub
4784              
4785             =item L - provides core screen and input handling
4786              
4787             =item L - to allow text arrays to be bound to objects
4788              
4789             =item L - to handle number-base conversion
4790              
4791             =back
4792              
4793             Curses::Simp uses (if available):
4794              
4795             =over 4
4796              
4797             =item L - for pt color coding
4798              
4799             =item L - to provide another mechanism for timing
4800              
4801             =back
4802              
4803             =head1 LICENSE
4804              
4805             Most source code should be Free!
4806             Code I have lawful authority over is && shall be!
4807             Copyright: (c) 2002-2010, Pip Stuart.
4808             Copyleft : This software is licensed under the GNU General Public
4809             License (version 3). Please consult the Free Software Foundation
4810             (http://FSF.Org) for important information about your freedom.
4811              
4812             =head1 AUTHOR
4813              
4814             Pip Stuart
4815              
4816             =cut