/* TUI layout window management. Copyright (C) 1998-2020 Free Software Foundation, Inc. Contributed by Hewlett-Packard Company. This file is part of GDB. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef TUI_TUI_LAYOUT_H #define TUI_TUI_LAYOUT_H #include "ui-file.h" #include "tui/tui.h" #include "tui/tui-data.h" /* 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 clone () const = 0; /* Change the size and location of this layout. */ virtual void apply (int x, int y, int width, int 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 bottommost item in this layout is boxed. */ virtual bool bottom_boxed_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; } /* Adjust the size of the window named NAME to NEW_HEIGHT, updating the sizes of the other windows around it. */ virtual tui_adjust_result adjust_size (const char *name, int new_height) = 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; /* 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 clone () const override; void apply (int x, int y, int width, int height) override; const char *get_name () const override { return m_contents.c_str (); } tui_adjust_result adjust_size (const char *name, int new_height) override { return m_contents == name ? FOUND : NOT_FOUND; } bool top_boxed_p () const override; bool bottom_boxed_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; 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 &&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 clone () const override; void apply (int x, int y, int width, int height) override; tui_adjust_result adjust_size (const char *name, int new_height) override; bool top_boxed_p () const override; bool bottom_boxed_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; protected: 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 (); struct split { /* The requested weight. */ int weight; /* The layout. */ std::unique_ptr layout; }; /* The splits. */ std::vector 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. */ bool m_applied = false; }; /* 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); /* 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. */ extern void tui_apply_current_layout (); /* Adjust the window height of WIN to NEW_HEIGHT. */ extern void tui_adjust_window_height (struct tui_win_info *win, int new_height); /* The type of a function that is used to create a TUI window. */ typedef std::function window_factory; /* 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); #endif /* TUI_TUI_LAYOUT_H */