remove print_status from UserInterface, pass status line to draw

Client store the current status line. This way calls to print status
do not force the user interface to display directly.
This commit is contained in:
Maxime Coste 2013-09-16 19:15:13 +01:00
parent 49903523a7
commit 06e06d6ea6
10 changed files with 72 additions and 83 deletions

View File

@ -182,7 +182,7 @@ public:
if (key == Key(Key::Modifiers::Control, 'm'))
{
context().ui().menu_hide();
context().ui().print_status(DisplayLine{});
context().print_status(DisplayLine{});
reset_normal_mode();
int selected = m_selected - m_choices.begin();
m_callback(selected, MenuEvent::Validate, context());
@ -195,7 +195,7 @@ public:
m_edit_filter = false;
m_filter = boost::regex(".*");
m_filter_editor.reset("");
context().ui().print_status(DisplayLine{});
context().print_status(DisplayLine{});
}
else
{
@ -246,7 +246,7 @@ public:
{
auto display_line = m_filter_editor.build_display_line();
display_line.insert(display_line.begin(), { "filter:"_str, get_color("Prompt") });
context().ui().print_status(display_line);
context().print_status(display_line);
}
}
@ -320,7 +320,7 @@ public:
history.erase(it);
history.push_back(line);
}
context().ui().print_status(DisplayLine{});
context().print_status(DisplayLine{});
context().ui().menu_hide();
reset_normal_mode();
// call callback after reset_normal_mode so that callback
@ -330,7 +330,7 @@ public:
}
else if (key == Key::Escape or key == Key { Key::Modifiers::Control, 'c' })
{
context().ui().print_status(DisplayLine{});
context().print_status(DisplayLine{});
context().ui().menu_hide();
reset_normal_mode();
m_callback(line, PromptEvent::Abort, context());
@ -453,7 +453,7 @@ private:
{
auto display_line = m_line_editor.build_display_line();
display_line.insert(display_line.begin(), { m_prompt, m_prompt_colors });
context().ui().print_status(display_line);
context().print_status(display_line);
}
PromptCallback m_callback;
@ -1019,4 +1019,47 @@ void Client::stop_recording()
m_recording_reg = 0;
}
void Client::print_status(DisplayLine status_line)
{
m_status_line = std::move(status_line);
m_context.window().forget_timestamp();
}
static DisplayLine generate_mode_line(Client& client)
{
auto& context = client.context();
auto pos = context.editor().main_selection().last();
auto col = context.buffer()[pos.line].char_count_to(pos.column);
std::ostringstream oss;
oss << context.buffer().display_name()
<< " " << (int)pos.line+1 << ":" << (int)col+1;
if (context.buffer().is_modified())
oss << " [+]";
if (context.client().is_recording())
oss << " [recording]";
if (context.buffer().flags() & Buffer::Flags::New)
oss << " [new file]";
oss << " [" << context.editor().selections().size() << " sel]";
if (context.editor().is_editing())
oss << " [insert]";
oss << " - " << client.name();
return { oss.str(), get_color("StatusLine") };
}
void Client::redraw_ifn()
{
if (m_context.window().timestamp() != m_context.buffer().timestamp())
{
DisplayCoord dimensions = m_context.ui().dimensions();
if (dimensions == DisplayCoord{0,0})
return;
m_context.window().set_dimensions(dimensions);
m_context.window().update_display_buffer();;
m_context.ui().draw(m_context.window().display_buffer(),
m_status_line, generate_mode_line(*this));
}
}
}

View File

