PageRenderTime 41ms CodeModel.GetById 24ms app.highlight 14ms RepoModel.GetById 0ms app.codeStats 0ms

/src/button.c

https://bitbucket.org/ekolis/jackband
C | 280 lines | 127 code | 57 blank | 96 comment | 20 complexity | 2c87b08343840a2e06ba82f05ff5e320 MD5 | raw file
  1/*
  2 * File: mouse.c
  3 * Purpose: Mousebutton handling code
  4 *
  5 * Copyright (c) 2007 Nick McConnell
  6 *
  7 * This work is free software; you can redistribute it and/or modify it
  8 * under the terms of either:
  9 *
 10 * a) the GNU General Public License as published by the Free Software
 11 *    Foundation, version 2, or
 12 *
 13 * b) the "Angband licence":
 14 *    This software may be copied and distributed for educational, research,
 15 *    and not for profit purposes provided that this copyright and statement
 16 *    are included in all such copies.  Other copyrights may also apply.
 17 */
 18#include "angband.h"
 19
 20
 21/*** Constants ***/
 22
 23/**
 24 * Maximum number of mouse buttons
 25 */
 26#define MAX_MOUSE_BUTTONS  20
 27
 28/**
 29 * Maximum length of a mouse button label
 30 */
 31#define MAX_MOUSE_LABEL 10
 32
 33
 34/*** Types ***/
 35
 36/**
 37 * Mouse button structure
 38 */
 39typedef struct
 40{
 41	char label[MAX_MOUSE_LABEL]; /*!< Label on the button */
 42	int left;                    /*!< Column containing the left edge of the button */
 43	int right;                   /*!< Column containing the right edge of the button */
 44	unsigned char key;           /*!< Keypress corresponding to the button */
 45} button_mouse;
 46
 47
 48
 49/*** Variables ***/
 50
 51static button_mouse *button_mse;
 52static button_mouse *button_backup;
 53
 54static int button_start;
 55static int button_length;
 56static int button_num;
 57
 58
 59/*
 60 * Hooks for making and unmaking buttons
 61 */
 62button_add_f button_add_hook;
 63button_kill_f button_kill_hook;
 64
 65
 66
 67/*** Code ***/
 68
 69/*
 70 * The mousebutton code. Buttons should be created when neccessary and
 71 * destroyed when no longer necessary.  By default, buttons occupy the section
 72 * of the bottom line between the status display and the location display
 73 * in normal screen mode, and the bottom line after any prompt in alternate
 74 * screen mode.
 75 *
 76 * Individual ports may (and preferably will) handle this differently using
 77 * button_add_gui and button_kill_gui.
 78 */
 79
 80/*
 81 * Add a button
 82 */
 83int button_add_text(const char *label, unsigned char keypress)
 84{
 85	int i;
 86	int length = strlen(label);
 87
 88	/* Check the label length */
 89	if (length > MAX_MOUSE_LABEL)
 90	{
 91		bell("Label too long - button abandoned!");
 92		return 0;
 93	}
 94
 95	/* Check we haven't already got a button for this keypress */
 96	for (i = 0; i < button_num; i++)
 97		if (button_mse[i].key == keypress)
 98			return 0;
 99
100	/* Make the button */
101	button_length += length;
102	my_strcpy(button_mse[button_num].label, label, MAX_MOUSE_LABEL);
103	button_mse[button_num].left = button_length - length + 1;
104	button_mse[button_num].right = button_length;
105	button_mse[button_num++].key = keypress;
106
107	/* Redraw */
108	p_ptr->redraw |= (PR_BUTTONS);
109
110	/* Return the size of the button */
111	return (length);
112}
113
114/*
115 * Add a button
116 */
117int button_add(const char *label, unsigned char keypress)
118{
119	if (!button_add_hook)
120		return 0;
121	else
122		return (*button_add_hook) (label, keypress);
123}
124
125/*
126 * Make a backup of the current buttons
127 */
128void button_backup_all(void)
129{
130	/* Check we haven't already done this */
131	if (button_backup[0].key) return;
132
133	/* Straight memory copy */
134	(void)C_COPY(button_backup, button_mse, MAX_MOUSE_BUTTONS, button_mouse);
135}
136
137
138/*
139 * Restore the buttons from backup
140 */
141void button_restore(void)
142{
143	int i = 0;
144
145	/* Remove the current lot */
146	button_kill_all();
147
148	/* Get all the previous buttons, copy them back */
149	while (button_backup[i].key)
150	{
151		/* Add them all back, forget the backups */
152		button_add(button_backup[i].label, button_backup[i].key);
153		button_backup[i].key = '\0';
154		i++;
155	}
156}
157
158
159/*
160 * Remove a button
161 */
162int button_kill_text(unsigned char keypress)
163{
164	int i, j, length;
165
166	/* Find the button */
167	for (i = 0; i < button_num; i++)
168		if (button_mse[i].key == keypress) break;
169
170	/* No such button */
171	if (i == button_num)
172	{
173		return 0;
174	}
175
176	/* Find the length */
177	length = button_mse[i].right - button_mse[i].left + 1;
178	button_length -= length;
179
180	/* Move each button up one */
181	for (j = i; j < button_num - 1; j++)
182	{
183		button_mse[j] = button_mse[j + 1];
184
185		/* Adjust length */
186		button_mse[j].left -= length;
187		button_mse[j].right -= length;
188	}
189
190	/* Wipe the data */
191	button_mse[button_num].label[0] = '\0';
192	button_mse[button_num].left = 0;
193	button_mse[button_num].right = 0;
194	button_mse[button_num--].key = 0;
195
196	/* Redraw */
197	p_ptr->redraw |= (PR_BUTTONS);
198	redraw_stuff();
199
200	/* Return the size of the button */
201	return (length);
202}
203
204/*
205 * Kill a button
206 */
207int button_kill(unsigned char keypress)
208{
209	if (!button_kill_hook) return 0;
210	else
211		return (*button_kill_hook) (keypress);
212}
213
214/*
215 * Kill all buttons
216 */
217void button_kill_all(void)
218{
219	int i;
220
221	/* Paranoia */
222	if (!button_kill_hook) return;
223
224	/* One by one */
225	for (i = button_num - 1; i >= 0; i--)
226		(void)(*button_kill_hook) (button_mse[i].key);
227}
228
229
230/*
231 * Initialise buttons.
232 */
233void button_init(button_add_f add, button_kill_f kill)
234{
235	/* Prepare mouse button arrays */
236	button_mse = C_ZNEW(MAX_MOUSE_BUTTONS, button_mouse);
237	button_backup = C_ZNEW(MAX_MOUSE_BUTTONS, button_mouse);
238
239	/* Initialise the hooks */
240	button_add_hook = add;
241	button_kill_hook = kill;
242}
243
244
245/**
246 * Return the character represented by a button at screen position (x, y),
247 * or 0.
248 */
249char button_get_key(int x, int y)
250{
251	int i;
252
253	for (i = 0; i < button_num; i++)
254	{
255		if ((y == Term->hgt - 1) &&
256		    (x >= button_start + button_mse[i].left) &&
257		    (x <= button_start + button_mse[i].right))
258		{
259			return button_mse[i].key;
260		}
261	}
262
263	return 0;
264}
265
266/**
267 * Print the current button list at the specified `row` and `col`umn.
268 */
269size_t button_print(int row, int col)
270{
271	int j;
272
273	button_start = col;
274
275	for (j = 0; j < button_num; j++)
276		c_put_str(TERM_SLATE, button_mse[j].label, row, col + button_mse[j].left);
277
278	return button_length;
279}
280