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

View File

@ -14,16 +14,6 @@ class Editor;
class Window;
class Context;
enum class MenuCommand
{
SelectFirst,
SelectLast,
SelectPrev,
SelectNext,
SelectNone,
Close,
};
using MenuCallback = std::function<void (int, Context&)>;
using PromptCallback = std::function<void (const String&, Context&)>;
using KeyCallback = std::function<void (const Key&, Context&)>;
@ -51,8 +41,9 @@ public:
void handle_next_input(Context& context);
private:
virtual void show_menu(const memoryview<String>& choices) = 0;
virtual void menu_ctrl(MenuCommand command) = 0;
virtual void menu_show(const memoryview<String>& choices) = 0;
virtual void menu_select(int selected) = 0;
virtual void menu_hide() = 0;
virtual Key get_key() = 0;
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().watch(fd, [=, &context](int fd) {
EventManager::instance().watch(fd, [buffer, &context](int fd) {
char data[512];
ssize_t count = read(fd, data, 512);
if (count > 0)
@ -675,8 +675,9 @@ public:
void print_status(const String& status, CharCount cursor_pos) override {}
void draw_window(Window& window) override {}
void show_menu(const memoryview<String>&) override {}
void menu_ctrl(MenuCommand) override {}
void menu_show(const memoryview<String>&) override {}
void menu_select(int) override {}
void menu_hide() override {}
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();
}
void NCursesClient::show_menu(const memoryview<String>& choices)
void NCursesClient::menu_show(const memoryview<String>& choices)
{
assert(m_menu == nullptr);
m_choices = std::vector<String>(choices.begin(), choices.end());
@ -244,45 +244,30 @@ void NCursesClient::show_menu(const memoryview<String>& choices)
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));
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;
}
set_menu_fore(m_menu, COLOR_PAIR(m_menu_fg));
set_current_item(m_menu, m_items[selected]);
}
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();
}

View File

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