@ -8,6 +8,7 @@
#include "keys.hh"
#include "string.hh"
#include "utils.hh"
#include "display_buffer.hh"
namespace Kakoune
{
@ -78,6 +79,10 @@ public:
const String& name() const { return m_name; }
void set_name(String name) { m_name = std::move(name); }
void print_status(DisplayLine status_line);
void redraw_ifn();
UserInterface& ui() const { return *m_ui; }
private:
Context m_context;
@ -87,6 +92,7 @@ private:
std::vector<std::unique_ptr<InputMode>> m_mode_trash;
String m_name;
DisplayLine m_status_line;
using Insertion = std::pair<InsertMode, std::vector<Key>>;
Insertion m_last_insert = {InsertMode::Insert, {}};

View File

@ -151,45 +151,10 @@ Client& ClientManager::get_client(const String& name)
throw runtime_error("no client named: " + name);
}
static DisplayLine generate_status_line(Client& client)
{
auto& context = client.context();
auto pos = context.editor().main_selection().last();
auto col = context.buffer()[pos.line].char_count_to(pos.column);
std::ostringstream oss;
oss << context.buffer().display_name()
<< " " << (int)pos.line+1 << ":" << (int)col+1;
if (context.buffer().is_modified())
oss << " [+]";
if (context.client().is_recording())
oss << " [recording]";
if (context.buffer().flags() & Buffer::Flags::New)
oss << " [new file]";
oss << " [" << context.editor().selections().size() << " sel]";
if (context.editor().is_editing())
oss << " [insert]";
oss << " - " << client.name();
return { oss.str(), get_color("StatusLine") };
}
void ClientManager::redraw_clients() const
{
for (auto& client : m_clients)
{
Context& context = client->context();
if (context.window().timestamp() != context.buffer().timestamp())
{
DisplayCoord dimensions = context.ui().dimensions();
if (dimensions == DisplayCoord{0,0})
return;
context.window().set_dimensions(dimensions);
context.window().update_display_buffer();;
context.ui().draw(context.window().display_buffer(),
generate_status_line(*client));
}
}
client->redraw_ifn();
}
}

View File

@ -540,8 +540,6 @@ void declare_option(CommandParameters params, Context& context)
class DraftUI : public UserInterface
{
public:
void print_status(const DisplayLine&) override {}
void menu_show(memoryview<String>, DisplayCoord, ColorPair, ColorPair, MenuStyle) override {}
void menu_select(int) override {}
void menu_hide() override {}
@ -549,7 +547,7 @@ public:
void info_show(const String&, DisplayCoord, ColorPair, MenuStyle) override {}
void info_hide() override {}
void draw(const DisplayBuffer&, const DisplayLine&) override {}
void draw(const DisplayBuffer&, const DisplayLine&, const DisplayLine&) override {}
DisplayCoord dimensions() override { return {0,0}; }
bool is_key_available() override { return false; }
Key get_key() override { return 'a'; }
@ -571,8 +569,7 @@ void context_wrap(CommandParameters params, Context& context, Func func)
{
Editor& editor = real_context.editor();
Client client(std::unique_ptr<UserInterface>(new DraftUI()), editor,
real_context.has_client() ?
real_context.client().name() : "");
real_context.has_client() ? real_context.client().name() : "");
DynamicSelectionList sels{editor.buffer(), editor.selections()};
auto restore_sels = on_scope_end([&]{ editor.select(sels); });
func(parser, client.context());

View File

@ -75,10 +75,10 @@ HookManager& Context::hooks() const
return GlobalHooks::instance();
}
void Context::print_status(const DisplayLine& status) const
void Context::print_status(DisplayLine status) const
{
if (has_ui())
ui().print_status(status);
if (has_client())
client().print_status(std::move(status));
}
void Context::push_jump()

View File

@ -49,7 +49,7 @@ struct Context
OptionManager& options() const;
HookManager& hooks() const;
void print_status(const DisplayLine& status) const;
void print_status(DisplayLine status) const;
void push_jump();
const DynamicSelectionList& jump_forward();

View File

