#include #include #include #include namespace raleigh { window::window(widget &root, _pixel_t bg_color, bool (*on_close)(window &)) : handle(0), size(root.size), root(root), bg_color(bg_color), needs_repaint(false), on_close(on_close) { root.w = this; root.window_offset = coord(0, 0); root.notify_window_change(); pixbuf = (_pixel_t *)get_block(size.x * size.y * sizeof(_pixel_t)); if (!pixbuf) show_error_and_quitf("Failed to create %d byte pixel buffer\nfor requested %dx%d pixel window.", size.x * size.y * sizeof(_pixel_t), size.x, size.y); paint_full(); } window::try_actions_return_t window::try_actions() { struct window_action wa; window::try_actions_return_t got = NONE; while (1) { _get_win_action(handle, &wa); if (!wa.action_type) { if (needs_repaint) { needs_repaint = false; _paint_window(handle); } return got; } if ((wa.action_type == wa.KEY_DOWN) && (wa.as_key.modifiers & wa.as_key.ALTS) && (wa.as_key.key_id == wa.as_key.KEY_F4)) if (!on_close || on_close(*this)) return DELETE; got = GOOD; if (wa.action_type == wa.MOUSE_DOWN) root.try_handle_click(coord(wa.as_mouse.x, wa.as_mouse.y), wa.as_mouse.which, false); if (wa.action_type == wa.MOUSE_UP) root.try_handle_click(coord(wa.as_mouse.x, wa.as_mouse.y), wa.as_mouse.which, true); } } void window::notify_needs_paint(widget &head) { if (head.closest_opaque) head.closest_opaque->paint(pixbuf, size.x); else paint_full(); needs_repaint = true; } void window::paint_full() { for (uint32_t i = 0; i < size.x * size.y; ++i) pixbuf[i] = bg_color; root.paint(pixbuf, size.x); } void window::show() { if (handle) return; handle = _new_window(size.x, size.y, pixbuf); if (!handle) show_error_and_quitf("Failed to get window handle for requested window."); open_windows.add_front(*this); } }