File: cmd_dpfocus.c

package info (click to toggle)
gentoo 0.11.46-1
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 5,648 kB
  • ctags: 4,313
  • sloc: ansic: 33,912; sh: 3,903; makefile: 649; yacc: 316; sed: 16
file content (190 lines) | stat: -rw-r--r-- 5,110 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
/*
** 1999-05-10 -	A module to deal with the command group DpFocus, the purpose of which is
**		to (finally!) make keyboard navigation possible in gentoo. Should at least
**		give people something else to mail me about. :^)
*/

#include "gentoo.h"

#include "dirpane.h"
#include "cmdarg.h"
#include "cmdseq_config.h"
#include "cmd_dpfocus.h"

/* ----------------------------------------------------------------------------------------- */

typedef struct {
	gboolean	modified;
	gboolean	edge_wrap;		/* Wrap focus at upper/lower edge? */
	gboolean	fake_select;		/* Treat focus as selection if no "real" selection exists? */
	gboolean	focus_select;		/* Move focus to last selected/deselected row? */
} OptDpFocus;

static OptDpFocus	dpfocus_options;
static CmdCfg		*dpfocus_cmc = NULL;

/* ----------------------------------------------------------------------------------------- */

#define	CMD_NONE	(0)
#define	CMD_SAME	(1)
#define	CMD_PREV	(2)
#define	CMD_NEXT	(3)
#define	CMD_PAGEPREV	(4)
#define	CMD_PAGENEXT	(5)
#define	CMD_FIRST	(6)
#define	CMD_LAST	(7)
#define	CMD_ACTIVATE	(8)

/* ----------------------------------------------------------------------------------------- */

#define	CELL_SPACING	1

/* Move focus bar one pageful. Based on stuff seen in gtkclist.c. Note horrid assumption
** that CELL_SPACING in said file is 1.
*/
static void move_page(DirPane *src, gint direction)
{
	gint	dest, ph, max;

	ph   = (GTK_CLIST(src->list)->clist_window_height / (GTK_CLIST(src->list)->row_height + CELL_SPACING)) - 1;
	max  = GTK_CLIST(src->list)->rows - 1;
	dest = src->focus_row + direction * ph;
	if(dest < 0)
	{
		if((dest == -ph) && dpfocus_options.edge_wrap)
			dest = max;
		else
			dest = 0;
	}
	else if(dest > max)
	{
		if((dest == max + ph) && dpfocus_options.edge_wrap)
			dest = 0;
		else
			dest = GTK_CLIST(src->list)->rows - 1;
	}
	/* Since dp_focus() scrolls, freeze. We want our own scrolling for this. */
	dp_freeze(src);
	dp_focus(src, dest);
	gtk_clist_moveto(src->list, dest, -1, 0.5 + direction * 0.5, 0.0);
	dp_thaw(src);
}

/* 1999-05-10 -	Do some focusing. */
gint cmd_dpfocus(MainInfo *min, DirPane *src, DirPane *dst, const CmdArg *ca)
{
	gboolean	sel = car_keyword_get_boolean(ca, "select", FALSE),
			center = car_keyword_get_boolean(ca, "center", FALSE);
	guint		cmd = car_bareword_get_enum(ca, 0, CMD_SAME, "none", "same", "prev", "next",
							"pageprev", "pagenext", "first", "last", "activate", NULL);

	if((sel == TRUE) && (cmd >= CMD_SAME && cmd <= CMD_LAST))
		dp_toggle(src, src->focus_row);

	switch(cmd)
	{
		case CMD_NONE:
			dp_unfocus(src);
			src->old_focus_row = -1;		/* None really means none. */
			break;
		case CMD_SAME:
			break;
		case CMD_PREV:
			if(src->focus_row == -1)
				dp_focus(src, src->dir.num_rows - 1);
			else
			{
				gint	dest = src->focus_row - 1;

				if(dest < 0)
				{
					if(dpfocus_options.edge_wrap)
						dest = src->dir.num_rows - 1;
					else
						dest = 0;
				}
				if(dest != src->focus_row)
					dp_focus(src, dest);
			}
			break;
		case CMD_NEXT:
			if(src->focus_row == -1)
				dp_focus(src, 0);
			else
			{
				gint	dest = src->focus_row + 1;

				if(dest >= src->dir.num_rows)
				{
					if(dpfocus_options.edge_wrap)
						dest = 0;
					else
						dest = src->dir.num_rows - 1;
				}
				if(dest != src->focus_row)
					dp_focus(src, dest);
			}
			break;
		case CMD_PAGEPREV:
			if(src->focus_row == -1)
				dp_focus(src, src->dir.num_rows - 1);
			else
				move_page(src, -1);
			break;
		case CMD_PAGENEXT:
			if(src->focus_row == -1)
				dp_focus(src, 0);
			else
				move_page(src, 1);
			break;
		case CMD_FIRST:
			dp_focus(src, 0);
			break;
		case CMD_LAST:
			dp_focus(src, src->dir.num_rows - 1);
			break;
		case CMD_ACTIVATE:
			dp_dbclk_row(src, src->focus_row);
			break;
	}

	if((center == TRUE) && (src->focus_row != -1))
		gtk_clist_moveto(src->list, src->focus_row, -1, 0.5, 0.0);

/*	gtk_widget_grab_focus(GTK_WIDGET(min->gui->top));*/

	return 1;
}

/* ----------------------------------------------------------------------------------------- */

/* Just return the "fake select" option. */
gboolean dpf_get_fake_select(void)
{
	return dpfocus_options.fake_select;
}

/* Return the "focus selected" option. */
gboolean dpf_get_focus_select(void)
{
	return dpfocus_options.focus_select;
}

void cfg_dpfocus(MainInfo *min)
{
	if(dpfocus_cmc == NULL)
	{
		dpfocus_options.modified  = FALSE;
		dpfocus_options.edge_wrap = FALSE;
		dpfocus_options.fake_select = FALSE;

		dpfocus_cmc = cmc_config_new("DpFocus", &dpfocus_options);
		cmc_field_add_boolean(dpfocus_cmc, "modified", NULL, offsetof(OptDpFocus, modified));
		cmc_field_add_boolean(dpfocus_cmc, "edge_wrap", _("Wrap Around At Top And Bottom?"), offsetof(OptDpFocus, edge_wrap));
		cmc_field_add_boolean(dpfocus_cmc, "fake_select", _("Treat Focused Row As Selection "
						"If No \"Real\" Selection Exists?"), offsetof(OptDpFocus, fake_select));
		cmc_field_add_boolean(dpfocus_cmc, "focus_select", _("Move Focus to Last Selected/Deselected "
						"Row?"), offsetof(OptDpFocus, focus_select));
		cmc_config_register(dpfocus_cmc);
	}
}