Remove path name from test case
[binutils-gdb.git] / gdb / tui / tui-layout.h
index 4351e260720a7863814909e59d9f2e27f1cfd8b7..a6d34851bef4a47e28977cc87d53fbddec15121b 100644 (file)
@@ -1,6 +1,6 @@
 /* TUI layout window management.
 
-   Copyright (C) 1998-2020 Free Software Foundation, Inc.
+   Copyright (C) 1998-2023 Free Software Foundation, Inc.
 
    Contributed by Hewlett-Packard Company.
 
 
 #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
@@ -43,17 +58,24 @@ public:
      "skeleton" layout.  */
   virtual std::unique_ptr<tui_layout_base> clone () const = 0;
 
-  /* Change the size and location of this layout.  */
-  virtual void apply (int x, int y, int width, int height) = 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 of this layout.  */
-  virtual void get_sizes (int *min_height, int *max_height) = 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 item in this layout is boxed.  */
-  virtual bool top_boxed_p () const = 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 item in this layout is boxed.  */
-  virtual bool bottom_boxed_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.  */
@@ -62,9 +84,13 @@ public:
     return nullptr;
   }
 
-  /* Adjust the size of the window named NAME to NEW_HEIGHT, updating
+  /* Set the height of the window named NAME to NEW_HEIGHT, updating
      the sizes of the other windows around it.  */
-  virtual bool adjust_size (const char *name, int new_height) = 0;
+  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.  */
@@ -78,6 +104,30 @@ public:
      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;
@@ -104,21 +154,27 @@ public:
 
   std::unique_ptr<tui_layout_base> clone () const override;
 
-  void apply (int x, int y, int width, int height) 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 ();
   }
 
-  bool adjust_size (const char *name, int new_height) override
+  tui_adjust_result set_height (const char *name, int new_height) override
   {
-    return false;
+    return m_contents == name ? FOUND : NOT_FOUND;
   }
 
-  bool top_boxed_p () const override;
+  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 bottom_boxed_p () const override;
+  bool last_edge_has_border_p () const override;
 
   void remove_windows (const char *name) override
   {
@@ -128,9 +184,17 @@ public:
 
   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 (int *min_height, int *max_height) override;
+  void get_sizes (bool height, int *min_value, int *max_value) override;
 
 private:
 
@@ -139,7 +203,7 @@ private:
 
   /* When a layout is applied, this is updated to point to the window
      object.  */
-  tui_gen_win_info *m_window = nullptr;
+  tui_win_info *m_window = nullptr;
 };
 
 /* A TUI layout that holds other layouts.  */
@@ -147,7 +211,12 @@ class tui_layout_split : public tui_layout_base
 {
 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);
 
@@ -163,13 +232,24 @@ public:
 
   std::unique_ptr<tui_layout_base> clone () const override;
 
-  void apply (int x, int y, int width, int height) 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);
+  }
 
-  bool adjust_size (const char *name, int new_height) override;
+  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 top_boxed_p () const override;
+  bool first_edge_has_border_p () const override;
 
-  bool bottom_boxed_p () const override;
+  bool last_edge_has_border_p () const override;
 
   void remove_windows (const char *name) override;
 
@@ -177,14 +257,58 @@ public:
 
   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 (int *min_height, int *max_height) override;
+  void get_sizes (bool height, int *min_value, int *max_value) override;
 
 private:
 
-  /* Set the weights from the current heights.  */
-  void set_weights_from_heights ();
+  /* 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
   {
@@ -197,8 +321,8 @@ private:
   /* The splits.  */
   std::vector<split> m_splits;
 
-  /* True if this layout has already been applied at least once.  */
-  bool m_applied = false;
+  /* 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
@@ -221,11 +345,73 @@ extern void tui_regs_layout ();
    some other window is chosen to remain.  */
 extern void tui_remove_some_windows ();
 
-/* Apply the current layout.  */
-extern void tui_apply_current_layout ();
+/* 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 */