Remove path name from test case
[binutils-gdb.git] / gdb / tui / tui-layout.h
index c8fa43e315cd54101402507551a51aa549e7676b..a6d34851bef4a47e28977cc87d53fbddec15121b 100644 (file)
@@ -1,6 +1,6 @@
 /* TUI layout window management.
 
-   Copyright (C) 1998-2016 Free Software Foundation, Inc.
+   Copyright (C) 1998-2023 Free Software Foundation, Inc.
 
    Contributed by Hewlett-Packard Company.
 
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
-#ifndef TUI_LAYOUT_H
-#define TUI_LAYOUT_H
+#ifndef TUI_TUI_LAYOUT_H
+#define TUI_TUI_LAYOUT_H
+
+#include "ui-file.h"
 
 #include "tui/tui.h"
 #include "tui/tui-data.h"
+#include "gdbsupport/iterator-range.h"
+
+#include <unordered_map>
+
+/* Values that can be returned when handling a request to adjust a
+   window's size.  */
+enum tui_adjust_result
+{
+  /* Requested window was not found here.  */
+  NOT_FOUND,
+  /* Window was found but not handled.  */
+  FOUND,
+  /* Window was found and handled.  */
+  HANDLED
+};
+
+/* The basic object in a TUI layout.  This represents a single piece
+   of screen real estate.  Subclasses determine the exact
+   behavior.  */
+class tui_layout_base
+{
+public:
+
+  DISABLE_COPY_AND_ASSIGN (tui_layout_base);
+
+  virtual ~tui_layout_base () = default;
+
+  /* Clone this object.  Ordinarily a layout is cloned before it is
+     used, so that any necessary modifications do not affect the
+     "skeleton" layout.  */
+  virtual std::unique_ptr<tui_layout_base> clone () const = 0;
+
+  /* Change the size and location of this layout.  When
+     PRESERVE_CMD_WIN_SIZE_P is true the current size of the TUI_CMD_WIN
+     is preserved, otherwise, the TUI_CMD_WIN will resize just like any
+     other window.  */
+  virtual void apply (int x, int y, int width, int height,
+                     bool preserve_cmd_win_size_p) = 0;
+
+  /* Return the minimum and maximum height or width of this layout.
+     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 (for vertical layouts), or the leftmost (for
+     horizontal layouts) item in this layout is boxed.  */
+  virtual bool first_edge_has_border_p () const = 0;
+
+  /* True if the bottommost (for vertical layouts), or the rightmost (for
+     horizontal layouts) item in this layout is boxed.  */
+  virtual bool last_edge_has_border_p () const = 0;
+
+  /* Return the name of this layout's window, or nullptr if this
+     layout does not represent a single window.  */
+  virtual const char *get_name () const
+  {
+    return nullptr;
+  }
+
+  /* Set the height of the window named NAME to NEW_HEIGHT, updating
+     the sizes of the other windows around it.  */
+  virtual tui_adjust_result set_height (const char *name, int new_height) = 0;
+
+  /* Set the width of the window named NAME to NEW_WIDTH, updating
+     the sizes of the other windows around it.  */
+  virtual tui_adjust_result set_width (const char *name, int new_width) = 0;
+
+  /* Remove some windows from the layout, leaving the command window
+     and the window being passed in here.  */
+  virtual void remove_windows (const char *name) = 0;
+
+  /* Replace the window named NAME in the layout with the window named
+     NEW_WINDOW.  */
+  virtual void replace_window (const char *name, const char *new_window) = 0;
+
+  /* Append the specification to this window to OUTPUT.  DEPTH is the
+     depth of this layout in the hierarchy (zero-based).  */
+  virtual void specification (ui_file *output, int depth) = 0;
+
+  /* Return a FINGERPRINT string containing an abstract representation of
+     the location of the cmd window in this layout.
+
+     When called on a complete, top-level layout, the fingerprint will be a
+     non-empty string made of 'V' and 'H' characters, followed by a single
+     'C' character.  Each 'V' and 'H' represents a vertical or horizontal
+     layout that must be passed through in order to find the cmd
+     window.  A vertical or horizontal layout of just one window does not add
+     a 'V' or 'H' character.
+
+     Of course, layouts are built recursively, so, when called on a partial
+     layout, if this object represents a single window, then either the
+     empty string is returned (for non-cmd windows), or a string
+     containing a single 'C' is returned.
+
+     For object representing layouts, if the layout contains the cmd
+     window then we will get back a valid fingerprint string (may contain 'V'
+     and 'H', ends with 'C'), or, if this layout doesn't contain the cmd
+     window, an empty string is returned.  */
+  virtual std::string layout_fingerprint () const = 0;
+
+  /* Add all windows to the WINDOWS vector.  */
+  virtual void get_windows (std::vector<tui_win_info *> *windows) = 0;
+
+  /* The most recent space allocation.  */
+  int x = 0;
+  int y = 0;
+  int width = 0;
+  int height = 0;
+
+protected:
+
+  tui_layout_base () = default;
+};
+
+/* A TUI layout object that displays a single window.  The window is
+   given by name.  */
+class tui_layout_window : public tui_layout_base
+{
+public:
+
+  explicit tui_layout_window (const char *name)
+    : m_contents (name)
+  {
+  }
+
+  DISABLE_COPY_AND_ASSIGN (tui_layout_window);
+
+  std::unique_ptr<tui_layout_base> clone () const override;
+
+  void apply (int x, int y, int width, int height,
+             bool preserve_cmd_win_size_p) override;
+
+  const char *get_name () const override
+  {
+    return m_contents.c_str ();
+  }
+
+  tui_adjust_result set_height (const char *name, int new_height) override
+  {
+    return m_contents == name ? FOUND : NOT_FOUND;
+  }
+
+  tui_adjust_result set_width (const char *name, int new_width) override
+  {
+    return m_contents == name ? FOUND : NOT_FOUND;
+  }
+
+  bool first_edge_has_border_p () const override;
+
+  bool last_edge_has_border_p () const override;
+
+  void remove_windows (const char *name) override
+  {
+  }
+
+  void replace_window (const char *name, const char *new_window) override;
+
+  void specification (ui_file *output, int depth) override;
+
+  std::string layout_fingerprint () const override;
+
+  /* See tui_layout_base::get_windows.  */
+  void get_windows (std::vector<tui_win_info *> *windows) override
+  {
+    windows->push_back (m_window);
+  }
+
+protected:
+
+  void get_sizes (bool height, int *min_value, int *max_value) override;
+
+private:
+
+  /* Type of content to display.  */
+  std::string m_contents;
+
+  /* When a layout is applied, this is updated to point to the window
+     object.  */
+  tui_win_info *m_window = nullptr;
+};
+
+/* A TUI layout that holds other layouts.  */
+class tui_layout_split : public tui_layout_base
+{
+public:
+
+  /* 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);
+
+  /* Add a new split layout to this layout.  WEIGHT is the desired
+     size, which is relative to the other weights given in this
+     layout.  */
+  void add_split (std::unique_ptr<tui_layout_split> &&layout, int weight);
 
+  /* Add a new window to this layout.  NAME is the name of the window
+     to add.  WEIGHT is the desired size, which is relative to the
+     other weights given in this layout.  */
+  void add_window (const char *name, int weight);
+
+  std::unique_ptr<tui_layout_base> clone () const override;
+
+  void apply (int x, int y, int width, int height,
+             bool preserve_cmd_win_size_p) override;
+
+  tui_adjust_result set_height (const char *name, int new_height) override
+  {
+    /* Pass false as the final argument to indicate change of height.  */
+    return set_size (name, new_height, false);
+  }
+
+  tui_adjust_result set_width (const char *name, int new_width) override
+  {
+    /* Pass true as the final argument to indicate change of width.  */
+    return set_size (name, new_width, true);
+  }
+
+  bool first_edge_has_border_p () const override;
+
+  bool last_edge_has_border_p () const override;
+
+  void remove_windows (const char *name) override;
+
+  void replace_window (const char *name, const char *new_window) override;
+
+  void specification (ui_file *output, int depth) override;
+
+  std::string layout_fingerprint () const override;
+
+  /* See tui_layout_base::get_windows.  */
+  void get_windows (std::vector<tui_win_info *> *windows) override
+  {
+    for (auto &item : m_splits)
+      item.layout->get_windows (windows);
+  }
+
+protected:
+
+  void get_sizes (bool height, int *min_value, int *max_value) override;
+
+private:
+
+  /* Used to implement set_height and set_width member functions.  When
+     SET_WIDTH_P is true, set the width, otherwise, set the height of the
+     window named NAME to NEW_SIZE, updating the sizes of the other windows
+     around it as needed.  The result indicates if the window NAME was
+     found and had its size adjusted, was found but was not adjusted, or
+     was not found at all.  */
+  tui_adjust_result set_size (const char *name, int new_size,
+                             bool set_width_p);
+
+  /* Set the weights from the current heights (when m_vertical is true) or
+     widths (when m_vertical is false).  */
+  void set_weights_from_sizes ();
+
+  /* Structure used when resizing, or applying a layout.  An instance of
+     this structure is created for each sub-layout.  */
+  struct size_info
+  {
+    /* The calculated size for this sub-layout.  */
+    int size;
+
+    /* The minimum and maximum sizes for this sub-layout, obtained by
+       calling the get_sizes member function.  */
+    int min_size;
+    int max_size;
+
+    /* True if this window will share a box border with the previous
+       window in the list.  */
+    bool share_box;
+  };
+
+  /* Used for debug, prints the contents of INFO using tui_debug_printf.
+     Only call this when the global debug_tui is true.  */
+  static void tui_debug_print_size_info (const std::vector<size_info> &info);
+
+  /* Used for debug, returns a string describing the current weight of each
+     sub-layout.  */
+  std::string tui_debug_weights_to_string () const;
+
+  struct split
+  {
+    /* The requested weight.  */
+    int weight;
+    /* The layout.  */
+    std::unique_ptr<tui_layout_base> layout;
+  };
+
+  /* The splits.  */
+  std::vector<split> m_splits;
+
+  /* True if the windows in this split are arranged vertically.  */
+  bool m_vertical;
+};
+
+/* Add the specified window to the layout in a logical way.  This
+   means setting up the most logical layout given the window to be
+   added.  Only the source or disassembly window can be added this
+   way.  */
 extern void tui_add_win_to_layout (enum tui_win_type);
