Subversion Repositories Projects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2136 - 1
/*****************************************************************************
2
 *   Copyright (C) 2013 Oliver Gemesi                                        *
3
 *                                                                           *
4
 *   This program is free software; you can redistribute it and/or modify    *
5
 *   it under the terms of the GNU General Public License as published by    *
6
 *   the Free Software Foundation; either version 2 of the License.          *
7
 *                                                                           *
8
 *   This program is distributed in the hope that it will be useful,         *
9
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of          *
10
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           *
11
 *   GNU General Public License for more details.                            *
12
 *                                                                           *
13
 *   You should have received a copy of the GNU General Public License       *
14
 *   along with this program; if not, write to the                           *
15
 *   Free Software Foundation, Inc.,                                         *
16
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.               *
17
 *****************************************************************************/
18
 
19
//############################################################################
20
//# HISTORY  scrollbox.c
21
//#
22
//# 31.05.2014 OG
23
//# - chg: ScrollBox_Refresh() - umgestellt auf PKT_KeylineUpDown()
24
//#
25
//# 29.03.2014 OG
26
//# - chg: ScrollBox_Show() umgestellt auf clear_key_all()
27
//#
28
//# 22.05.2013 OG
29
//# - fix: include pkt/pkt.h
30
//#
31
//# 19.05.2013 OG
32
//# - chg: ScrollBox_Show() erweitert um PKT_CtrlHook() um u.a. PKT-Updates
33
//#        zu ermoeglichen
34
//#
35
//# 04.05.2013 OG
36
//# - chg: angepasst auf xutils.c
37
//#
38
//# 28.04.2013 OG
39
//# - add: ScrollBox_Push() - Variante fuer 'format' im RAM
40
//# - chg: ScrollBox_Push_P() -> keine Rueckgabe mehr (void)
41
//# - chg: auf xprintf umgestellt (siehe utils/xstring.c)
42
//# - add: verschiedene Beschreibungen ueber Funktionen
43
//#
44
//# 20.04.2013 OG - NEU
45
//############################################################################
46
 
47
//#define USE_SCROLLBOX_DEBUG       // Debug-Funktionen einkompilieren/aktivieren (gesendet wird an uart1)
48
 
49
#include "../cpu.h"
50
#include <avr/pgmspace.h>
51
#include <stdio.h>
52
#include <stdarg.h>
53
#include <string.h>
54
#include <stdlib.h>
55
 
56
#include "../main.h"
57
#include "../lcd/lcd.h"
58
#include "../eeprom/eeprom.h"
59
#include "../messages.h"
60
#include "../pkt/pkt.h"
61
#include "../utils/xutils.h"        // xprintf
62
#include "scrollbox.h"
63
 
64
// Debug
65
#ifdef USE_SCROLLBOX_DEBUG
66
  #include "../uart/uart1.h"
67
  #include <util/delay.h>
68
#endif
69
 
70
#define SCROLLBOX_ALLOC_MEM         // dynamische RAM-Belegen (malloc) verwenden?   (Standardeinstellung: ja)
71
 
72
#define SCROLLBOX_LINESIZE  20+1    // Ausgabezeile der ScrollBox (20 Chars + 0x00)
73
#define SCROLLBOX_KEYSIZE   4+1     // Textlabel einer Taste (4 Chars + 0x00)
74
 
75
#define SCROLLBOX_W         20      // Textbreite
76
#define SCROLLBOX_H         7       // Textzeilen
77
#define MSBLINE             10      // drawmode-code fuer: Linie
78
 
79
 
80
 
81
 
82
//-----------------------------------------------------------
83
// statischer Speicher wenn nicht SCROLLBOX_ALLOC_MEM
84
// verwendet wird
85
//-----------------------------------------------------------
86
#ifndef SCROLLBOX_ALLOC_MEM
87
    #define SCROLLBOX_BUFFER_SIZE                   2048    // 2 KByte - ram-size in bytes
88
    char scrollbox_buffer[SCROLLBOX_BUFFER_SIZE];
89
#endif
90
 
91
 
92
//-----------------------------------------------------------
93
// typedef: scrollbox_key_t
94
//-----------------------------------------------------------
95
typedef struct
96
{
97
    uint8_t     active;                         // Taste aktiv? (true/false)
98
    char        text[SCROLLBOX_KEYSIZE];        // Tastentext
99
}  scrollbox_key_t;
100
 
101
 
