Menus can be placed anywhere on the screen, and takes a style parameter
This paves the way for insert mode completion menu using the current prompt menu system.
This commit is contained in:
parent
f230feec7f
commit
5b6cb500fc
|
@ -69,7 +69,8 @@ public:
|
||||||
: ClientMode(context.client()),
|
: ClientMode(context.client()),
|
||||||
m_callback(callback), m_choice_count(choices.size()), m_selected(0)
|
m_callback(callback), m_choice_count(choices.size()), m_selected(0)
|
||||||
{
|
{
|
||||||
context.ui().menu_show(choices);
|
DisplayCoord menu_pos{ context.window().dimensions().line, 0_char };
|
||||||
|
context.ui().menu_show(choices, menu_pos, MenuStyle::Prompt);
|
||||||
}
|
}
|
||||||
|
|
||||||
void on_key(const Key& key, Context& context) override
|
void on_key(const Key& key, Context& context) override
|
||||||
|
@ -253,7 +254,8 @@ public:
|
||||||
return;
|
return;
|
||||||
|
|
||||||
context.ui().menu_hide();
|
context.ui().menu_hide();
|
||||||
context.ui().menu_show(candidates);
|
DisplayCoord menu_pos{ context.window().dimensions().line, 0_char };
|
||||||
|
context.ui().menu_show(candidates, menu_pos, MenuStyle::Prompt);
|
||||||
String prefix = m_result.substr(m_completions.start,
|
String prefix = m_result.substr(m_completions.start,
|
||||||
m_completions.end - m_completions.start);
|
m_completions.end - m_completions.start);
|
||||||
if (not contains(candidates, prefix))
|
if (not contains(candidates, prefix))
|
||||||
|
|
|
@ -666,7 +666,8 @@ public:
|
||||||
|
|
||||||
void print_status(const String& , CharCount) override {}
|
void print_status(const String& , CharCount) override {}
|
||||||
void draw_window(Window&) override {}
|
void draw_window(Window&) override {}
|
||||||
void menu_show(const memoryview<String>&) override {}
|
void menu_show(const memoryview<String>&,
|
||||||
|
const DisplayCoord&, MenuStyle) override {}
|
||||||
void menu_select(int) override {}
|
void menu_select(int) override {}
|
||||||
void menu_hide() override {}
|
void menu_hide() override {}
|
||||||
|
|
||||||
|
|
|
@ -71,7 +71,6 @@ static void set_color(Color fg_color, Color bg_color)
|
||||||
|
|
||||||
|
|
||||||
NCursesUI::NCursesUI()
|
NCursesUI::NCursesUI()
|
||||||
: m_menu(nullptr)
|
|
||||||
{
|
{
|
||||||
// setlocale(LC_ALL, "");
|
// setlocale(LC_ALL, "");
|
||||||
initscr();
|
initscr();
|
||||||
|
@ -94,6 +93,17 @@ NCursesUI::~NCursesUI()
|
||||||
endwin();
|
endwin();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void redraw(WINDOW* menu_win)
|
||||||
|
{
|
||||||
|
wnoutrefresh(stdscr);
|
||||||
|
if (menu_win)
|
||||||
|
{
|
||||||
|
redrawwin(menu_win);
|
||||||
|
wnoutrefresh(menu_win);
|
||||||
|
}
|
||||||
|
doupdate();
|
||||||
|
}
|
||||||
|
|
||||||
void NCursesUI::draw_window(Window& window)
|
void NCursesUI::draw_window(Window& window)
|
||||||
{
|
{
|
||||||
int max_x,max_y;
|
int max_x,max_y;
|
||||||
|
@ -101,19 +111,10 @@ void NCursesUI::draw_window(Window& window)
|
||||||
max_y -= 1;
|
max_y -= 1;
|
||||||
int status_y = max_y;
|
int status_y = max_y;
|
||||||
|
|
||||||
if (m_menu)
|
|
||||||
{
|
|
||||||
int rows;
|
|
||||||
int cols;
|
|
||||||
menu_format(m_menu, &rows, &cols);
|
|
||||||
max_y -= rows;
|
|
||||||
}
|
|
||||||
|
|
||||||
window.set_dimensions(DisplayCoord(LineCount(max_y), max_x));
|
window.set_dimensions(DisplayCoord(LineCount(max_y), max_x));
|
||||||
window.update_display_buffer();
|
window.update_display_buffer();
|
||||||
|
|
||||||
int line_index = 0;
|
int line_index = 0;
|
||||||
int last_line = INT_MAX;
|
|
||||||
for (const DisplayLine& line : window.display_buffer().lines())
|
for (const DisplayLine& line : window.display_buffer().lines())
|
||||||
{
|
{
|
||||||
move(line_index, 0);
|
move(line_index, 0);
|
||||||
|
@ -161,7 +162,8 @@ void NCursesUI::draw_window(Window& window)
|
||||||
move(status_y, max_x - (int)status_line.length());
|
move(status_y, max_x - (int)status_line.length());
|
||||||
addstr(status_line.c_str());
|
addstr(status_line.c_str());
|
||||||
last_status_length = (int)status_line.length();
|
last_status_length = (int)status_line.length();
|
||||||
refresh();
|
|
||||||
|
redraw(m_menu_win);
|
||||||
}
|
}
|
||||||
|
|
||||||
Key NCursesUI::get_key()
|
Key NCursesUI::get_key()
|
||||||
|
@ -219,12 +221,14 @@ void NCursesUI::print_status(const String& status, CharCount cursor_pos)
|
||||||
addch(' ');
|
addch(' ');
|
||||||
set_attribute(A_REVERSE, 0);
|
set_attribute(A_REVERSE, 0);
|
||||||
}
|
}
|
||||||
refresh();
|
redraw(m_menu_win);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NCursesUI::menu_show(const memoryview<String>& choices)
|
void NCursesUI::menu_show(const memoryview<String>& choices,
|
||||||
|
const DisplayCoord& anchor, MenuStyle style)
|
||||||
{
|
{
|
||||||
assert(m_menu == nullptr);
|
assert(m_menu == nullptr);
|
||||||
|
assert(m_menu_win == nullptr);
|
||||||
m_choices = std::vector<String>(choices.begin(), choices.end());
|
m_choices = std::vector<String>(choices.begin(), choices.end());
|
||||||
CharCount longest = 0;
|
CharCount longest = 0;
|
||||||
for (int i = 0; i < m_choices.size(); ++i)
|
for (int i = 0; i < m_choices.size(); ++i)
|
||||||
|
@ -237,19 +241,26 @@ void NCursesUI::menu_show(const memoryview<String>& choices)
|
||||||
|
|
||||||
int max_x,max_y;
|
int max_x,max_y;
|
||||||
getmaxyx(stdscr, max_y, max_x);
|
getmaxyx(stdscr, max_y, max_x);
|
||||||
|
max_x -= (int)anchor.column;
|
||||||
|
|
||||||
int columns = max_x / std::min(max_x, (int)longest);
|
int columns = (style == MenuStyle::Prompt) ?
|
||||||
|
(max_x / std::min(max_x, (int)longest)) : 1;
|
||||||
int lines = std::min(10, (int)ceilf((float)m_choices.size()/columns));
|
int lines = std::min(10, (int)ceilf((float)m_choices.size()/columns));
|
||||||
|
|
||||||
|
m_menu_pos = { anchor.line+1, anchor.column };
|
||||||
|
if (m_menu_pos.line + lines >= max_y)
|
||||||
|
m_menu_pos.line = anchor.line - lines;
|
||||||
|
m_menu_size = { lines, columns == 1 ? longest : max_x };
|
||||||
|
|
||||||
m_menu = new_menu(&m_items[0]);
|
m_menu = new_menu(&m_items[0]);
|
||||||
int pos_y = max_y - lines - 1;
|
m_menu_win = newwin((int)m_menu_size.line, (int)m_menu_size.column,
|
||||||
set_menu_sub(m_menu, derwin(stdscr, max_y - pos_y - 1, max_x, pos_y, 0));
|
(int)m_menu_pos.line, (int)m_menu_pos.column);
|
||||||
|
set_menu_win(m_menu, m_menu_win);
|
||||||
set_menu_format(m_menu, lines, columns);
|
set_menu_format(m_menu, lines, columns);
|
||||||
set_menu_mark(m_menu, nullptr);
|
set_menu_mark(m_menu, nullptr);
|
||||||
set_menu_fore(m_menu, COLOR_PAIR(m_menu_fg));
|
set_menu_fore(m_menu, COLOR_PAIR(m_menu_fg));
|
||||||
set_menu_back(m_menu, COLOR_PAIR(m_menu_bg));
|
set_menu_back(m_menu, COLOR_PAIR(m_menu_bg));
|
||||||
post_menu(m_menu);
|
post_menu(m_menu);
|
||||||
refresh();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NCursesUI::menu_select(int selected)
|
void NCursesUI::menu_select(int selected)
|
||||||
|
@ -262,7 +273,6 @@ void NCursesUI::menu_select(int selected)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
set_menu_fore(m_menu, COLOR_PAIR(m_menu_bg));
|
set_menu_fore(m_menu, COLOR_PAIR(m_menu_bg));
|
||||||
refresh();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NCursesUI::menu_hide()
|
void NCursesUI::menu_hide()
|
||||||
|
@ -275,8 +285,9 @@ void NCursesUI::menu_hide()
|
||||||
if (item)
|
if (item)
|
||||||
free_item(item);
|
free_item(item);
|
||||||
m_menu = nullptr;
|
m_menu = nullptr;
|
||||||
|
delwin(m_menu_win);
|
||||||
|
m_menu_win = nullptr;
|
||||||
m_items.clear();
|
m_items.clear();
|
||||||
refresh();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <menu.h>
|
#include <menu.h>
|
||||||
|
|
||||||
#include "user_interface.hh"
|
#include "user_interface.hh"
|
||||||
|
#include "display_buffer.hh"
|
||||||
|
|
||||||
namespace Kakoune
|
namespace Kakoune
|
||||||
{
|
{
|
||||||
|
@ -23,14 +24,19 @@ public:
|
||||||
|
|
||||||
Key get_key() override;
|
Key get_key() override;
|
||||||
|
|
||||||
void menu_show(const memoryview<String>& choices) override;
|
void menu_show(const memoryview<String>& choices,
|
||||||
|
const DisplayCoord& anchor, MenuStyle style) override;
|
||||||
void menu_select(int selected) override;
|
void menu_select(int selected) override;
|
||||||
void menu_hide() override;
|
void menu_hide() override;
|
||||||
private:
|
private:
|
||||||
MENU* m_menu;
|
MENU* m_menu = nullptr;
|
||||||
|
WINDOW* m_menu_win = nullptr;
|
||||||
std::vector<ITEM*> m_items;
|
std::vector<ITEM*> m_items;
|
||||||
std::vector<String> m_choices;
|
std::vector<String> m_choices;
|
||||||
|
|
||||||
|
DisplayCoord m_menu_pos;
|
||||||
|
DisplayCoord m_menu_size;
|
||||||
|
|
||||||
int m_menu_fg;
|
int m_menu_fg;
|
||||||
int m_menu_bg;
|
int m_menu_bg;
|
||||||
};
|
};
|
||||||
|
|
|
@ -11,13 +11,21 @@ namespace Kakoune
|
||||||
|
|
||||||
class String;
|
class String;
|
||||||
class Window;
|
class Window;
|
||||||
|
class DisplayCoord;
|
||||||
|
|
||||||
|
enum class MenuStyle
|
||||||
|
{
|
||||||
|
Prompt,
|
||||||
|
Inline
|
||||||
|
};
|
||||||
|
|
||||||
class UserInterface : public SafeCountable
|
class UserInterface : public SafeCountable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~UserInterface() {}
|
virtual ~UserInterface() {}
|
||||||
virtual void print_status(const String& status, CharCount cursor_pos = -1) = 0;
|
virtual void print_status(const String& status, CharCount cursor_pos = -1) = 0;
|
||||||
virtual void menu_show(const memoryview<String>& choices) = 0;
|
virtual void menu_show(const memoryview<String>& choices,
|
||||||
|
const DisplayCoord& anchor, MenuStyle style) = 0;
|
||||||
virtual void menu_select(int selected) = 0;
|
virtual void menu_select(int selected) = 0;
|
||||||
virtual void menu_hide() = 0;
|
virtual void menu_hide() = 0;
|
||||||
virtual void draw_window(Window& window) = 0;
|
virtual void draw_window(Window& window) = 0;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user