Skip to content

Commit 2b89f40

Browse files
OmarEmaraDevclayborg
authored andcommitted
[LLDB][GUI] Refactor form drawing using subsurfaces
This patch adds a new method SubSurface to the Surface class. The method returns another surface that is a subset of this surface. This is important to further abstract away drawing from the ncurses objects. For instance, fields could previously be drawn on subpads only but can now be drawn on any surface. This is needed to create the file search dialogs and similar functionalities. There is an opportunity to refactor window drawing in general using surfaces, but we shall consider this separately later. Reviewed By: clayborg Differential Revision: https://reviews.llvm.org/D107182
1 parent 623cf3d commit 2b89f40

File tree

1 file changed

+52
-39
lines changed

1 file changed

+52
-39
lines changed

lldb/source/Core/IOHandlerCursesGUI.cpp

Lines changed: 52 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,19 @@ class Surface {
352352

353353
operator WINDOW *() { return m_window; }
354354

355+
Surface SubSurface(Rect bounds) {
356+
Surface subSurface;
357+
if (is_pad(m_window))
358+
subSurface.m_window =
359+
::subpad(m_window, bounds.size.height, bounds.size.width,
360+
bounds.origin.y, bounds.origin.x);
361+
else
362+
subSurface.m_window =
363+
::derwin(m_window, bounds.size.height, bounds.size.width,
364+
bounds.origin.y, bounds.origin.x);
365+
return subSurface;
366+
}
367+
355368
// Copy a region of the surface to another surface.
356369
void CopyToSurface(Surface &target, Point source_origin, Point target_origin,
357370
Size size) {
@@ -1025,7 +1038,7 @@ class FieldDelegate {
10251038
// Draw the field in the given subpad surface. The surface have a height that
10261039
// is equal to the height returned by FieldDelegateGetHeight(). If the field
10271040
// is selected in the form window, then is_selected will be true.
1028-
virtual void FieldDelegateDraw(SubPad &surface, bool is_selected) = 0;
1041+
virtual void FieldDelegateDraw(Surface &surface, bool is_selected) = 0;
10291042

10301043
// Handle the key that wasn't handled by the form window or a container field.
10311044
virtual HandleCharResult FieldDelegateHandleChar(int key) {
@@ -1112,7 +1125,7 @@ class TextFieldDelegate : public FieldDelegate {
11121125

11131126
int GetContentLength() { return m_content.length(); }
11141127

1115-
void DrawContent(SubPad &surface, bool is_selected) {
1128+
void DrawContent(Surface &surface, bool is_selected) {
11161129
surface.MoveCursor(0, 0);
11171130
const char *text = m_content.c_str() + m_first_visibile_char;
11181131
surface.PutCString(text, surface.GetWidth());
@@ -1131,17 +1144,17 @@ class TextFieldDelegate : public FieldDelegate {
11311144
surface.AttributeOff(A_REVERSE);
11321145
}
11331146

1134-
void DrawField(SubPad &surface, bool is_selected) {
1147+
void DrawField(Surface &surface, bool is_selected) {
11351148
surface.TitledBox(m_label.c_str());
11361149

11371150
Rect content_bounds = surface.GetFrame();
11381151
content_bounds.Inset(1, 1);
1139-
SubPad content_surface = SubPad(surface, content_bounds);
1152+
Surface content_surface = surface.SubSurface(content_bounds);
11401153

11411154
DrawContent(content_surface, is_selected);
11421155
}
11431156

1144-
void DrawError(SubPad &surface) {
1157+
void DrawError(Surface &surface) {
11451158
if (!FieldDelegateHasError())
11461159
return;
11471160
surface.MoveCursor(0, 0);
@@ -1152,12 +1165,12 @@ class TextFieldDelegate : public FieldDelegate {
11521165
surface.AttributeOff(COLOR_PAIR(RedOnBlack));
11531166
}
11541167

1155-
void FieldDelegateDraw(SubPad &surface, bool is_selected) override {
1168+
void FieldDelegateDraw(Surface &surface, bool is_selected) override {
11561169
Rect frame = surface.GetFrame();
11571170
Rect field_bounds, error_bounds;
11581171
frame.HorizontalSplit(GetFieldHeight(), field_bounds, error_bounds);
1159-
SubPad field_surface = SubPad(surface, field_bounds);
1160-
SubPad error_surface = SubPad(surface, error_bounds);
1172+
Surface field_surface = surface.SubSurface(field_bounds);
1173+
Surface error_surface = surface.SubSurface(error_bounds);
11611174

11621175
DrawField(field_surface, is_selected);
11631176
DrawError(error_surface);
@@ -1406,7 +1419,7 @@ class BooleanFieldDelegate : public FieldDelegate {
14061419
// Boolean fields are have a single line.
14071420
int FieldDelegateGetHeight() override { return 1; }
14081421

1409-
void FieldDelegateDraw(SubPad &surface, bool is_selected) override {
1422+
void FieldDelegateDraw(Surface &surface, bool is_selected) override {
14101423
surface.MoveCursor(0, 0);
14111424
surface.PutChar('[');
14121425
if (is_selected)
@@ -1486,7 +1499,7 @@ class ChoicesFieldDelegate : public FieldDelegate {
14861499
return std::min(index, GetNumberOfChoices()) - 1;
14871500
}
14881501

1489-
void DrawContent(SubPad &surface, bool is_selected) {
1502+
void DrawContent(Surface &surface, bool is_selected) {
14901503
int choices_to_draw = GetLastVisibleChoice() - m_first_visibile_choice + 1;
14911504
for (int i = 0; i < choices_to_draw; i++) {
14921505
surface.MoveCursor(0, i);
@@ -1502,14 +1515,14 @@ class ChoicesFieldDelegate : public FieldDelegate {
15021515
}
15031516
}
15041517

1505-
void FieldDelegateDraw(SubPad &surface, bool is_selected) override {
1518+
void FieldDelegateDraw(Surface &surface, bool is_selected) override {
15061519
UpdateScrolling();
15071520

15081521
surface.TitledBox(m_label.c_str());
15091522

15101523
Rect content_bounds = surface.GetFrame();
15111524
content_bounds.Inset(1, 1);
1512-
SubPad content_surface = SubPad(surface, content_bounds);
1525+
Surface content_surface = surface.SubSurface(content_bounds);
15131526

15141527
DrawContent(content_surface, is_selected);
15151528
}
@@ -1684,7 +1697,7 @@ template <class T> class ListFieldDelegate : public FieldDelegate {
16841697
return context;
16851698
}
16861699

1687-
void DrawRemoveButton(SubPad &surface, int highlight) {
1700+
void DrawRemoveButton(Surface &surface, int highlight) {
16881701
surface.MoveCursor(1, surface.GetHeight() / 2);
16891702
if (highlight)
16901703
surface.AttributeOn(A_REVERSE);
@@ -1693,7 +1706,7 @@ template <class T> class ListFieldDelegate : public FieldDelegate {
16931706
surface.AttributeOff(A_REVERSE);
16941707
}
16951708

1696-
void DrawFields(SubPad &surface, bool is_selected) {
1709+
void DrawFields(Surface &surface, bool is_selected) {
16971710
int line = 0;
16981711
int width = surface.GetWidth();
16991712
for (int i = 0; i < GetNumberOfFields(); i++) {
@@ -1702,8 +1715,8 @@ template <class T> class ListFieldDelegate : public FieldDelegate {
17021715
Rect field_bounds, remove_button_bounds;
17031716
bounds.VerticalSplit(bounds.size.width - sizeof(" [Remove]"),
17041717
field_bounds, remove_button_bounds);
1705-
SubPad field_surface = SubPad(surface, field_bounds);
1706-
SubPad remove_button_surface = SubPad(surface, remove_button_bounds);
1718+
Surface field_surface = surface.SubSurface(field_bounds);
1719+
Surface remove_button_surface = surface.SubSurface(remove_button_bounds);
17071720

17081721
bool is_element_selected = m_selection_index == i && is_selected;
17091722
bool is_field_selected =
@@ -1718,7 +1731,7 @@ template <class T> class ListFieldDelegate : public FieldDelegate {
17181731
}
17191732
}
17201733

1721-
void DrawNewButton(SubPad &surface, bool is_selected) {
1734+
void DrawNewButton(Surface &surface, bool is_selected) {
17221735
const char *button_text = "[New]";
17231736
int x = (surface.GetWidth() - sizeof(button_text) - 1) / 2;
17241737
surface.MoveCursor(x, 0);
@@ -1731,16 +1744,16 @@ template <class T> class ListFieldDelegate : public FieldDelegate {
17311744
surface.AttributeOff(A_REVERSE);
17321745
}
17331746

1734-
void FieldDelegateDraw(SubPad &surface, bool is_selected) override {
1747+
void FieldDelegateDraw(Surface &surface, bool is_selected) override {
17351748
surface.TitledBox(m_label.c_str());
17361749

17371750
Rect content_bounds = surface.GetFrame();
17381751
content_bounds.Inset(1, 1);
17391752
Rect fields_bounds, new_button_bounds;
17401753
content_bounds.HorizontalSplit(content_bounds.size.height - 1,
17411754
fields_bounds, new_button_bounds);
1742-
SubPad fields_surface = SubPad(surface, fields_bounds);
1743-
SubPad new_button_surface = SubPad(surface, new_button_bounds);
1755+
Surface fields_surface = surface.SubSurface(fields_bounds);
1756+
Surface new_button_surface = surface.SubSurface(new_button_bounds);
17441757

17451758
DrawFields(fields_surface, is_selected);
17461759
DrawNewButton(new_button_surface, is_selected);
@@ -1936,12 +1949,12 @@ class MappingFieldDelegate : public FieldDelegate {
19361949
m_value_field.FieldDelegateGetHeight());
19371950
}
19381951

1939-
void DrawArrow(SubPad &surface) {
1952+
void DrawArrow(Surface &surface) {
19401953
surface.MoveCursor(0, 1);
19411954
surface.PutChar(ACS_RARROW);
19421955
}
19431956

1944-
void FieldDelegateDraw(SubPad &surface, bool is_selected) override {
1957+
void FieldDelegateDraw(Surface &surface, bool is_selected) override {
19451958
Rect bounds = surface.GetFrame();
19461959
Rect key_field_bounds, arrow_and_value_field_bounds;
19471960
bounds.VerticalSplit(bounds.size.width / 2, key_field_bounds,
@@ -1950,9 +1963,9 @@ class MappingFieldDelegate : public FieldDelegate {
19501963
arrow_and_value_field_bounds.VerticalSplit(1, arrow_bounds,
19511964
value_field_bounds);
19521965

1953-
SubPad key_field_surface = SubPad(surface, key_field_bounds);
1954-
SubPad arrow_surface = SubPad(surface, arrow_bounds);
1955-
SubPad value_field_surface = SubPad(surface, value_field_bounds);
1966+
Surface key_field_surface = surface.SubSurface(key_field_bounds);
1967+
Surface arrow_surface = surface.SubSurface(arrow_bounds);
1968+
Surface value_field_surface = surface.SubSurface(value_field_bounds);
19561969

19571970
bool key_is_selected =
19581971
m_selection_type == SelectionType::Key && is_selected;
@@ -2088,7 +2101,7 @@ class FormAction {
20882101
}
20892102

20902103
// Draw a centered [Label].
2091-
void Draw(SubPad &surface, bool is_selected) {
2104+
void Draw(Surface &surface, bool is_selected) {
20922105
int x = (surface.GetWidth() - m_label.length()) / 2;
20932106
surface.MoveCursor(x, 0);
20942107
if (is_selected)
@@ -2357,7 +2370,7 @@ class FormWindowDelegate : public WindowDelegate {
23572370
return context;
23582371
}
23592372

2360-
void UpdateScrolling(DerivedWindow &surface) {
2373+
void UpdateScrolling(Surface &surface) {
23612374
ScrollContext context = GetScrollContext();
23622375
int content_height = GetContentHeight();
23632376
int surface_height = surface.GetHeight();
@@ -2381,7 +2394,7 @@ class FormWindowDelegate : public WindowDelegate {
23812394
}
23822395
}
23832396

2384-
void DrawError(SubPad &surface) {
2397+
void DrawError(Surface &surface) {
23852398
if (!m_delegate_sp->HasError())
23862399
return;
23872400
surface.MoveCursor(0, 0);
@@ -2395,7 +2408,7 @@ class FormWindowDelegate : public WindowDelegate {
23952408
surface.HorizontalLine(surface.GetWidth());
23962409
}
23972410

2398-
void DrawFields(SubPad &surface) {
2411+
void DrawFields(Surface &surface) {
23992412
int line = 0;
24002413
int width = surface.GetWidth();
24012414
bool a_field_is_selected = m_selection_type == SelectionType::Field;
@@ -2406,13 +2419,13 @@ class FormWindowDelegate : public WindowDelegate {
24062419
bool is_field_selected = a_field_is_selected && m_selection_index == i;
24072420
int height = field->FieldDelegateGetHeight();
24082421
Rect bounds = Rect(Point(0, line), Size(width, height));
2409-
SubPad field_surface = SubPad(surface, bounds);
2422+
Surface field_surface = surface.SubSurface(bounds);
24102423
field->FieldDelegateDraw(field_surface, is_field_selected);
24112424
line += height;
24122425
}
24132426
}
24142427

2415-
void DrawActions(SubPad &surface) {
2428+
void DrawActions(Surface &surface) {
24162429
int number_of_actions = m_delegate_sp->GetNumberOfActions();
24172430
int width = surface.GetWidth() / number_of_actions;
24182431
bool an_action_is_selected = m_selection_type == SelectionType::Action;
@@ -2421,19 +2434,19 @@ class FormWindowDelegate : public WindowDelegate {
24212434
bool is_action_selected = an_action_is_selected && m_selection_index == i;
24222435
FormAction &action = m_delegate_sp->GetAction(i);
24232436
Rect bounds = Rect(Point(x, 0), Size(width, 1));
2424-
SubPad action_surface = SubPad(surface, bounds);
2437+
Surface action_surface = surface.SubSurface(bounds);
24252438
action.Draw(action_surface, is_action_selected);
24262439
x += width;
24272440
}
24282441
}
24292442

2430-
void DrawElements(SubPad &surface) {
2443+
void DrawElements(Surface &surface) {
24312444
Rect frame = surface.GetFrame();
24322445
Rect fields_bounds, actions_bounds;
24332446
frame.HorizontalSplit(surface.GetHeight() - GetActionsHeight(),
24342447
fields_bounds, actions_bounds);
2435-
SubPad fields_surface = SubPad(surface, fields_bounds);
2436-
SubPad actions_surface = SubPad(surface, actions_bounds);
2448+
Surface fields_surface = surface.SubSurface(fields_bounds);
2449+
Surface actions_surface = surface.SubSurface(actions_bounds);
24372450

24382451
DrawFields(fields_surface);
24392452
DrawActions(actions_surface);
@@ -2442,7 +2455,7 @@ class FormWindowDelegate : public WindowDelegate {
24422455
// Contents are first drawn on a pad. Then a subset of that pad is copied to
24432456
// the derived window starting at the first visible line. This essentially
24442457
// provides scrolling functionality.
2445-
void DrawContent(DerivedWindow &surface) {
2458+
void DrawContent(Surface &surface) {
24462459
UpdateScrolling(surface);
24472460

24482461
int width = surface.GetWidth();
@@ -2452,8 +2465,8 @@ class FormWindowDelegate : public WindowDelegate {
24522465
Rect frame = pad.GetFrame();
24532466
Rect error_bounds, elements_bounds;
24542467
frame.HorizontalSplit(GetErrorHeight(), error_bounds, elements_bounds);
2455-
SubPad error_surface = SubPad(pad, error_bounds);
2456-
SubPad elements_surface = SubPad(pad, elements_bounds);
2468+
Surface error_surface = pad.SubSurface(error_bounds);
2469+
Surface elements_surface = pad.SubSurface(elements_bounds);
24572470

24582471
DrawError(error_surface);
24592472
DrawElements(elements_surface);
@@ -2473,7 +2486,7 @@ class FormWindowDelegate : public WindowDelegate {
24732486

24742487
Rect content_bounds = window.GetFrame();
24752488
content_bounds.Inset(2, 2);
2476-
DerivedWindow content_surface = DerivedWindow(window, content_bounds);
2489+
Surface content_surface = window.SubSurface(content_bounds);
24772490

24782491
DrawContent(content_surface);
24792492
return true;

0 commit comments

Comments
 (0)