#include namespace raleigh { colorpicker::colorpicker(_pixel_t default_color, uint8_t resolution) : picked_color(default_color), resolution(resolution), inv_res(256 / resolution) { size = coord(inv_res * 2, inv_res * 2); closest_opaque = this; } __attribute__ ((pure)) _pixel_t colorpicker::get_picked_color() { return picked_color; } void colorpicker::paint(_pixel_t *pixbuf, uint32_t pitch) { _pixel_t *pb_ptr = pixbuf + window_offset.y * pitch + window_offset.x; for (uint16_t b = 0; b < inv_res; ++b) for (uint16_t g = 0; g < inv_res; ++g) pb_ptr[b * pitch + g] = (_pixel_t){.r = picked_color.r, .g = g * resolution, .b = b * resolution}; pb_ptr += inv_res; for (uint16_t r = 0; r < inv_res; ++r) for (uint16_t b = 0; b < inv_res; ++b) pb_ptr[r * pitch + b] = (_pixel_t){.r = r * resolution, .g = picked_color.g, .b = b * resolution}; pb_ptr += inv_res * (pitch - 1); for (uint16_t g = 0; g < inv_res; ++g) for (uint16_t r = 0; r < inv_res; ++r) pb_ptr[g * pitch + r] = (_pixel_t){.r = r * resolution, .g = g * resolution, .b = picked_color.b}; pb_ptr += inv_res; for (uint16_t y = 0; y < inv_res; ++y) for (uint16_t x = 0; x < inv_res; ++x) pb_ptr[y * pitch + x] = picked_color; } void colorpicker::set_picked_color(_pixel_t c) { picked_color = c; if (w) w->notify_needs_paint(*this); } void colorpicker::handle_click(coord window_coords, enum mouse_packet::mouse_button click_type, bool up) { if (up || (click_type != mouse_packet::LEFT)) return; window_coords.x -= window_offset.x; window_coords.y -= window_offset.y; if ((window_coords.x < inv_res) && (window_coords.y < inv_res)) { selected = R; picked_color.g = window_coords.x * resolution; picked_color.b = window_coords.y * resolution; } else if (window_coords.y < inv_res) { selected = G; picked_color.b = (window_coords.x - inv_res) * resolution; picked_color.r = window_coords.y * resolution; } else if (window_coords.x < inv_res) { selected = B; picked_color.r = window_coords.x * resolution; picked_color.g = (window_coords.y - inv_res) * resolution; } w->notify_needs_paint(*this); w->notify_wants_movements(*this, mouse_packet::LEFT); } void colorpicker::notify_has_opaque_parent(widget *parent) {} void colorpicker::on_mouse_move(coord window_coords) { int32_t x = window_coords.x - window_offset.x; int32_t y = window_coords.y - window_offset.y; switch (selected) { case R: if (x >= inv_res) x = inv_res - 1; if (x < 0) x = 0; if (y >= inv_res) y = inv_res - 1; if (y < 0) y = 0; picked_color.g = x * resolution; picked_color.b = y * resolution; break; case G: if (x < inv_res) x = inv_res; if (x >= inv_res * 2) x = inv_res * 2 - 1; if (y >= inv_res) y = inv_res - 1; if (y < 0) y = 0; picked_color.b = x * resolution; picked_color.r = y * resolution; break; case B: if (x >= inv_res) x = inv_res - 1; if (x < 0) x = 0; if (y < inv_res) y = inv_res; if (y >= inv_res * 2) y = inv_res * 2 - 1; picked_color.r = x * resolution; picked_color.g = y * resolution; break; } w->notify_needs_paint(*this); } }