void ColorRampEdit::_input_event(const InputEvent& p_event) { if (p_event.type==InputEvent::KEY && p_event.key.pressed && p_event.key.scancode==KEY_DELETE && grabbed!=-1) { points.remove(grabbed); grabbed=-1; grabbing=false; update(); emit_signal("ramp_changed"); accept_event(); } //Show color picker on double click. if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==1 && p_event.mouse_button.doubleclick && p_event.mouse_button.pressed) { grabbed=_get_point_from_pos(p_event.mouse_button.x); _show_color_picker(); accept_event(); } //Delete point on right click if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==2 && p_event.mouse_button.pressed) { grabbed=_get_point_from_pos(p_event.mouse_button.x); if(grabbed != -1) { points.remove(grabbed); grabbed=-1; grabbing=false; update(); emit_signal("ramp_changed"); accept_event(); } } //Hold alt key to duplicate selected color if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==1 && p_event.mouse_button.pressed && p_event.key.mod.alt ) { int x = p_event.mouse_button.x; grabbed=_get_point_from_pos(x); if( grabbed != -1 ) { int total_w = get_size().width-get_size().height-3; ColorRamp::Point newPoint = points[grabbed]; newPoint.offset=CLAMP(x/float(total_w),0,1); points.push_back(newPoint); points.sort(); for(int i=0;i<points.size();++i) { if (points[i].offset==newPoint.offset) { grabbed=i; break; } } emit_signal("ramp_changed"); update(); } } if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==1 && p_event.mouse_button.pressed) { update(); int x = p_event.mouse_button.x; int total_w = get_size().width-get_size().height-3; //Check if color selector was clicked. if (x>total_w+3) { _show_color_picker(); return; } grabbing=true; grabbed=_get_point_from_pos(x); //grab or select if (grabbed!=-1) { return; } //insert ColorRamp::Point newPoint; newPoint.offset=CLAMP(x/float(total_w),0,1); ColorRamp::Point prev; ColorRamp::Point next; int pos=-1; for(int i=0;i<points.size();i++) { if (points[i].offset<newPoint.offset) pos=i; } if (pos==-1) { prev.color=Color(0,0,0); prev.offset=0; if (points.size()) { next=points[0]; } else { next.color=Color(1,1,1); next.offset=1.0; } } else { if (pos==points.size()-1) { next.color=Color(1,1,1); next.offset=1.0; } else { next=points[pos+1]; } prev=points[pos]; } newPoint.color=prev.color.linear_interpolate(next.color,(newPoint.offset-prev.offset)/(next.offset-prev.offset)); points.push_back(newPoint); points.sort(); for(int i=0;i<points.size();i++) { if (points[i].offset==newPoint.offset) { grabbed=i; break; } } emit_signal("ramp_changed"); } if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==1 && !p_event.mouse_button.pressed) { if (grabbing) { grabbing=false; emit_signal("ramp_changed"); } update(); } if (p_event.type==InputEvent::MOUSE_MOTION && grabbing) { int total_w = get_size().width-get_size().height-3; int x = p_event.mouse_motion.x; float newofs = CLAMP(x/float(total_w),0,1); //Snap to nearest point if holding shift if (p_event.key.mod.shift) { float snap_treshhold = 0.03; float smallest_ofs = snap_treshhold; bool founded = false; int nearest_point; for(int i=0;i<points.size();++i) { if (i != grabbed) { float temp_ofs = ABS(points[i].offset - newofs); if (temp_ofs < smallest_ofs) { smallest_ofs = temp_ofs; nearest_point = i; if (founded) break; founded = true; } } } if (founded) { if (points[nearest_point].offset < newofs) newofs = points[nearest_point].offset+0.00001; else newofs = points[nearest_point].offset-0.00001; newofs = CLAMP(newofs,0,1); } } bool valid=true; for(int i=0;i<points.size();i++) { if (points[i].offset==newofs && i!=grabbed) { valid=false; } } if (!valid) return; points[grabbed].offset=newofs; points.sort(); for(int i=0;i<points.size();i++) { if (points[i].offset==newofs) { grabbed=i; break; } } emit_signal("ramp_changed"); update(); } }
void GradientEdit::_gui_input(const Ref<InputEvent> &p_event) { Ref<InputEventKey> k = p_event; if (k.is_valid() && k->is_pressed() && k->get_scancode() == KEY_DELETE && grabbed != -1) { points.remove(grabbed); grabbed = -1; grabbing = false; update(); emit_signal("ramp_changed"); accept_event(); } Ref<InputEventMouseButton> mb = p_event; //Show color picker on double click. if (mb.is_valid() && mb->get_button_index() == 1 && mb->is_doubleclick() && mb->is_pressed()) { grabbed = _get_point_from_pos(mb->get_position().x); _show_color_picker(); accept_event(); } //Delete point on right click if (mb.is_valid() && mb->get_button_index() == 2 && mb->is_pressed()) { grabbed = _get_point_from_pos(mb->get_position().x); if (grabbed != -1) { points.remove(grabbed); grabbed = -1; grabbing = false; update(); emit_signal("ramp_changed"); accept_event(); } } //Hold alt key to duplicate selected color if (mb.is_valid() && mb->get_button_index() == 1 && mb->is_pressed() && mb->get_alt()) { int x = mb->get_position().x; grabbed = _get_point_from_pos(x); if (grabbed != -1) { int total_w = get_size().width - get_size().height - 3; Gradient::Point newPoint = points[grabbed]; newPoint.offset = CLAMP(x / float(total_w), 0, 1); points.push_back(newPoint); points.sort(); for (int i = 0; i < points.size(); ++i) { if (points[i].offset == newPoint.offset) { grabbed = i; break; } } emit_signal("ramp_changed"); update(); } } if (mb.is_valid() && mb->get_button_index() == 1 && mb->is_pressed()) { update(); int x = mb->get_position().x; int total_w = get_size().width - get_size().height - 3; //Check if color selector was clicked. if (x > total_w + 3) { _show_color_picker(); return; } grabbing = true; grabbed = _get_point_from_pos(x); //grab or select if (grabbed != -1) { return; } //insert Gradient::Point newPoint; newPoint.offset = CLAMP(x / float(total_w), 0, 1); Gradient::Point prev; Gradient::Point next; int pos = -1; for (int i = 0; i < points.size(); i++) { if (points[i].offset < newPoint.offset) pos = i; } if (pos == -1) { prev.color = Color(0, 0, 0); prev.offset = 0; if (points.size()) { next = points[0]; } else { next.color = Color(1, 1, 1); next.offset = 1.0; } } else { if (pos == points.size() - 1) { next.color = Color(1, 1, 1); next.offset = 1.0; } else { next = points[pos + 1]; } prev = points[pos]; } newPoint.color = prev.color.linear_interpolate(next.color, (newPoint.offset - prev.offset) / (next.offset - prev.offset)); points.push_back(newPoint); points.sort(); for (int i = 0; i < points.size(); i++) { if (points[i].offset == newPoint.offset) { grabbed = i; break; } } emit_signal("ramp_changed"); } if (mb.is_valid() && mb->get_button_index() == 1 && !mb->is_pressed()) { if (grabbing) { grabbing = false; emit_signal("ramp_changed"); } update(); } Ref<InputEventMouseMotion> mm = p_event; if (mm.is_valid() && grabbing) { int total_w = get_size().width - get_size().height - 3; int x = mm->get_position().x; float newofs = CLAMP(x / float(total_w), 0, 1); //Snap to nearest point if holding shift if (mm->get_shift()) { float snap_treshhold = 0.03; float smallest_ofs = snap_treshhold; bool founded = false; int nearest_point; for (int i = 0; i < points.size(); ++i) { if (i != grabbed) { float temp_ofs = ABS(points[i].offset - newofs); if (temp_ofs < smallest_ofs) { smallest_ofs = temp_ofs; nearest_point = i; if (founded) break; founded = true; } } } if (founded) { if (points[nearest_point].offset < newofs) newofs = points[nearest_point].offset + 0.00001; else newofs = points[nearest_point].offset - 0.00001; newofs = CLAMP(newofs, 0, 1); } } bool valid = true; for (int i = 0; i < points.size(); i++) { if (points[i].offset == newofs && i != grabbed) { valid = false; } } if (!valid) return; points[grabbed].offset = newofs; points.sort(); for (int i = 0; i < points.size(); i++) { if (points[i].offset == newofs) { grabbed = i; break; } } emit_signal("ramp_changed"); update(); } }