simplify menu api
This commit is contained in:
parent
11d86ca3f3
commit
16e1c2daf9
|
@ -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;
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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(); }
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user