mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-29 16:38:05 +08:00
Add horizontal splitting to TUI layout
This changes the TUI layout engine to add horizontal splitting. Now, windows can be side-by-side. A horizontal split is defined using the "-horizontal" parameter to "tui new-layout". This also adds the first "winheight" test to the test suite. One open question is whether we want a new "winwidth" command, now that horizontal layouts are possible. This is easily done using the generic layout code. gdb/ChangeLog 2020-02-22 Tom Tromey <tom@tromey.com> PR tui/17850: * tui/tui-win.c (tui_gen_win_info::max_width): New method. * tui/tui-layout.h (class tui_layout_base) <get_sizes>: Add "height" argument. (class tui_layout_window) <get_sizes>: Likewise. (class tui_layout_split) <tui_layout_split>: Add "vertical" argument. <get_sizes>: Add "height" argument. <m_vertical>: New field. * tui/tui-layout.c (tui_layout_split::clone): Update. (tui_layout_split::get_sizes): Add "height" argument. (tui_layout_split::adjust_size, tui_layout_split::apply): Update. (tui_new_layout_command): Parse "-horizontal". (_initialize_tui_layout): Update help string. (tui_layout_split::specification): Add "-horizontal" when needed. * tui/tui-layout.c (tui_layout_window::get_sizes): Add "height" argument. * tui/tui-data.h (struct tui_gen_win_info) <max_width, min_width>: New methods. gdb/doc/ChangeLog 2020-02-22 Tom Tromey <tom@tromey.com> PR tui/17850: * gdb.texinfo (TUI Commands): Document horizontal layouts. gdb/testsuite/ChangeLog 2020-02-22 Tom Tromey <tom@tromey.com> PR tui/17850: * gdb.tui/new-layout.exp: Add horizontal layout and winheight tests. Change-Id: I38b35e504f34698578af86686be03c0fefd954ae
This commit is contained in:
@ -1,3 +1,25 @@
|
|||||||
|
2020-02-22 Tom Tromey <tom@tromey.com>
|
||||||
|
|
||||||
|
PR tui/17850:
|
||||||
|
* tui/tui-win.c (tui_gen_win_info::max_width): New method.
|
||||||
|
* tui/tui-layout.h (class tui_layout_base) <get_sizes>: Add
|
||||||
|
"height" argument.
|
||||||
|
(class tui_layout_window) <get_sizes>: Likewise.
|
||||||
|
(class tui_layout_split) <tui_layout_split>: Add "vertical"
|
||||||
|
argument.
|
||||||
|
<get_sizes>: Add "height" argument.
|
||||||
|
<m_vertical>: New field.
|
||||||
|
* tui/tui-layout.c (tui_layout_split::clone): Update.
|
||||||
|
(tui_layout_split::get_sizes): Add "height" argument.
|
||||||
|
(tui_layout_split::adjust_size, tui_layout_split::apply): Update.
|
||||||
|
(tui_new_layout_command): Parse "-horizontal".
|
||||||
|
(_initialize_tui_layout): Update help string.
|
||||||
|
(tui_layout_split::specification): Add "-horizontal" when needed.
|
||||||
|
* tui/tui-layout.c (tui_layout_window::get_sizes): Add "height"
|
||||||
|
argument.
|
||||||
|
* tui/tui-data.h (struct tui_gen_win_info) <max_width, min_width>:
|
||||||
|
New methods.
|
||||||
|
|
||||||
2020-02-22 Tom Tromey <tom@tromey.com>
|
2020-02-22 Tom Tromey <tom@tromey.com>
|
||||||
|
|
||||||
* tui/tui-layout.h (enum tui_adjust_result): New.
|
* tui/tui-layout.h (enum tui_adjust_result): New.
|
||||||
|
2
gdb/NEWS
2
gdb/NEWS
@ -17,6 +17,8 @@
|
|||||||
* The $_siginfo convenience variable now also works on Windows targets,
|
* The $_siginfo convenience variable now also works on Windows targets,
|
||||||
and will display the EXCEPTION_RECORD of the last handled exception.
|
and will display the EXCEPTION_RECORD of the last handled exception.
|
||||||
|
|
||||||
|
* TUI windows can now be arranged horizontally.
|
||||||
|
|
||||||
* New commands
|
* New commands
|
||||||
|
|
||||||
set exec-file-mismatch -- Set exec-file-mismatch handling (ask|warn|off).
|
set exec-file-mismatch -- Set exec-file-mismatch handling (ask|warn|off).
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
2020-02-22 Tom Tromey <tom@tromey.com>
|
||||||
|
|
||||||
|
PR tui/17850:
|
||||||
|
* gdb.texinfo (TUI Commands): Document horizontal layouts.
|
||||||
|
|
||||||
2020-02-22 Tom Tromey <tom@tromey.com>
|
2020-02-22 Tom Tromey <tom@tromey.com>
|
||||||
|
|
||||||
* gdb.texinfo (TUI Overview): Mention user layouts.
|
* gdb.texinfo (TUI Overview): Mention user layouts.
|
||||||
|
@ -27998,11 +27998,23 @@ List and give the size of all displayed windows.
|
|||||||
Create a new TUI layout. The new layout will be named @var{name}, and
|
Create a new TUI layout. The new layout will be named @var{name}, and
|
||||||
can be accessed using the @code{layout} command (see below).
|
can be accessed using the @code{layout} command (see below).
|
||||||
|
|
||||||
Each @var{window} parameter is the name of a window to display. The
|
Each @var{window} parameter is either the name of a window to display,
|
||||||
windows will be displayed from top to bottom in the order listed. The
|
or a window description. The windows will be displayed from top to
|
||||||
names of the windows are the same as the ones given to the
|
bottom in the order listed.
|
||||||
|
|
||||||
|
The names of the windows are the same as the ones given to the
|
||||||
@code{focus} command (see below); additional, the @code{status}
|
@code{focus} command (see below); additional, the @code{status}
|
||||||
window can be specified.
|
window can be specified. Note that, because it is of fixed height,
|
||||||
|
the weight assigned to the status window is of no importance. It is
|
||||||
|
conventional to use @samp{0} here.
|
||||||
|
|
||||||
|
A window description looks a bit like an invocation of @code{tui
|
||||||
|
new-layout}, and is of the form
|
||||||
|
@{@r{[}@code{-horizontal}@r{]}@var{window} @var{weight} @r{[}@var{window} @var{weight}@dots{}@r{]}@}.
|
||||||
|
|
||||||
|
This specifies a sub-layout. If @code{-horizontal} is given, the
|
||||||
|
windows in this description will be arranged side-by-side, rather than
|
||||||
|
top-to-bottom.
|
||||||
|
|
||||||
Each @var{weight} is an integer. It is the weight of this window
|
Each @var{weight} is an integer. It is the weight of this window
|
||||||
relative to all the other windows in the layout. These numbers are
|
relative to all the other windows in the layout. These numbers are
|
||||||
@ -28019,6 +28031,17 @@ and register windows, followed by the status window, and then finally
|
|||||||
the command window. The non-status windows all have the same weight,
|
the command window. The non-status windows all have the same weight,
|
||||||
so the terminal will be split into three roughly equal sections.
|
so the terminal will be split into three roughly equal sections.
|
||||||
|
|
||||||
|
Here is a more complex example, showing a horizontal layout:
|
||||||
|
|
||||||
|
@example
|
||||||
|
(gdb) tui new-layout example @{-horizontal src 1 asm 1@} 2 status 0 cmd 1
|
||||||
|
@end example
|
||||||
|
|
||||||
|
This will result in side-by-side source and assembly windows; with the
|
||||||
|
status and command window being beneath these, filling the entire
|
||||||
|
width of the terminal. Because they have weight 2, the source and
|
||||||
|
assembly windows will be twice the height of the command window.
|
||||||
|
|
||||||
@item layout @var{name}
|
@item layout @var{name}
|
||||||
@kindex layout
|
@kindex layout
|
||||||
Changes which TUI windows are displayed. The @var{name} parameter
|
Changes which TUI windows are displayed. The @var{name} parameter
|
||||||
|
@ -1,3 +1,9 @@
|
|||||||
|
2020-02-22 Tom Tromey <tom@tromey.com>
|
||||||
|
|
||||||
|
PR tui/17850:
|
||||||
|
* gdb.tui/new-layout.exp: Add horizontal layout and winheight
|
||||||
|
tests.
|
||||||
|
|
||||||
2020-02-22 Tom Tromey <tom@tromey.com>
|
2020-02-22 Tom Tromey <tom@tromey.com>
|
||||||
|
|
||||||
* gdb.tui/new-layout.exp: Add sub-layout tests.
|
* gdb.tui/new-layout.exp: Add sub-layout tests.
|
||||||
|
@ -52,6 +52,11 @@ gdb_test_no_output "tui new-layout example2 {asm 1 status 0} 1 cmd 1"
|
|||||||
gdb_test "help layout example2" \
|
gdb_test "help layout example2" \
|
||||||
"Apply the \"example2\" layout.*tui new-layout example2 {asm 1 status 0} 1 cmd 1"
|
"Apply the \"example2\" layout.*tui new-layout example2 {asm 1 status 0} 1 cmd 1"
|
||||||
|
|
||||||
|
gdb_test_no_output "tui new-layout h {-horizontal asm 1 src 1} 1 status 0 cmd 1"
|
||||||
|
|
||||||
|
gdb_test "help layout h" \
|
||||||
|
"Apply the \"h\" layout.*tui new-layout h {-horizontal asm 1 src 1} 1 status 0 cmd 1"
|
||||||
|
|
||||||
if {![Term::enter_tui]} {
|
if {![Term::enter_tui]} {
|
||||||
unsupported "TUI not supported"
|
unsupported "TUI not supported"
|
||||||
}
|
}
|
||||||
@ -62,4 +67,18 @@ gdb_assert {![string match "No Source Available" $text]} \
|
|||||||
|
|
||||||
Term::command "layout example"
|
Term::command "layout example"
|
||||||
Term::check_contents "example layout shows assembly" \
|
Term::check_contents "example layout shows assembly" \
|
||||||
"No Assembly Available"
|
"$hex <main>"
|
||||||
|
|
||||||
|
Term::command "layout h"
|
||||||
|
Term::check_box "left window box" 0 0 40 15
|
||||||
|
Term::check_box "right window box" 39 0 41 15
|
||||||
|
Term::check_contents "horizontal display" \
|
||||||
|
"$hex <main>.*21.*return 0"
|
||||||
|
|
||||||
|
Term::command "winheight src - 5"
|
||||||
|
Term::check_box "left window box after shrink" 0 0 40 10
|
||||||
|
Term::check_box "right window box after shrink" 39 0 41 10
|
||||||
|
|
||||||
|
Term::command "winheight src + 5"
|
||||||
|
Term::check_box "left window box after grow" 0 0 40 15
|
||||||
|
Term::check_box "right window box after grow" 39 0 41 15
|
||||||
|
@ -82,6 +82,15 @@ public:
|
|||||||
/* Compute the minimum height of this window. */
|
/* Compute the minimum height of this window. */
|
||||||
virtual int min_height () const = 0;
|
virtual int min_height () const = 0;
|
||||||
|
|
||||||
|
/* Compute the maximum width of this window. */
|
||||||
|
int max_width () const;
|
||||||
|
|
||||||
|
/* Compute the minimum width of this window. */
|
||||||
|
int min_width () const
|
||||||
|
{
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
/* Return true if this window can be boxed. */
|
/* Return true if this window can be boxed. */
|
||||||
virtual bool can_box () const
|
virtual bool can_box () const
|
||||||
{
|
{
|
||||||
|
@ -355,12 +355,20 @@ tui_layout_window::apply (int x_, int y_, int width_, int height_)
|
|||||||
/* See tui-layout.h. */
|
/* See tui-layout.h. */
|
||||||
|
|
||||||
void
|
void
|
||||||
tui_layout_window::get_sizes (int *min_height, int *max_height)
|
tui_layout_window::get_sizes (bool height, int *min_value, int *max_value)
|
||||||
{
|
{
|
||||||
if (m_window == nullptr)
|
if (m_window == nullptr)
|
||||||
m_window = tui_get_window_by_name (m_contents);
|
m_window = tui_get_window_by_name (m_contents);
|
||||||
*min_height = m_window->min_height ();
|
if (height)
|
||||||
*max_height = m_window->max_height ();
|
{
|
||||||
|
*min_value = m_window->min_height ();
|
||||||
|
*max_value = m_window->max_height ();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*min_value = m_window->min_width ();
|
||||||
|
*max_value = m_window->max_width ();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* See tui-layout.h. */
|
/* See tui-layout.h. */
|
||||||
@ -430,7 +438,7 @@ tui_layout_split::add_window (const char *name, int weight)
|
|||||||
std::unique_ptr<tui_layout_base>
|
std::unique_ptr<tui_layout_base>
|
||||||
tui_layout_split::clone () const
|
tui_layout_split::clone () const
|
||||||
{
|
{
|
||||||
tui_layout_split *result = new tui_layout_split ();
|
tui_layout_split *result = new tui_layout_split (m_vertical);
|
||||||
for (const split &item : m_splits)
|
for (const split &item : m_splits)
|
||||||
{
|
{
|
||||||
std::unique_ptr<tui_layout_base> next = item.layout->clone ();
|
std::unique_ptr<tui_layout_base> next = item.layout->clone ();
|
||||||
@ -443,16 +451,29 @@ tui_layout_split::clone () const
|
|||||||
/* See tui-layout.h. */
|
/* See tui-layout.h. */
|
||||||
|
|
||||||
void
|
void
|
||||||
tui_layout_split::get_sizes (int *min_height, int *max_height)
|
tui_layout_split::get_sizes (bool height, int *min_value, int *max_value)
|
||||||
{
|
{
|
||||||
*min_height = 0;
|
*min_value = 0;
|
||||||
*max_height = 0;
|
*max_value = 0;
|
||||||
|
bool first_time = true;
|
||||||
for (const split &item : m_splits)
|
for (const split &item : m_splits)
|
||||||
{
|
{
|
||||||
int new_min, new_max;
|
int new_min, new_max;
|
||||||
item.layout->get_sizes (&new_min, &new_max);
|
item.layout->get_sizes (height, &new_min, &new_max);
|
||||||
*min_height += new_min;
|
/* For the mismatch case, the first time through we want to set
|
||||||
*max_height += new_max;
|
the min and max to the computed values -- the "first_time"
|
||||||
|
check here is just a funny way of doing that. */
|
||||||
|
if (height == m_vertical || first_time)
|
||||||
|
{
|
||||||
|
*min_value += new_min;
|
||||||
|
*max_value += new_max;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*min_value = std::max (*min_value, new_min);
|
||||||
|
*max_value = std::min (*max_value, new_max);
|
||||||
|
}
|
||||||
|
first_time = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -502,6 +523,8 @@ tui_layout_split::adjust_size (const char *name, int new_height)
|
|||||||
return HANDLED;
|
return HANDLED;
|
||||||
if (adjusted == FOUND)
|
if (adjusted == FOUND)
|
||||||
{
|
{
|
||||||
|
if (!m_vertical)
|
||||||
|
return FOUND;
|
||||||
found_index = i;
|
found_index = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -524,7 +547,7 @@ tui_layout_split::adjust_size (const char *name, int new_height)
|
|||||||
int index = (found_index + 1 + i) % m_splits.size ();
|
int index = (found_index + 1 + i) % m_splits.size ();
|
||||||
|
|
||||||
int new_min, new_max;
|
int new_min, new_max;
|
||||||
m_splits[index].layout->get_sizes (&new_min, &new_max);
|
m_splits[index].layout->get_sizes (m_vertical, &new_min, &new_max);
|
||||||
|
|
||||||
if (delta < 0)
|
if (delta < 0)
|
||||||
{
|
{
|
||||||
@ -571,23 +594,23 @@ tui_layout_split::apply (int x_, int y_, int width_, int height_)
|
|||||||
width = width_;
|
width = width_;
|
||||||
height = height_;
|
height = height_;
|
||||||
|
|
||||||
struct height_info
|
struct size_info
|
||||||
{
|
{
|
||||||
int height;
|
int size;
|
||||||
int min_height;
|
int min_size;
|
||||||
int max_height;
|
int max_size;
|
||||||
/* True if this window will share a box border with the previous
|
/* True if this window will share a box border with the previous
|
||||||
window in the list. */
|
window in the list. */
|
||||||
bool share_box;
|
bool share_box;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<height_info> info (m_splits.size ());
|
std::vector<size_info> info (m_splits.size ());
|
||||||
|
|
||||||
/* Step 1: Find the min and max height of each sub-layout.
|
/* Step 1: Find the min and max size of each sub-layout.
|
||||||
Fixed-sized layouts are given their desired height, and then the
|
Fixed-sized layouts are given their desired size, and then the
|
||||||
remaining space is distributed among the remaining windows
|
remaining space is distributed among the remaining windows
|
||||||
according to the weights given. */
|
according to the weights given. */
|
||||||
int available_height = height;
|
int available_size = m_vertical ? height : width;
|
||||||
int last_index = -1;
|
int last_index = -1;
|
||||||
int total_weight = 0;
|
int total_weight = 0;
|
||||||
for (int i = 0; i < m_splits.size (); ++i)
|
for (int i = 0; i < m_splits.size (); ++i)
|
||||||
@ -597,7 +620,8 @@ tui_layout_split::apply (int x_, int y_, int width_, int height_)
|
|||||||
/* Always call get_sizes, to ensure that the window is
|
/* Always call get_sizes, to ensure that the window is
|
||||||
instantiated. This is a bit gross but less gross than adding
|
instantiated. This is a bit gross but less gross than adding
|
||||||
special cases for this in other places. */
|
special cases for this in other places. */
|
||||||
m_splits[i].layout->get_sizes (&info[i].min_height, &info[i].max_height);
|
m_splits[i].layout->get_sizes (m_vertical, &info[i].min_size,
|
||||||
|
&info[i].max_size);
|
||||||
|
|
||||||
if (!m_applied
|
if (!m_applied
|
||||||
&& cmd_win_already_exists
|
&& cmd_win_already_exists
|
||||||
@ -607,15 +631,17 @@ tui_layout_split::apply (int x_, int y_, int width_, int height_)
|
|||||||
/* If this layout has never been applied, then it means the
|
/* If this layout has never been applied, then it means the
|
||||||
user just changed the layout. In this situation, it's
|
user just changed the layout. In this situation, it's
|
||||||
desirable to keep the size of the command window the
|
desirable to keep the size of the command window the
|
||||||
same. Setting the min and max heights this way ensures
|
same. Setting the min and max sizes this way ensures
|
||||||
that the resizing step, below, does the right thing with
|
that the resizing step, below, does the right thing with
|
||||||
this window. */
|
this window. */
|
||||||
info[i].min_height = TUI_CMD_WIN->height;
|
info[i].min_size = (m_vertical
|
||||||
info[i].max_height = TUI_CMD_WIN->height;
|
? TUI_CMD_WIN->height
|
||||||
|
: TUI_CMD_WIN->width);
|
||||||
|
info[i].max_size = info[i].min_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info[i].min_height == info[i].max_height)
|
if (info[i].min_size == info[i].max_size)
|
||||||
available_height -= info[i].min_height;
|
available_size -= info[i].min_size;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
last_index = i;
|
last_index = i;
|
||||||
@ -623,54 +649,58 @@ tui_layout_split::apply (int x_, int y_, int width_, int height_)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Two adjacent boxed windows will share a border, making a bit
|
/* Two adjacent boxed windows will share a border, making a bit
|
||||||
more height available. */
|
more size available. */
|
||||||
if (i > 0
|
if (i > 0
|
||||||
&& m_splits[i - 1].layout->bottom_boxed_p ()
|
&& m_splits[i - 1].layout->bottom_boxed_p ()
|
||||||
&& m_splits[i].layout->top_boxed_p ())
|
&& m_splits[i].layout->top_boxed_p ())
|
||||||
info[i].share_box = true;
|
info[i].share_box = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Step 2: Compute the height of each sub-layout. Fixed-sized items
|
/* Step 2: Compute the size of each sub-layout. Fixed-sized items
|
||||||
are given their fixed size, while others are resized according to
|
are given their fixed size, while others are resized according to
|
||||||
their weight. */
|
their weight. */
|
||||||
int used_height = 0;
|
int used_size = 0;
|
||||||
for (int i = 0; i < m_splits.size (); ++i)
|
for (int i = 0; i < m_splits.size (); ++i)
|
||||||
{
|
{
|
||||||
/* Compute the height and clamp to the allowable range. */
|
/* Compute the height and clamp to the allowable range. */
|
||||||
info[i].height = available_height * m_splits[i].weight / total_weight;
|
info[i].size = available_size * m_splits[i].weight / total_weight;
|
||||||
if (info[i].height > info[i].max_height)
|
if (info[i].size > info[i].max_size)
|
||||||
info[i].height = info[i].max_height;
|
info[i].size = info[i].max_size;
|
||||||
if (info[i].height < info[i].min_height)
|
if (info[i].size < info[i].min_size)
|
||||||
info[i].height = info[i].min_height;
|
info[i].size = info[i].min_size;
|
||||||
/* If there is any leftover height, just redistribute it to the
|
/* If there is any leftover size, just redistribute it to the
|
||||||
last resizeable window, by dropping it from the allocated
|
last resizeable window, by dropping it from the allocated
|
||||||
height. We could try to be fancier here perhaps, by
|
size. We could try to be fancier here perhaps, by
|
||||||
redistributing this height among all windows, not just the
|
redistributing this size among all windows, not just the
|
||||||
last window. */
|
last window. */
|
||||||
if (info[i].min_height != info[i].max_height)
|
if (info[i].min_size != info[i].max_size)
|
||||||
{
|
{
|
||||||
used_height += info[i].height;
|
used_size += info[i].size;
|
||||||
if (info[i].share_box)
|
if (info[i].share_box)
|
||||||
--used_height;
|
--used_size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate any leftover height. */
|
/* Allocate any leftover size. */
|
||||||
if (available_height >= used_height && last_index != -1)
|
if (available_size >= used_size && last_index != -1)
|
||||||
info[last_index].height += available_height - used_height;
|
info[last_index].size += available_size - used_size;
|
||||||
|
|
||||||
/* Step 3: Resize. */
|
/* Step 3: Resize. */
|
||||||
int height_accum = 0;
|
int size_accum = 0;
|
||||||
|
const int maximum = m_vertical ? height : width;
|
||||||
for (int i = 0; i < m_splits.size (); ++i)
|
for (int i = 0; i < m_splits.size (); ++i)
|
||||||
{
|
{
|
||||||
/* If we fall off the bottom, just make allocations overlap.
|
/* If we fall off the bottom, just make allocations overlap.
|
||||||
GIGO. */
|
GIGO. */
|
||||||
if (height_accum + info[i].height > height)
|
if (size_accum + info[i].size > maximum)
|
||||||
height_accum = height - info[i].height;
|
size_accum = maximum - info[i].size;
|
||||||
else if (info[i].share_box)
|
else if (info[i].share_box)
|
||||||
--height_accum;
|
--size_accum;
|
||||||
m_splits[i].layout->apply (x, y + height_accum, width, info[i].height);
|
if (m_vertical)
|
||||||
height_accum += info[i].height;
|
m_splits[i].layout->apply (x, y + size_accum, width, info[i].size);
|
||||||
|
else
|
||||||
|
m_splits[i].layout->apply (x + size_accum, y, info[i].size, height);
|
||||||
|
size_accum += info[i].size;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_applied = true;
|
m_applied = true;
|
||||||
@ -716,6 +746,9 @@ tui_layout_split::specification (ui_file *output, int depth)
|
|||||||
if (depth > 0)
|
if (depth > 0)
|
||||||
fputs_unfiltered ("{", output);
|
fputs_unfiltered ("{", output);
|
||||||
|
|
||||||
|
if (!m_vertical)
|
||||||
|
fputs_unfiltered ("-horizontal ", output);
|
||||||
|
|
||||||
bool first = true;
|
bool first = true;
|
||||||
for (auto &item : m_splits)
|
for (auto &item : m_splits)
|
||||||
{
|
{
|
||||||
@ -839,8 +872,13 @@ tui_new_layout_command (const char *spec, int from_tty)
|
|||||||
if (new_name[0] == '-')
|
if (new_name[0] == '-')
|
||||||
error (_("Layout name cannot start with '-'"));
|
error (_("Layout name cannot start with '-'"));
|
||||||
|
|
||||||
|
bool is_vertical = true;
|
||||||
|
spec = skip_spaces (spec);
|
||||||
|
if (check_for_argument (&spec, "-horizontal"))
|
||||||
|
is_vertical = false;
|
||||||
|
|
||||||
std::vector<std::unique_ptr<tui_layout_split>> splits;
|
std::vector<std::unique_ptr<tui_layout_split>> splits;
|
||||||
splits.emplace_back (new tui_layout_split);
|
splits.emplace_back (new tui_layout_split (is_vertical));
|
||||||
std::unordered_set<std::string> seen_windows;
|
std::unordered_set<std::string> seen_windows;
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
@ -850,8 +888,11 @@ tui_new_layout_command (const char *spec, int from_tty)
|
|||||||
|
|
||||||
if (spec[0] == '{')
|
if (spec[0] == '{')
|
||||||
{
|
{
|
||||||
splits.emplace_back (new tui_layout_split);
|
is_vertical = true;
|
||||||
++spec;
|
spec = skip_spaces (spec + 1);
|
||||||
|
if (check_for_argument (&spec, "-horizontal"))
|
||||||
|
is_vertical = false;
|
||||||
|
splits.emplace_back (new tui_layout_split (is_vertical));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -940,12 +981,12 @@ Usage: layout prev | next | LAYOUT-NAME"),
|
|||||||
|
|
||||||
add_cmd ("new-layout", class_tui, tui_new_layout_command,
|
add_cmd ("new-layout", class_tui, tui_new_layout_command,
|
||||||
_("Create a new TUI layout.\n\
|
_("Create a new TUI layout.\n\
|
||||||
Usage: tui new-layout NAME WINDOW WEIGHT [WINDOW WEIGHT]...\n\
|
Usage: tui new-layout [-horizontal] NAME WINDOW WEIGHT [WINDOW WEIGHT]...\n\
|
||||||
Create a new TUI layout. The new layout will be named NAME,\n\
|
Create a new TUI layout. The new layout will be named NAME,\n\
|
||||||
and can be accessed using \"layout NAME\".\n\
|
and can be accessed using \"layout NAME\".\n\
|
||||||
The windows will be displayed in the specified order.\n\
|
The windows will be displayed in the specified order.\n\
|
||||||
A WINDOW can also be of the form:\n\
|
A WINDOW can also be of the form:\n\
|
||||||
{ NAME WEIGHT [NAME WEIGHT]... }\n\
|
{ [-horizontal] NAME WEIGHT [NAME WEIGHT]... }\n\
|
||||||
This form indicates a sub-frame.\n\
|
This form indicates a sub-frame.\n\
|
||||||
Each WEIGHT is an integer, which holds the relative size\n\
|
Each WEIGHT is an integer, which holds the relative size\n\
|
||||||
to be allocated to the window."),
|
to be allocated to the window."),
|
||||||
|
@ -58,8 +58,9 @@ public:
|
|||||||
/* Change the size and location of this layout. */
|
/* Change the size and location of this layout. */
|
||||||
virtual void apply (int x, int y, int width, int height) = 0;
|
virtual void apply (int x, int y, int width, int height) = 0;
|
||||||
|
|
||||||
/* Return the minimum and maximum height of this layout. */
|
/* Return the minimum and maximum height or width of this layout.
|
||||||
virtual void get_sizes (int *min_height, int *max_height) = 0;
|
HEIGHT is true to fetch height, false to fetch width. */
|
||||||
|
virtual void get_sizes (bool height, int *min_value, int *max_value) = 0;
|
||||||
|
|
||||||
/* True if the topmost item in this layout is boxed. */
|
/* True if the topmost item in this layout is boxed. */
|
||||||
virtual bool top_boxed_p () const = 0;
|
virtual bool top_boxed_p () const = 0;
|
||||||
@ -142,7 +143,7 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
void get_sizes (int *min_height, int *max_height) override;
|
void get_sizes (bool height, int *min_value, int *max_value) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -159,7 +160,12 @@ class tui_layout_split : public tui_layout_base
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
tui_layout_split () = default;
|
/* Create a new layout. If VERTICAL is true, then windows in this
|
||||||
|
layout will be arranged vertically. */
|
||||||
|
explicit tui_layout_split (bool vertical = true)
|
||||||
|
: m_vertical (vertical)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
DISABLE_COPY_AND_ASSIGN (tui_layout_split);
|
DISABLE_COPY_AND_ASSIGN (tui_layout_split);
|
||||||
|
|
||||||
@ -191,7 +197,7 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
void get_sizes (int *min_height, int *max_height) override;
|
void get_sizes (bool height, int *min_value, int *max_value) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -209,6 +215,9 @@ private:
|
|||||||
/* The splits. */
|
/* The splits. */
|
||||||
std::vector<split> m_splits;
|
std::vector<split> m_splits;
|
||||||
|
|
||||||
|
/* True if the windows in this split are arranged vertically. */
|
||||||
|
bool m_vertical;
|
||||||
|
|
||||||
/* True if this layout has already been applied at least once. */
|
/* True if this layout has already been applied at least once. */
|
||||||
bool m_applied = false;
|
bool m_applied = false;
|
||||||
};
|
};
|
||||||
|
@ -952,6 +952,14 @@ tui_win_info::max_height () const
|
|||||||
return tui_term_height () - 2;
|
return tui_term_height () - 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* See tui-data.h. */
|
||||||
|
|
||||||
|
int
|
||||||
|
tui_gen_win_info::max_width () const
|
||||||
|
{
|
||||||
|
return tui_term_width () - 2;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
parse_scrolling_args (const char *arg,
|
parse_scrolling_args (const char *arg,
|
||||||
struct tui_win_info **win_to_scroll,
|
struct tui_win_info **win_to_scroll,
|
||||||
|
Reference in New Issue
Block a user