diff options
| author | AndreaCatania <info@andreacatania.com> | 2017-11-22 22:29:27 +0100 | 
|---|---|---|
| committer | AndreaCatania <info@andreacatania.com> | 2017-12-10 03:15:52 +0100 | 
| commit | 63ec5823d18ca1f93b0a3b76b171ec2d46465da3 (patch) | |
| tree | e6a72602a5979a47e6a17e459543ea74091473a4 | |
| parent | 20b07a1fb55c31d326c3f9c36d1276eb1bcf15e6 (diff) | |
Implemented skeleton visibility
Removed code visibility code from popup menu
| -rw-r--r-- | editor/editor_themes.cpp | 3 | ||||
| -rw-r--r-- | editor/icons/icon_GUI_visibility_hidden.svg | 55 | ||||
| -rw-r--r-- | editor/icons/icon_GUI_visibility_visible.svg | 63 | ||||
| -rw-r--r-- | editor/icons/icon_GUI_visibility_xray.svg | 61 | ||||
| -rw-r--r-- | editor/plugins/spatial_editor_plugin.cpp | 47 | ||||
| -rw-r--r-- | editor/plugins/spatial_editor_plugin.h | 8 | ||||
| -rw-r--r-- | editor/spatial_editor_gizmos.cpp | 28 | ||||
| -rw-r--r-- | scene/gui/popup_menu.cpp | 95 | ||||
| -rw-r--r-- | scene/gui/popup_menu.h | 17 | 
9 files changed, 359 insertions, 18 deletions
diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp index ae29b7420e..8bc932018a 100644 --- a/editor/editor_themes.cpp +++ b/editor/editor_themes.cpp @@ -625,6 +625,9 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {  	theme->set_icon("radio_checked", "PopupMenu", theme->get_icon("GuiChecked", "EditorIcons"));  	theme->set_icon("radio_unchecked", "PopupMenu", theme->get_icon("GuiUnchecked", "EditorIcons"));  	theme->set_icon("submenu", "PopupMenu", theme->get_icon("ArrowRight", "EditorIcons")); +	theme->set_icon("visibility_hidden", "PopupMenu", theme->get_icon("GuiVisibilityHidden", "EditorIcons")); +	theme->set_icon("visibility_visible", "PopupMenu", theme->get_icon("GuiVisibilityVisible", "EditorIcons")); +	theme->set_icon("visibility_xray", "PopupMenu", theme->get_icon("GuiVisibilityXray", "EditorIcons"));  	theme->set_constant("vseparation", "PopupMenu", (extra_spacing + default_margin_size) * EDSCALE);  	// Tree & ItemList background diff --git a/editor/icons/icon_GUI_visibility_hidden.svg b/editor/icons/icon_GUI_visibility_hidden.svg new file mode 100644 index 0000000000..2add2e9eb8 --- /dev/null +++ b/editor/icons/icon_GUI_visibility_hidden.svg @@ -0,0 +1,55 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg +   xmlns:dc="http://purl.org/dc/elements/1.1/" +   xmlns:cc="http://creativecommons.org/ns#" +   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" +   xmlns:svg="http://www.w3.org/2000/svg" +   xmlns="http://www.w3.org/2000/svg" +   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" +   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" +   width="16" +   height="16" +   version="1.1" +   viewBox="0 0 16 16" +   id="svg2" +   inkscape:version="0.91 r13725" +   sodipodi:docname="icon_GUI_visibility_hidden.svg"> +  <metadata +     id="metadata12"> +    <rdf:RDF> +      <cc:Work +         rdf:about=""> +        <dc:format>image/svg+xml</dc:format> +        <dc:type +           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> +        <dc:title /> +      </cc:Work> +    </rdf:RDF> +  </metadata> +  <defs +     id="defs10" /> +  <sodipodi:namedview +     pagecolor="#ffffff" +     bordercolor="#666666" +     borderopacity="1" +     objecttolerance="10" +     gridtolerance="10" +     guidetolerance="10" +     inkscape:pageopacity="0" +     inkscape:pageshadow="2" +     inkscape:window-width="1920" +     inkscape:window-height="1027" +     id="namedview8" +     showgrid="false" +     inkscape:zoom="14.75" +     inkscape:cx="18.882384" +     inkscape:cy="7.2939487" +     inkscape:window-x="-8" +     inkscape:window-y="-8" +     inkscape:window-maximized="1" +     inkscape:current-layer="svg2" /> +  <path +     style="color:#000000;text-indent:0;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;text-transform:none;white-space:normal;isolation:auto;mix-blend-mode:normal;solid-color:#000000;fill:#e0e0e0;fill-opacity:1;fill-rule:evenodd;color-rendering:auto;image-rendering:auto;shape-rendering:auto" +     d="M 8.3320312 2.1328125 C 8.1166713 2.129146 7.900423 2.1368613 7.6855469 2.1542969 C 4.8418629 2.3850399 2.1034153 4.4237115 1.0449219 7.5722656 C 0.98765482 7.7577705 0.9856205 7.9559357 1.0390625 8.1425781 C 1.2458895 8.8664725 1.5352035 9.5092453 1.8730469 10.089844 L 12.501953 3.7890625 C 11.256805 2.6845102 9.797893 2.1577685 8.3320312 2.1328125 z M 14.554688 3.3046875 L 0.7421875 11.507812 L 1.4453125 12.695312 L 15.257812 4.4921875 L 14.554688 3.3046875 z M 14.169922 5.8847656 L 3.6171875 12.140625 C 4.9944165 13.294116 6.6188565 13.867188 8 13.867188 C 10.5 13.867188 13.836536 12.077978 14.960938 8.1425781 C 15.012856 7.9619931 15.012856 7.7704285 14.960938 7.5898438 C 14.731965 6.9583712 14.46336 6.3981967 14.169922 5.8847656 z " +     id="path6" /> +</svg> diff --git a/editor/icons/icon_GUI_visibility_visible.svg b/editor/icons/icon_GUI_visibility_visible.svg new file mode 100644 index 0000000000..11ae563779 --- /dev/null +++ b/editor/icons/icon_GUI_visibility_visible.svg @@ -0,0 +1,63 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg +   xmlns:dc="http://purl.org/dc/elements/1.1/" +   xmlns:cc="http://creativecommons.org/ns#" +   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" +   xmlns:svg="http://www.w3.org/2000/svg" +   xmlns="http://www.w3.org/2000/svg" +   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" +   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" +   width="16" +   height="16" +   version="1.1" +   viewBox="0 0 16 16" +   id="svg2" +   inkscape:version="0.91 r13725" +   sodipodi:docname="icon_visibility_visible.svg"> +  <metadata +     id="metadata12"> +    <rdf:RDF> +      <cc:Work +         rdf:about=""> +        <dc:format>image/svg+xml</dc:format> +        <dc:type +           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> +        <dc:title></dc:title> +      </cc:Work> +    </rdf:RDF> +  </metadata> +  <defs +     id="defs10" /> +  <sodipodi:namedview +     pagecolor="#ffffff" +     bordercolor="#666666" +     borderopacity="1" +     objecttolerance="10" +     gridtolerance="10" +     guidetolerance="10" +     inkscape:pageopacity="0" +     inkscape:pageshadow="2" +     inkscape:window-width="1920" +     inkscape:window-height="1027" +     id="namedview8" +     showgrid="false" +     inkscape:zoom="14.75" +     inkscape:cx="15.823281" +     inkscape:cy="12.108563" +     inkscape:window-x="-8" +     inkscape:window-y="-8" +     inkscape:window-maximized="1" +     inkscape:current-layer="svg2" /> +  <g +     transform="translate(0 -1036.4)" +     id="g4" +     style="fill:#e0e0e0;fill-opacity:1"> +    <path +       transform="translate(0,1036.4)" +       d="M 8,2 C 5.4433,2 2.2093,3.9477 1.0449,7.7051 c -0.0572671,0.1855049 -0.059303,0.3836676 -0.00586,0.57031 1.1244,3.9354 4.4609,5.7246 6.9609,5.7246 2.5000004,0 5.8365004,-1.7892 6.9609004,-5.7246 0.05192,-0.180585 0.05192,-0.372145 0,-0.55273 -1.1003,-3.7876 -4.4066,-5.7227 -6.9609004,-5.7227 z m 0,2 c 2.209139,0 4,1.790861 4,4 0,2.209139 -1.790861,4 -4,4 C 5.790861,12 4,10.209139 4,8 4,5.790861 5.790861,4 8,4 Z M 8,6 C 6.8954305,6 6,6.8954305 6,8 6,9.1045695 6.8954305,10 8,10 9.1045695,10 10,9.1045695 10,8 10,6.8954305 9.1045695,6 8,6 Z" +       style="color:#000000;text-indent:0;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;text-transform:none;white-space:normal;isolation:auto;mix-blend-mode:normal;solid-color:#000000;fill:#e0e0e0;fill-opacity:1;fill-rule:evenodd;color-rendering:auto;image-rendering:auto;shape-rendering:auto" +       id="path6" +       inkscape:connector-curvature="0" +       sodipodi:nodetypes="cccsccccssssssssss" /> +  </g> +</svg> diff --git a/editor/icons/icon_GUI_visibility_xray.svg b/editor/icons/icon_GUI_visibility_xray.svg new file mode 100644 index 0000000000..1fd9fcf1b5 --- /dev/null +++ b/editor/icons/icon_GUI_visibility_xray.svg @@ -0,0 +1,61 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg +   xmlns:dc="http://purl.org/dc/elements/1.1/" +   xmlns:cc="http://creativecommons.org/ns#" +   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" +   xmlns:svg="http://www.w3.org/2000/svg" +   xmlns="http://www.w3.org/2000/svg" +   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" +   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" +   width="16" +   height="16" +   version="1.1" +   viewBox="0 0 16 16" +   id="svg2" +   inkscape:version="0.91 r13725" +   sodipodi:docname="icon_GUI_visibility_xray.svg"> +  <metadata +     id="metadata12"> +    <rdf:RDF> +      <cc:Work +         rdf:about=""> +        <dc:format>image/svg+xml</dc:format> +        <dc:type +           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> +        <dc:title /> +      </cc:Work> +    </rdf:RDF> +  </metadata> +  <defs +     id="defs10" /> +  <sodipodi:namedview +     pagecolor="#ffffff" +     bordercolor="#666666" +     borderopacity="1" +     objecttolerance="10" +     gridtolerance="10" +     guidetolerance="10" +     inkscape:pageopacity="0" +     inkscape:pageshadow="2" +     inkscape:window-width="1920" +     inkscape:window-height="1027" +     id="namedview8" +     showgrid="false" +     inkscape:zoom="7.375" +     inkscape:cx="43.019438" +     inkscape:cy="-8.9853027" +     inkscape:window-x="-8" +     inkscape:window-y="-8" +     inkscape:window-maximized="1" +     inkscape:current-layer="svg2" /> +  <g +     transform="translate(0.20338214,-1036.671)" +     id="g4" +     style="fill:#e0e0e0;fill-opacity:1" /> +  <path +     id="path4154" +     style="opacity:1;fill:#e0e0e0;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.42799997;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" +     d="m 5.0107427,7.1191578 c -0.084872,0.2859445 -0.1282828,0.5825859 -0.128907,0.8808593 8.579e-4,0.263009 0.034983,0.5248532 0.101563,0.7792969 l 6.0312493,0 C 11.081887,8.5249547 11.116668,8.2631092 11.118164,8.0000171 11.11754,7.7017437 11.074129,7.4051023 10.989257,7.1191578 Z M 7.9999096,2.000005 c -2.5567,0 -5.7907,1.9477 -6.9551,5.7051 -0.057267,0.1855049 -0.059303,0.3836676 -0.00586,0.57031 1.1244,3.9354 4.4609,5.7246 6.9609,5.7246 2.4999994,0 5.8364994,-1.7892 6.9608994,-5.7246 0.05192,-0.180585 0.05192,-0.372145 0,-0.55273 -1.1003,-3.7876 -4.4066,-5.7227 -6.9608994,-5.7227 z m 0,2 c 2.2091384,0 3.9999994,1.790861 3.9999994,4 0,2.209139 -1.790861,4 -3.9999994,4 -2.209139,0 -4,-1.790861 -4,-4 0,-2.209139 1.790861,-4 4,-4 z" +     inkscape:connector-curvature="0" +     sodipodi:nodetypes="ccccccccccsccccsssss" /> +</svg> diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp index 921ba529a2..5273d0ed89 100644 --- a/editor/plugins/spatial_editor_plugin.cpp +++ b/editor/plugins/spatial_editor_plugin.cpp @@ -2614,7 +2614,6 @@ void SpatialEditorViewport::_menu_option(int p_option) {  			view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_DISPLAY_WIREFRAME), false);  			view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_DISPLAY_OVERDRAW), false);  			view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_DISPLAY_SHADELESS), false); -  		} break;  		case VIEW_DISPLAY_WIREFRAME: { @@ -3727,6 +3726,10 @@ void SpatialEditor::select_gizmo_highlight_axis(int p_axis) {  	}  } +int SpatialEditor::get_skeleton_visibility_state() const { +	return view_menu->get_popup()->get_item_state(view_menu->get_popup()->get_item_index(MENU_VISIBILITY_SKELETON)); +} +  void SpatialEditor::update_transform_gizmo() {  	List<Node *> &selection = editor_selection->get_selected_node_list(); @@ -3771,6 +3774,21 @@ void SpatialEditor::update_transform_gizmo() {  	}  } +void _update_all_gizmos(Node *p_node) { +	for (int i = p_node->get_child_count() - 1; 0 <= i; --i) { +		Spatial *spatial_node = Object::cast_to<Spatial>(p_node->get_child(i)); +		if (spatial_node) { +			spatial_node->update_gizmo(); +		} + +		_update_all_gizmos(p_node->get_child(i)); +	} +} + +void SpatialEditor::update_all_gizmos() { +	_update_all_gizmos(SceneTree::get_singleton()->get_root()); +} +  Object *SpatialEditor::_get_editor_data(Object *p_what) {  	Spatial *sp = Object::cast_to<Spatial>(p_what); @@ -4218,6 +4236,28 @@ void SpatialEditor::_menu_item_pressed(int p_option) {  			_refresh_menu_icons();  		} break; +		case MENU_VISIBILITY_SKELETON: { + +			const int idx = view_menu->get_popup()->get_item_index(MENU_VISIBILITY_SKELETON); +			view_menu->get_popup()->toggle_item_statable(idx); + +			// Change icon +			const int state = view_menu->get_popup()->get_item_state(idx); +			switch (state) { +				case 0: +					view_menu->get_popup()->set_item_icon(idx, view_menu->get_popup()->get_icon("visibility_hidden")); +					break; +				case 1: +					view_menu->get_popup()->set_item_icon(idx, view_menu->get_popup()->get_icon("visibility_visible")); +					break; +				case 2: +					view_menu->get_popup()->set_item_icon(idx, view_menu->get_popup()->get_icon("visibility_xray")); +					break; +			} + +			update_all_gizmos(); + +		} break;  	}  } @@ -4670,6 +4710,7 @@ void SpatialEditor::_notification(int p_what) {  		view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS), get_icon("Panels3", "EditorIcons"));  		view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS_ALT), get_icon("Panels3Alt", "EditorIcons"));  		view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_4_VIEWPORTS), get_icon("Panels4", "EditorIcons")); +		view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VISIBILITY_SKELETON), view_menu->get_popup()->get_icon("visibility_visible"));  		_menu_item_pressed(MENU_VIEW_USE_1_VIEWPORT); @@ -5006,6 +5047,10 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {  	p->add_separator();  	p->add_shortcut(ED_SHORTCUT("spatial_editor/settings", TTR("Settings")), MENU_VIEW_CAMERA_SETTINGS); +	p->add_separator(); +	p->add_statable_item(TTR("Skeleton Gizmo visibility"), 3, 1, MENU_VISIBILITY_SKELETON); +	p->add_separator(); +  	p->set_item_checked(p->get_item_index(MENU_VIEW_ORIGIN), true);  	p->set_item_checked(p->get_item_index(MENU_VIEW_GRID), true); diff --git a/editor/plugins/spatial_editor_plugin.h b/editor/plugins/spatial_editor_plugin.h index 14558fc878..9571c96506 100644 --- a/editor/plugins/spatial_editor_plugin.h +++ b/editor/plugins/spatial_editor_plugin.h @@ -92,7 +92,7 @@ class SpatialEditorViewport : public Control {  		VIEW_DISPLAY_NORMAL,  		VIEW_DISPLAY_WIREFRAME,  		VIEW_DISPLAY_OVERDRAW, -		VIEW_DISPLAY_SHADELESS, +		VIEW_DISPLAY_SHADELESS  	};  public: @@ -487,7 +487,8 @@ private:  		MENU_VIEW_GRID,  		MENU_VIEW_CAMERA_SETTINGS,  		MENU_LOCK_SELECTED, -		MENU_UNLOCK_SELECTED +		MENU_UNLOCK_SELECTED, +		MENU_VISIBILITY_SKELETON  	};  	Button *tool_button[TOOL_MAX]; @@ -590,7 +591,10 @@ public:  	Ref<ArrayMesh> get_scale_gizmo(int idx) const { return scale_gizmo[idx]; }  	Ref<ArrayMesh> get_scale_plane_gizmo(int idx) const { return scale_plane_gizmo[idx]; } +	int get_skeleton_visibility_state() const; +  	void update_transform_gizmo(); +	void update_all_gizmos();  	void select_gizmo_highlight_axis(int p_axis);  	void set_custom_camera(Node *p_camera) { custom_camera = p_camera; } diff --git a/editor/spatial_editor_gizmos.cpp b/editor/spatial_editor_gizmos.cpp index 3ffc61cb45..43010ed985 100644 --- a/editor/spatial_editor_gizmos.cpp +++ b/editor/spatial_editor_gizmos.cpp @@ -1316,6 +1316,34 @@ void SkeletonSpatialGizmo::redraw() {  	Color gizmo_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/skeleton");  	Ref<Material> material = create_material("skeleton_material", gizmo_color); +	SpatialMaterial *sm = Object::cast_to<SpatialMaterial>(material.ptr()); + +	{ // Reset +		Color c(sm->get_albedo()); +		c.a = 1; +		sm->set_albedo(c); +	} +	if (sm) { +		switch (SpatialEditor::get_singleton()->get_skeleton_visibility_state()) { +			case 0: { +				// Hidden +				Color c(sm->get_albedo()); +				c.a = 0; +				sm->set_albedo(c); +				sm->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true); +			} break; +			case 1: +				// Visible +				sm->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, false); +				sm->set_render_priority(SpatialMaterial::RENDER_PRIORITY_MIN); +				sm->set_flag(SpatialMaterial::FLAG_DISABLE_DEPTH_TEST, false); +				break; +			case 2: +				// x-ray +				sm->set_on_top_of_alpha(); +				break; +		} +	}  	Ref<SurfaceTool> surface_tool(memnew(SurfaceTool)); diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp index f3711b86b6..b94b785530 100644 --- a/scene/gui/popup_menu.cpp +++ b/scene/gui/popup_menu.cpp @@ -624,6 +624,20 @@ void PopupMenu::add_check_shortcut(const Ref<ShortCut> &p_shortcut, int p_ID, bo  	update();  } +void PopupMenu::add_statable_item(const String &p_label, int p_max_states, int p_default_state, int p_ID, uint32_t p_accel) { + +	Item item; +	item.text = p_label; +	item.xl_text = tr(p_label); +	item.accel = p_accel; +	item.ID = p_ID; +	item.checkable = false; +	item.max_states = p_max_states; +	item.state = p_default_state; +	items.push_back(item); +	update(); +} +  void PopupMenu::set_item_text(int p_idx, const String &p_text) {  	ERR_FAIL_INDEX(p_idx, items.size()); @@ -772,6 +786,11 @@ Ref<ShortCut> PopupMenu::get_item_shortcut(int p_idx) const {  	return items[p_idx].shortcut;  } +int PopupMenu::get_item_state(int p_idx) const { +	ERR_FAIL_INDEX_V(p_idx, items.size(), -1); +	return items[p_idx].state; +} +  void PopupMenu::set_item_as_separator(int p_idx, bool p_separator) {  	ERR_FAIL_INDEX(p_idx, items.size()); @@ -820,6 +839,27 @@ void PopupMenu::set_item_h_offset(int p_idx, int p_offset) {  	update();  } +void PopupMenu::set_item_statable(int p_idx, int p_state) { + +	ERR_FAIL_INDEX(p_idx, items.size()); +	items[p_idx].state = p_state; +	update(); +} + +void PopupMenu::toggle_item_statable(int p_idx) { + +	ERR_FAIL_INDEX(p_idx, items.size()); +	if (0 >= items[p_idx].max_states) { +		return; +	} + +	++items[p_idx].state; +	if (items[p_idx].max_states <= items[p_idx].state) +		items[p_idx].state = 0; + +	update(); +} +  bool PopupMenu::is_item_checkable(int p_idx) const {  	ERR_FAIL_INDEX_V(p_idx, items.size(), false);  	return items[p_idx].checkable; @@ -895,21 +935,34 @@ void PopupMenu::activate_item(int p_item) {  	while (pop) {  		// We close all parents that are chained together,  		// with hide_on_item_selection enabled -		if ((items[p_item].checkable && hide_on_checkable_item_selection && pop->is_hide_on_checkable_item_selection()) || (!items[p_item].checkable && hide_on_item_selection && pop->is_hide_on_item_selection())) { -			pop->hide(); -			next = next->get_parent(); -			pop = Object::cast_to<PopupMenu>(next); -		} else { -			// Break out of loop when the next parent has -			// hide_on_item_selection disabled + +		if (items[p_item].checkable) { +			if (!hide_on_checkable_item_selection || !pop->is_hide_on_checkable_item_selection()) +				break; +		} else if (0 < items[p_item].max_states) { +			if (!hide_on_statable_item_selection || !pop->is_hide_on_statable_item_selection()) +				break; +		} else if (!hide_on_item_selection || !pop->is_hide_on_item_selection())  			break; -		} + +		pop->hide(); +		next = next->get_parent(); +		pop = Object::cast_to<PopupMenu>(next);  	} +  	// Hides popup by default; unless otherwise specified  	// by using set_hide_on_item_selection and set_hide_on_checkable_item_selection -	if ((items[p_item].checkable && hide_on_checkable_item_selection) || (!items[p_item].checkable && hide_on_item_selection)) { -		hide(); -	} + +	if (items[p_item].checkable) { +		if (!hide_on_checkable_item_selection) +			return; +	} else if (0 < items[p_item].max_states) { +		if (!hide_on_statable_item_selection) +			return; +	} else if (!hide_on_item_selection) +		return; + +	hide();  }  void PopupMenu::remove_item(int p_idx) { @@ -1025,7 +1078,7 @@ void PopupMenu::set_hide_on_item_selection(bool p_enabled) {  	hide_on_item_selection = p_enabled;  } -bool PopupMenu::is_hide_on_item_selection() { +bool PopupMenu::is_hide_on_item_selection() const {  	return hide_on_item_selection;  } @@ -1035,11 +1088,21 @@ void PopupMenu::set_hide_on_checkable_item_selection(bool p_enabled) {  	hide_on_checkable_item_selection = p_enabled;  } -bool PopupMenu::is_hide_on_checkable_item_selection() { +bool PopupMenu::is_hide_on_checkable_item_selection() const {  	return hide_on_checkable_item_selection;  } +void PopupMenu::set_hide_on_statable_item_selection(bool p_enabled) { + +	hide_on_statable_item_selection = p_enabled; +} + +bool PopupMenu::is_hide_on_statable_item_selection() const { + +	return hide_on_statable_item_selection; +} +  String PopupMenu::get_tooltip(const Point2 &p_pos) const {  	int over = _get_mouse_over(p_pos); @@ -1098,8 +1161,10 @@ void PopupMenu::_bind_methods() {  	ClassDB::bind_method(D_METHOD("set_item_as_checkable", "idx", "enable"), &PopupMenu::set_item_as_checkable);  	ClassDB::bind_method(D_METHOD("set_item_tooltip", "idx", "tooltip"), &PopupMenu::set_item_tooltip);  	ClassDB::bind_method(D_METHOD("set_item_shortcut", "idx", "shortcut", "global"), &PopupMenu::set_item_shortcut, DEFVAL(false)); +	ClassDB::bind_method(D_METHOD("set_item_statable", "idx", "state"), &PopupMenu::set_item_statable);  	ClassDB::bind_method(D_METHOD("toggle_item_checked", "idx"), &PopupMenu::toggle_item_checked); +	ClassDB::bind_method(D_METHOD("toggle_item_statable", "idx"), &PopupMenu::toggle_item_statable);  	ClassDB::bind_method(D_METHOD("get_item_text", "idx"), &PopupMenu::get_item_text);  	ClassDB::bind_method(D_METHOD("get_item_icon", "idx"), &PopupMenu::get_item_icon); @@ -1131,6 +1196,9 @@ void PopupMenu::_bind_methods() {  	ClassDB::bind_method(D_METHOD("set_hide_on_checkable_item_selection", "enable"), &PopupMenu::set_hide_on_checkable_item_selection);  	ClassDB::bind_method(D_METHOD("is_hide_on_checkable_item_selection"), &PopupMenu::is_hide_on_checkable_item_selection); +	ClassDB::bind_method(D_METHOD("set_hide_on_state_item_selection", "enable"), &PopupMenu::set_hide_on_statable_item_selection); +	ClassDB::bind_method(D_METHOD("is_hide_on_state_item_selection"), &PopupMenu::is_hide_on_statable_item_selection); +  	ClassDB::bind_method(D_METHOD("_submenu_timeout"), &PopupMenu::_submenu_timeout);  	ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "items", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "_set_items", "_get_items"); @@ -1154,6 +1222,7 @@ PopupMenu::PopupMenu() {  	set_as_toplevel(true);  	set_hide_on_item_selection(true);  	set_hide_on_checkable_item_selection(true); +	set_hide_on_statable_item_selection(false);  	submenu_timer = memnew(Timer);  	submenu_timer->set_wait_time(0.3); diff --git a/scene/gui/popup_menu.h b/scene/gui/popup_menu.h index c9e9c8e311..5a10bf0765 100644 --- a/scene/gui/popup_menu.h +++ b/scene/gui/popup_menu.h @@ -46,6 +46,8 @@ class PopupMenu : public Popup {  		String xl_text;  		bool checked;  		bool checkable; +		int max_states; +		int state;  		bool separator;  		bool disabled;  		int ID; @@ -62,6 +64,8 @@ class PopupMenu : public Popup {  			checked = false;  			checkable = false;  			separator = false; +			max_states = 0; +			state = 0;  			accel = 0;  			disabled = false;  			_ofs_cache = 0; @@ -86,6 +90,7 @@ class PopupMenu : public Popup {  	bool invalidated_click;  	bool hide_on_item_selection;  	bool hide_on_checkable_item_selection; +	bool hide_on_statable_item_selection;  	Vector2 moved;  	Array _get_items() const; @@ -115,6 +120,8 @@ public:  	void add_icon_check_shortcut(const Ref<Texture> &p_icon, const Ref<ShortCut> &p_shortcut, int p_ID = -1, bool p_global = false);  	void add_check_shortcut(const Ref<ShortCut> &p_shortcut, int p_ID = -1, bool p_global = false); +	void add_statable_item(const String &p_label, int p_max_states, int p_default_state, int p_ID = -1, uint32_t p_accel = 0); +  	void set_item_text(int p_idx, const String &p_text);  	void set_item_icon(int p_idx, const Ref<Texture> &p_icon);  	void set_item_checked(int p_idx, bool p_checked); @@ -128,6 +135,8 @@ public:  	void set_item_tooltip(int p_idx, const String &p_tooltip);  	void set_item_shortcut(int p_idx, const Ref<ShortCut> &p_shortcut, bool p_global = false);  	void set_item_h_offset(int p_idx, int p_offset); +	void set_item_statable(int p_idx, int p_state); +	void toggle_item_statable(int p_idx);  	void toggle_item_checked(int p_idx); @@ -145,6 +154,7 @@ public:  	bool is_item_checkable(int p_idx) const;  	String get_item_tooltip(int p_idx) const;  	Ref<ShortCut> get_item_shortcut(int p_idx) const; +	int get_item_state(int p_idx) const;  	int get_item_count() const; @@ -168,10 +178,13 @@ public:  	void set_invalidate_click_until_motion();  	void set_hide_on_item_selection(bool p_enabled); -	bool is_hide_on_item_selection(); +	bool is_hide_on_item_selection() const;  	void set_hide_on_checkable_item_selection(bool p_enabled); -	bool is_hide_on_checkable_item_selection(); +	bool is_hide_on_checkable_item_selection() const; + +	void set_hide_on_statable_item_selection(bool p_enabled); +	bool is_hide_on_statable_item_selection() const;  	PopupMenu();  	~PopupMenu();  |