Example #1
0
void PopupMenu::_scroll(float p_factor, const Point2 &p_over) {

	const float global_y = get_global_position().y;

	int vseparation = get_constant("vseparation");
	Ref<Font> font = get_font("font");

	float dy = (vseparation + font->get_height()) * 3 * p_factor;
	if (dy > 0 && global_y < 0)
		dy = MIN(dy, -global_y - 1);
	else if (dy < 0 && global_y + get_size().y > get_viewport_rect().size.y)
		dy = -MIN(-dy, global_y + get_size().y - get_viewport_rect().size.y - 1);
	set_position(get_position() + Vector2(0, dy));

	Ref<InputEventMouseMotion> ie;
	ie.instance();
	ie->set_position(p_over - Vector2(0, dy));
	_gui_input(ie);
}
Example #2
0
void PopupMenu::_gui_input(const Ref<InputEvent> &p_event) {

	Ref<InputEventKey> k = p_event;

	if (k.is_valid()) {

		if (!k->is_pressed())
			return;

		switch (k->get_scancode()) {

			case KEY_DOWN: {

				for (int i = mouse_over + 1; i < items.size(); i++) {

					if (i < 0 || i >= items.size())
						continue;

					if (!items[i].separator && !items[i].disabled) {

						mouse_over = i;
						update();
						break;
					}
				}
			} break;
			case KEY_UP: {

				for (int i = mouse_over - 1; i >= 0; i--) {

					if (i < 0 || i >= items.size())
						continue;

					if (!items[i].separator && !items[i].disabled) {

						mouse_over = i;
						update();
						break;
					}
				}
			} break;
			case KEY_ENTER:
			case KEY_KP_ENTER: {

				if (mouse_over >= 0 && mouse_over < items.size() && !items[mouse_over].separator) {

					activate_item(mouse_over);
				}
			} break;
		}
	}

	Ref<InputEventMouseButton> b = p_event;

	if (b.is_valid()) {

		if (b->is_pressed())
			return;

		switch (b->get_button_index()) {

			case BUTTON_WHEEL_DOWN: {

				if (get_global_position().y + get_size().y > get_viewport_rect().size.y) {

					int vseparation = get_constant("vseparation");
					Ref<Font> font = get_font("font");

					Point2 pos = get_position();
					int s = (vseparation + font->get_height()) * 3;
					pos.y -= (s * b->get_factor());
					set_position(pos);

					//update hover
					Ref<InputEventMouseMotion> ie;
					ie.instance();
					ie->set_position(b->get_position() + Vector2(0, s));
					_gui_input(ie);
				}
			} break;
			case BUTTON_WHEEL_UP: {

				if (get_global_position().y < 0) {

					int vseparation = get_constant("vseparation");
					Ref<Font> font = get_font("font");

					Point2 pos = get_position();
					int s = (vseparation + font->get_height()) * 3;
					pos.y += (s * b->get_factor());
					set_position(pos);

					//update hover
					Ref<InputEventMouseMotion> ie;
					ie.instance();
					ie->set_position(b->get_position() - Vector2(0, s));
					_gui_input(ie);
				}
			} break;
			case BUTTON_LEFT: {

				int over = _get_mouse_over(b->get_position());

				if (invalidated_click) {
					invalidated_click = false;
					break;
				}
				if (over < 0) {
					hide();
					break; //non-activable
				}

				if (items[over].separator || items[over].disabled)
					break;

				if (items[over].submenu != "") {

					_activate_submenu(over);
					return;
				}
				activate_item(over);

			} break;
		}

		//update();
	}

	Ref<InputEventMouseMotion> m = p_event;

	if (m.is_valid()) {

		if (invalidated_click) {
			moved += m->get_relative();
			if (moved.length() > 4)
				invalidated_click = false;
		}

		for (List<Rect2>::Element *E = autohide_areas.front(); E; E = E->next()) {

			if (!Rect2(Point2(), get_size()).has_point(m->get_position()) && E->get().has_point(m->get_position())) {
				call_deferred("hide");
				return;
			}
		}

		int over = _get_mouse_over(m->get_position());
		int id = (over < 0 || items[over].separator || items[over].disabled) ? -1 : (items[over].ID >= 0 ? items[over].ID : over);

		if (id < 0) {
			mouse_over = -1;
			update();
			return;
		}

		if (items[over].submenu != "" && submenu_over != over) {
			submenu_over = over;
			submenu_timer->start();
		}

		if (over != mouse_over) {
			mouse_over = over;
			update();
		}
	}
}