X-Git-Url: http://git.mutantstargoat.com?p=winnie;a=blobdiff_plain;f=libwinnie%2Fsrc%2Fwindow.cc;fp=libwinnie%2Fsrc%2Fwindow.cc;h=04f72cd9e4ebd83010660db32c2ba0daec6c407b;hp=0000000000000000000000000000000000000000;hb=7b5d2df884abb7084d71f17cc29a618c0b6f47ef;hpb=b4c8d68e0357683cec82fb8a9c5a4447155b3192 diff --git a/libwinnie/src/window.cc b/libwinnie/src/window.cc new file mode 100644 index 0000000..04f72cd --- /dev/null +++ b/libwinnie/src/window.cc @@ -0,0 +1,271 @@ +/* +winnie - an experimental window system + +Copyright (C) 2013 Eleni Maria Stea + +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 . + +Author: Eleni Maria Stea +*/ + +#include +#include //TODO +#include + +#include "gfx.h" +#include "window.h" +#include "wm.h" + +Window::Window() +{ + parent = 0; + title = 0; + rect.x = rect.y = 0; + rect.width = rect.height = 128; + memset(&callbacks, 0, sizeof callbacks); + dirty = true; + managed = true; + focusable = true; + state = STATE_NORMAL; +} + +Window::~Window() +{ + for(size_t i=0; iremove_window(children[i]); + delete children[i]; + } + + delete [] title; +} + +const Rect &Window::get_rect() const +{ + return rect; +} + +Rect Window::get_absolute_rect() const +{ + if(!parent) { + return rect; + } + + Rect absolute_rect; + absolute_rect = parent->get_absolute_rect(); + + absolute_rect.x += rect.x; + absolute_rect.y += rect.y; + absolute_rect.width = rect.width; + absolute_rect.height = rect.height; + + return absolute_rect; +} + +bool Window::contains_point(int ptr_x, int ptr_y) +{ + Rect abs_rect = get_absolute_rect(); + return ptr_x >= abs_rect.x && ptr_x < abs_rect.x + abs_rect.width && + ptr_y >= abs_rect.y && ptr_y < abs_rect.y + abs_rect.height; +} + +void Window::move(int x, int y) +{ + invalidate(); // moved, should redraw, MUST BE CALLED FIRST + rect.x = x; + rect.y = y; +} + +void Window::resize(int x, int y) +{ + invalidate(); // resized, should redraw, MUST BE CALLED FIRST + rect.width = x; + rect.height = y; +} + +void Window::set_title(const char *s) +{ + delete [] title; + + title = new char[strlen(s) + 1]; + strcpy(title, s); +} + +const char *Window::get_title() const +{ + return title; +} + +void Window::invalidate() +{ + dirty = true; + Rect abs_rect = get_absolute_rect(); + wm->invalidate_region(abs_rect); +} + +void Window::draw(Rect *dirty_region) +{ + Rect abs_rect = get_absolute_rect(); + Rect intersect = rect_intersection(abs_rect, *dirty_region); + if(intersect.width && intersect.height) { + Rect prev_clip = get_clipping_rect(); + set_clipping_rect(abs_rect); + + if(callbacks.display) { + callbacks.display(this); + } + dirty = false; + + draw_children(abs_rect); + + *dirty_region = rect_union(*dirty_region, abs_rect); + set_clipping_rect(prev_clip); + } +} + +void Window::draw_children(const Rect &dirty_region) +{ + Rect drect = dirty_region; + for(size_t i=0; idraw(&drect); + } +} + +unsigned char *Window::get_win_start_on_fb() +{ + unsigned char *fb = get_framebuffer(); + Rect abs_rect = get_absolute_rect(); + return fb + get_color_depth() * (get_screen_size().x * abs_rect.y + abs_rect.x) / 8; +} + +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_focusable(bool focusable) +{ + this->focusable = focusable; +} + +bool Window::get_focusable() const +{ + return focusable; +} + +bool Window::get_dirty() const +{ + return dirty; +} + +void Window::set_display_callback(DisplayFuncType func) +{ + callbacks.display = func; +} + +void Window::set_keyboard_callback(KeyboardFuncType func) +{ + callbacks.keyboard = func; +} + +void Window::set_mouse_button_callback(MouseButtonFuncType func) +{ + callbacks.button = func; +} + +void Window::set_mouse_motion_callback(MouseMotionFuncType func) +{ + callbacks.motion = func; +} + +const DisplayFuncType Window::get_display_callback() const +{ + return callbacks.display; +} + +const KeyboardFuncType Window::get_keyboard_callback() const +{ + return callbacks.keyboard; +} + +const MouseButtonFuncType Window::get_mouse_button_callback() const +{ + return callbacks.button; +} + +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; + } +} + +Window **Window::get_children() +{ + if(children.empty()) { + return 0; + } + return &children[0]; +} + +int Window::get_children_count() const +{ + return (int)children.size(); +} + +const Window *Window::get_parent() const +{ + return parent; +} + +Window *Window::get_parent() +{ + return parent; +} + +void Window::set_state(State state) +{ + this->state = state; +} + +Window::State Window::get_state() const +{ + return state; +}