/*
* Descent 3
* Copyright (C) 2024 Parallax Software
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#include
#ifdef NEWEDITOR
#include "../neweditor/stdafx.h"
#include "../neweditor/globals.h"
#endif
#include "SelManager.h"
#include "stdafx.h"
#include "macros.h"
#ifndef NEWEDITOR
#include "ddio.h"
#endif
editorSelectorManager SelManager;
editorSelectorManager::editorSelectorManager() {
m_l = m_t = m_r = m_b = -1;
m_OwnerWnd = NULL;
m_DragX = m_DragY = -1;
m_DragState = 0;
m_EndFunc = NULL;
}
// sets the owner window of selection
// starts a selection at x,y
void editorSelectorManager::StartSelection(CWnd *wnd, void (*func)(editorSelectorManager *), int x, int y) {
ASSERT(wnd != NULL);
if (m_DragState != 1) {
POINT pt;
RECT rect;
SIZE size = {2, 2};
if (m_DragState == 2) {
CClientDC dc(m_OwnerWnd);
int r_l, r_b, r_t, r_r;
RECT client_rect;
m_OwnerWnd->GetClientRect(&client_rect);
r_l = m_l;
r_t = m_t;
r_r = m_r;
r_b = m_b;
if (r_r < r_l)
std::swap(r_l, r_r);
if (r_b < r_t)
std::swap(r_t, r_b);
if (r_l < client_rect.left)
r_l = client_rect.left;
if (r_t < client_rect.top)
r_t = client_rect.top;
if (r_r > client_rect.right)
r_r = client_rect.right;
if (r_b > client_rect.bottom)
r_b = client_rect.bottom;
SetRect(&rect, r_l, r_t, r_r, r_b);
dc.DrawDragRect(&rect, size, NULL, size, NULL, NULL);
}
CClientDC dc(wnd);
m_OwnerWnd = wnd;
m_DragState = 1;
m_EndFunc = func;
m_l = x;
m_t = y;
m_r = x;
m_b = y;
SetRect(&rect, m_l, m_t, m_r, m_b);
dc.DrawDragRect(&rect, size, NULL, size, NULL, NULL);
GetCursorPos(&pt);
m_DragX = pt.x;
m_DragY = pt.y;
}
}
// returns the selected rectangle.
void editorSelectorManager::GetSelectedRect(int *l, int *t, int *r, int *b) {
RECT client_rect;
// make sure selected rectangle is clipped to the owner window and normalized.
m_OwnerWnd->GetClientRect(&client_rect);
if (m_r < m_l)
std::swap(m_l, m_r);
if (m_b < m_t)
std::swap(m_t, m_b);
if (m_l < client_rect.left)
m_l = client_rect.left;
if (m_t < client_rect.top)
m_t = client_rect.top;
if (m_r > client_rect.right)
m_r = client_rect.right;
if (m_b > client_rect.bottom)
m_b = client_rect.bottom;
*l = m_l;
*t = m_t;
*r = m_r;
*b = m_b;
}
// defers control to the selector manager
void editorSelectorManager::Defer() {
int mx, my, mdx, mdy;
#ifndef NEWEDITOR
int mouse_state;
#endif
POINT pt;
if (m_DragState != 1)
return;
// get mouse deltas and button state
#ifdef NEWEDITOR
mx = mouse.x;
my = mouse.y;
mdx = mouse.x - mouse.oldx;
mdy = mouse.y - mouse.oldy;
#else
mouse_state = ddio_MouseGetState(&mx, &my, &mdx, &mdy);
#endif
GetCursorPos(&pt);
mx = pt.x;
my = pt.y;
mdx = mx - m_DragX;
mdy = my - m_DragY;
#ifdef NEWEDITOR
if (mouse.left && m_DragState == 1) {
#else
if ((mouse_state & MOUSE_LB) && m_DragState == 1) {
#endif
// if dragging mouse, then draw drag rectangle. if dragging outside owner window
// then still do sizing of window within bounds of owner (why we use deltas for mouse)
CClientDC dc(m_OwnerWnd);
RECT old_draw_rect, draw_rect, client_rect;
SIZE size = {2, 2};
int r_l, r_b, r_t, r_r;
m_OwnerWnd->GetClientRect(&client_rect);
// get current selected rect, normalize rectangle if left,top is invalid for drawing.
r_l = m_l;
r_t = m_t;
r_r = m_r;
r_b = m_b;
if (r_r < r_l)
std::swap(r_l, r_r);
if (r_b < r_t)
std::swap(r_t, r_b);
if (r_l < client_rect.left)
r_l = client_rect.left;
if (r_t < client_rect.top)
r_t = client_rect.top;
if (r_r > client_rect.right)
r_r = client_rect.right;
if (r_b > client_rect.bottom)
r_b = client_rect.bottom;
SetRect(&old_draw_rect, r_l, r_t, r_r, r_b);
m_r = m_r + mdx;
m_b = m_b + mdy;
r_l = m_l;
r_t = m_t;
r_r = m_r;
r_b = m_b;
if (r_r < r_l)
std::swap(r_l, r_r);
if (r_b < r_t)
std::swap(r_t, r_b);
if (r_l < client_rect.left)
r_l = client_rect.left;
if (r_t < client_rect.top)
r_t = client_rect.top;
if (r_r > client_rect.right)
r_r = client_rect.right;
if (r_b > client_rect.bottom)
r_b = client_rect.bottom;
SetRect(&draw_rect, r_l, r_t, r_r, r_b);
dc.DrawDragRect(&draw_rect, size, &old_draw_rect, size, NULL, NULL);
}
#ifdef NEWEDITOR
else if (mouse.left && m_DragState == 1) {
#else
else if (!(mouse_state & MOUSE_LB) && m_DragState == 1) {
#endif
// if mouse up then call our ending function
m_DragState = 2;
if (m_EndFunc)
(*m_EndFunc)(this);
}
m_DragX = mx;
m_DragY = my;
}
void editorSelectorManager::EndSelection() {
RECT rect;
SIZE size = {2, 2};
CClientDC dc(m_OwnerWnd);
int r_l, r_b, r_t, r_r;
RECT client_rect;
// clip drawing rectangle to owner window.
m_OwnerWnd->GetClientRect(&client_rect);
r_l = m_l;
r_t = m_t;
r_r = m_r;
r_b = m_b;
if (r_r < r_l)
std::swap(r_l, r_r);
if (r_b < r_t)
std::swap(r_t, r_b);
if (r_l < client_rect.left)
r_l = client_rect.left;
if (r_t < client_rect.top)
r_t = client_rect.top;
if (r_r > client_rect.right)
r_r = client_rect.right;
if (r_b > client_rect.bottom)
r_b = client_rect.bottom;
SetRect(&rect, r_l, r_t, r_r, r_b);
dc.DrawDragRect(&rect, size, NULL, size, NULL, NULL);
m_l = -1;
m_t = -1;
m_r = -1;
m_b = -1;
m_DragState = 0;
}