aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTheJackiMonster <thejackimonster@gmail.com>2022-08-18 23:47:38 +0200
committerTheJackiMonster <thejackimonster@gmail.com>2022-08-18 23:47:38 +0200
commit3e527b0e1eeb1ce61cda8251494a35b2a3ce872e (patch)
tree34cd3b778509c38ded31b2fd16824d9ae2916341
parent82dfd76ff534e362b7bfb3c12b870286a354f80b (diff)
downloadmessenger-cli-3e527b0e1eeb1ce61cda8251494a35b2a3ce872e.tar.gz
messenger-cli-3e527b0e1eeb1ce61cda8251494a35b2a3ce872e.zip
Normalized list input via macros
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
-rw-r--r--Makefile3
-rw-r--r--src/ui/accounts.c71
-rw-r--r--src/ui/chats.c88
-rw-r--r--src/ui/list_input.h114
-rw-r--r--src/ui/lobby_create_dialog.c53
-rw-r--r--src/ui/lobby_create_dialog.h49
-rw-r--r--src/ui/members.c60
-rw-r--r--src/ui/messages.c74
8 files changed, 259 insertions, 253 deletions
diff --git a/Makefile b/Makefile
index 1713bff..6ab183d 100644
--- a/Makefile
+++ b/Makefile
@@ -11,6 +11,7 @@ SOURCES = messenger_cli.c\
11 ui/accounts.c\ 11 ui/accounts.c\
12 ui/chat_open_dialog.c\ 12 ui/chat_open_dialog.c\
13 ui/chats.c\ 13 ui/chats.c\
14 ui/lobby_create_dialog.c\
14 ui/lobby_enter_dialog.c\ 15 ui/lobby_enter_dialog.c\
15 ui/members.c\ 16 ui/members.c\
16 ui/messages.c 17 ui/messages.c
@@ -22,6 +23,8 @@ HEADERS = application.h\
22 ui/chat.h\ 23 ui/chat.h\
23 ui/chat_open_dialog.h\ 24 ui/chat_open_dialog.h\
24 ui/chats.h\ 25 ui/chats.h\
26 ui/list_input.h\
27 ui/lobby_create_dialog.h\
25 ui/lobby_enter_dialog.h\ 28 ui/lobby_enter_dialog.h\
26 ui/members.h\ 29 ui/members.h\
27 ui/messages.h\ 30 ui/messages.h\
diff --git a/src/ui/accounts.c b/src/ui/accounts.c
index 4936c82..380506d 100644
--- a/src/ui/accounts.c
+++ b/src/ui/accounts.c
@@ -24,6 +24,7 @@
24 24
25#include "accounts.h" 25#include "accounts.h"
26 26
27#include "list_input.h"
27#include "../application.h" 28#include "../application.h"
28#include "../util.h" 29#include "../util.h"
29 30
@@ -33,14 +34,7 @@ _accounts_iterate(void *cls,
33 struct GNUNET_CHAT_Account *account) 34 struct GNUNET_CHAT_Account *account)
34{ 35{
35 UI_ACCOUNTS_Handle *accounts = cls; 36 UI_ACCOUNTS_Handle *accounts = cls;
36 37 list_input_select(accounts, 1, account);
37 const bool selected = (accounts->line_selected == accounts->line_index);
38
39 accounts->line_index++;
40
41 if (selected)
42 accounts->selected = account;
43
44 return GNUNET_YES; 38 return GNUNET_YES;
45} 39}
46 40
@@ -55,66 +49,34 @@ accounts_event(UI_ACCOUNTS_Handle *accounts,
55 return; 49 return;
56 } 50 }
57 51
58 accounts->line_index = 0; 52 list_input_reset(accounts);
59 accounts->selected = NULL;
60 53
61 int count = GNUNET_CHAT_iterate_accounts( 54 GNUNET_CHAT_iterate_accounts(
62 app->chat.handle, 55 app->chat.handle,
63 &_accounts_iterate, 56 &_accounts_iterate,
64 accounts 57 accounts
65 ) + 1; 58 );
59
60 list_input_select(accounts, 1, NULL);
66 61
67 switch (key) 62 switch (key)
68 { 63 {
69 case 27: 64 case 27:
70 case KEY_EXIT: 65 case KEY_EXIT:
71 {
72 app->chat.quit = TRUE; 66 app->chat.quit = TRUE;
73 break; 67 break;
74 }
75 case KEY_UP:
76 {
77 accounts->line_selected--;
78 break;
79 }
80 case KEY_DOWN:
81 {
82 accounts->line_selected++;
83 break;
84 }
85 case '\n': 68 case '\n':
86 case KEY_ENTER: 69 case KEY_ENTER:
87 {
88 if (accounts->selected) 70 if (accounts->selected)
89 GNUNET_CHAT_connect(app->chat.handle, accounts->selected); 71 GNUNET_CHAT_connect(app->chat.handle, accounts->selected);
90 else 72 else
91 accounts->create_dialog.window = &(accounts->window); 73 accounts->create_dialog.window = &(accounts->window);
92 break; 74 break;
93 }
94 default: 75 default:
95 break; 76 break;
96 } 77 }
97 78
98 if (accounts->line_selected < 0) 79 list_input_event(accounts, key);
99 accounts->line_selected = 0;
100 else if (accounts->line_selected >= count)
101 accounts->line_selected = count - 1;
102
103 if (!(accounts->window))
104 return;
105
106 const int height = getmaxy(accounts->window);
107 const int y = accounts->line_selected - accounts->line_offset;
108
109 if (y < 0)
110 accounts->line_offset += y;
111 else if (y + 1 >= height)
112 accounts->line_offset += y + 1 - height;
113
114 if (accounts->line_offset < 0)
115 accounts->line_offset = 0;
116 else if (accounts->line_offset >= count)
117 accounts->line_offset = count - 1;
118} 80}
119 81
120static int 82static int
@@ -122,18 +84,7 @@ _accounts_print_entry(UI_ACCOUNTS_Handle *accounts,
122 char type, 84 char type,
123 const char *text) 85 const char *text)
124{ 86{
125 const bool selected = (accounts->line_selected == accounts->line_index); 87 list_input_print_gnunet(accounts, 1);
126 const int y = accounts->line_index - accounts->line_offset;
127
128 accounts->line_index++;
129
130 if (y < 0)
131 return GNUNET_YES;
132
133 const int height = getmaxy(accounts->window);
134
135 if (y >= height)
136 return GNUNET_NO;
137 88
138 const int attrs_select = A_BOLD; 89 const int attrs_select = A_BOLD;
139 90
@@ -153,9 +104,7 @@ _accounts_iterate_print(void *cls,
153 struct GNUNET_CHAT_Account *account) 104 struct GNUNET_CHAT_Account *account)
154{ 105{
155 UI_ACCOUNTS_Handle *accounts = cls; 106 UI_ACCOUNTS_Handle *accounts = cls;
156
157 const char *name = GNUNET_CHAT_account_get_name(account); 107 const char *name = GNUNET_CHAT_account_get_name(account);
158
159 return _accounts_print_entry(accounts, 'x', name); 108 return _accounts_print_entry(accounts, 'x', name);
160} 109}
161 110
@@ -172,7 +121,7 @@ accounts_print(UI_ACCOUNTS_Handle *accounts,
172 if (!(accounts->window)) 121 if (!(accounts->window))
173 return; 122 return;
174 123
175 accounts->line_index = 0; 124 list_input_reset(accounts);
176 werase(accounts->window); 125 werase(accounts->window);
177 126
178 GNUNET_CHAT_iterate_accounts( 127 GNUNET_CHAT_iterate_accounts(
diff --git a/src/ui/chats.c b/src/ui/chats.c
index 1a25927..5517541 100644
--- a/src/ui/chats.c
+++ b/src/ui/chats.c
@@ -24,6 +24,7 @@
24 24
25#include "chats.h" 25#include "chats.h"
26 26
27#include "list_input.h"
27#include "../application.h" 28#include "../application.h"
28#include "../util.h" 29#include "../util.h"
29 30
@@ -33,14 +34,7 @@ _chats_iterate_group(void *cls,
33 struct GNUNET_CHAT_Group *group) 34 struct GNUNET_CHAT_Group *group)
34{ 35{
35 UI_CHATS_Handle *chats = cls; 36 UI_CHATS_Handle *chats = cls;
36 37 list_input_select(chats, 1, GNUNET_CHAT_group_get_context(group));
37 const bool selected = (chats->line_selected == chats->line_index);
38
39 chats->line_index++;
40
41 if (selected)
42 chats->selected = GNUNET_CHAT_group_get_context(group);
43
44 return GNUNET_YES; 38 return GNUNET_YES;
45} 39}
46 40
@@ -50,14 +44,7 @@ _chats_iterate_contact(void *cls,
50 struct GNUNET_CHAT_Contact *contact) 44 struct GNUNET_CHAT_Contact *contact)
51{ 45{
52 UI_CHATS_Handle *chats = cls; 46 UI_CHATS_Handle *chats = cls;
53 47 list_input_select(chats, 1, GNUNET_CHAT_contact_get_context(contact));
54 const bool selected = (chats->line_selected == chats->line_index);
55
56 chats->line_index++;
57
58 if (selected)
59 chats->selected = GNUNET_CHAT_contact_get_context(contact);
60
61 return GNUNET_YES; 48 return GNUNET_YES;
62} 49}
63 50
@@ -87,44 +74,34 @@ chats_event(UI_CHATS_Handle *chats,
87 return; 74 return;
88 } 75 }
89 76
90 chats->line_index = 0; 77 list_input_reset(chats);
91 chats->selected = NULL;
92 78
93 int count = 3; 79 GNUNET_CHAT_iterate_groups(
94
95 count += GNUNET_CHAT_iterate_groups(
96 app->chat.handle, 80 app->chat.handle,
97 &_chats_iterate_group, 81 &_chats_iterate_group,
98 chats 82 chats
99 ); 83 );
100 84
101 count += GNUNET_CHAT_iterate_contacts( 85 GNUNET_CHAT_iterate_contacts(
102 app->chat.handle, 86 app->chat.handle,
103 &_chats_iterate_contact, 87 &_chats_iterate_contact,
104 chats 88 chats
105 ); 89 );
106 90
91 list_input_select(chats, 1, NULL);
92 list_input_select(chats, 1, NULL);
93 list_input_select(chats, 1, NULL);
94
95 const int count = chats->line_index;
96
107 switch (key) 97 switch (key)
108 { 98 {
109 case 27: 99 case 27:
110 case KEY_EXIT: 100 case KEY_EXIT:
111 {
112 GNUNET_CHAT_disconnect(app->chat.handle); 101 GNUNET_CHAT_disconnect(app->chat.handle);
113 break; 102 break;
114 }
115 case KEY_UP:
116 {
117 chats->line_selected--;
118 break;
119 }
120 case KEY_DOWN:
121 {
122 chats->line_selected++;
123 break;
124 }
125 case '\n': 103 case '\n':
126 case KEY_ENTER: 104 case KEY_ENTER:
127 {
128 if (chats->selected) 105 if (chats->selected)
129 { 106 {
130 GNUNET_CHAT_context_request(chats->selected); 107 GNUNET_CHAT_context_request(chats->selected);
@@ -150,31 +127,11 @@ chats_event(UI_CHATS_Handle *chats,
150 else if (chats->line_selected == count - 1) 127 else if (chats->line_selected == count - 1)
151 chats->enter_dialog.window = &(chats->window); 128 chats->enter_dialog.window = &(chats->window);
152 break; 129 break;
153 }
154 default: 130 default:
155 break; 131 break;
156 } 132 }
157 133
158 if (chats->line_selected < 0) 134 list_input_event(chats, key);
159 chats->line_selected = 0;
160 else if (chats->line_selected >= count)
161 chats->line_selected = count - 1;
162
163 if (!(chats->window))
164 return;
165
166 const int height = getmaxy(chats->window);
167 const int y = chats->line_selected - chats->line_offset;
168
169 if (y < 0)
170 chats->line_offset += y;
171 else if (y + 1 >= height)
172 chats->line_offset += y + 1 - height;
173
174 if (chats->line_offset < 0)
175 chats->line_offset = 0;
176 else if (chats->line_offset >= count)
177 chats->line_offset = count - 1;
178} 135}
179 136
180static int 137static int
@@ -183,18 +140,7 @@ _chats_print_entry(UI_CHATS_Handle *chats,
183 char chat_type, 140 char chat_type,
184 const char *text) 141 const char *text)
185{ 142{
186 const bool selected = (chats->line_selected == chats->line_index); 143 list_input_print_gnunet(chats, 1);
187 const int y = chats->line_index - chats->line_offset;
188
189 chats->line_index++;
190
191 if (y < 0)
192 return GNUNET_YES;
193
194 const int height = getmaxy(chats->window);
195
196 if (y >= height)
197 return GNUNET_NO;
198 144
199 const int attrs_select = A_BOLD; 145 const int attrs_select = A_BOLD;
200 146
@@ -218,9 +164,7 @@ _chats_iterate_print_group(void *cls,
218 struct GNUNET_CHAT_Group *group) 164 struct GNUNET_CHAT_Group *group)
219{ 165{
220 UI_CHATS_Handle *chats = cls; 166 UI_CHATS_Handle *chats = cls;
221
222 const char *name = GNUNET_CHAT_group_get_name(group); 167 const char *name = GNUNET_CHAT_group_get_name(group);
223
224 return _chats_print_entry(chats, 'x', 'G', name); 168 return _chats_print_entry(chats, 'x', 'G', name);
225} 169}
226 170
@@ -230,9 +174,7 @@ _chats_iterate_print_contact(void *cls,
230 struct GNUNET_CHAT_Contact *contact) 174 struct GNUNET_CHAT_Contact *contact)
231{ 175{
232 UI_CHATS_Handle *chats = cls; 176 UI_CHATS_Handle *chats = cls;
233
234 const char *name = GNUNET_CHAT_contact_get_name(contact); 177 const char *name = GNUNET_CHAT_contact_get_name(contact);
235
236 return _chats_print_entry(chats, 'x', 'C', name); 178 return _chats_print_entry(chats, 'x', 'C', name);
237} 179}
238 180
@@ -254,7 +196,7 @@ chats_print(UI_CHATS_Handle *chats,
254 if (!(chats->window)) 196 if (!(chats->window))
255 return; 197 return;
256 198
257 chats->line_index = 0; 199 list_input_reset(chats);
258 werase(chats->window); 200 werase(chats->window);
259 201
260 GNUNET_CHAT_iterate_groups( 202 GNUNET_CHAT_iterate_groups(
diff --git a/src/ui/list_input.h b/src/ui/list_input.h
new file mode 100644
index 0000000..aad3ae4
--- /dev/null
+++ b/src/ui/list_input.h
@@ -0,0 +1,114 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2022 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20/*
21 * @author Tobias Frisch
22 * @file ui/list_input.h
23 */
24
25#ifndef UI_LIST_INPUT_H_
26#define UI_LIST_INPUT_H_
27
28#include <stdbool.h>
29#include <stdlib.h>
30
31#define list_input_reset(list) { \
32 (list)->line_index = 0; \
33 (list)->selected = NULL; \
34}
35
36#define list_input_select(list, line_width, item) { \
37 const bool selected = ( \
38 ((list)->line_selected >= (list)->line_index) && \
39 ((list)->line_selected < (list)->line_index + line_width) \
40 ); \
41 \
42 (list)->line_index += line_width; \
43 \
44 if (selected) \
45 (list)->selected = item; \
46}
47
48#define list_input_event(list, key) { \
49 int count = (list)->line_index; \
50 \
51 switch (key) \
52 { \
53 case KEY_UP: \
54 { \
55 (list)->line_selected--; \
56 break; \
57 } \
58 case KEY_DOWN: \
59 { \
60 (list)->line_selected++; \
61 break; \
62 } \
63 default: \
64 break; \
65 } \
66 \
67 if ((list)->line_selected < 0) \
68 (list)->line_selected = 0; \
69 else if ((list)->line_selected >= count) \
70 (list)->line_selected = count - 1; \
71 \
72 if ((list)->window) \
73 { \
74 const int height = getmaxy((list)->window); \
75 const int y = (list)->line_selected - (list)->line_offset; \
76 \
77 if (y < 0) \
78 (list)->line_offset += y; \
79 else if (y + 1 >= height) \
80 (list)->line_offset += y + 1 - height; \
81 \
82 if ((list)->line_offset < 0) \
83 (list)->line_offset = 0; \
84 else if ((list)->line_offset >= count) \
85 (list)->line_offset = count - 1; \
86 } \
87}
88
89#define list_input_print_(list, line_width, yes_res, no_res) \
90 const bool selected = ( \
91 ((list)->line_selected >= (list)->line_index) && \
92 ((list)->line_selected < (list)->line_index + line_width) \
93 ); \
94 \
95 const int y = (list)->line_index - (list)->line_offset; { \
96 \
97 (list)->line_index += line_width; \
98 \
99 if (y + line_width < 1) \
100 return yes_res; \
101 \
102 const int height = getmaxy((list)->window); \
103 \
104 if (y >= height) \
105 return no_res; \
106}
107
108#define list_input_print_gnunet(list, line_width) \
109 list_input_print_(list, line_width, GNUNET_YES, GNUNET_NO)
110
111#define list_input_print(list, line_width) \
112 list_input_print_(list, line_width, , )
113
114#endif /* UI_LIST_INPUT_H_ */
diff --git a/src/ui/lobby_create_dialog.c b/src/ui/lobby_create_dialog.c
new file mode 100644
index 0000000..9c80929
--- /dev/null
+++ b/src/ui/lobby_create_dialog.c
@@ -0,0 +1,53 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2022 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20/*
21 * @author Tobias Frisch
22 * @file ui/lobby_create_dialog.c
23 */
24
25#include "lobby_create_dialog.h"
26
27void
28lobby_create_dialog_event(UI_LOBBY_CREATE_DIALOG_Handle *create_dialog,
29 struct MESSENGER_Application *app,
30 int key)
31{
32 // TODO
33}
34
35void
36lobby_create_dialog_print(UI_LOBBY_CREATE_DIALOG_Handle *create_dialog,
37 struct MESSENGER_Application *app)
38{
39 /*
40 Delay until it expires:
41
42 30 seconds
43 5 minutes
44 1 hour
45 8 hours
46 1 day
47 1 week
48 4 weeks
49 Off
50 */
51
52 // TODO
53}
diff --git a/src/ui/lobby_create_dialog.h b/src/ui/lobby_create_dialog.h
new file mode 100644
index 0000000..f780522
--- /dev/null
+++ b/src/ui/lobby_create_dialog.h
@@ -0,0 +1,49 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2022 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20/*
21 * @author Tobias Frisch
22 * @file ui/lobby_create_dialog.h
23 */
24
25#ifndef UI_LOBBY_CREATE_DIALOG_H_
26#define UI_LOBBY_CREATE_DIALOG_H_
27
28#include <stdlib.h>
29#include <curses.h>
30
31struct MESSENGER_Application;
32
33typedef struct UI_LOBBY_CREATE_DIALOG_Handle
34{
35 WINDOW **window;
36
37 // TODO
38} UI_LOBBY_CREATE_DIALOG_Handle;
39
40void
41lobby_create_dialog_event(UI_LOBBY_CREATE_DIALOG_Handle *create_dialog,
42 struct MESSENGER_Application *app,
43 int key);
44
45void
46lobby_create_dialog_print(UI_LOBBY_CREATE_DIALOG_Handle *create_dialog,
47 struct MESSENGER_Application *app);
48
49#endif /* UI_LOBBY_CREATE_DIALOG_H_ */
diff --git a/src/ui/members.c b/src/ui/members.c
index 509e03b..b0abb7c 100644
--- a/src/ui/members.c
+++ b/src/ui/members.c
@@ -24,6 +24,7 @@
24 24
25#include "members.h" 25#include "members.h"
26 26
27#include "list_input.h"
27#include "../application.h" 28#include "../application.h"
28#include "../util.h" 29#include "../util.h"
29 30
@@ -32,16 +33,12 @@ members_event(UI_MEMBERS_Handle *members,
32 struct MESSENGER_Application *app, 33 struct MESSENGER_Application *app,
33 int key) 34 int key)
34{ 35{
35 members->line_index = 0; 36 list_input_reset(members);
36 members->selected = NULL;
37
38 int count = 0;
39 37
40 UI_MEMBERS_List *element = members->head; 38 UI_MEMBERS_List *element = members->head;
41 while (element) 39 while (element)
42 { 40 {
43 count++; 41 list_input_select(members, 1, element->contact);
44
45 element = element->next; 42 element = element->next;
46 } 43 }
47 44
@@ -50,72 +47,28 @@ members_event(UI_MEMBERS_Handle *members,
50 case 27: 47 case 27:
51 case KEY_EXIT: 48 case KEY_EXIT:
52 case '\t': 49 case '\t':
53 {
54 app->chat.show_members = FALSE; 50 app->chat.show_members = FALSE;
55 break; 51 break;
56 }
57 case KEY_UP:
58 {
59 members->line_selected--;
60 break;
61 }
62 case KEY_DOWN:
63 {
64 members->line_selected++;
65 break;
66 }
67 case '\n': 52 case '\n':
68 case KEY_ENTER: 53 case KEY_ENTER:
69 {
70 if (members->selected) 54 if (members->selected)
71 { 55 {
72 // TODO 56 // TODO
73 } 57 }
74 58
75 break; 59 break;
76 }
77 default: 60 default:
78 break; 61 break;
79 } 62 }
80 63
81 if (members->line_selected < 0) 64 list_input_event(members, key);
82 members->line_selected = 0;
83 else if (members->line_selected >= count)
84 members->line_selected = count - 1;
85
86 if (!(members->window))
87 return;
88
89 const int height = getmaxy(members->window);
90 const int y = members->line_selected - members->line_offset;
91
92 if (y < 0)
93 members->line_offset += y;
94 else if (y + 1 >= height)
95 members->line_offset += y + 1 - height;
96
97 if (members->line_offset < 0)
98 members->line_offset = 0;
99 else if (members->line_offset >= count)
100 members->line_offset = count - 1;
101} 65}
102 66
103static void 67static void
104_members_iterate_print(UI_MEMBERS_Handle *members, 68_members_iterate_print(UI_MEMBERS_Handle *members,
105 const struct GNUNET_CHAT_Contact *contact) 69 const struct GNUNET_CHAT_Contact *contact)
106{ 70{
107 const bool selected = (members->line_selected == members->line_index); 71 list_input_print(members, 1);
108 const int y = members->line_index - members->line_offset;
109
110 members->line_index++;
111
112 if (y < 0)
113 return;
114
115 const int height = getmaxy(members->window);
116
117 if (y >= height)
118 return;
119 72
120 const int attrs_select = A_BOLD; 73 const int attrs_select = A_BOLD;
121 74
@@ -142,14 +95,13 @@ members_print(UI_MEMBERS_Handle *members)
142 if (!(members->window)) 95 if (!(members->window))
143 return; 96 return;
144 97
145 members->line_index = 0; 98 list_input_reset(members);
146 werase(members->window); 99 werase(members->window);
147 100
148 UI_MEMBERS_List *element = members->head; 101 UI_MEMBERS_List *element = members->head;
149 while (element) 102 while (element)
150 { 103 {
151 _members_iterate_print(members, element->contact); 104 _members_iterate_print(members, element->contact);
152
153 element = element->next; 105 element = element->next;
154 } 106 }
155} 107}
diff --git a/src/ui/messages.c b/src/ui/messages.c
index 211fe94..86df8e5 100644
--- a/src/ui/messages.c
+++ b/src/ui/messages.c
@@ -24,23 +24,12 @@
24 24
25#include "messages.h" 25#include "messages.h"
26 26
27#include "list_input.h"
27#include "text_input.h" 28#include "text_input.h"
28#include "../application.h" 29#include "../application.h"
29#include "../util.h" 30#include "../util.h"
30 31
31void 32void
32_messages_iterate(UI_MESSAGES_Handle *messages,
33 const struct GNUNET_CHAT_Message *message)
34{
35 const bool selected = (messages->line_selected == messages->line_index);
36
37 messages->line_index++;
38
39 if (selected)
40 messages->selected = message;
41}
42
43void
44_messages_handle_message(UI_MESSAGES_Handle *messages) 33_messages_handle_message(UI_MESSAGES_Handle *messages)
45{ 34{
46 switch (GNUNET_CHAT_message_get_kind(messages->selected)) 35 switch (GNUNET_CHAT_message_get_kind(messages->selected))
@@ -75,32 +64,23 @@ messages_event(UI_MESSAGES_Handle *messages,
75 MESSENGER_Application *app, 64 MESSENGER_Application *app,
76 int key) 65 int key)
77{ 66{
78 messages->line_index = 0; 67 list_input_reset(messages);
79 messages->selected = NULL;
80
81 int count = 1;
82 68
83 UI_MESSAGES_List *element = messages->head; 69 UI_MESSAGES_List *element = messages->head;
84 while (element) 70 while (element)
85 { 71 {
86 _messages_iterate(messages, element->message); 72 list_input_select(messages, 1, element->message);
87 count++;
88
89 element = element->next; 73 element = element->next;
90 } 74 }
91 75
76 list_input_select(messages, 1, NULL);
77
92 switch (key) 78 switch (key)
93 { 79 {
94 case 27: 80 case 27:
95 case KEY_EXIT: 81 case KEY_EXIT:
96 app->chat.context = NULL; 82 app->chat.context = NULL;
97 break; 83 break;
98 case KEY_UP:
99 messages->line_selected--;
100 break;
101 case KEY_DOWN:
102 messages->line_selected++;
103 break;
104 case '\t': 84 case '\t':
105 app->chat.show_members = TRUE; 85 app->chat.show_members = TRUE;
106 break; 86 break;
@@ -128,28 +108,7 @@ messages_event(UI_MESSAGES_Handle *messages,
128 if (!(messages->selected)) 108 if (!(messages->selected))
129 text_input_event(messages->text, key); 109 text_input_event(messages->text, key);
130 110
131 if (messages->line_selected < 0) 111 list_input_event(messages, key);
132 messages->line_selected = 0;
133 else if (messages->line_selected >= count)
134 messages->line_selected = count - 1;
135
136 if (!(messages->window))
137 return;
138
139 const int height = getmaxy(messages->window);
140 const int y = messages->line_selected - messages->line_offset;
141
142 const int line_height = height - 2;
143
144 if (y < 0)
145 messages->line_offset += y;
146 else if (y + 1 >= line_height)
147 messages->line_offset += y + 1 - line_height;
148
149 if (messages->line_offset < 0)
150 messages->line_offset = 0;
151 else if (messages->line_offset >= count)
152 messages->line_offset = count - 1;
153} 112}
154 113
155void 114void
@@ -158,19 +117,7 @@ _messages_iterate_print(UI_MESSAGES_Handle *messages,
158{ 117{
159 enum GNUNET_CHAT_MessageKind kind = GNUNET_CHAT_message_get_kind(message); 118 enum GNUNET_CHAT_MessageKind kind = GNUNET_CHAT_message_get_kind(message);
160 119
161 const bool selected = (messages->line_selected == messages->line_index); 120 list_input_print(messages, 1);
162 const int y = messages->line_index - messages->line_offset;
163
164 messages->line_index++;
165
166 if (y < 0)
167 return;
168
169 const int height = getmaxy(messages->window);
170 const int line_height = height - 2;
171
172 if (y >= line_height)
173 return;
174 121
175 struct GNUNET_CHAT_Contact *sender = GNUNET_CHAT_message_get_sender(message); 122 struct GNUNET_CHAT_Contact *sender = GNUNET_CHAT_message_get_sender(message);
176 123
@@ -270,20 +217,17 @@ messages_print(UI_MESSAGES_Handle *messages)
270 if (!(messages->window)) 217 if (!(messages->window))
271 return; 218 return;
272 219
273 messages->line_index = 0; 220 list_input_reset(messages);
274 werase(messages->window); 221 werase(messages->window);
275 222
276 int count = 0;
277
278 UI_MESSAGES_List *element = messages->head; 223 UI_MESSAGES_List *element = messages->head;
279 while (element) 224 while (element)
280 { 225 {
281 _messages_iterate_print(messages, element->message); 226 _messages_iterate_print(messages, element->message);
282 count++;
283
284 element = element->next; 227 element = element->next;
285 } 228 }
286 229
230 const int count = messages->line_index;
287 const bool selected = (count == messages->line_selected); 231 const bool selected = (count == messages->line_selected);
288 232
289 const int width = getmaxx(messages->window); 233 const int width = getmaxx(messages->window);