simplify menu api

This commit is contained in:
Maxime Coste 2012-09-05 19:02:06 +02:00
parent 11d86ca3f3
commit 16e1c2daf9
5 changed files with 44 additions and 78 deletions

View File

@ -42,7 +42,6 @@ private:
int m_count = 0; int m_count = 0;
}; };
class Client::MenuMode : public Client::Mode class Client::MenuMode : public Client::Mode
{ {
public: public:
@ -50,12 +49,12 @@ public:
: Client::Mode(client), : Client::Mode(client),
m_callback(callback), m_choice_count(choices.size()), m_selected(0) m_callback(callback), m_choice_count(choices.size()), m_selected(0)
{ {
client.show_menu(choices); client.menu_show(choices);
} }
~MenuMode() ~MenuMode()
{ {
m_client.menu_ctrl(MenuCommand::Close); m_client.menu_hide();
} }
void on_key(const Key& key, Context& context) override void on_key(const Key& key, Context& context) override
@ -65,23 +64,15 @@ public:
key == Key(Key::Modifiers::None, 'j')) key == Key(Key::Modifiers::None, 'j'))
{ {
if (++m_selected >= m_choice_count) if (++m_selected >= m_choice_count)
{
m_client.menu_ctrl(MenuCommand::SelectFirst);
m_selected = 0; m_selected = 0;
} m_client.menu_select(m_selected);
else
m_client.menu_ctrl(MenuCommand::SelectNext);
} }
if (key == Key(Key::Modifiers::Control, 'p') or if (key == Key(Key::Modifiers::Control, 'p') or
key == Key(Key::Modifiers::None, 'k')) key == Key(Key::Modifiers::None, 'k'))
{ {
if (--m_selected < 0) if (--m_selected < 0)
{
m_client.menu_ctrl(MenuCommand::SelectLast);
m_selected = m_choice_count-1; m_selected = m_choice_count-1;
} m_client.menu_select(m_selected);
else
m_client.menu_ctrl(MenuCommand::SelectPrev);
} }
if (key == Key(Key::Modifiers::Control, 'm')) if (key == Key(Key::Modifiers::Control, 'm'))
{ {
@ -98,7 +89,7 @@ public:
if (key.modifiers == Key::Modifiers::None and if (key.modifiers == Key::Modifiers::None and
key.key >= '0' and key.key <= '9') key.key >= '0' and key.key <= '9')
{ {
m_client.menu_ctrl(MenuCommand::Close); m_client.menu_hide();
// save callback as reset_normal_mode will delete this // save callback as reset_normal_mode will delete this
MenuCallback callback = std::move(m_callback); MenuCallback callback = std::move(m_callback);
m_client.reset_normal_mode(); m_client.reset_normal_mode();
@ -125,7 +116,7 @@ public:
~PromptMode() ~PromptMode()
{ {
m_client.menu_ctrl(MenuCommand::Close); m_client.menu_hide();
} }
void on_key(const Key& key, Context& context) override void on_key(const Key& key, Context& context) override
@ -214,14 +205,14 @@ public:
--m_cursor_pos; --m_cursor_pos;
} }
m_client.menu_ctrl(MenuCommand::Close); m_client.menu_hide();
m_current_completion = -1; m_current_completion = -1;
} }
else if (key == Key(Key::Modifiers::Control, 'r')) else if (key == Key(Key::Modifiers::Control, 'r'))
{ {
Key k = m_client.get_key(); Key k = m_client.get_key();
String reg = RegisterManager::instance()[k.key].values(context)[0]; String reg = RegisterManager::instance()[k.key].values(context)[0];
m_client.menu_ctrl(MenuCommand::Close); m_client.menu_hide();
m_current_completion = -1; m_current_completion = -1;
m_result = m_result.substr(0, m_cursor_pos) + reg + m_result.substr(m_cursor_pos, String::npos); m_result = m_result.substr(0, m_cursor_pos) + reg + m_result.substr(m_cursor_pos, String::npos);
m_cursor_pos += reg.length(); m_cursor_pos += reg.length();
@ -234,13 +225,11 @@ public:
if (m_completions.candidates.empty()) if (m_completions.candidates.empty())
return; return;
m_client.menu_ctrl(MenuCommand::Close); m_client.menu_hide();
m_client.show_menu(m_completions.candidates); m_client.menu_show(m_completions.candidates);
m_text_before_completion = m_result.substr(m_completions.start, m_text_before_completion = m_result.substr(m_completions.start,
m_completions.end - m_completions.start); m_completions.end - m_completions.start);
} }
else
m_client.menu_ctrl(MenuCommand::SelectNext);
++m_current_completion; ++m_current_completion;
String completion; String completion;
@ -250,24 +239,23 @@ public:
std::find(m_completions.candidates.begin(), m_completions.candidates.end(), m_text_before_completion) == m_completions.candidates.end()) std::find(m_completions.candidates.begin(), m_completions.candidates.end(), m_text_before_completion) == m_completions.candidates.end())
{ {
completion = m_text_before_completion; completion = m_text_before_completion;
m_client.menu_ctrl(MenuCommand::SelectNone);
} }
else else
{ {
m_current_completion = 0; m_current_completion = 0;
completion = m_completions.candidates[0]; completion = m_completions.candidates[0];
m_client.menu_ctrl(MenuCommand::SelectFirst);
} }
} }
else else
completion = m_completions.candidates[m_current_completion]; completion = m_completions.candidates[m_current_completion];
m_client.menu_select(m_current_completion);
m_result = m_result.substr(0, m_completions.start) + completion; m_result = m_result.substr(0, m_completions.start) + completion;
m_cursor_pos = m_completions.start + completion.length(); m_cursor_pos = m_completions.start + completion.length();
} }
else else
{ {
m_client.menu_ctrl(MenuCommand::Close); m_client.menu_hide();
m_current_completion = -1; m_current_completion = -1;
m_result = m_result.substr(0, m_cursor_pos) + key.key + m_result.substr(m_cursor_pos, String::npos); m_result = m_result.substr(0, m_cursor_pos) + key.key + m_result.substr(m_cursor_pos, String::npos);
++m_cursor_pos; ++m_cursor_pos;

View File

@ -14,16 +14,6 @@ class Editor;
class Window; class Window;
class Context; class Context;
enum class MenuCommand
{
SelectFirst,
SelectLast,
SelectPrev,
SelectNext,
SelectNone,
Close,
};
using MenuCallback = std::function<void (int, Context&)>; using MenuCallback = std::function<void (int, Context&)>;
using PromptCallback = std::function<void (const String&, Context&)>; using PromptCallback = std::function<void (const String&, Context&)>;
using KeyCallback = std::function<void (const Key&, Context&)>; using KeyCallback = std::function<void (const Key&, Context&)>;
@ -51,8 +41,9 @@ public:
void handle_next_input(Context& context); void handle_next_input(Context& context);
private: private:
virtual void show_menu(const memoryview<String>& choices) = 0; virtual void menu_show(const memoryview<String>& choices) = 0;
virtual void menu_ctrl(MenuCommand command) = 0; virtual void menu_select(int selected) = 0;
virtual void menu_hide() = 0;
virtual Key get_key() = 0; virtual Key get_key() = 0;
void reset_normal_mode(); void reset_normal_mode();

View File

@ -246,7 +246,7 @@ Buffer* open_fifo(const String& name , const String& filename, Context& context)
{ EventManager::instance().unwatch(fd); close(fd); } { EventManager::instance().unwatch(fd); close(fd); }
); );
EventManager::instance().watch(fd, [=, &context](int fd) { EventManager::instance().watch(fd, [buffer, &context](int fd) {
char data[512]; char data[512];
ssize_t count = read(fd, data, 512); ssize_t count = read(fd, data, 512);
if (count > 0) if (count > 0)
@ -675,8 +675,9 @@ public:
void print_status(const String& status, CharCount cursor_pos) override {} void print_status(const String& status, CharCount cursor_pos) override {}
void draw_window(Window& window) override {} void draw_window(Window& window) override {}
void show_menu(const memoryview<String>&) override {} void menu_show(const memoryview<String>&) override {}
void menu_ctrl(MenuCommand) override {} void menu_select(int) override {}
void menu_hide() override {}
bool has_key_left() const { return m_pos < m_keys.size(); } bool has_key_left() const { return m_pos < m_keys.size(); }

View File

@ -212,7 +212,7 @@ void NCursesClient::print_status(const String& status, CharCount cursor_pos)
refresh(); refresh();
} }
void NCursesClient::show_menu(const memoryview<String>& choices) void NCursesClient::menu_show(const memoryview<String>& choices)
{ {
assert(m_menu == nullptr); assert(m_menu == nullptr);
m_choices = std::vector<String>(choices.begin(), choices.end()); m_choices = std::vector<String>(choices.begin(), choices.end());
@ -244,45 +244,30 @@ void NCursesClient::show_menu(const memoryview<String>& choices)
refresh(); refresh();
} }
void NCursesClient::menu_ctrl(MenuCommand command) void NCursesClient::menu_select(int selected)
{ {
switch(command) if (0 <= selected and selected < m_items.size())
{ {
case MenuCommand::SelectFirst: set_menu_fore(m_menu, COLOR_PAIR(m_menu_fg));
set_menu_fore(m_menu, COLOR_PAIR(m_menu_fg)); set_current_item(m_menu, m_items[selected]);
menu_driver(m_menu, REQ_FIRST_ITEM);
break;
case MenuCommand::SelectLast:
set_menu_fore(m_menu, COLOR_PAIR(m_menu_fg));
menu_driver(m_menu, REQ_LAST_ITEM);
break;
case MenuCommand::SelectNext:
set_menu_fore(m_menu, COLOR_PAIR(m_menu_fg));
menu_driver(m_menu, REQ_NEXT_ITEM);
break;
case MenuCommand::SelectPrev:
set_menu_fore(m_menu, COLOR_PAIR(m_menu_fg));
menu_driver(m_menu, REQ_PREV_ITEM);
break;
case MenuCommand::SelectNone:
set_menu_fore(m_menu, COLOR_PAIR(m_menu_bg));
break;
case MenuCommand::Close:
{
if (not m_menu)
break;
unpost_menu(m_menu);
free_menu(m_menu);
for (auto item : m_items)
if (item)
free_item(item);
m_menu = nullptr;
m_items.clear();
m_counts.clear();
m_counts.clear();
break;
}
} }
else
set_menu_fore(m_menu, COLOR_PAIR(m_menu_bg));
refresh();
}
void NCursesClient::menu_hide()
{
if (not m_menu)
return;
unpost_menu(m_menu);
free_menu(m_menu);
for (auto item : m_items)
if (item)
free_item(item);
m_menu = nullptr;
m_items.clear();
m_counts.clear();
refresh(); refresh();
} }

View File

@ -23,8 +23,9 @@ public:
Key get_key() override; Key get_key() override;
void show_menu(const memoryview<String>& choices) override; void menu_show(const memoryview<String>& choices) override;
void menu_ctrl(MenuCommand command) override; void menu_select(int selected) override;
void menu_hide() override;
private: private:
MENU* m_menu; MENU* m_menu;
std::vector<ITEM*> m_items; std::vector<ITEM*> m_items;