102
//-----------------------------------------------------------
103
// typedef: scrollbox_line_t
104
//-----------------------------------------------------------
105
typedef struct
106
{
107
    uint8_t     mode;                           // drawmode: MNORMAL, MINVERSE oder MSBLINE
108
    char        line[SCROLLBOX_LINESIZE];       // malloc: lines * 21 bytes (20 chars + 0)
109
}  scrollbox_line_t;
110
 
111
 
112
//-----------------------------------------------------------
113
// typedef: scrollbox_t
114
//-----------------------------------------------------------
115
typedef struct
116
{
117
    scrollbox_line_t    *buffer;                // malloc: lines * 22 bytes (21 chars + 0)
118
    uint8_t             maxlines;               // max. reservierte Lines (malloc buffer)
119
    uint8_t             lines;                  // Anzahl gepushte lines
120
    uint8_t             display_pos;            // aktuelle obere Anzeigezeile
121
    scrollbox_key_t     key_enter;
122
    scrollbox_key_t     key_enter_long;
123
}  scrollbox_t;
124
 
125
 
126
//-----------------------------------------------------------
127
// Buffer & Co.
128
//-----------------------------------------------------------
129
scrollbox_t     scrollbox;
130
char            buffer_sbline[SCROLLBOX_LINESIZE];
131
 
132
 
133
//#############################################################################################
134
//#############################################################################################
135
 
136
 
137
 
138
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
139
#ifdef USE_SCROLLBOX_DEBUG
140
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
141
//--------------------------------------------------------------
142
// nur wenn define: USE_SCROLLBOX_DEBUG
143
//--------------------------------------------------------------
144
void ScrollBox_Debug( void )
145
{
146
    char s[33];
147
    uint8_t i,j;
148
    char *p;
149
    scrollbox_line_t *sboxp;
150
    uint32_t h;
151
 
152
    uart1_puts_p( PSTR("\r\nScrollBox_Debug: BEGIN\r\n\r\n") );
153
 
154
    ltoa( scrollbox.buffer, s, 16);
155
    uart1_puts_p( PSTR("address: buffer          = 0x") );
156
    uart1_puts( s );
157
    ltoa( scrollbox.buffer, s, 10);
158
    uart1_puts( " (" );
159
    uart1_puts( s );
160
    uart1_puts( ")\r\n" );
161
 
162
    ltoa( scrollbox_buffer, s, 16);
163
    uart1_puts_p( PSTR("address: scrollbox_buffer  = 0x") );
164
    uart1_puts( s );
165
    ltoa( scrollbox.buffer, s, 10);
166
    uart1_puts( " (" );
167
    uart1_puts( s );
168
    uart1_puts( ")\r\n" );
169
 
170
 
171
    itoa( sizeof(scrollbox_line_t), s, 10);
172
    uart1_puts_p( PSTR("sizeof(scrollbox_line_t) = ") );
173
    uart1_puts( s );
174
    uart1_puts( "\r\n" );
175
 
176
    uart1_puts( "\r\n" );
177
 
178
    itoa( scrollbox.lines, s, 10);
179
    uart1_puts_p( PSTR("scrollbox.lines = ") );
180
    uart1_puts( s );
181
    uart1_puts( "\r\n" );
182
 
183
    itoa( scrollbox.maxlines, s, 10);
184
    uart1_puts_p( PSTR("scrollbox.maxlines = ") );
185
    uart1_puts( s );
186
    uart1_puts( "\r\n" );
187
 
188
    itoa( scrollbox.display_pos, s, 10);
189
    uart1_puts_p( PSTR("scrollbox.display_pos = ") );
190
    uart1_puts( s );
191
    uart1_puts( "\r\n" );
192
 
193
    uart1_puts( "\r\n" );
194
 
195
    for(i=0; i<scrollbox.lines; i++)
196
    {
197
        itoa( i, s, 10);
198
        if( strlen(s)<2 ) uart1_puts( " " );
199
        uart1_puts( s );
200
        uart1_puts( ": " );
201
 
202
        //sboxp = scrollbox.buffer + sizeof(scrollbox_line_t)*i;
203
        sboxp = scrollbox.buffer + i;
204
 
205
        ltoa( sboxp, s, 16); // hex
206
        uart1_puts( "[0x" );
207
        uart1_puts( s );
208
        uart1_puts( "]" );
209
 
210
        ltoa( sboxp, s, 10); // dec
211
        uart1_puts( "[" );
212
        uart1_puts( s );
213
        uart1_puts( "] " );
214
 
215
        itoa( sboxp->mode, s, 10);
216
        if( strlen(s)<2 ) uart1_puts( " " );
217
        uart1_puts( s );
218
        uart1_puts( ": " );
219
 
220
        p = sboxp->line;
221
 
222
        if( sboxp->mode != 10 )
223
        {
224
            uart1_puts( p );
225
        }
226
 
227
        uart1_puts( "|\r\n" );
228
    }
229
 
230
    //--------------------------------------------------------------
231
    // Hier wird fuer eine gewisse Zeit (insgesamt 2500 mal) permanent die Zeile 23 ausgegeben.
232
    // Wenn ich das richtig sehe schreibe ich hierbei nicht ;-)
233
    // Aber was sagt das Empfangsterminal....
234
    //--------------------------------------------------------------
235
    sboxp = scrollbox.buffer + 23;
236
    for( h=0; h<10; h++)
237
    {
238
        itoa( h, s, 10);
239
        uart1_puts( s );
240
        uart1_puts( "# " );
241
 
242
        uart1_puts( sboxp->line );
243
        uart1_puts( "|\r\n" );
244
        _delay_ms(10);
245
    }
246
    //--------------------------------------------------------------
247
 
248
    uart1_puts_p( PSTR("\r\nScrollBox_Debug: END\r\n") );
249
    uart1_puts( "##########################################\r\n\r\n" );
250
}
251
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
252
#endif // USER_SCROLLBOX_DEBUG
253
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
254
 
