diff --git a/lldb/source/Core/IOHandlerCursesGUI.cpp b/lldb/source/Core/IOHandlerCursesGUI.cpp --- a/lldb/source/Core/IOHandlerCursesGUI.cpp +++ b/lldb/source/Core/IOHandlerCursesGUI.cpp @@ -343,15 +343,30 @@ // A surface is an abstraction for something than can be drawn on. The surface // have a width, a height, a cursor position, and a multitude of drawing // operations. This type should be sub-classed to get an actually useful ncurses -// object, such as a Window, SubWindow, Pad, or a SubPad. +// object, such as a Window or a Pad. class Surface { public: - Surface() : m_window(nullptr) {} + enum class Type { Window, Pad }; + + Surface(Surface::Type type) : m_type(type), m_window(nullptr) {} WINDOW *get() { return m_window; } operator WINDOW *() { return m_window; } + Surface SubSurface(Rect bounds) { + Surface subSurface(m_type); + if (m_type == Type::Pad) + subSurface.m_window = + ::subpad(m_window, bounds.size.height, bounds.size.width, + bounds.origin.y, bounds.origin.x); + else + subSurface.m_window = + ::derwin(m_window, bounds.size.height, bounds.size.width, + bounds.origin.y, bounds.origin.x); + return subSurface; + } + // Copy a region of the surface to another surface. void CopyToSurface(Surface &target, Point source_origin, Point target_origin, Size size) { @@ -535,41 +550,32 @@ } protected: + Type m_type; WINDOW *m_window; }; class Pad : public Surface { public: - Pad(Size size) { m_window = ::newpad(size.height, size.width); } - - ~Pad() { ::delwin(m_window); } -}; - -class SubPad : public Surface { -public: - SubPad(Pad &pad, Rect bounds) { - m_window = ::subpad(pad.get(), bounds.size.height, bounds.size.width, - bounds.origin.y, bounds.origin.x); - } - SubPad(SubPad &subpad, Rect bounds) { - m_window = ::subpad(subpad.get(), bounds.size.height, bounds.size.width, - bounds.origin.y, bounds.origin.x); + Pad(Size size) : Surface(Surface::Type::Pad) { + m_window = ::newpad(size.height, size.width); } - ~SubPad() { ::delwin(m_window); } + ~Pad() { ::delwin(m_window); } }; class Window : public Surface { public: Window(const char *name) - : m_name(name), m_panel(nullptr), m_parent(nullptr), m_subwindows(), - m_delegate_sp(), m_curr_active_window_idx(UINT32_MAX), + : Surface(Surface::Type::Window), m_name(name), m_panel(nullptr), + m_parent(nullptr), m_subwindows(), m_delegate_sp(), + m_curr_active_window_idx(UINT32_MAX), m_prev_active_window_idx(UINT32_MAX), m_delete(false), m_needs_update(true), m_can_activate(true), m_is_subwin(false) {} Window(const char *name, WINDOW *w, bool del = true) - : m_name(name), m_panel(nullptr), m_parent(nullptr), m_subwindows(), - m_delegate_sp(), m_curr_active_window_idx(UINT32_MAX), + : Surface(Surface::Type::Window), m_name(name), m_panel(nullptr), + m_parent(nullptr), m_subwindows(), m_delegate_sp(), + m_curr_active_window_idx(UINT32_MAX), m_prev_active_window_idx(UINT32_MAX), m_delete(del), m_needs_update(true), m_can_activate(true), m_is_subwin(false) { if (w) @@ -577,8 +583,8 @@ } Window(const char *name, const Rect &bounds) - : m_name(name), m_parent(nullptr), m_subwindows(), m_delegate_sp(), - m_curr_active_window_idx(UINT32_MAX), + : Surface(Surface::Type::Window), m_name(name), m_parent(nullptr), + m_subwindows(), m_delegate_sp(), m_curr_active_window_idx(UINT32_MAX), m_prev_active_window_idx(UINT32_MAX), m_delete(true), m_needs_update(true), m_can_activate(true), m_is_subwin(false) { Reset(::newwin(bounds.size.height, bounds.size.width, bounds.origin.y, @@ -970,20 +976,6 @@ const Window &operator=(const Window &) = delete; }; -class DerivedWindow : public Surface { -public: - DerivedWindow(Window &window, Rect bounds) { - m_window = ::derwin(window.get(), bounds.size.height, bounds.size.width, - bounds.origin.y, bounds.origin.x); - } - DerivedWindow(DerivedWindow &derived_window, Rect bounds) { - m_window = ::derwin(derived_window.get(), bounds.size.height, - bounds.size.width, bounds.origin.y, bounds.origin.x); - } - - ~DerivedWindow() { ::delwin(m_window); } -}; - ///////// // Forms ///////// @@ -1025,7 +1017,7 @@ // Draw the field in the given subpad surface. The surface have a height that // is equal to the height returned by FieldDelegateGetHeight(). If the field // is selected in the form window, then is_selected will be true. - virtual void FieldDelegateDraw(SubPad &surface, bool is_selected) = 0; + virtual void FieldDelegateDraw(Surface &surface, bool is_selected) = 0; // Handle the key that wasn't handled by the form window or a container field. virtual HandleCharResult FieldDelegateHandleChar(int key) { @@ -1112,7 +1104,7 @@ int GetContentLength() { return m_content.length(); } - void DrawContent(SubPad &surface, bool is_selected) { + void DrawContent(Surface &surface, bool is_selected) { surface.MoveCursor(0, 0); const char *text = m_content.c_str() + m_first_visibile_char; surface.PutCString(text, surface.GetWidth()); @@ -1131,17 +1123,17 @@ surface.AttributeOff(A_REVERSE); } - void DrawField(SubPad &surface, bool is_selected) { + void DrawField(Surface &surface, bool is_selected) { surface.TitledBox(m_label.c_str()); Rect content_bounds = surface.GetFrame(); content_bounds.Inset(1, 1); - SubPad content_surface = SubPad(surface, content_bounds); + Surface content_surface = surface.SubSurface(content_bounds); DrawContent(content_surface, is_selected); } - void DrawError(SubPad &surface) { + void DrawError(Surface &surface) { if (!FieldDelegateHasError()) return; surface.MoveCursor(0, 0); @@ -1152,12 +1144,12 @@ surface.AttributeOff(COLOR_PAIR(RedOnBlack)); } - void FieldDelegateDraw(SubPad &surface, bool is_selected) override { + void FieldDelegateDraw(Surface &surface, bool is_selected) override { Rect frame = surface.GetFrame(); Rect field_bounds, error_bounds; frame.HorizontalSplit(GetFieldHeight(), field_bounds, error_bounds); - SubPad field_surface = SubPad(surface, field_bounds); - SubPad error_surface = SubPad(surface, error_bounds); + Surface field_surface = surface.SubSurface(field_bounds); + Surface error_surface = surface.SubSurface(error_bounds); DrawField(field_surface, is_selected); DrawError(error_surface); @@ -1406,7 +1398,7 @@ // Boolean fields are have a single line. int FieldDelegateGetHeight() override { return 1; } - void FieldDelegateDraw(SubPad &surface, bool is_selected) override { + void FieldDelegateDraw(Surface &surface, bool is_selected) override { surface.MoveCursor(0, 0); surface.PutChar('['); if (is_selected) @@ -1486,7 +1478,7 @@ return std::min(index, GetNumberOfChoices()) - 1; } - void DrawContent(SubPad &surface, bool is_selected) { + void DrawContent(Surface &surface, bool is_selected) { int choices_to_draw = GetLastVisibleChoice() - m_first_visibile_choice + 1; for (int i = 0; i < choices_to_draw; i++) { surface.MoveCursor(0, i); @@ -1502,14 +1494,14 @@ } } - void FieldDelegateDraw(SubPad &surface, bool is_selected) override { + void FieldDelegateDraw(Surface &surface, bool is_selected) override { UpdateScrolling(); surface.TitledBox(m_label.c_str()); Rect content_bounds = surface.GetFrame(); content_bounds.Inset(1, 1); - SubPad content_surface = SubPad(surface, content_bounds); + Surface content_surface = surface.SubSurface(content_bounds); DrawContent(content_surface, is_selected); } @@ -1684,7 +1676,7 @@ return context; } - void DrawRemoveButton(SubPad &surface, int highlight) { + void DrawRemoveButton(Surface &surface, int highlight) { surface.MoveCursor(1, surface.GetHeight() / 2); if (highlight) surface.AttributeOn(A_REVERSE); @@ -1693,7 +1685,7 @@ surface.AttributeOff(A_REVERSE); } - void DrawFields(SubPad &surface, bool is_selected) { + void DrawFields(Surface &surface, bool is_selected) { int line = 0; int width = surface.GetWidth(); for (int i = 0; i < GetNumberOfFields(); i++) { @@ -1702,8 +1694,8 @@ Rect field_bounds, remove_button_bounds; bounds.VerticalSplit(bounds.size.width - sizeof(" [Remove]"), field_bounds, remove_button_bounds); - SubPad field_surface = SubPad(surface, field_bounds); - SubPad remove_button_surface = SubPad(surface, remove_button_bounds); + Surface field_surface = surface.SubSurface(field_bounds); + Surface remove_button_surface = surface.SubSurface(remove_button_bounds); bool is_element_selected = m_selection_index == i && is_selected; bool is_field_selected = @@ -1718,7 +1710,7 @@ } } - void DrawNewButton(SubPad &surface, bool is_selected) { + void DrawNewButton(Surface &surface, bool is_selected) { const char *button_text = "[New]"; int x = (surface.GetWidth() - sizeof(button_text) - 1) / 2; surface.MoveCursor(x, 0); @@ -1731,7 +1723,7 @@ surface.AttributeOff(A_REVERSE); } - void FieldDelegateDraw(SubPad &surface, bool is_selected) override { + void FieldDelegateDraw(Surface &surface, bool is_selected) override { surface.TitledBox(m_label.c_str()); Rect content_bounds = surface.GetFrame(); @@ -1739,8 +1731,8 @@ Rect fields_bounds, new_button_bounds; content_bounds.HorizontalSplit(content_bounds.size.height - 1, fields_bounds, new_button_bounds); - SubPad fields_surface = SubPad(surface, fields_bounds); - SubPad new_button_surface = SubPad(surface, new_button_bounds); + Surface fields_surface = surface.SubSurface(fields_bounds); + Surface new_button_surface = surface.SubSurface(new_button_bounds); DrawFields(fields_surface, is_selected); DrawNewButton(new_button_surface, is_selected); @@ -1936,12 +1928,12 @@ m_value_field.FieldDelegateGetHeight()); } - void DrawArrow(SubPad &surface) { + void DrawArrow(Surface &surface) { surface.MoveCursor(0, 1); surface.PutChar(ACS_RARROW); } - void FieldDelegateDraw(SubPad &surface, bool is_selected) override { + void FieldDelegateDraw(Surface &surface, bool is_selected) override { Rect bounds = surface.GetFrame(); Rect key_field_bounds, arrow_and_value_field_bounds; bounds.VerticalSplit(bounds.size.width / 2, key_field_bounds, @@ -1950,9 +1942,9 @@ arrow_and_value_field_bounds.VerticalSplit(1, arrow_bounds, value_field_bounds); - SubPad key_field_surface = SubPad(surface, key_field_bounds); - SubPad arrow_surface = SubPad(surface, arrow_bounds); - SubPad value_field_surface = SubPad(surface, value_field_bounds); + Surface key_field_surface = surface.SubSurface(key_field_bounds); + Surface arrow_surface = surface.SubSurface(arrow_bounds); + Surface value_field_surface = surface.SubSurface(value_field_bounds); bool key_is_selected = m_selection_type == SelectionType::Key && is_selected; @@ -2088,7 +2080,7 @@ } // Draw a centered [Label]. - void Draw(SubPad &surface, bool is_selected) { + void Draw(Surface &surface, bool is_selected) { int x = (surface.GetWidth() - m_label.length()) / 2; surface.MoveCursor(x, 0); if (is_selected) @@ -2357,7 +2349,7 @@ return context; } - void UpdateScrolling(DerivedWindow &surface) { + void UpdateScrolling(Surface &surface) { ScrollContext context = GetScrollContext(); int content_height = GetContentHeight(); int surface_height = surface.GetHeight(); @@ -2381,7 +2373,7 @@ } } - void DrawError(SubPad &surface) { + void DrawError(Surface &surface) { if (!m_delegate_sp->HasError()) return; surface.MoveCursor(0, 0); @@ -2395,7 +2387,7 @@ surface.HorizontalLine(surface.GetWidth()); } - void DrawFields(SubPad &surface) { + void DrawFields(Surface &surface) { int line = 0; int width = surface.GetWidth(); bool a_field_is_selected = m_selection_type == SelectionType::Field; @@ -2406,13 +2398,13 @@ bool is_field_selected = a_field_is_selected && m_selection_index == i; int height = field->FieldDelegateGetHeight(); Rect bounds = Rect(Point(0, line), Size(width, height)); - SubPad field_surface = SubPad(surface, bounds); + Surface field_surface = surface.SubSurface(bounds); field->FieldDelegateDraw(field_surface, is_field_selected); line += height; } } - void DrawActions(SubPad &surface) { + void DrawActions(Surface &surface) { int number_of_actions = m_delegate_sp->GetNumberOfActions(); int width = surface.GetWidth() / number_of_actions; bool an_action_is_selected = m_selection_type == SelectionType::Action; @@ -2421,19 +2413,19 @@ bool is_action_selected = an_action_is_selected && m_selection_index == i; FormAction &action = m_delegate_sp->GetAction(i); Rect bounds = Rect(Point(x, 0), Size(width, 1)); - SubPad action_surface = SubPad(surface, bounds); + Surface action_surface = surface.SubSurface(bounds); action.Draw(action_surface, is_action_selected); x += width; } } - void DrawElements(SubPad &surface) { + void DrawElements(Surface &surface) { Rect frame = surface.GetFrame(); Rect fields_bounds, actions_bounds; frame.HorizontalSplit(surface.GetHeight() - GetActionsHeight(), fields_bounds, actions_bounds); - SubPad fields_surface = SubPad(surface, fields_bounds); - SubPad actions_surface = SubPad(surface, actions_bounds); + Surface fields_surface = surface.SubSurface(fields_bounds); + Surface actions_surface = surface.SubSurface(actions_bounds); DrawFields(fields_surface); DrawActions(actions_surface); @@ -2442,7 +2434,7 @@ // Contents are first drawn on a pad. Then a subset of that pad is copied to // the derived window starting at the first visible line. This essentially // provides scrolling functionality. - void DrawContent(DerivedWindow &surface) { + void DrawContent(Surface &surface) { UpdateScrolling(surface); int width = surface.GetWidth(); @@ -2452,8 +2444,8 @@ Rect frame = pad.GetFrame(); Rect error_bounds, elements_bounds; frame.HorizontalSplit(GetErrorHeight(), error_bounds, elements_bounds); - SubPad error_surface = SubPad(pad, error_bounds); - SubPad elements_surface = SubPad(pad, elements_bounds); + Surface error_surface = pad.SubSurface(error_bounds); + Surface elements_surface = pad.SubSurface(elements_bounds); DrawError(error_surface); DrawElements(elements_surface); @@ -2473,7 +2465,7 @@ Rect content_bounds = window.GetFrame(); content_bounds.Inset(2, 2); - DerivedWindow content_surface = DerivedWindow(window, content_bounds); + Surface content_surface = window.SubSurface(content_bounds); DrawContent(content_surface); return true;