diff --git a/dbus-top/menu.cpp b/dbus-top/menu.cpp
new file mode 100644
index 0000000..af59f14
--- /dev/null
+++ b/dbus-top/menu.cpp
@@ -0,0 +1,322 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "menu.hpp"
+
+#include "views.hpp"
+
+ArrowKeyNavigationMenu::ArrowKeyNavigationMenu(DBusTopWindow* view) :
+    win_(view->win), parent_(view), idx0_(INVALID), idx1_(INVALID),
+    h_padding_(2), col_width_(15), h_spacing_(2), choice_(INVALID)
+{}
+
+void ArrowKeyNavigationMenu::do_Render(bool is_column_major)
+{
+    const int nrows = DispEntriesPerColumn();
+    const int ncols = DispEntriesPerRow();
+    const int items_per_page = nrows * ncols;
+    if (items_per_page < 1)
+        return;
+    int tot_num_items = items_.size();
+    // int tot_num_columns = (tot_num_items - 1) / nrows + 1;
+    // Determine whether cursor is outside the current rectangular viewport
+    bool is_cursor_out_of_view = false;
+    if (idx0_ > choice_ || idx1_ <= choice_)
+    {
+        is_cursor_out_of_view = true;
+    }
+    if (idx0_ == INVALID || idx1_ == INVALID)
+    {
+        is_cursor_out_of_view = true;
+    }
+    // Scroll the viewport such that it contains the cursor
+    if (is_cursor_out_of_view)
+    {
+        idx0_ = 0;
+        idx1_ = items_per_page;
+    }
+    while (idx1_ <= choice_)
+    {
+        if (is_column_major)
+        {
+            idx0_ += nrows;
+            idx1_ += nrows;
+        }
+        else
+        {
+            idx0_ += ncols;
+            idx1_ += ncols;
+        }
+    }
+    int y0 = rect_.y, x0 = rect_.x;
+    int y = y0, x = x0;
+    for (int i = 0; i < items_per_page; i++)
+    {
+        int idx = idx0_ + i;
+        if (idx < tot_num_items)
+        {
+            if (idx == choice_)
+            {
+                wattrset(win_, A_REVERSE);
+            }
+            std::string s = items_[idx];
+            while (s.size() < col_width_)
+            {
+                s.push_back(' ');
+            }
+            mvwprintw(win_, y, x, s.c_str());
+            wattrset(win_, 0);
+        }
+        else
+        {
+            break;
+        }
+        if (is_column_major)
+        {
+            y++;
+            if (i % nrows == nrows - 1)
+            {
+                y = y0;
+                x += col_width_ + h_spacing_;
+            }
+        }
+        else
+        {
+            x += col_width_ + h_spacing_;
+            if (i % ncols == ncols - 1)
+            {
+                x = x0;
+                y++;
+            }
+        }
+    }
+}
+
+void ArrowKeyNavigationMenu::Render()
+{
+    do_Render(order == ColumnMajor);
+}
+
+void ArrowKeyNavigationMenu::OnKeyDown(const std::string& key)
+{
+    switch (order)
+    {
+        case ColumnMajor:
+            if (key == "up")
+            {
+                MoveCursorAlongPrimaryAxis(-1);
+            }
+            else if (key == "down")
+            {
+                MoveCursorAlongPrimaryAxis(1);
+            }
+            else if (key == "left")
+            {
+                MoveCursorAlongSecondaryAxis(-1);
+            }
+            else if (key == "right")
+            {
+                MoveCursorAlongSecondaryAxis(1);
+            }
+            break;
+        case RowMajor:
+            if (key == "up")
+            {
+                MoveCursorAlongSecondaryAxis(-1);
+            }
+            else if (key == "down")
+            {
+                MoveCursorAlongSecondaryAxis(1);
+            }
+            else if (key == "left")
+            {
+                MoveCursorAlongPrimaryAxis(-1);
+            }
+            else if (key == "right")
+            {
+                MoveCursorAlongPrimaryAxis(1);
+            }
+            break;
+            break;
+    }
+}
+
+void ArrowKeyNavigationMenu::MoveCursorAlongPrimaryAxis(int delta)
+{
+    const int N = items_.size();
+    if (N < 1)
+        return;
+    // If the cursor is inactive, activate it
+    if (choice_ == INVALID)
+    {
+        if (delta > 0)
+        {
+            choice_ = 0;
+        }
+        else
+        {
+            choice_ = N - 1;
+        }
+        return;
+    }
+    int choice_next = choice_ + delta;
+    while (choice_next >= N)
+    {
+        choice_next -= N;
+    }
+    while (choice_next < 0)
+    {
+        choice_next += N;
+    }
+    choice_ = choice_next;
+}
+
+void ArrowKeyNavigationMenu::MoveCursorAlongSecondaryAxis(int delta)
+{
+    if (delta != 0 && delta != 1 && delta != -1)
+        return;
+    const int N = items_.size();
+    if (N < 1)
+        return;
+    // If the cursor is inactive, activate it
+    if (choice_ == INVALID)
+    {
+        if (delta > 0)
+        {
+            choice_ = 0;
+        }
+        else
+        {
+            choice_ = N - 1;
+        }
+        return;
+    }
+    const int nrows =
+        (order == ColumnMajor) ? DispEntriesPerColumn() : DispEntriesPerRow();
+    const int tot_columns = (N - 1) / nrows + 1;
+    const int num_rows_last_column = N - nrows * (tot_columns - 1);
+    int y = choice_ % nrows, x = choice_ / nrows;
+    if (delta == 1)
+    {
+        x++;
+    }
+    else
+    {
+        x--;
+    }
+    bool overflow_to_right = false;
+    if (y < num_rows_last_column && x >= tot_columns)
+    {
+        overflow_to_right = true;
+    }
+    if (y >= num_rows_last_column && x >= tot_columns - 1)
+    {
+        overflow_to_right = true;
+    }
+    bool overflow_to_left = false;
+    if (x < 0)
+    {
+        overflow_to_left = true;
+    }
+    if (overflow_to_right)
+    {
+        y++;
+        if (y >= nrows)
+        {
+            choice_ = 0;
+            return;
+        }
+        else
+        {
+            choice_ = y;
+            return;
+        }
+    }
+    else if (overflow_to_left)
+    {
+        y--;
+        if (y < 0)
+        {
+            if (num_rows_last_column == nrows)
+            {
+                choice_ = N - 1;
+            }
+            else
+            {
+                choice_ = N - num_rows_last_column - 1;
+            }
+            return;
+        }
+        else
+        {
+            if (y < num_rows_last_column)
+            {
+                choice_ = nrows * (tot_columns - 1) + y;
+            }
+            else
+            {
+                choice_ = nrows * (tot_columns - 2) + y;
+            }
+        }
+    }
+    else
+    {
+        choice_ = y + x * nrows;
+    }
+}
+
+void ArrowKeyNavigationMenu::SetChoiceAndConstrain(int c)
+{
+    if (Empty())
+    {
+        choice_ = INVALID;
+        return;
+    }
+    if (c < 0)
+        c = 0;
+    if (c >= static_cast<int>(items_.size()))
+    {
+        c = static_cast<int>(items_.size() - 1);
+    }
+    choice_ = c;
+}
+
+void ArrowKeyNavigationMenu::AddItem(const std::string& s)
+{
+    items_.push_back(s);
+}
+
+bool ArrowKeyNavigationMenu::RemoveHighlightedItem(std::string* ret)
+{
+    if (choice_ < 0 || choice_ >= items_.size())
+        return false;
+    std::string r = items_[choice_];
+    items_.erase(items_.begin() + choice_);
+    if (items_.empty())
+    {
+        Deselect();
+    }
+    else
+    {
+        if (choice_ >= items_.size())
+        {
+            choice_ = items_.size() - 1;
+        }
+    }
+    if (ret)
+    {
+        *ret = r;
+    }
+    return true;
+}
\ No newline at end of file
