diff --git a/views.hpp b/views.hpp
new file mode 100644
index 0000000..d4f3779
--- /dev/null
+++ b/views.hpp
@@ -0,0 +1,539 @@
+// 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.
+
+#pragma once
+
+#include "analyzer.hpp"
+#include "bargraph.hpp"
+#include "main.hpp"
+#include "menu.hpp"
+#include "sensorhelper.hpp"
+
+#include <ncurses.h>
+#include <string>
+#include <vector>
+constexpr int MARGIN_BOTTOM = 1;
+class DBusTopWindow
+{
+  public:
+    DBusTopWindow()
+    {
+        win = newwin(25, 80, 0, 0); // Default to 80x25, will be updated
+        has_border_ = true;
+        focused_ = false;
+        selectable_ = true;
+        visible_ = true;
+        maximize_ = false;
+    }
+
+    virtual ~DBusTopWindow()
+    {}
+    virtual void OnKeyDown(const std::string& key) = 0;
+    virtual void Render() = 0;
+    virtual void OnResize(int win_w, int win_h) = 0;
+    void UpdateWindowSizeAndPosition()
+    {
+        mvwin(win, rect.y, rect.x);
+        wresize(win, rect.h, rect.w);
+    }
+
+    void DrawBorderIfNeeded()
+    {
+        if (focused_)
+        {
+            wborder(win, '*', '*', '*', '*', '*', '*', '*', '*');
+        }
+        else
+        {
+            wborder(win, '|', '|', '-', '-', '+', '+', '+', '+');
+        }
+        wrefresh(win);
+    }
+
+    virtual void RecreateWindow()
+    {
+        delwin(win);
+        win = newwin(25, 80, 0, 0);
+        UpdateWindowSizeAndPosition();
+    }
+
+    virtual std::string GetStatusString() = 0;
+    WINDOW* win;
+    Rect rect;
+    bool has_border_;
+    bool focused_;
+    bool selectable_;
+    bool maximize_;
+    bool visible_;
+};
+
+class SummaryView : public DBusTopWindow
+{
+  public:
+    SummaryView() : DBusTopWindow()
+    {}
+    void Render() override;
+    void OnResize(int win_w, int win_h) override
+    {
+        rect.h = 8;
+        rect.w = win_w;
+        rect.x = 0;
+        rect.y = 0;
+        UpdateWindowSizeAndPosition();
+    }
+
+    void UpdateDBusTopStatistics(DBusTopStatistics* stat);
+    void OnKeyDown(const std::string& key) override
+    {}
+    std::string GetStatusString() override
+    {
+        return "Summary View";
+    }
+
+  private:
+    float method_call_, method_return_, signal_, error_, total_;
+};
+
+class SensorDetailView : public DBusTopWindow
+{
+  public:
+    SensorDetailView() : DBusTopWindow()
+    {
+        choice_ = -999; // -999 means invalid
+        h_padding = 2;
+        h_spacing = 3;
+        col_width = 15;
+        idx0 = idx1 = -999;
+        state = SensorList;
+    }
+
+    void Render() override;
+    int DispSensorsPerColumn()
+    {
+        return rect.h - 3;
+    }
+
+    int DispSensorsPerRow()
+    {
+        int ncols = 0;
+        while (true)
+        {
+            int next = ncols + 1;
+            int w = 2 * h_padding + col_width * next;
+            if (next > 1)
+                w += (next - 1) * h_spacing;
+            if (w <= rect.w - 2)
+            {
+                ncols = next;
+            }
+            else
+            {
+                break;
+            }
+        }
+        return ncols;
+    }
+
+    void OnKeyDown(const std::string& key) override
+    {
+        if (state == SensorList)
+        { // Currently in sensor list
+            if (key == "right")
+            {
+                MoveChoiceCursorHorizontally(1);
+            }
+            else if (key == "left")
+            {
+                MoveChoiceCursorHorizontally(-1);
+            }
+            else if (key == "up")
+            {
+                MoveChoiceCursor(-1, true);
+            }
+            else if (key == "down")
+            {
+                MoveChoiceCursor(1, true);
+            }
+            else if (key == "enter")
+            {
+                if (choice_ != -999)
+                {
+                    state = SensorDetail;
+                }
+            }
+            else if (key == "escape")
+            {
+                choice_ = -999;
+            }
+        }
+        else if (state == SensorDetail)
+        { // Currently focusing on a sensor
+            if (key == "right" || key == "down")
+            {
+                MoveChoiceCursor(1, true);
+            }
+            else if (key == "left" || key == "up")
+            {
+                MoveChoiceCursor(-1, true);
+            }
+            else if (key == "escape")
+            {
+                state = SensorList;
+            }
+        }
+
+        Render(); // This window is already on top, redrawing won't corrupt
+    }
+
+    void MoveChoiceCursor(int delta, bool wrap_around = true)
+    {
+        const int ns = sensor_ids_.size();
+        if (ns < 1)
+            return;
+        // First of all, if cursor is inactive, activate it
+        if (choice_ == -999)
+        {
+            if (delta > 0)
+            {
+                choice_ = 0;
+                curr_sensor_id_ = sensor_ids_[0];
+                return;
+            }
+            else
+            {
+                choice_ = ns - 1;
+                curr_sensor_id_ = sensor_ids_.back();
+                return;
+            }
+        }
+        int choice_next = choice_ + delta;
+        while (choice_next >= ns)
+        {
+            if (wrap_around)
+            {
+                choice_next -= ns;
+            }
+            else
+            {
+                choice_next = ns - 1;
+            }
+        }
+        while (choice_next < 0)
+        {
+            if (wrap_around)
+            {
+                choice_next += ns;
+            }
+            else
+            {
+                choice_next = 0;
+            }
+        }
+        choice_ = choice_next;
+        curr_sensor_id_ = sensor_ids_[choice_];
+    }
+
+    void MoveChoiceCursorHorizontally(int delta)
+    {
+        if (delta != 0 && delta != -1 && delta != 1)
+            return;
+        const int ns = sensor_ids_.size();
+        if (ns < 1)
+            return;
+        if (choice_ == -999)
+        {
+            if (delta > 0)
+            {
+                choice_ = 0;
+                curr_sensor_id_ = sensor_ids_[0];
+                return;
+            }
+            else
+            {
+                curr_sensor_id_ = sensor_ids_.back();
+                choice_ = ns - 1;
+                return;
+            }
+        }
+        const int nrows = DispSensorsPerColumn();
+        int tot_columns = (ns - 1) / nrows + 1;
+        int num_rows_last_column = ns - 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)
+        {
+            if (x >= tot_columns)
+            {
+                overflow_to_right = true;
+            }
+        }
+        else
+        {
+            if (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++;
+                // overflow past the right of window
+                // Start probing next line
+                if (y >= nrows)
+                {
+                    choice_ = 0;
+                    return;
+                }
+                else
+                {
+                    choice_ = y;
+                    return;
+                }
+            }
+            else if (overflow_to_left)
+            { // overflow past the left of window
+                y--;
+                if (y < 0)
+                { // overflow past the top of window
+                    // Focus on the visually bottom-right entry
+                    if (num_rows_last_column == nrows)
+                    { // last col fully populated
+                        choice_ = ns - 1;
+                    }
+                    else
+                    { // last column is not fully populated
+                        choice_ = ns - 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;
+            }
+        }
+        curr_sensor_id_ = sensor_ids_[choice_];
+    }
+
+    // Cache the sensor list in the sensor snapshot
+    void UpdateSensorSnapshot(SensorSnapshot* snapshot)
+    {
+        std::string old_sensor_id = "";
+        if (choice_ != -999)
+        {
+            old_sensor_id = sensor_ids_[choice_];
+        }
+        std::vector<std::string> new_sensors =
+            snapshot->GetDistinctSensorNames();
+        if (new_sensors == sensor_ids_)
+        {
+            return; // Nothing is changed
+        }
+        // Assume changed
+        sensor_ids_ = new_sensors;
+        choice_ = -999;
+        for (int i = 0; i < static_cast<int>(new_sensors.size()); i++)
+        {
+            if (new_sensors[i] == old_sensor_id)
+            {
+                choice_ = i;
+                break;
+                curr_sensor_id_ = sensor_ids_[choice_];
+            }
+        }
+    }
+
+    void OnResize(int win_w, int win_h) override
+    {
+        rect.x = 0;
+        rect.y = 8 - MARGIN_BOTTOM;
+        rect.w = win_w / 2;
+        rect.h = win_h - rect.y - MARGIN_BOTTOM;
+        UpdateWindowSizeAndPosition();
+    }
+
+    std::vector<std::string> sensor_ids_;
+    // We need to keep track of the currently-selected sensor ID because
+    // the sensor ID might theoretically become invalidated at any moment, and
+    // we should allow the UI to show an error gracefully in that case.
+    std::string curr_sensor_id_;
+    int choice_;
+    int h_padding;
+    int h_spacing;
+    int col_width;
+    int idx0, idx1; // Range of sensors on display
+    enum State
+    {
+        SensorList,
+        SensorDetail,
+    };
+
+    State state;
+    std::string GetStatusString() override;
+};
+
+class DBusStatListView : public DBusTopWindow
+{
+  public:
+    DBusStatListView();
+    void Render() override;
+    void OnResize(int win_w, int win_h) override;
+    void OnKeyDown(const std::string& key) override;
+    int horizontal_pan_;
+    int menu_h_, menu_w_, menu_margin_;
+    ArrowKeyNavigationMenu* menu1_;
+    ArrowKeyNavigationMenu* menu2_;
+    int highlight_col_idx_; // Currently highlighted column
+    int row_idx_;           // Currently highlighted row
+
+    int sort_col_idx_; // Column used for sorting
+    enum SortOrder
+    {
+        Ascending,
+        Descending,
+    };
+    SortOrder sort_order_;
+
+    int disp_row_idx_; // From which row to start displaying? (essentially a
+                       // vertical scroll bar)
+    int last_choices_[2]; // Last choice index on either side
+    enum MenuState
+    {
+        Hidden,
+        LeftSide,  // When the user is choosing an entry on the left side
+        RightSide, // When the user is choosing an entry on the right side
+    };
+
+    std::vector<DBusTopSortField> GetSortFields();
+    MenuState curr_menu_state_, last_menu_state_;
+    std::string GetStatusString() override;
+    void RecreateWindow()
+    {
+        delwin(win);
+        win = newwin(25, 80, 0, 0);
+        menu1_->win_ = win;
+        menu2_->win_ = win;
+        UpdateWindowSizeAndPosition();
+    }
+    
+  private:
+    void SetMenuState(MenuState s)
+    {
+        last_menu_state_ = curr_menu_state_;
+        // Moving out from a certain side: save the last choice of that side
+        switch (curr_menu_state_)
+        {
+            case LeftSide:
+                if (s == RightSide)
+                {
+                    last_choices_[0] = menu1_->Choice();
+                    menu1_->Deselect();
+                }
+                break;
+            case RightSide:
+                if (s == LeftSide)
+                {
+                    last_choices_[1] = menu2_->Choice();
+                    menu2_->Deselect();
+                }
+                break;
+            default:
+                break;
+        }
+        // Moving into a certain side: save the cursor
+        switch (s)
+        {
+            case LeftSide:
+                if (!menu1_->Empty())
+                {
+                    menu1_->SetChoiceAndConstrain(last_choices_[0]);
+                }
+                break;
+            case RightSide:
+                if (!menu2_->Empty())
+                {
+                    menu2_->SetChoiceAndConstrain(last_choices_[1]);
+                }
+                break;
+            default:
+                break;
+        }
+        curr_menu_state_ = s;
+    }
+    void PanViewportOrMoveHighlightedColumn(const int delta_x);
+    // ColumnHeaders and ColumnWidths are the actual column widths used for
+    // display. They are "msg/s" or "I2c/s" prepended to the chosen set of
+    // fields.
+    std::vector<std::string> ColumnHeaders();
+    std::vector<int> ColumnWidths();
+    // X span, for checking visibility
+    std::pair<int, int> GetXSpanForColumn(const int col_idx);
+    bool IsXSpanVisible(const std::pair<int, int>& xs,
+                        const int tolerance); // uses horizontal_pan_
+    std::vector<std::string> visible_columns_;
+    std::unordered_map<std::string, int> column_widths_;
+    std::map<std::vector<std::string>, DBusTopComputedMetrics> stats_snapshot_;
+};
+
+class FooterView : public DBusTopWindow
+{
+  public:
+    FooterView() : DBusTopWindow()
+    {
+        selectable_ = false; // Cannot be selected by the tab key
+    }
+
+    void OnKeyDown(const std::string& key) override
+    {}
+    void OnResize(int win_w, int win_h) override
+    {
+        rect.h = 1;
+        rect.w = win_w;
+        rect.x = 0;
+        rect.y = win_h - 1;
+        UpdateWindowSizeAndPosition();
+    }
+
+    void Render() override;
+    std::string GetStatusString() override
+    {
+        return "";
+    }
+
+};