255
 
256
 
257
//--------------------------------------------------------------
258
// ok = ScrollBox_Create( uint8_t maxlines )
259
//
260
// Rueckgabe:
261
//   true  = ok
262
//   false = kein Speicher
263
//
264
// - reserviert speicher fuer max. maxlines
265
// - initialisiert scrollbox-Datenstruktur
266
//--------------------------------------------------------------
267
uint8_t ScrollBox_Create( uint8_t maxlines )
268
{
269
    scrollbox.buffer = 0;
270
 
271
    #ifdef SCROLLBOX_ALLOC_MEM
272
        scrollbox.buffer = malloc( maxlines * sizeof(scrollbox_line_t));
273
        //scrollbox.buffer = calloc( maxlines, sizeof(scrollbox_line_t) );
274
    #else
275
        scrollbox.buffer = (scrollbox_line_t *) scrollbox_buffer;
276
    #endif
277
 
278
    if( !scrollbox.buffer ) // kein RAM mehr
279
    {
280
        lcd_cls();
281
        lcd_printp_at( 1, 3, PSTR("Error: ScrollBox"), MNORMAL);
282
        lcd_printp_at( 1, 4, PSTR("No more RAM"), MNORMAL);
283
        set_beep ( 500, 0x3333, BeepNormal);
284
        while (!get_key_short (1 << KEY_ESC));
285
        return false;
286
    }
287
 
288
    scrollbox.maxlines      = maxlines;
289
    scrollbox.lines         = 0;
290
    scrollbox.display_pos   = 0;
291
 
292
    scrollbox.key_enter.active      = false;
293
    scrollbox.key_enter_long.active = false;
294
    return true;
295
}
296
 
297
 
298
 
299
//--------------------------------------------------------------
300
// ScrollBox_Destroy()
301
//
302
// gibt reservierten Speicher wieder frei
303
// Wichtig! Da malloc verwendet wird!
304
//--------------------------------------------------------------
305
void ScrollBox_Destroy( void )
306
{
307
    if( scrollbox.buffer )
308
    {
309
        #ifdef SCROLLBOX_ALLOC_MEM
310
        free( scrollbox.buffer );
311
        #endif
312
    }
313
    scrollbox.buffer = 0;
314
}
315
 
316
 
317
//--------------------------------------------------------------
318
// ScrollBox_PushLine()
319
//
320
// fuegt eine Trennlinie hinzu
321
//--------------------------------------------------------------
322
void ScrollBox_PushLine( void )
323
{
324
    scrollbox_line_t *sboxp;
325
 
326
    if( scrollbox.lines < scrollbox.maxlines )
327
    {
328
        sboxp = scrollbox.buffer + scrollbox.lines;
329
        sboxp->mode = MSBLINE;
330
        scrollbox.lines++;
331
    }
332
}
333
 
334
 
335
 