@ -240,6 +240,7 @@ void NCursesUI::draw_line(const DisplayLine& line, CharCount col_index) const
}
void NCursesUI::draw(const DisplayBuffer& display_buffer,
const DisplayLine& status_line,
const DisplayLine& mode_line)
{
LineCount line_index = 0;
@ -265,10 +266,10 @@ void NCursesUI::draw(const DisplayBuffer& display_buffer,
move((int)m_dimensions.line, 0);
clrtoeol();
draw_line(m_status_line, 0);
draw_line(status_line, 0);
CharCount status_len = mode_line.length();
// only draw mode_line if it does not overlap one status line
if (m_dimensions.column - m_status_line.length() > status_len + 1)
if (m_dimensions.column - status_line.length() > status_len + 1)
{
CharCount col = m_dimensions.column - status_len;
move((int)m_dimensions.line, (int)col);
@ -358,15 +359,6 @@ Key NCursesUI::get_key()
return Key::Invalid;
}
void NCursesUI::print_status(const DisplayLine& status)
{
m_status_line = status;
move((int)m_dimensions.line, 0);
clrtoeol();
draw_line(status, 0);
redraw();
}
void NCursesUI::draw_menu()
{
// menu show may have not created the window if it did not fit.

View File

@ -20,8 +20,8 @@ public:
NCursesUI& operator=(const NCursesUI&) = delete;
void draw(const DisplayBuffer& display_buffer,
const DisplayLine& status_line,
const DisplayLine& mode_line) override;
void print_status(const DisplayLine& status) override;
bool is_key_available() override;
Key get_key() override;
@ -49,8 +49,6 @@ private:
DisplayCoord m_dimensions;
void update_dimensions();
DisplayLine m_status_line;
NCursesWin* m_menu_win = nullptr;
std::vector<String> m_choices;
ColorPair m_menu_fg;

View File

@ -20,7 +20,6 @@ namespace Kakoune
enum class RemoteUIMsg
{
PrintStatus,
MenuShow,
MenuSelect,
MenuHide,
@ -217,8 +216,6 @@ public:
RemoteUI(int socket);
~RemoteUI();
void print_status(const DisplayLine& status) override;
void menu_show(memoryview<String> choices,
DisplayCoord anchor, ColorPair fg, ColorPair bg,
MenuStyle style) override;
@ -230,6 +227,7 @@ public:
void info_hide() override;
void draw(const DisplayBuffer& display_buffer,
const DisplayLine& status_line,
const DisplayLine& mode_line) override;
bool is_key_available() override;
@ -257,13 +255,6 @@ RemoteUI::~RemoteUI()
close(m_socket_watcher.fd());
}
void RemoteUI::print_status(const DisplayLine& status)
{
Message msg(m_socket_watcher.fd());
msg.write(RemoteUIMsg::PrintStatus);
msg.write(status);
}
void RemoteUI::menu_show(memoryview<String> choices,
DisplayCoord anchor, ColorPair fg, ColorPair bg,
MenuStyle style)
@ -308,11 +299,13 @@ void RemoteUI::info_hide()
}
void RemoteUI::draw(const DisplayBuffer& display_buffer,
const DisplayLine& status_line,
const DisplayLine& mode_line)
{
Message msg(m_socket_watcher.fd());
msg.write(RemoteUIMsg::Draw);
msg.write(display_buffer);
msg.write(status_line);
msg.write(mode_line);
}
@ -385,12 +378,6 @@ void RemoteClient::process_next_message()
RemoteUIMsg msg = read<RemoteUIMsg>(socket);
switch (msg)
{
case RemoteUIMsg::PrintStatus:
{
auto status = read<DisplayLine>(socket);
m_ui->print_status(status);
break;
}
case RemoteUIMsg::MenuShow:
{
auto choices = read_vector<String>(socket);
@ -422,8 +409,9 @@ void RemoteClient::process_next_message()
case RemoteUIMsg::Draw:
{
auto display_buffer = read<DisplayBuffer>(socket);
auto status_line = read<DisplayLine>(socket);
auto mode_line = read<DisplayLine>(socket);
m_ui->draw(display_buffer, mode_line);
m_ui->draw(display_buffer, status_line, mode_line);
break;
}
}

View File

@ -26,7 +26,6 @@ class UserInterface : public SafeCountable
{
public:
virtual ~UserInterface() {}
virtual void print_status(const DisplayLine& status) = 0;
virtual void menu_show(memoryview<String> choices,
DisplayCoord anchor, ColorPair fg, ColorPair bg,
@ -39,6 +38,7 @@ public:
virtual void info_hide() = 0;
virtual void draw(const DisplayBuffer& display_buffer,
const DisplayLine& status_line,
const DisplayLine& mode_line) = 0;
virtual DisplayCoord dimensions() = 0;
virtual bool is_key_available() = 0;