diff --git a/display/display-code.c b/display/display-code.c index d9ceb58f..23abaa2e 100644 --- a/display/display-code.c +++ b/display/display-code.c @@ -346,6 +346,7 @@ void display_composit(struct display* display, struct framebuffer fb) switch ( display->mouse_state ) { case MOUSE_STATE_NONE: break; + case MOUSE_STATE_BUTTON_PRESS: break; case MOUSE_STATE_TITLE_MOVE: break; case MOUSE_STATE_RESIZE_BOTTOM: cursor_text = "↓"; break; case MOUSE_STATE_RESIZE_BOTTOM_LEFT: cursor_text = "└"; break; @@ -653,34 +654,83 @@ void display_mouse_event(struct display* display, uint8_t byte) ssize_t window_pointer_x = display->pointer_x - window->left; ssize_t window_pointer_y = display->pointer_y - window->top; + if ( display->active_window != window ) + { + if ( bytes[0] & (MOUSE_BUTTON_LEFT | MOUSE_BUTTON_MIDDLE | + MOUSE_BUTTON_RIGHT) ) + { + // TODO: Exit mouse from the current window. + display_set_active_window(display, window); + } + else + return; + } + + size_t border_width = window_border_width(window); + size_t button_width = FONT_WIDTH * 2; + ssize_t buttons_x = window->width - border_width + - button_width * 3 + 1; + size_t tt_height = FONT_HEIGHT; + size_t tt_pos_y = (TITLE_HEIGHT - FONT_HEIGHT) / 2 + 2; + + bool mouse_on_title = 0 <= window_pointer_x && + window_pointer_x < (ssize_t) window->width && + 0 <= window_pointer_y && + window_pointer_y <= (ssize_t) TITLE_HEIGHT; + + for ( size_t n = 0; n < 3; n++ ) + { + if ( (ssize_t) tt_pos_y <= window_pointer_y && + window_pointer_y <= (ssize_t) (tt_height + tt_pos_y) && + (ssize_t) (button_width * n) <= window_pointer_x - buttons_x && + window_pointer_x - buttons_x < (ssize_t) (button_width * (n + 1)) ) + { + if ( display->mouse_state == MOUSE_STATE_NONE && + (bytes[0] & MOUSE_BUTTON_LEFT) ) + { + display->mouse_state = MOUSE_STATE_BUTTON_PRESS; + window->button_states[n] = BUTTON_STATE_PRESSED; + window_render_frame(window); + } + else if ( display->mouse_state == MOUSE_STATE_BUTTON_PRESS && + window->button_states[n] == BUTTON_STATE_PRESSED ) + { + window->button_states[n] = BUTTON_STATE_NORMAL; + window_render_frame(window); + switch ( n ) + { + case 0: /* TODO: Minimize. */ break; + case 1: window_toggle_maximized(window); break; + case 2: window_quit(window); break; + } + return; + } + else if ( display->mouse_state == MOUSE_STATE_NONE && + window->button_states[n] != BUTTON_STATE_HOVER ) + { + window->button_states[n] = BUTTON_STATE_HOVER; + window_render_frame(window); + } + } + else if ( window->button_states[n] != BUTTON_STATE_NORMAL ) + { + window->button_states[n] = BUTTON_STATE_NORMAL; + display->mouse_state = MOUSE_STATE_NONE; + window_render_frame(window); + } + } + if ( bytes[0] & MOUSE_BUTTON_LEFT ) { - display_set_active_window(display, window); if ( display->mouse_state == MOUSE_STATE_NONE ) { // TODO: Stay in state until mouse release. - if ( display->key_lalt || - (0 <= window_pointer_x && - window_pointer_x < (ssize_t) window->width && - 0 <= window_pointer_y && - window_pointer_y <= (ssize_t) TITLE_HEIGHT) ) + if ( display->key_lalt || mouse_on_title ) { - size_t border_width = window_border_width(window); - size_t button_width = FONT_WIDTH * 2; - ssize_t buttons_x = window->width - border_width - - button_width * 3 + 1; - ssize_t rel_x = window_pointer_x - buttons_x; - if ( 0 <= rel_x && rel_x < (ssize_t) button_width ) - { - // TODO Minimize window. - } - else if ( 0 <= rel_x && rel_x < (ssize_t) button_width * 2 ) - window_toggle_maximized(window); - else if ( 0 <= rel_x && rel_x < (ssize_t) button_width * 3 ) - window_quit(window); - else + if ( window_pointer_x < buttons_x || !mouse_on_title ) display->mouse_state = MOUSE_STATE_TITLE_MOVE; - } else if ( window_pointer_x < 0 && window_pointer_y < 0 ) + } + else if ( window_pointer_x < 0 && window_pointer_y < 0 ) display->mouse_state = MOUSE_STATE_RESIZE_TOP_LEFT; else if ( window_pointer_x < 0 && 0 <= window_pointer_y && @@ -719,6 +769,7 @@ void display_mouse_event(struct display* display, uint8_t byte) switch ( display->mouse_state ) { case MOUSE_STATE_NONE: break; + case MOUSE_STATE_BUTTON_PRESS: break; case MOUSE_STATE_TITLE_MOVE: if ( clipped_edge ) { diff --git a/display/display.h b/display/display.h index 9b3c9b5f..d0f0d5d9 100644 --- a/display/display.h +++ b/display/display.h @@ -32,6 +32,7 @@ enum mouse_state { MOUSE_STATE_NONE, + MOUSE_STATE_BUTTON_PRESS, MOUSE_STATE_TITLE_MOVE, MOUSE_STATE_RESIZE_BOTTOM, MOUSE_STATE_RESIZE_BOTTOM_LEFT, diff --git a/display/window.c b/display/window.c index e6715b40..3c31e6d8 100644 --- a/display/window.c +++ b/display/window.c @@ -56,6 +56,8 @@ void window_render_frame(struct window* window) : make_color_a(180, 180, 255, 128); uint32_t title_color = has_focus ? make_color_a(16, 16, 16, 240) : make_color_a(32, 32, 32, 200); + uint32_t button_hover_glass = make_color_a(220, 220, 255, 255); + uint32_t button_press_glass = make_color_a(180, 180, 255, 255); size_t start_x = 0; size_t start_y = 0; @@ -125,6 +127,21 @@ void window_render_frame(struct window* window) for (size_t y = 0; y < button_height; y++) framebuffer_set_pixel(buttons_fb, button_width * 2 + x, y, 0xFF8080FF); #endif + for ( size_t n = 0; n < 3; n++ ) + { + uint32_t color = glass_color; + switch ( window->button_states[n] ) + { + case BUTTON_STATE_NORMAL: continue; + case BUTTON_STATE_HOVER: color = button_hover_glass; break; + case BUTTON_STATE_PRESSED: color = button_press_glass; break; + } + size_t bx = button_width * n; + size_t by = 0; + for ( size_t y = 0; y < tt_height; y++ ) + for ( size_t x = 0; x < button_width; x++ ) + framebuffer_set_pixel(buttons_fb, bx + x, by + y, color); + } for ( size_t i = 0; i < button_size; i++ ) { size_t bx = button_width * 0 + (button_width - button_size) / 2; diff --git a/display/window.h b/display/window.h index c8dd8241..5c9c205f 100644 --- a/display/window.h +++ b/display/window.h @@ -35,6 +35,13 @@ static const size_t BORDER_WIDTH = 8; static const size_t TITLE_HEIGHT = 28; static const size_t RESIZE_GRACE = 16; +enum button_state +{ + BUTTON_STATE_NORMAL, + BUTTON_STATE_HOVER, + BUTTON_STATE_PRESSED, +}; + enum window_state { WINDOW_STATE_REGULAR, @@ -68,6 +75,7 @@ struct window size_t saved_height; uint32_t window_id; enum window_state window_state; + enum button_state button_states[3]; bool created; bool show; bool focus;