336
//--------------------------------------------------------------
337
// _scrollbox_push(...)
338
//
339
// intern fuer: ScrollBox_Push_P(), ScrollBox_Push()
340
// Beschreibung siehe dort
341
//--------------------------------------------------------------
342
void _scrollbox_push( uint8_t useprogmem, uint8_t mode, const char *format, va_list ap )
343
{
344
    scrollbox_line_t *sboxp;
345
 
346
    if( scrollbox.lines < scrollbox.maxlines )
347
    {
348
        sboxp = scrollbox.buffer + scrollbox.lines;
349
 
350
        _xvsnprintf( useprogmem, buffer_sbline, SCROLLBOX_LINESIZE, format, ap);
351
 
352
        strncpyfill( sboxp->line, buffer_sbline, SCROLLBOX_LINESIZE);   // copy: buffer_sbline zur scrollbox
353
        sboxp->mode  = mode;
354
 
355
        scrollbox.lines++;
356
    }
357
}
358
 
359
 
360
 
361
//--------------------------------------------------------------
362
// ScrollBox_Push_P( mode, format, ...)
363
//
364
// Textzeile hinzufuegen - 'format' ist im PROGMEM.
365
//
366
// Parameter:
367
//   mode   : MNORMAL, MINVERS
368
//   format : siehe xprint-Doku in utils/xstring.c
369
//   ...    : Parameterliste fuer 'format'
370
//--------------------------------------------------------------
371
void ScrollBox_Push_P( uint8_t mode, const char *format, ... )
372
{
373
    va_list ap;
374
 
375
    va_start(ap, format);
376
    _scrollbox_push( true, mode, format, ap);
377
    va_end(ap);
378
}
379
 
380
 
381
//--------------------------------------------------------------
382
// ScrollBox_Push( mode, format, ...)
383
//
384
// Textzeile hinzufuegen - 'format' ist im RAM.
385
//
386
// Parameter:
387
//   mode   : MNORMAL, MINVERS
388
//   format : siehe xprint-Doku in utils/xstring.c
389
//   ...    : Parameterliste fuer 'format'
390
//--------------------------------------------------------------
391
void ScrollBox_Push( uint8_t mode, const char *format, ... )
392
{
393
    va_list ap;
394
 
395
    va_start(ap, format);
396
    _scrollbox_push( false, mode, format, ap);
397
    va_end(ap);
398
}
399
 
400
 
401
//--------------------------------------------------------------
402
// key: KEY_ENTER, KEY_ENTER_LONG  (keine weiteren bisher!)
403
//--------------------------------------------------------------
404
void ScrollBox_SetKey( uint8_t key, const char *keytext )
405
{
406
    if( key == KEY_ENTER )
407
    {
408
        scrollbox.key_enter.active   = true;
409
        strncpyfill( scrollbox.key_enter.text, keytext, SCROLLBOX_KEYSIZE);
410
    }
411
 
412
    if( key == KEY_ENTER_LONG )
413
    {
414
        scrollbox.key_enter_long.active = true;
415
        strncpyfill( scrollbox.key_enter_long.text, keytext, SCROLLBOX_KEYSIZE);
416
    }
417
}
418
 
419
 
420
 
