diff options
| author | srdusr <trevorgray@srdusr.com> | 2025-09-26 12:23:19 +0200 |
|---|---|---|
| committer | srdusr <trevorgray@srdusr.com> | 2025-09-26 12:23:19 +0200 |
| commit | e4a0432383331e013808a97b7c24707e4ddc4726 (patch) | |
| tree | 3ef4465be03bc7b92a0b048f02f76475045404b6 /src/layouts | |
| parent | 105732dde10b317a81d5a10a3f66b315d6f85015 (diff) | |
| download | srdwm-e4a0432383331e013808a97b7c24707e4ddc4726.tar.gz srdwm-e4a0432383331e013808a97b7c24707e4ddc4726.zip | |
Initial Commit
Diffstat (limited to 'src/layouts')
| -rw-r--r-- | src/layouts/dynamic_layout.cc | 31 | ||||
| -rw-r--r-- | src/layouts/dynamic_layout.h | 17 | ||||
| -rw-r--r-- | src/layouts/layout.h | 33 | ||||
| -rw-r--r-- | src/layouts/layout_engine.cc | 188 | ||||
| -rw-r--r-- | src/layouts/layout_engine.h | 70 | ||||
| -rw-r--r-- | src/layouts/smart_placement.cc | 278 | ||||
| -rw-r--r-- | src/layouts/smart_placement.h | 62 | ||||
| -rw-r--r-- | src/layouts/tiling_layout.cc | 38 | ||||
| -rw-r--r-- | src/layouts/tiling_layout.h | 17 |
9 files changed, 734 insertions, 0 deletions
diff --git a/src/layouts/dynamic_layout.cc b/src/layouts/dynamic_layout.cc new file mode 100644 index 0000000..7f10ac8 --- /dev/null +++ b/src/layouts/dynamic_layout.cc @@ -0,0 +1,31 @@ +#include "dynamic_layout.h" +#include "../core/window.h" +#include <iostream> + +DynamicLayout::DynamicLayout() { + // Constructor implementation if needed +} + +DynamicLayout::~DynamicLayout() { + // Destructor implementation if needed +} + +void DynamicLayout::arrange_windows(const std::vector<SRDWindow*>& windows, const Monitor& monitor) { + std::cout << "DynamicLayout::arrange_windows called for monitor (" << monitor.x << ", " << monitor.y << ", " << monitor.width << ", " << monitor.height << ")" << std::endl; + std::cout << "Arranging " << windows.size() << " windows dynamically." << std::endl; + + // Basic placeholder: In a real dynamic layout, you might not resize/reposition + // windows automatically here unless triggered by user interaction or specific rules. + // For now, just iterate through the windows and acknowledge them. + for (const auto& window : windows) { + std::cout << " - SRDWindow ID: " << window->getId() << ", Title: " << window->getTitle() << std::endl; + // In a real implementation, you might update window properties based on + // the dynamic layout logic, or simply leave their positions/sizes as they are + // unless a move/resize operation is in progress. + } + + // Future implementation would involve logic for: + // - Remembering window positions and sizes. + // - Handling user-initiated moves and resizes. + // - Potentially snapping windows to grid or other windows. +} diff --git a/src/layouts/dynamic_layout.h b/src/layouts/dynamic_layout.h new file mode 100644 index 0000000..3692c36 --- /dev/null +++ b/src/layouts/dynamic_layout.h @@ -0,0 +1,17 @@ +#ifndef SRDWM_DYNAMIC_LAYOUT_H +#define SRDWM_DYNAMIC_LAYOUT_H + +#include "layout.h" +#include "../core/window.h" +#include <vector> + +class DynamicLayout : public Layout { +public: + DynamicLayout(); + ~DynamicLayout(); + + // Implement the pure virtual method from the base class + void arrange_windows(const std::vector<SRDWindow*>& windows, const Monitor& monitor) override; +}; + +#endif // SRDWM_DYNAMIC_LAYOUT_H diff --git a/src/layouts/layout.h b/src/layouts/layout.h new file mode 100644 index 0000000..00c002f --- /dev/null +++ b/src/layouts/layout.h @@ -0,0 +1,33 @@ +#ifndef SRDWM_LAYOUT_H +#define SRDWM_LAYOUT_H + +#include <vector> +#include "../core/window.h" + +struct Monitor { + int id; + int x; + int y; + int width; + int height; + std::string name; + int refresh_rate; + + Monitor() : id(0), x(0), y(0), width(0), height(0), refresh_rate(60) {} + Monitor(int id, int x, int y, int width, int height, const std::string& name = "", int refresh = 60) + : id(id), x(x), y(y), width(width), height(height), name(name), refresh_rate(refresh) {} +}; + +class Layout { +public: + virtual ~Layout() = default; + + // Pure virtual method to arrange windows on a given monitor + virtual void arrange_windows(const std::vector<SRDWindow*>& windows, const Monitor& monitor) = 0; + + // You might add other common layout methods here later, e.g.: + // virtual void add_window(SRDWindow* window) = 0; + // virtual void remove_window(SRDWindow* window) = 0; +}; + +#endif // SRDWM_LAYOUT_H diff --git a/src/layouts/layout_engine.cc b/src/layouts/layout_engine.cc new file mode 100644 index 0000000..f6bc20f --- /dev/null +++ b/src/layouts/layout_engine.cc @@ -0,0 +1,188 @@ +#include "layout_engine.h" +#include <iostream> +#include <algorithm> + +LayoutEngine::LayoutEngine() { + std::cout << "LayoutEngine: Initializing..." << std::endl; +} + +LayoutEngine::~LayoutEngine() { + std::cout << "LayoutEngine: Shutting down..." << std::endl; +} + +// Layout management +bool LayoutEngine::set_layout(int monitor_id, LayoutType layout_type) { + active_layouts_[monitor_id] = layout_type; + std::cout << "LayoutEngine: Set layout " << layout_type_to_string(layout_type) + << " for monitor " << monitor_id << std::endl; + return true; +} + +bool LayoutEngine::set_layout(int monitor_id, const std::string& layout_name) { + LayoutType layout_type = string_to_layout_type(layout_name); + if (layout_type != LayoutType::TILING && layout_type != LayoutType::DYNAMIC && layout_type != LayoutType::FLOATING) { + std::cerr << "LayoutEngine: Unknown layout type: " << layout_name << std::endl; + return false; + } + return set_layout(monitor_id, layout_type); +} + +LayoutType LayoutEngine::get_layout(int monitor_id) const { + auto it = active_layouts_.find(monitor_id); + if (it != active_layouts_.end()) { + return it->second; + } + return LayoutType::DYNAMIC; // Default layout +} + +std::string LayoutEngine::get_layout_name(int monitor_id) const { + return layout_type_to_string(get_layout(monitor_id)); +} + +// Layout configuration +bool LayoutEngine::configure_layout(const std::string& layout_name, const std::map<std::string, std::string>& config) { + layout_configs_[layout_name] = config; + std::cout << "LayoutEngine: Configured layout '" << layout_name << "' with " + << config.size() << " parameters" << std::endl; + return true; +} + +bool LayoutEngine::register_custom_layout(const std::string& name, std::function<void(const std::vector<SRDWindow*>&, const Monitor&)> layout_func) { + custom_layouts_[name] = layout_func; + std::cout << "LayoutEngine: Registered custom layout '" << name << "'" << std::endl; + return true; +} + +// SRDWindow management +void LayoutEngine::add_window(SRDWindow* window) { + if (window && std::find(windows_.begin(), windows_.end(), window) == windows_.end()) { + windows_.push_back(window); + std::cout << "LayoutEngine: Added window " << window->getId() << std::endl; + } +} + +void LayoutEngine::remove_window(SRDWindow* window) { + auto it = std::find(windows_.begin(), windows_.end(), window); + if (it != windows_.end()) { + windows_.erase(it); + std::cout << "LayoutEngine: Removed window " << window->getId() << std::endl; + } +} + +void LayoutEngine::update_window(SRDWindow* window) { + // Trigger rearrangement for the monitor this window is on + // For now, just log the update + std::cout << "LayoutEngine: Updated window " << window->getId() << std::endl; +} + +// Monitor management +void LayoutEngine::add_monitor(const Monitor& monitor) { + // Check if monitor already exists + auto it = std::find_if(monitors_.begin(), monitors_.end(), + [&](const Monitor& m) { return m.id == monitor.id; }); + if (it == monitors_.end()) { + monitors_.push_back(monitor); + // Set default layout for new monitor + active_layouts_[monitor.id] = LayoutType::DYNAMIC; + std::cout << "LayoutEngine: Added monitor " << monitor.id << std::endl; + } +} + +void LayoutEngine::remove_monitor(int monitor_id) { + auto it = std::find_if(monitors_.begin(), monitors_.end(), + [monitor_id](const Monitor& m) { return m.id == monitor_id; }); + if (it != monitors_.end()) { + monitors_.erase(it); + active_layouts_.erase(monitor_id); + std::cout << "LayoutEngine: Removed monitor " << monitor_id << std::endl; + } +} + +void LayoutEngine::update_monitor(const Monitor& monitor) { + auto it = std::find_if(monitors_.begin(), monitors_.end(), + [&](const Monitor& m) { return m.id == monitor.id; }); + if (it != monitors_.end()) { + *it = monitor; + std::cout << "LayoutEngine: Updated monitor " << monitor.id << std::endl; + } +} + +// Arrangement +void LayoutEngine::arrange_on_monitor(const Monitor& monitor) { + if (active_layouts_.count(monitor.id)) { + LayoutType current_layout_type = active_layouts_[monitor.id]; + std::vector<SRDWindow*> windows_on_monitor = get_windows_on_monitor(monitor.id); + + std::cout << "LayoutEngine: Arranging " << windows_on_monitor.size() + << " windows on monitor " << monitor.id + << " with layout " << layout_type_to_string(current_layout_type) << std::endl; + + if (current_layout_type == LayoutType::TILING) { + tiling_layout_.arrange_windows(windows_on_monitor, monitor); + } else if (current_layout_type == LayoutType::DYNAMIC) { + dynamic_layout_.arrange_windows(windows_on_monitor, monitor); + } else if (current_layout_type == LayoutType::FLOATING) { + // Floating layout - windows keep their current positions + std::cout << "LayoutEngine: Floating layout - no arrangement needed" << std::endl; + } + } +} + +void LayoutEngine::arrange_all_monitors() { + for (const auto& monitor : monitors_) { + arrange_on_monitor(monitor); + } +} + +// Utility +std::vector<std::string> LayoutEngine::get_available_layouts() const { + return {"tiling", "dynamic", "floating"}; +} + +std::vector<SRDWindow*> LayoutEngine::get_windows_on_monitor(int monitor_id) const { + std::vector<SRDWindow*> windows_on_monitor; + + // Find the monitor + auto monitor_it = std::find_if(monitors_.begin(), monitors_.end(), + [monitor_id](const Monitor& m) { return m.id == monitor_id; }); + if (monitor_it == monitors_.end()) { + return windows_on_monitor; + } + + // Get windows that are on this monitor + for (SRDWindow* window : windows_) { + if (is_window_on_monitor(window, *monitor_it)) { + windows_on_monitor.push_back(window); + } + } + + return windows_on_monitor; +} + +// Helper methods +LayoutType LayoutEngine::string_to_layout_type(const std::string& name) const { + if (name == "tiling") return LayoutType::TILING; + if (name == "dynamic") return LayoutType::DYNAMIC; + if (name == "floating") return LayoutType::FLOATING; + return LayoutType::DYNAMIC; // Default +} + +std::string LayoutEngine::layout_type_to_string(LayoutType type) const { + switch (type) { + case LayoutType::TILING: return "tiling"; + case LayoutType::DYNAMIC: return "dynamic"; + case LayoutType::FLOATING: return "floating"; + default: return "dynamic"; + } +} + +bool LayoutEngine::is_window_on_monitor(const SRDWindow* window, const Monitor& monitor) const { + if (!window) return false; + + // Simple check: window center is within monitor bounds + int window_center_x = window->getX() + window->getWidth() / 2; + int window_center_y = window->getY() + window->getHeight() / 2; + + return window_center_x >= monitor.x && window_center_x < monitor.x + monitor.width && + window_center_y >= monitor.y && window_center_y < monitor.y + monitor.height; +} diff --git a/src/layouts/layout_engine.h b/src/layouts/layout_engine.h new file mode 100644 index 0000000..d23033c --- /dev/null +++ b/src/layouts/layout_engine.h @@ -0,0 +1,70 @@ +#ifndef SRDWM_LAYOUT_ENGINE_H +#define SRDWM_LAYOUT_ENGINE_H + +#include "layout.h" +#include "tiling_layout.h" +#include "dynamic_layout.h" +#include <vector> +#include <map> +#include <string> +#include <functional> + +class SRDWindow; // Forward declaration to avoid circular dependency + +enum class LayoutType { + TILING, + DYNAMIC, + FLOATING + // Add other layout types here later +}; + +class LayoutEngine { +public: + LayoutEngine(); + ~LayoutEngine(); + + // Layout management + bool set_layout(int monitor_id, LayoutType layout_type); + bool set_layout(int monitor_id, const std::string& layout_name); + LayoutType get_layout(int monitor_id) const; + std::string get_layout_name(int monitor_id) const; + + // Layout configuration + bool configure_layout(const std::string& layout_name, const std::map<std::string, std::string>& config); + bool register_custom_layout(const std::string& name, std::function<void(const std::vector<SRDWindow*>&, const Monitor&)> layout_func); + + // SRDWindow management + void add_window(SRDWindow* window); + void remove_window(SRDWindow* window); + void update_window(SRDWindow* window); + + // Monitor management + void add_monitor(const Monitor& monitor); + void remove_monitor(int monitor_id); + void update_monitor(const Monitor& monitor); + + // Arrangement + void arrange_on_monitor(const Monitor& monitor); + void arrange_all_monitors(); + + // Utility + std::vector<std::string> get_available_layouts() const; + std::vector<SRDWindow*> get_windows_on_monitor(int monitor_id) const; + +private: + // Member variables for layout state + std::vector<Monitor> monitors_; + std::vector<SRDWindow*> windows_; + TilingLayout tiling_layout_; + DynamicLayout dynamic_layout_; + std::map<int, LayoutType> active_layouts_; // Map monitor ID to active layout type + std::map<std::string, std::function<void(const std::vector<SRDWindow*>&, const Monitor&)>> custom_layouts_; + std::map<std::string, std::map<std::string, std::string>> layout_configs_; + + // Helper methods + LayoutType string_to_layout_type(const std::string& name) const; + std::string layout_type_to_string(LayoutType type) const; + bool is_window_on_monitor(const SRDWindow* window, const Monitor& monitor) const; +}; + +#endif // SRDWM_LAYOUT_ENGINE_H diff --git a/src/layouts/smart_placement.cc b/src/layouts/smart_placement.cc new file mode 100644 index 0000000..b23844c --- /dev/null +++ b/src/layouts/smart_placement.cc @@ -0,0 +1,278 @@ +#include "smart_placement.h" +#include <algorithm> +#include <cmath> +#include <iostream> + +// Constants +constexpr int SmartPlacement::MIN_WINDOW_WIDTH; +constexpr int SmartPlacement::MIN_WINDOW_HEIGHT; +constexpr int SmartPlacement::GRID_MARGIN; +constexpr int SmartPlacement::CASCADE_OFFSET; + +SmartPlacement::PlacementResult SmartPlacement::place_window( + const SRDWindow* window, const Monitor& monitor, + const std::vector<SRDWindow*>& existing_windows) { + + // Try grid placement first (SRDWindows 11 style) + auto grid_result = place_in_grid(window, monitor, existing_windows); + if (grid_result.success) { + return grid_result; + } + + // Fall back to cascade placement + return cascade_place(window, monitor, existing_windows); +} + +SmartPlacement::PlacementResult SmartPlacement::place_in_grid( + const SRDWindow* window, const Monitor& monitor, + const std::vector<SRDWindow*>& existing_windows) { + + PlacementResult result = {0, 0, 0, 0, false, "Grid placement failed"}; + + // Calculate optimal grid size based on monitor and window count + int window_count = existing_windows.size() + 1; + int grid_size = calculate_optimal_grid_size(monitor, window_count); + + if (grid_size <= 0) { + result.reason = "Invalid grid size"; + return result; + } + + // Calculate grid position for this window + auto [grid_x, grid_y] = calculate_grid_position(window, monitor); + + // Calculate cell dimensions + int cell_width = (monitor.width - (grid_size + 1) * GRID_MARGIN) / grid_size; + int cell_height = (monitor.height - (grid_size + 1) * GRID_MARGIN) / grid_size; + + // Ensure minimum cell size + cell_width = std::max(cell_width, MIN_WINDOW_WIDTH); + cell_height = std::max(cell_height, MIN_WINDOW_HEIGHT); + + // Calculate window position + int x = monitor.x + GRID_MARGIN + grid_x * (cell_width + GRID_MARGIN); + int y = monitor.y + GRID_MARGIN + grid_y * (cell_height + GRID_MARGIN); + + // Check if position is valid + if (is_position_valid(x, y, cell_width, cell_height, monitor)) { + result.x = x; + result.y = y; + result.width = cell_width; + result.height = cell_height; + result.success = true; + result.reason = "Grid placement successful"; + } + + return result; +} + +SmartPlacement::PlacementResult SmartPlacement::snap_to_edge( + const SRDWindow* window, const Monitor& monitor, + const std::vector<SRDWindow*>& existing_windows) { + + PlacementResult result = {0, 0, 0, 0, false, "Snap placement failed"}; + + // For now, implement simple edge snapping + // In a full implementation, this would detect when windows are dragged near edges + + int x = monitor.x + monitor.width / 4; + int y = monitor.y + monitor.height / 4; + int width = monitor.width / 2; + int height = monitor.height / 2; + + if (is_position_valid(x, y, width, height, monitor)) { + result.x = x; + result.y = y; + result.width = width; + result.height = height; + result.success = true; + result.reason = "Snap placement successful"; + } + + return result; +} + +SmartPlacement::PlacementResult SmartPlacement::cascade_place( + const SRDWindow* window, const Monitor& monitor, + const std::vector<SRDWindow*>& existing_windows) { + + PlacementResult result = {0, 0, 0, 0, false, "Cascade placement failed"}; + + // Find a free space for cascading + auto free_spaces = find_free_spaces(monitor, existing_windows); + + if (free_spaces.empty()) { + // No free spaces, use default position + int x = monitor.x + CASCADE_OFFSET; + int y = monitor.y + CASCADE_OFFSET; + int width = std::min(800, monitor.width - 2 * CASCADE_OFFSET); + int height = std::min(600, monitor.height - 2 * CASCADE_OFFSET); + + if (is_position_valid(x, y, width, height, monitor)) { + result.x = x; + result.y = y; + result.width = width; + result.height = height; + result.success = true; + result.reason = "Default cascade placement"; + } + } else { + // Use the first free space + auto [x, y] = free_spaces[0]; + int width = std::min(800, monitor.width - x - CASCADE_OFFSET); + int height = std::min(600, monitor.height - y - CASCADE_OFFSET); + + if (is_position_valid(x, y, width, height, monitor)) { + result.x = x; + result.y = y; + result.width = width; + result.height = height; + result.success = true; + result.reason = "Cascade placement in free space"; + } + } + + return result; +} + +SmartPlacement::PlacementResult SmartPlacement::smart_tile( + const SRDWindow* window, const Monitor& monitor, + const std::vector<SRDWindow*>& existing_windows) { + + PlacementResult result = {0, 0, 0, 0, false, "Smart tile placement failed"}; + + // Calculate overlap score to find best position + int best_score = -1; + int best_x = monitor.x; + int best_y = monitor.y; + int best_width = monitor.width / 2; + int best_height = monitor.height / 2; + + // Try different positions and find the one with least overlap + for (int x = monitor.x; x < monitor.x + monitor.width - MIN_WINDOW_WIDTH; x += 50) { + for (int y = monitor.y; y < monitor.y + monitor.height - MIN_WINDOW_HEIGHT; y += 50) { + int width = std::min(800, monitor.width - x); + int height = std::min(600, monitor.height - y); + + if (is_position_valid(x, y, width, height, monitor)) { + int score = calculate_overlap_score(window, monitor, existing_windows); + if (score > best_score) { + best_score = score; + best_x = x; + best_y = y; + best_width = width; + best_height = height; + } + } + } + } + + if (best_score >= 0) { + result.x = best_x; + result.y = best_y; + result.width = best_width; + result.height = best_height; + result.success = true; + result.reason = "Smart tile placement successful"; + } + + return result; +} + +bool SmartPlacement::windows_overlap(const SRDWindow* w1, const SRDWindow* w2) { + // Simple AABB overlap detection + int x1 = w1->getX(); + int y1 = w1->getY(); + int w1_width = w1->getWidth(); + int w1_height = w1->getHeight(); + + int x2 = w2->getX(); + int y2 = w2->getY(); + int w2_width = w2->getWidth(); + int w2_height = w2->getHeight(); + + return !(x1 + w1_width <= x2 || x2 + w2_width <= x1 || + y1 + w1_height <= y2 || y2 + w2_height <= y1); +} + +int SmartPlacement::calculate_overlap_score(const SRDWindow* window, const Monitor& monitor, + const std::vector<SRDWindow*>& existing_windows) { + int score = 0; + + // Calculate how much this position overlaps with existing windows + for (const auto* existing : existing_windows) { + if (windows_overlap(window, existing)) { + score -= 10; // Penalty for overlap + } else { + score += 1; // Bonus for no overlap + } + } + + return score; +} + +std::vector<std::pair<int, int>> SmartPlacement::find_free_spaces( + const Monitor& monitor, const std::vector<SRDWindow*>& existing_windows) { + + std::vector<std::pair<int, int>> free_spaces; + + // Simple algorithm: try positions in a grid pattern + for (int x = monitor.x; x < monitor.x + monitor.width - MIN_WINDOW_WIDTH; x += 100) { + for (int y = monitor.y; y < monitor.y + monitor.height - MIN_WINDOW_HEIGHT; y += 100) { + bool is_free = true; + + // Check if this position overlaps with any existing window + for (const auto* existing : existing_windows) { + int ex = existing->getX(); + int ey = existing->getY(); + int ew = existing->getWidth(); + int eh = existing->getHeight(); + + if (x < ex + ew && x + MIN_WINDOW_WIDTH > ex && + y < ey + eh && y + MIN_WINDOW_HEIGHT > ey) { + is_free = false; + break; + } + } + + if (is_free) { + free_spaces.emplace_back(x, y); + } + } + } + + return free_spaces; +} + +bool SmartPlacement::is_position_valid(int x, int y, int width, int height, const Monitor& monitor) { + return x >= monitor.x && y >= monitor.y && + x + width <= monitor.x + monitor.width && + y + height <= monitor.y + monitor.height && + width >= MIN_WINDOW_WIDTH && height >= MIN_WINDOW_HEIGHT; +} + +std::pair<int, int> SmartPlacement::calculate_grid_position(const SRDWindow* window, const Monitor& monitor) { + // Simple grid position calculation + // In a real implementation, this might consider window properties or user preferences + + // For now, use a simple pattern: first window top-left, second top-right, etc. + static int window_counter = 0; + int grid_x = window_counter % 2; + int grid_y = window_counter / 2; + window_counter++; + + return {grid_x, grid_y}; +} + +int SmartPlacement::calculate_optimal_grid_size(const Monitor& monitor, int window_count) { + // Calculate optimal grid size based on monitor dimensions and window count + if (window_count <= 0) return 1; + + // Simple heuristic: try to create a roughly square grid + int grid_size = static_cast<int>(std::ceil(std::sqrt(window_count))); + + // Ensure grid size is reasonable + grid_size = std::max(1, std::min(grid_size, 4)); + + return grid_size; +} diff --git a/src/layouts/smart_placement.h b/src/layouts/smart_placement.h new file mode 100644 index 0000000..69f4b94 --- /dev/null +++ b/src/layouts/smart_placement.h @@ -0,0 +1,62 @@ +#ifndef SRDWM_SMART_PLACEMENT_H +#define SRDWM_SMART_PLACEMENT_H + +#include "layout.h" +#include <vector> +#include <memory> + +// Forward declarations +class SRDWindow; +class Monitor; + +// Smart placement algorithm that mimics SRDWindows 11 behavior +class SmartPlacement { +public: + struct PlacementResult { + int x, y, width, height; + bool success; + std::string reason; + }; + + // Main placement function + static PlacementResult place_window(const SRDWindow* window, const Monitor& monitor, + const std::vector<SRDWindow*>& existing_windows); + + // Grid-based placement (SRDWindows 11 style) + static PlacementResult place_in_grid(const SRDWindow* window, const Monitor& monitor, + const std::vector<SRDWindow*>& existing_windows); + + // Snap-to-edge placement + static PlacementResult snap_to_edge(const SRDWindow* window, const Monitor& monitor, + const std::vector<SRDWindow*>& existing_windows); + + // Cascade placement for overlapping windows + static PlacementResult cascade_place(const SRDWindow* window, const Monitor& monitor, + const std::vector<SRDWindow*>& existing_windows); + + // Smart tiling placement + static PlacementResult smart_tile(const SRDWindow* window, const Monitor& monitor, + const std::vector<SRDWindow*>& existing_windows); + +private: + // Helper functions + static bool windows_overlap(const SRDWindow* w1, const SRDWindow* w2); + static int calculate_overlap_score(const SRDWindow* window, const Monitor& monitor, + const std::vector<SRDWindow*>& existing_windows); + static std::vector<std::pair<int, int>> find_free_spaces(const Monitor& monitor, + const std::vector<SRDWindow*>& existing_windows); + static bool is_position_valid(int x, int y, int width, int height, const Monitor& monitor); + + // Grid calculations + static std::pair<int, int> calculate_grid_position(const SRDWindow* window, const Monitor& monitor); + static int calculate_optimal_grid_size(const Monitor& monitor, int window_count); + + // Constants + static constexpr int MIN_WINDOW_WIDTH = 200; + static constexpr int MIN_WINDOW_HEIGHT = 150; + static constexpr int GRID_MARGIN = 10; + static constexpr int CASCADE_OFFSET = 30; +}; + +#endif // SRDWM_SMART_PLACEMENT_H + diff --git a/src/layouts/tiling_layout.cc b/src/layouts/tiling_layout.cc new file mode 100644 index 0000000..440c95a --- /dev/null +++ b/src/layouts/tiling_layout.cc @@ -0,0 +1,38 @@ +#include "tiling_layout.h" +#include <iostream> + +TilingLayout::TilingLayout() { + // Constructor implementation +} + +TilingLayout::~TilingLayout() { + // Destructor implementation +} + +void TilingLayout::arrange_windows(const std::vector<SRDWindow*>& windows, const Monitor& monitor) { + std::cout << "TilingLayout::arrange_windows called for monitor:" << std::endl; + std::cout << " Position: (" << monitor.x << ", " << monitor.y << "), Dimensions: (" << monitor.width << ", " << monitor.height << ")" << std::endl; + std::cout << " Number of windows: " << windows.size() << std::endl; + + // Basic placeholder tiling logic (e.g., splitting the screen vertically) + if (!windows.empty()) { + int window_width = monitor.width / windows.size(); + int current_x = monitor.x; + + for (size_t i = 0; i < windows.size(); ++i) { + SRDWindow* window = windows[i]; + // In a real implementation, you would calculate the desired + // position and size for the window based on the tiling algorithm + // and then call a method on the window object (which would + // internally use the platform backend) to apply these changes. + std::cout << " SRDWindow " << window->getId() << ": Placeholder position (" << current_x << ", " << monitor.y << "), size (" << window_width << ", " << monitor.height << ")" << std::endl; + + // Update the window's properties in the SRDWindow object + window->setPosition(current_x, monitor.y); + window->setDimensions(current_x, monitor.y, window_width, monitor.height); + + + current_x += window_width; + } + } +} diff --git a/src/layouts/tiling_layout.h b/src/layouts/tiling_layout.h new file mode 100644 index 0000000..333950a --- /dev/null +++ b/src/layouts/tiling_layout.h @@ -0,0 +1,17 @@ +#ifndef SRDWM_TILING_LAYOUT_H +#define SRDWM_TILING_LAYOUT_H + +#include "layout.h" +#include <iostream> +#include <vector> + +class TilingLayout : public Layout { +public: + TilingLayout(); + ~TilingLayout(); + + // Implement the pure virtual method from the base class + void arrange_windows(const std::vector<SRDWindow*>& windows, const Monitor& monitor) override; +}; + +#endif // SRDWM_TILING_LAYOUT_H |
