summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMaxime Coste <frrrwww@gmail.com>2012-09-30 15:18:37 +0200
committerMaxime Coste <frrrwww@gmail.com>2012-09-30 15:18:37 +0200
commit5b6cb500fcc392de1b1264677985337a8bfcc201 (patch)
tree94665b02b7918a0daf9ce46c9056484d77b05b09 /src
parentf230feec7f18fcea705cd4d6e507d2256d1658f8 (diff)
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.
Diffstat (limited to 'src')
-rw-r--r--src/client.cc6
-rw-r--r--src/commands.cc3
-rw-r--r--src/ncurses.cc49
-rw-r--r--src/ncurses.hh10
-rw-r--r--src/user_interface.hh10
5 files changed, 53 insertions, 25 deletions
diff --git a/src/client.cc b/src/client.cc
index 829bfd3f..e037ed19 100644
--- a/src/client.cc
+++ b/src/client.cc
@@ -69,7 +69,8 @@ public:
: ClientMode(context.client()),
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
@@ -253,7 +254,8 @@ public:
return;
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,
m_completions.end - m_completions.start);
if (not contains(candidates, prefix))
diff --git a/src/commands.cc b/src/commands.cc
index 6b7cfccd..055ba22d 100644
--- a/src/commands.cc
+++ b/src/commands.cc
@@ -666,7 +666,8 @@ public:
void print_status(const String& , CharCount) 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_hide() override {}
diff --git a/src/ncurses.cc b/src/ncurses.cc
index 2581cf48..2115d002 100644
--- a/src/ncurses.cc
+++ b/src/ncurses.cc
@@ -71,7 +71,6 @@ static void set_color(Color fg_color, Color bg_color)
NCursesUI::NCursesUI()
- : m_menu(nullptr)
{
// setlocale(LC_ALL, "");
initscr();
@@ -94,6 +93,17 @@ NCursesUI::~NCursesUI()
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)
{
int max_x,max_y;
@@ -101,19 +111,10 @@ void NCursesUI::draw_window(Window& window)
max_y -= 1;
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.update_display_buffer();
int line_index = 0;
- int last_line = INT_MAX;
for (const DisplayLine& line : window.display_buffer().lines())
{
move(line_index, 0);
@@ -161,7 +162,8 @@ void NCursesUI::draw_window(Window& window)
move(status_y, max_x - (int)status_line.length());
addstr(status_line.c_str());
last_status_length = (int)status_line.length();
- refresh();
+
+ redraw(m_menu_win);
}
Key NCursesUI::get_key()
@@ -219,12 +221,14 @@ void NCursesUI::print_status(const String& status, CharCount cursor_pos)
addch(' ');
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_win == nullptr);
m_choices = std::vector<String>(choices.begin(), choices.end());
CharCount longest = 0;
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;
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));
+ 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]);
- int pos_y = max_y - lines - 1;
- set_menu_sub(m_menu, derwin(stdscr, max_y - pos_y - 1, max_x, pos_y, 0));
+ m_menu_win = newwin((int)m_menu_size.line, (int)m_menu_size.column,
+ (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_mark(m_menu, nullptr);
set_menu_fore(m_menu, COLOR_PAIR(m_menu_fg));
set_menu_back(m_menu, COLOR_PAIR(m_menu_bg));
post_menu(m_menu);
- refresh();
}
void NCursesUI::menu_select(int selected)
@@ -262,7 +273,6 @@ void NCursesUI::menu_select(int selected)
}
else
set_menu_fore(m_menu, COLOR_PAIR(m_menu_bg));
- refresh();
}
void NCursesUI::menu_hide()
@@ -275,8 +285,9 @@ void NCursesUI::menu_hide()
if (item)
free_item(item);
m_menu = nullptr;
+ delwin(m_menu_win);
+ m_menu_win = nullptr;
m_items.clear();
- refresh();
}
}
diff --git a/src/ncurses.hh b/src/ncurses.hh
index b7a7c54b..fa8743bf 100644
--- a/src/ncurses.hh
+++ b/src/ncurses.hh
@@ -5,6 +5,7 @@
#include <menu.h>
#include "user_interface.hh"
+#include "display_buffer.hh"
namespace Kakoune
{
@@ -23,14 +24,19 @@ public:
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_hide() override;
private:
- MENU* m_menu;
+ MENU* m_menu = nullptr;
+ WINDOW* m_menu_win = nullptr;
std::vector<ITEM*> m_items;
std::vector<String> m_choices;
+ DisplayCoord m_menu_pos;
+ DisplayCoord m_menu_size;
+
int m_menu_fg;
int m_menu_bg;
};
diff --git a/src/user_interface.hh b/src/user_interface.hh
index a6df5ec2..80b59c8a 100644
--- a/src/user_interface.hh
+++ b/src/user_interface.hh
@@ -11,13 +11,21 @@ namespace Kakoune
class String;
class Window;
+class DisplayCoord;
+
+enum class MenuStyle
+{
+ Prompt,
+ Inline
+};
class UserInterface : public SafeCountable
{
public:
virtual ~UserInterface() {}
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_hide() = 0;
virtual void draw_window(Window& window) = 0;