void Window::process(const InputState &state) { Window *popup = nullptr; m_is_focused = true; for(int n = 0; n < (int)m_children.size(); n++) { m_children[n]->m_is_focused = false; m_children[n]->m_is_mouse_over = false; if(m_children[n]->m_is_closing) { PWindow window = m_children[n]; m_children.erase(m_children.begin() + n); sendEvent(window.get(), Event::window_closed, m_children[n]->m_closing_value); n--; } else if(m_children[n]->m_is_popup) popup = m_children[n].get(); } if(popup) { popup->process(state); return; } int2 mouse_pos = state.mousePos(); int2 local_mouse_pos = mouse_pos - m_clipped_rect.min; int finished_dragging = 0; bool escape = state.isKeyDown(InputKey::esc); InputButton button_map[3] = { InputButton::left, InputButton::right, InputButton::middle }; if(m_dragging_mode) { if(!state.isMouseButtonPressed(button_map[m_dragging_mode - 1]) || escape) finished_dragging = escape? -1 : 1; } else { for(int k = 0; k < 3; k++) { if(state.isMouseButtonDown(button_map[k])) { m_dragging_mode = k + 1; m_drag_start = local_mouse_pos; break; } } } int2 focus_point = m_dragging_mode? m_drag_start : local_mouse_pos; bool is_handled = false; for(int n = (int)m_children.size() - 1; n >= 0; n--) { Window *child = m_children[n].get(); if(child->isVisible() && m_has_hard_focus == child->m_has_hard_focus) { if(m_has_hard_focus || child->rect().isInside(focus_point)) { child->m_is_mouse_over = child->clippedRect().isInside(mouse_pos); child->process(state); is_handled = true; break; } } } if(!is_handled) { if(m_dragging_mode && !is_handled) { if(m_has_inner_rect && m_dragging_mode - 1 == 2) { setInnerRect(m_inner_rect + state.mouseMove()); is_handled = true; } if(!is_handled) is_handled = onMouseDrag(state, m_drag_start, local_mouse_pos, m_dragging_mode - 1, finished_dragging); if(!is_handled) is_handled = onMouseClick(state, local_mouse_pos, m_dragging_mode - 1, finished_dragging); } if(!is_handled) { if(m_has_inner_rect) { int wheel = state.mouseWheelMove(); int2 vector(0, 0); if(wheel) vector.y += wheel * rect().height() / 8; if(state.isKeyDownAuto(InputKey::pageup, 2)) vector.y += rect().height(); if(state.isKeyDownAuto(InputKey::pagedown, 2)) vector.y -= rect().height(); setInnerRect(m_inner_rect + vector); } onInput(state); } } if(escape && (!m_parent || m_is_popup) && !m_dragging_mode) // sending Event::escape only from main window sendEvent(this, Event::escape); //TODO: send only to focused windows if(finished_dragging) m_dragging_mode = 0; }
bool EntitiesEditor::onMouseDrag(const InputState &state, int2 start, int2 current, int key, int is_final) { bool shift_pressed = state.isKeyPressed(InputKey::lshift); if(key == 0 && !state.isKeyPressed(InputKey::lctrl)) { computeCursor(start, current, shift_pressed); m_is_selecting = !is_final; if(m_mode == Mode::selecting && is_final && is_final != -1) { findVisible(m_selected_ids, m_selection); computeCursor(current, current, shift_pressed); } else if(m_mode == Mode::placing) { if(m_proto->typeId() == EntityId::trigger) { Trigger *trigger = static_cast<Trigger*>(m_proto.get()); if(m_trigger_mode == 0) { m_trigger_box = m_view.computeCursor(start, current, int3(1, 1, 1), m_cursor_pos.y, 0); if(state.isMouseButtonDown(InputButton::right)) { m_trigger_mode = 1; m_trigger_offset = current; } } IBox new_box = m_trigger_box; if(m_trigger_mode == 1) { int offset = screenToWorld(int2(0, m_trigger_offset.y - current.y)).y; if(offset < 0) new_box.min.y += offset; else new_box.max.y += offset; } trigger->setBox((FBox)new_box); m_cursor_pos = trigger->pos(); if(is_final > 0) { m_entity_map.add(PEntity(m_proto->clone())); } if(is_final) { m_trigger_mode = 0; trigger->setBox(FBox(0, 0, 0, 1, 1, 1) + trigger->pos()); } } else if(is_final > 0) m_entity_map.add(PEntity(m_proto->clone())); } return true; } else if(key == 1 && m_mode == Mode::selecting) { if(!m_is_moving) { m_is_moving_vertically = state.isKeyPressed(InputKey::lshift); m_is_moving = true; } if(m_is_moving_vertically) m_move_offset = int3(0, screenToWorld(int2(0, start.y - current.y)).y, 0); else m_move_offset = asXZY(screenToWorld(current - start), 0); if(is_final) m_is_moving = false; if(is_final > 0) { for(int n = 0; n < (int)m_selected_ids.size(); n++) { auto &object = m_entity_map[m_selected_ids[n]]; object.ptr->setPos(object.ptr->pos() + float3(m_move_offset)); m_entity_map.update(m_selected_ids[n]); } } return true; } return false; }