-extern int tui_default_win_height (enum tui_win_type, 
-                                  enum tui_layout_type);
-extern int tui_default_win_viewport_height (enum tui_win_type,
-                                           enum tui_layout_type);
-extern enum tui_status tui_set_layout (enum tui_layout_type);
 
-#endif /*TUI_LAYOUT_H */
+/* Set the initial layout.  */
+extern void tui_set_initial_layout ();
+
+/* Switch to the next layout.  */
+extern void tui_next_layout ();
+
+/* Show the register window.  Like "layout regs".  */
+extern void tui_regs_layout ();
+
+/* Remove some windows from the layout, leaving only the focused
+   window and the command window; if no window has the focus, then
+   some other window is chosen to remain.  */
+extern void tui_remove_some_windows ();
+
+/* Apply the current layout.  When PRESERVE_CMD_WIN_SIZE_P is true the
+   current size of the TUI_CMD_WIN is preserved, otherwise, the TUI_CMD_WIN
+   will resize just like any other window.  */
+extern void tui_apply_current_layout (bool);
+
+/* Adjust the window height of WIN to NEW_HEIGHT.  */
+extern void tui_adjust_window_height (struct tui_win_info *win,
+                                     int new_height);
+
+/* Adjust the window width of WIN to NEW_WIDTH.  */
+extern void tui_adjust_window_width (struct tui_win_info *win,
+                                    int new_width);
+
+/* The type of a function that is used to create a TUI window.  */
+
+typedef std::function<tui_win_info * (const char *name)> window_factory;
+
+/* The type for a data structure that maps a window name to that window's
+   factory function.  */
+typedef std::unordered_map<std::string, window_factory> window_types_map;
+
+/* Register a new TUI window type.  NAME is the name of the window
+   type.  FACTORY is a function that can be called to instantiate the
+   window.  */
+
+extern void tui_register_window (const char *name, window_factory &&factory);
+
+/* An iterator class that exposes just the window names from the
+   known_window_types map in tui-layout.c.  This is just a wrapper around
+   an iterator of the underlying known_window_types map, but this just
+   exposes the window names.  */
+
+struct known_window_names_iterator
+{
+  using known_window_types_iterator = window_types_map::iterator;
+
+  known_window_names_iterator (known_window_types_iterator &&iter)
+    : m_iter (std::move (iter))
+  { /* Nothing.  */ }
+
+  known_window_names_iterator &operator++ ()
+  {
+    ++m_iter;
+    return *this;
+  }
+
+  const std::string &operator* () const
+  { return (*m_iter).first; }
+
+  bool operator!= (const known_window_names_iterator &other) const
+  { return m_iter != other.m_iter; }
+
+private:
+
+  /* The underlying iterator.  */
+  known_window_types_iterator m_iter;
+};
+
+/* A range adapter that makes it possible to iterate over the names of all
+   known tui windows.  */
+
+using known_window_names_range
+  = iterator_range<known_window_names_iterator>;
+
+/* Return a range that can be used to walk over the name of all known tui
+   windows in a range-for loop.  */
+
+extern known_window_names_range all_known_window_names ();
+
+#endif /* TUI_TUI_LAYOUT_H */