/*************************************************************************/ /* color_ramp_edit.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ /* "Software"), to deal in the Software without restriction, including */ /* without limitation the rights to use, copy, modify, merge, publish, */ /* distribute, sublicense, and/or sell copies of the Software, and to */ /* permit persons to whom the Software is furnished to do so, subject to */ /* the following conditions: */ /* */ /* The above copyright notice and this permission notice shall be */ /* included in all copies or substantial portions of the Software. */ /* */ /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #include "color_ramp_edit.h" #include "os/keyboard.h" ColorRampEdit::ColorRampEdit(){ grabbed=-1; grabbing=false; set_focus_mode(FOCUS_ALL); popup = memnew( PopupPanel ); picker = memnew( ColorPicker ); popup->add_child(picker); popup->set_child_rect(picker); add_child(popup); checker = Ref(memnew( ImageTexture )); checker->create_from_image( Image(checker_bg_png),ImageTexture::FLAG_REPEAT ); } int ColorRampEdit::_get_point_from_pos(int x) { int result = -1; int total_w = get_size().width-get_size().height-3; for(int i=0;iget_combined_minimum_size().height+10); picker->set_color(points[grabbed].color); popup->set_pos(get_global_pos()-Vector2(ms.width-get_size().width,ms.height)); popup->set_size(ms); popup->popup(); } ColorRampEdit::~ColorRampEdit() { } 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;itotal_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;iis_connected("color_changed",this,"_color_changed")) { picker->connect("color_changed",this,"_color_changed"); } } if (p_what==NOTIFICATION_DRAW) { int w = get_size().x; int h = get_size().y; if (w == 0 || h == 0) return; //Safety check. We have division by 'h'. And in any case there is nothing to draw with such size int total_w = get_size().width-get_size().height-3; //Draw checker pattern for ramp _draw_checker(0,0, total_w, h); //Draw color ramp ColorRamp::Point prev; prev.offset=0; if(points.size() == 0) prev.color=Color(0,0,0); //Draw black rectangle if we have no points else prev.color = points[0].color; //Extend color of first point to the beginning. for(int i=-1;i points; Vector colors; points.push_back(Vector2(prev.offset*total_w,h)); points.push_back(Vector2(prev.offset*total_w,0)); points.push_back(Vector2(next.offset*total_w,0)); points.push_back(Vector2(next.offset*total_w,h)); colors.push_back(prev.color); colors.push_back(prev.color); colors.push_back(next.color); colors.push_back(next.color); draw_primitive(points,colors,Vector()); prev=next; } //Draw point markers for(int i=0;i backPoints; backPoints.push_back(Vector2(x, y)); backPoints.push_back(Vector2(x, y+h)); backPoints.push_back(Vector2(x+w, y+h)); backPoints.push_back(Vector2(x+w, y)); Vector colorPoints; colorPoints.push_back(Color(1, 1, 1, 1)); colorPoints.push_back(Color(1, 1, 1, 1)); colorPoints.push_back(Color(1, 1, 1, 1)); colorPoints.push_back(Color(1, 1, 1, 1)); Vector uvPoints; //Draw checker pattern pixel-perfect and scale it by 2. uvPoints.push_back(Vector2(x, y)); uvPoints.push_back(Vector2(x, y+h*.5f/checker->get_height())); uvPoints.push_back(Vector2(x+w*.5f/checker->get_width(), y+h*.5f/checker->get_height())); uvPoints.push_back(Vector2(x+w*.5f/checker->get_width(), y)); draw_polygon(backPoints, colorPoints, uvPoints, checker); } Size2 ColorRampEdit::get_minimum_size() const { return Vector2(0,16); } void ColorRampEdit::_color_changed(const Color& p_color) { if (grabbed==-1) return; points[grabbed].color=p_color; update(); emit_signal("ramp_changed"); } void ColorRampEdit::set_ramp(const Vector& p_offsets,const Vector& p_colors) { ERR_FAIL_COND(p_offsets.size()!=p_colors.size()); points.clear(); for(int i=0;i ColorRampEdit::get_offsets() const { Vector ret; for(int i=0;i ColorRampEdit::get_colors() const { Vector ret; for(int i=0;i& p_points) { if(points.size() != p_points.size()) grabbed = -1; points.clear(); points = p_points; } Vector& ColorRampEdit::get_points() { return points; } void ColorRampEdit::_bind_methods() { ObjectTypeDB::bind_method(_MD("_input_event"),&ColorRampEdit::_input_event); ObjectTypeDB::bind_method(_MD("_color_changed"),&ColorRampEdit::_color_changed); ADD_SIGNAL(MethodInfo("ramp_changed")); }