aboutsummaryrefslogtreecommitdiff
path: root/src/layouts/layout_engine.cc
blob: f6bc20f85be1dfc10c918f6094ec46e773a00557 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
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;
}