From a43297a61d69ca5fa5bb7ae8407757da978b4dd4 Mon Sep 17 00:00:00 2001 From: Eleni Maria Stea Date: Wed, 20 Feb 2013 23:04:43 +0200 Subject: [PATCH] *in progress* added frames TODO: 1 - relative positions before implementing the mouse button/motion callbacks 2 - get_absolute_pos function --- src/mouse.cc | 8 ----- src/window.cc | 68 ++++++++++++++++++++++++++++++++++++-- src/window.h | 19 ++++++++++- src/wm.cc | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++++----- src/wm.h | 14 ++++++++ 5 files changed, 189 insertions(+), 21 deletions(-) diff --git a/src/mouse.cc b/src/mouse.cc index 1fed5d1..b3f329b 100644 --- a/src/mouse.cc +++ b/src/mouse.cc @@ -69,14 +69,6 @@ void process_mouse_event() return; } - /*unsigned char *fb = get_framebuffer(); - fb += (bounds.width * pointer_y + pointer_x) * 4; - fb[0] = 0; - fb[1] = 0; - fb[2] = 0;*/ - - //printf("pointer (x, y) = (%d, %d)\r\n", pointer_x, pointer_y); - Window *top = wm->get_window_at_pos(pointer_x, pointer_y); if(top) { wm->set_focused_window(top); diff --git a/src/window.cc b/src/window.cc index 608d93b..f5b1ada 100644 --- a/src/window.cc +++ b/src/window.cc @@ -1,4 +1,6 @@ +#include #include + #include "gfx.h" #include "window.h" #include "wm.h" @@ -10,10 +12,16 @@ Window::Window() rect.width = rect.height = 128; memset(&callbacks, 0, sizeof callbacks); dirty = true; + managed = true; } Window::~Window() { + for(size_t i=0; iremove_window(children[i]); + delete children[i]; + } + delete [] title; } @@ -61,12 +69,27 @@ void Window::invalidate() wm->invalidate_region(rect); } -void Window::draw() +void Window::draw(const Rect &dirty_region) { //TODO //titlebar, frame - callbacks.display(this); - dirty = false; + + Rect intersect = rect_intersection(rect, dirty_region); + if(intersect.width && intersect.height) { + if(callbacks.display) { + callbacks.display(this); + } + dirty = false; + + draw_children(rect); + } +} + +void Window::draw_children(const Rect &dirty_region) +{ + for(size_t i=0; idraw(dirty_region); + } } unsigned char *Window::get_win_start_on_fb() @@ -80,6 +103,16 @@ int Window::get_scanline_width() return get_screen_size().x; } +void Window::set_managed(bool managed) +{ + this->managed = managed; +} + +bool Window::get_managed() const +{ + return managed; +} + void Window::set_display_callback(DisplayFuncType func) { callbacks.display = func; @@ -119,3 +152,32 @@ const MouseMotionFuncType Window::get_mouse_motion_callback() const { return callbacks.motion; } + +void Window::add_child(Window *win) +{ + children.push_back(win); + if(win->parent) { + win->parent->remove_child(win); + } + win->parent = this; +} + +void Window::remove_child(Window *win) +{ + std::vector::iterator it; + it = std::find(children.begin(), children.end(), win); + if(it != children.end()) { + children.erase(it); + win->parent = 0; + } +} + +const Window *Window::get_parent() const +{ + return parent; +} + +Window *Window::get_parent() +{ + return parent; +} diff --git a/src/window.h b/src/window.h index 3a9cab0..040f6b5 100644 --- a/src/window.h +++ b/src/window.h @@ -1,6 +1,8 @@ #ifndef WINDOW_H_ #define WINDOW_H_ +#include + #include "geom.h" #include "event.h" @@ -10,7 +12,11 @@ private: Rect rect; Callbacks callbacks; + std::vector children; + Window* parent; + bool dirty; + bool managed; // whether the wm manages (+decorates) this win public: Window(); @@ -30,11 +36,15 @@ public: */ void invalidate(); - void draw(); + void draw(const Rect &dirty_region); + void draw_children(const Rect &dirty_region); unsigned char *get_win_start_on_fb(); int get_scanline_width(); + void set_managed(bool managed); + bool get_managed() const; + void set_display_callback(DisplayFuncType func); void set_keyboard_callback(KeyboardFuncType func); void set_mouse_button_callback(MouseButtonFuncType func); @@ -45,6 +55,13 @@ public: const MouseButtonFuncType get_mouse_button_callback() const; const MouseMotionFuncType get_mouse_motion_callback() const; + // win hierarchy + void add_child(Window *win); + void remove_child(Window *win); + + const Window *get_parent() const; + Window *get_parent(); + // XXX remove if not needed friend class WindowManager; }; diff --git a/src/wm.cc b/src/wm.cc index b661234..d3b3c95 100644 --- a/src/wm.cc +++ b/src/wm.cc @@ -1,4 +1,6 @@ +#include #include + #include "gfx.h" #include "wm.h" #include "window.h" @@ -8,6 +10,47 @@ WindowManager *wm; static WindowManager wminst; +static void display(Window *win); +static void mouse(Window *win, int key, bool pressed); +static void motion(Window *win, int x, int y); + +void WindowManager::create_frame(Window *win) +{ + Window *frame = new Window; + Window *parent = win->get_parent(); + + frame->set_display_callback(display); +// frame->set_mouse_button_callback(mouse); +// frame->set_mouse_motion_callback(motion); + + frame->add_child(win); + frames.push_back(frame); + + Rect win_rect = win->get_rect(); + frame->move(win_rect.x - frame_thickness, + win_rect.y - frame_thickness - titlebar_thickness); + frame->resize(win_rect.width + frame_thickness * 2, + win_rect.height + frame_thickness * 2 + titlebar_thickness); + + parent->add_child(frame); +} + +void WindowManager::destroy_frame(Window *win) +{ + Window *frame = win->parent; + if(!frame) { + return; + } + + std::list::iterator it; + it = std::find(frames.begin(), frames.end(), frame); + if(it != frames.end()) { + root_win->add_child(win); + frames.erase(it); + delete frame; + } +} + WindowManager::WindowManager() { if(!wm) { @@ -16,12 +59,23 @@ WindowManager::WindowManager() throw std::runtime_error("Trying to create a second instance of WindowManager!\n"); } + root_win = new Window; + root_win->resize(get_screen_size().width, get_screen_size().height); + root_win->move(0, 0); + root_win->set_managed(false); + focused_win = 0; bg_color[0] = 210; bg_color[1] = 106; bg_color[2] = 106; + frame_thickness = 2; + titlebar_thickness = 4; + + frame_fcolor[0] = frame_fcolor[1] = frame_fcolor[2] = 142; + frame_ucolor[0] = frame_ucolor[1] = frame_ucolor[2] = 210; + mouse_cursor.set_image(mouse_cursor_width, mouse_cursor_height); unsigned char *pixels = mouse_cursor.get_image(); @@ -36,6 +90,11 @@ WindowManager::WindowManager() } } +WindowManager::~WindowManager() +{ + delete root_win; +} + void WindowManager::invalidate_region(const Rect &rect) { dirty_rects.push_back(rect); @@ -55,15 +114,8 @@ void WindowManager::process_windows() dirty_rects.clear(); fill_rect(uni, bg_color[0], bg_color[1], bg_color[2]); - - std::list::iterator it = windows.begin(); - while(it != windows.end()) { - Rect intersect = rect_intersection((*it)->rect, uni); - if(intersect.width && intersect.height) { - (*it)->draw(); - } - it++; - } + + root_win->draw_children(uni); // draw mouse cursor int mouse_x, mouse_y; @@ -79,13 +131,33 @@ void WindowManager::process_windows() void WindowManager::add_window(Window *win) { + if(!win || win == root_win) { + return; + } + + root_win->add_child(win); + if(windows.empty()) { focused_win = win; } + if(win->get_managed()) { + create_frame(win); + } + windows.push_back(win); } +void WindowManager::remove_window(Window *win) +{ + std::list::iterator it; + it = std::find(windows.begin(), windows.end(), win); + + if(it != windows.end()) { + windows.erase(it); + } +} + void WindowManager::set_focused_window(Window *win) { focused_win = win; @@ -115,3 +187,14 @@ Window *WindowManager::get_window_at_pos(int pointer_x, int pointer_y) return win; } + +static void display(Window *win) +{ + if(win->get_managed()) { + fill_rect(win->get_rect(), 255, 211, 5); + win->draw(win->get_parent()->get_rect()); + } +} + +//static void mouse(Window *win, int key, bool pressed); +//static void motion(Window *win, int x, int y); diff --git a/src/wm.h b/src/wm.h index e3f4040..15c197b 100644 --- a/src/wm.h +++ b/src/wm.h @@ -2,6 +2,7 @@ #define WM_H_ #include + #include "geom.h" #include "pixmap.h" @@ -10,20 +11,33 @@ class Window; class WindowManager { private: std::list windows; + std::list frames; + std::list dirty_rects; int bg_color[3]; + int frame_thickness; + int titlebar_thickness; + int frame_fcolor[3]; + int frame_ucolor[3]; + + Window *root_win; Window *focused_win; Pixmap mouse_cursor; + void create_frame(Window *win); + void destroy_frame(Window *win); + public: WindowManager(); + ~WindowManager(); void invalidate_region(const Rect &rect); void process_windows(); void add_window(Window *win); + void remove_window(Window *win); void set_focused_window(Window *win); const Window *get_focused_window() const; -- 1.7.10.4