176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/*
276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>.
376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * This program is free software; you can redistribute it and/or
576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * modify it under the terms of the GNU General Public License as
676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * published by the Free Software Foundation; either version 2 of the
776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * License, or any later version.
876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * This program is distributed in the hope that it will be useful, but
1076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * WITHOUT ANY WARRANTY; without even the implied warranty of
1176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
1276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * General Public License for more details.
1376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
1476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * You should have received a copy of the GNU General Public License
1576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * along with this program; if not, write to the Free Software
1676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
1776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
1876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
1976d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanFILE_LICENCE ( GPL2_OR_LATER );
2076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
2176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <string.h>
2276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <assert.h>
2376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <gpxe/editbox.h>
2476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
2576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** @file
2676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
2776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Editable text box widget
2876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
2976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
3076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
3176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define EDITBOX_MIN_CHARS 3
3276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
3376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/**
3476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Initialise text box widget
3576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
3676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v box		Editable text box widget
3776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v buf		Text buffer
3876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v len		Size of text buffer
3976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v win		Containing window
4076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v row		Row
4176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v col		Starting column
4276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v width		Width
4376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v flags		Flags
4476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
4576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanvoid init_editbox ( struct edit_box *box, char *buf, size_t len,
4676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		    WINDOW *win, unsigned int row, unsigned int col,
4776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		    unsigned int width, unsigned int flags ) {
4876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	memset ( box, 0, sizeof ( *box ) );
4976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	box->string.buf = buf;
5076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	box->string.len = len;
5176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	box->string.cursor = strlen ( buf );
5276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	box->win = ( win ? win : stdscr );
5376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	box->row = row;
5476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	box->col = col;
5576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	box->width = width;
5676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	box->flags = flags;
5776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
5876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
5976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/**
6076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Draw text box widget
6176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
6276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v box		Editable text box widget
6376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
6476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
6576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanvoid draw_editbox ( struct edit_box *box ) {
6676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	size_t width = box->width;
6776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	char buf[ width + 1 ];
6876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	signed int cursor_offset, underflow, overflow, first;
6976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	size_t len;
7076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
7176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Adjust starting offset so that cursor remains within box */
7276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	cursor_offset = ( box->string.cursor - box->first );
7376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	underflow = ( EDITBOX_MIN_CHARS - cursor_offset );
7476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	overflow = ( cursor_offset - ( width - 1 ) );
7576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	first = box->first;
7676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( underflow > 0 ) {
7776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		first -= underflow;
7876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		if ( first < 0 )
7976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman			first = 0;
8076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	} else if ( overflow > 0 ) {
8176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		first += overflow;
8276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
8376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	box->first = first;
8476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	cursor_offset = ( box->string.cursor - first );
8576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
8676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Construct underscore-padded string portion */
8776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	memset ( buf, '_', width );
8876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	buf[width] = '\0';
8976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	len = ( strlen ( box->string.buf ) - first );
9076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( len > width )
9176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		len = width;
9276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( box->flags & EDITBOX_STARS ) {
9376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		memset ( buf, '*', len );
9476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	} else {
9576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		memcpy ( buf, ( box->string.buf + first ), len );
9676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
9776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
9876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Print box content and move cursor */
9976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( ! box->win )
10076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		box->win = stdscr;
10176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	mvwprintw ( box->win, box->row, box->col, "%s", buf );
10276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	wmove ( box->win, box->row, ( box->col + cursor_offset ) );
10376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
104