421
//--------------------------------------------------------------
422
// ScrollBox_Refresh()
423
//
424
// zeigt die ScrollBox - wird normalerweise von ScrollBox_Show()
425
// automatisch durchgefuehrt
426
//--------------------------------------------------------------
427
void ScrollBox_Refresh( void )
428
{
429
    uint8_t y;
430
    uint8_t sh;
431
    uint8_t sy;
432
    scrollbox_line_t *sboxp;
433
 
434
    //--------------------------
435
    // Text
436
    //--------------------------
437
    for( y=0; y<7; y++)
438
    {
439
        sboxp = scrollbox.buffer + (scrollbox.display_pos + y);
440
 
441
        if( y + scrollbox.display_pos < scrollbox.lines )
442
        {
443
 
444
            if( sboxp->mode == MSBLINE )
445
            {
446
                lcd_frect( (21-SCROLLBOX_W)*6, (y*8), (SCROLLBOX_W*6), 7, 0);   // clear
447
                lcd_line ( (21-SCROLLBOX_W)*6, (y*8)+3, 125, (y*8)+3, 1);       // line
448
            }
449
            else
450
            {
451
                lcd_puts_at( 21-SCROLLBOX_W, y, sboxp->line, sboxp->mode);
452
            }
453
            //p += sizeof(scrollbox_line_t);
454
        }
455
        else    // clear
456
        {
457
              lcd_frect( (21-SCROLLBOX_W)*6, (y*8), (SCROLLBOX_W*6), 7, 0); // clear
458
        }
459
    }
460
 
461
 
462
    //--------------------------
463
    // Slider
464
    //--------------------------
465
    #define SLIDERH   55                                                // Finetuning der Slider-Hoehe
466
 
467
    // Slider: 7 zeilen * 8 pixel = 56 pixel
468
    sh = (SLIDERH * 7) / scrollbox.lines;                               // Slider: Hoehe
469
    sh = (sh > SLIDERH) ? SLIDERH : sh;
470
 
471
    sy = (scrollbox.display_pos * (SLIDERH-sh)) / (scrollbox.lines-7);  // Slider: Position
472
 
473
    lcd_frect( 0,  0, 1, SLIDERH, 0);                                   // Slider: Clear
474
    lcd_frect( 0, sy, 1, sh, 1);    // Slider: draw                     // Slider: Draw
475
 
476
 
477
    //--------------------------
478
    // Keyline
479
    //--------------------------
480
    PKT_KeylineUpDown( 1, 7,  0,0);                                     // Keyline: Up / Down
481
    lcd_printp_at( 12, 7, strGet(ENDE), MNORMAL);                       // Keyline: Ende
482
 
483
    if( scrollbox.key_enter.active )            lcd_print_at (17, 7, (uint8_t *)scrollbox.key_enter.text     , MNORMAL);
484
    else if ( scrollbox.key_enter_long.active ) lcd_print_at (17, 7, (uint8_t *)scrollbox.key_enter_long.text, MNORMAL);
485
    else                                        lcd_printp_at(17, 7, PSTR("    ")  , MNORMAL);
486
 
487
    //ScrollBox_Debug();
488
}
489
 
490
 
491
//--------------------------------------------------------------
492
// key = ScrollBox_Show()
493
//
494
//--------------------------------------------------------------
495
uint8_t ScrollBox_Show( void )
496
{
497
    uint8_t keyexit = 0;
498
 
499
    clear_key_all();
500
 
501
    if( scrollbox.buffer )
502
    {
503
        ScrollBox_Refresh();
504
 
505
        do
506
        {
507
            //--------------------------
508
            // Pruefe auf PKT-Update und
509
            // andere interne PKT-Aktionen
510
            //--------------------------
511
            if( PKT_CtrlHook() )                  // Update vom Updatetool angefordert?
512
            {
513
                lcd_cls();
514
                ScrollBox_Refresh();
515
            }
516
 
517
            //--------------------------
518
            // scrollen: nach unten
519
            //--------------------------
520
            if( get_key_press(1 << KEY_PLUS) || get_key_long_rpt_sp( (1 << KEY_PLUS),2 ))       // down
521
            {
522
                if( scrollbox.display_pos < ( scrollbox.lines - SCROLLBOX_H) )
523
                {
524
                    scrollbox.display_pos++;
525
                    ScrollBox_Refresh();
526
                }
527
                else
528
                {
529
                    set_beep ( 25, 0xffff, BeepNormal);                                         // am unteren Ende angelangt
530
                }
531
            }
532
 
533
            //--------------------------
534
            // scrollen: nach oben
535
            //--------------------------
536
            if( get_key_press(1 << KEY_MINUS) || get_key_long_rpt_sp( (1 << KEY_MINUS),2 ))     // up
537
            {
538
                if( scrollbox.display_pos > 0 )
539
                {
540
                    scrollbox.display_pos--;
541
                    ScrollBox_Refresh();
542
                }
543
                else
544
                {
545
                    set_beep ( 25, 0xffff, BeepNormal);                                         // am oberen Ende angelangt
546
                }
547
            }
548
 
549
            //--------------------------
550
            //--------------------------
551
            if( scrollbox.key_enter.active && get_key_short(1 << KEY_ENTER) )
552
            {
553
                keyexit = KEY_ENTER;
554
            }
555
 
556
            //--------------------------
557
            //--------------------------
558
            if( scrollbox.key_enter_long.active && get_key_long(1 << KEY_ENTER) )
559
            {
560
                keyexit = KEY_ENTER_LONG;
561
            }
562
 
563
        } while( !get_key_press(1 << KEY_ESC) && (keyexit == 0) );
564
    }
565
 
566
    //get_key_press(KEY_ALL);   // ersetzt durch obiges clear_key_all()
567
 
568
    return keyexit;
569
}
570