From 226db75aeb992ffb6ac7b8792f3f50b8d27f7bb5 Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Tue, 19 Jun 2018 20:20:38 +1000 Subject: [PATCH] Change Search completion to display on top of the modeline --- src/client.cc | 2 +- src/keys.hh | 3 +- src/ncurses_ui.cc | 104 +++++++++++++++++++++++++++++++++------------- src/ncurses_ui.hh | 6 +-- src/window.cc | 13 +++--- src/window.hh | 3 +- 6 files changed, 84 insertions(+), 47 deletions(-) diff --git a/src/client.cc b/src/client.cc index 850d46ac..313011d0 100644 --- a/src/client.cc +++ b/src/client.cc @@ -50,7 +50,7 @@ Client::Client(std::unique_ptr&& ui, killpg(getpgrp(), SIGINT); else if (key.modifiers & Key::Modifiers::Resize) { - m_window->set_dimensions(key.coord(), key.modifiers & Key::Modifiers::OffsetPos); + m_window->set_dimensions(key.coord()); force_redraw(); } else diff --git a/src/keys.hh b/src/keys.hh index f50a0f9c..a7684f22 100644 --- a/src/keys.hh +++ b/src/keys.hh @@ -30,7 +30,6 @@ struct Key MouseWheelDown | MouseWheelUp, Resize = 1 << 8, - OffsetPos = 1 << 9, MenuSelect = 1 << 10, }; enum NamedKey : Codepoint @@ -113,7 +112,7 @@ constexpr Key ctrl(Key key) constexpr Codepoint encode_coord(DisplayCoord coord) { return (Codepoint)(((int)coord.line << 16) | ((int)coord.column & 0x0000FFFF)); } -constexpr Key resize(DisplayCoord dim, Key::Modifiers additional = Key::Modifiers::None) { return { Key::Modifiers::Resize | additional, encode_coord(dim) }; } +constexpr Key resize(DisplayCoord dim) { return { Key::Modifiers::Resize, encode_coord(dim) }; } constexpr size_t hash_value(const Key& key) { return hash_values(key.modifiers, key.key); } diff --git a/src/ncurses_ui.cc b/src/ncurses_ui.cc index 7f2ec9f9..fd206bad 100644 --- a/src/ncurses_ui.cc +++ b/src/ncurses_ui.cc @@ -516,7 +516,7 @@ void NCursesUI::check_resize(bool force) if (info) info_show(m_info.title, m_info.content, m_info.anchor, m_info.face, m_info.style); - set_resize_pending(ResizePending::Yes); + set_resize_pending(); clearok(curscr, true); werase(curscr); } @@ -533,12 +533,10 @@ Optional NCursesUI::get_next_key() check_resize(); - if (m_resize_pending != ResizePending::No) + if (m_resize_pending) { - const auto modifiers = (m_resize_pending == ResizePending::OffsetPos) ? - Key::Modifiers::OffsetPos : Key::Modifiers::None; - m_resize_pending = ResizePending::No; - return resize(dimensions(), modifiers); + m_resize_pending = false; + return resize(dimensions()); } wtimeout(m_window, 0); @@ -694,6 +692,37 @@ void NCursesUI::draw_menu() wbkgdset(m_menu.win, COLOR_PAIR(menu_bg)); const int item_count = (int)m_menu.items.size(); + if (m_menu.columns == 0) + { + const auto win_width = m_menu.size.column - 3; + kak_assert(m_menu.size.line == 1); + ColumnCount pos = 0; + + wmove(m_menu.win, 0, 0); + add_str(m_menu.win, m_menu.first_item > 0 ? "< " : " "); + + int i = m_menu.first_item; + for (; i < item_count; ++i) + { + const DisplayLine& item = m_menu.items[i]; + const ColumnCount item_width = item.length() + 1 ; + if (pos + item_width > win_width) + break; + + draw_line(m_menu.win, item, 0, win_width - pos, + i == m_menu.selected_item ? m_menu.fg : m_menu.bg); + wattron(m_menu.win, COLOR_PAIR(menu_bg)); + add_str(m_menu.win, String{" "}); + pos += item_width; + } + + set_face(m_menu.win, m_menu.bg, m_menu.bg); + add_str(m_menu.win, String{' ', win_width - pos}); + add_str(m_menu.win, i == item_count ? " " : ">"); + m_dirty = true; + return; + } + const LineCount menu_lines = div_round_up(item_count, m_menu.columns); const LineCount win_height = m_menu.size.line; kak_assert(win_height <= menu_lines); @@ -746,7 +775,6 @@ void NCursesUI::menu_show(ConstArrayView items, DisplayCoord anchor, Face fg, Face bg, MenuStyle style) { - const LineCount previous_height = m_menu ? m_menu.size.line : 0; if (m_menu) { mark_dirty(m_menu); @@ -770,10 +798,12 @@ void NCursesUI::menu_show(ConstArrayView items, const ColumnCount max_width = m_dimensions.column - 1; const bool is_inline = style == MenuStyle::Inline; - m_menu.columns = is_inline ? 1 : max((int)(max_width / (longest+1)), 1); + const bool is_search = style == MenuStyle::Search; + m_menu.columns = is_search ? 0 : (is_inline ? 1 : max((int)(max_width / (longest+1)), 1)); const LineCount max_height = min(height_limit(style), max(anchor.line, m_dimensions.line - anchor.line - 1)); - const LineCount height = min(max_height, div_round_up(item_count, m_menu.columns)); + const LineCount height = is_search ? + 1 : (min(max_height, div_round_up(item_count, m_menu.columns))); const ColumnCount maxlen = (m_menu.columns > 1 and item_count > 1) ? max_width / m_menu.columns - 1 : max_width; @@ -789,22 +819,24 @@ void NCursesUI::menu_show(ConstArrayView items, anchor.line += content_line_offset(); LineCount line = anchor.line + 1; - if (not is_inline) + ColumnCount column = std::max(0_col, std::min(anchor.column, m_dimensions.column - longest - 1)); + if (is_search) + { + line = m_status_on_top ? 0_line : m_dimensions.line; + column = m_dimensions.column / 2; + } + else if (not is_inline) line = m_status_on_top ? 1_line : m_dimensions.line - height; else if (line + height > m_dimensions.line) line = anchor.line - height; - const ColumnCount column = std::max(0_col, std::min(anchor.column, m_dimensions.column - longest - 1)); - - auto width = is_inline ? min(longest+1, m_dimensions.column) : m_dimensions.column; + const auto width = is_search ? m_dimensions.column - m_dimensions.column / 2 + : (is_inline ? min(longest+1, m_dimensions.column) + : m_dimensions.column); m_menu.create({line, column}, {height, width}); m_menu.selected_item = item_count; m_menu.first_item = 0; - if (style == MenuStyle::Search and previous_height != height) - set_resize_pending(m_status_on_top ? - ResizePending::OffsetPos : ResizePending::Yes); - draw_menu(); if (m_info) @@ -815,18 +847,37 @@ void NCursesUI::menu_show(ConstArrayView items, void NCursesUI::menu_select(int selected) { const int item_count = m_menu.items.size(); - const LineCount menu_lines = div_round_up(item_count, m_menu.columns); if (selected < 0 or selected >= item_count) { m_menu.selected_item = -1; m_menu.first_item = 0; } + else if (m_menu.columns == 0) // Do not columnize + { + m_menu.selected_item = selected; + const ColumnCount width = m_menu.size.column - 3; + int first = 0; + ColumnCount item_col = 0; + for (int i = 0; i <= selected; ++i) + { + const ColumnCount item_width = m_menu.items[i].length() + 1; + if (item_col + item_width > width) + { + first = i; + item_col = item_width; + } + else + item_col += item_width; + } + m_menu.first_item = first; + } else { m_menu.selected_item = selected; - const LineCount selected_line = m_menu.selected_item / m_menu.columns; const LineCount win_height = m_menu.size.line; const LineCount top_line = m_menu.first_item / m_menu.columns; + const LineCount menu_lines = div_round_up(item_count, m_menu.columns); + const LineCount selected_line = m_menu.selected_item / m_menu.columns; kak_assert(menu_lines >= win_height); if (selected_line < top_line) m_menu.first_item = (int)selected_line * m_menu.columns; @@ -841,10 +892,6 @@ void NCursesUI::menu_hide() if (not m_menu) return; - if (m_menu.style == MenuStyle::Search) - set_resize_pending(m_status_on_top ? - ResizePending::OffsetPos : ResizePending::Yes); - m_menu.items.clear(); mark_dirty(m_menu); m_menu.destroy(); @@ -1065,20 +1112,17 @@ void NCursesUI::set_on_key(OnKeyCallback callback) DisplayCoord NCursesUI::dimensions() { - auto res = m_dimensions; - if (m_menu and m_menu.style == MenuStyle::Search) - res.line -= m_menu.size.line; - return res; + return m_dimensions; } LineCount NCursesUI::content_line_offset() const { - return (m_status_on_top ? 1 + (m_menu.style == MenuStyle::Search ? m_menu.size.line : 0) : 0); + return m_status_on_top ? 1 : 0; } -void NCursesUI::set_resize_pending(ResizePending resize_pending) +void NCursesUI::set_resize_pending() { - m_resize_pending = resize_pending; + m_resize_pending = true; EventManager::instance().force_signal(0); } diff --git a/src/ncurses_ui.hh b/src/ncurses_ui.hh index c20e4ed0..acb3558a 100644 --- a/src/ncurses_ui.hh +++ b/src/ncurses_ui.hh @@ -149,10 +149,8 @@ private: bool m_dirty = false; - enum class ResizePending { No, Yes, OffsetPos }; - ResizePending m_resize_pending = ResizePending::No; - - void set_resize_pending(ResizePending resize_pending); + bool m_resize_pending = false; + void set_resize_pending(); }; } diff --git a/src/window.cc b/src/window.cc index a17bc45e..648d14ee 100644 --- a/src/window.cc +++ b/src/window.cc @@ -90,7 +90,7 @@ Window::Setup Window::build_setup(const Context& context) const for (auto& sel : context.selections()) selections.push_back({sel.cursor(), sel.anchor()}); - return { m_position + m_position_offset, m_dimensions, + return { m_position, m_dimensions, context.buffer().timestamp(), compute_faces_hash(context.faces()), context.selections().main_index(), @@ -101,7 +101,7 @@ bool Window::needs_redraw(const Context& context) const { auto& selections = context.selections(); - if (m_position + m_position_offset != m_last_setup.position or + if (m_position != m_last_setup.position or m_dimensions != m_last_setup.dimensions or context.buffer().timestamp() != m_last_setup.timestamp or selections.main_index() != m_last_setup.main_selection or @@ -171,7 +171,7 @@ const DisplayBuffer& Window::update_display_buffer(const Context& context) m_display_buffer.optimize(); m_last_setup = build_setup(context); - set_position(setup.window_pos - m_position_offset); + set_position(setup.window_pos); if (profile and not (buffer().flags() & Buffer::Flags::Debug)) { @@ -190,13 +190,10 @@ void Window::set_position(DisplayCoord position) m_position.column = std::max(0_col, position.column); } -void Window::set_dimensions(DisplayCoord dimensions, bool offset_pos) +void Window::set_dimensions(DisplayCoord dimensions) { if (m_dimensions != dimensions) { - if (offset_pos) - m_position_offset += m_dimensions - dimensions; - m_dimensions = dimensions; run_hook_in_own_context("WinResize", format("{}.{}", dimensions.line, dimensions.column)); @@ -213,7 +210,7 @@ static void check_display_setup(const DisplaySetup& setup, const Window& window) DisplaySetup Window::compute_display_setup(const Context& context) const { - auto win_pos = m_position + m_position_offset; + auto win_pos = m_position; DisplayCoord offset = options()["scrolloff"].get(); offset.line = std::min(offset.line, (m_dimensions.line + 1) / 2); diff --git a/src/window.hh b/src/window.hh index f63fc9a1..0abca45d 100644 --- a/src/window.hh +++ b/src/window.hh @@ -23,7 +23,7 @@ public: void set_position(DisplayCoord position); const DisplayCoord& dimensions() const { return m_dimensions; } - void set_dimensions(DisplayCoord dimensions, bool offset_pos = false); + void set_dimensions(DisplayCoord dimensions); void scroll(LineCount offset); void center_line(LineCount buffer_line); @@ -59,7 +59,6 @@ private: SafePtr m_client; DisplayCoord m_position; - DisplayCoord m_position_offset; DisplayCoord m_dimensions; DisplayBuffer m_display_buffer;