Rev 2097 |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
/*
* viewwin.cc
* DIN Is Noise is copyright (c) 2006-2025 Jagannathan Sampath
* For more information, please visit https://dinisnoise.org/
*/
#include "dingl.h"
#include "viewwin.h"
#include "main.h"
#include "log.h"
#include <iostream>
using namespace std;
viewport::viewport () {
width = height = 0;
xmax = ymax = 0;
xmax_1 = ymax_1 = 0;
}
viewport::~viewport () {
dlog << "--- destroyed viewport: " << width << spc << height << " ---" << endl;
}
void viewport::operator() (int w, int h) {
if (w != width || h != height) calc (w, h);
}
void viewport::calc (int w, int h) {
width = w;
height = h;
xmax = width - 1;
ymax = height - 1;
xmax_1 = 1.0f / xmax;
ymax_1 = 1.0f / ymax;
midx = width / 2;
midy = height / 2;
handle_factor = handle_radius * 1.0f / width;
dlog << "*** viewport changed to : " << w << spc << h << " ***" << endl;
}
bool viewport::inside (int x, int y) {
int xi = (x > -1) && (x < width);
int yi = (y > -1) && (y < height);
return (xi && yi);
}
void window::calc_panxy () {
pan_x = PAN_AMOUNT * width;
pan_y = PAN_AMOUNT * height;
}
void window::calc_handle_radius () {
handle_radius = viewport::handle_factor * width;
handle_radius2 = handle_radius * handle_radius;
sus_handle_radius = 2 * handle_radius;
}
window::window () : box<float>() {
width_1 = height_1 = 0;
aspect_ratio = 0;
}
window::window (float l, float b, float r, float t) {
set (l, b, r, t);
}
void window::set (float l, float b, float r, float t) {
operator() (l, b, r, t);
aspect_ratio = width * height_1;
calc_panxy ();
calc_viewwin ();
calc_handle_radius ();
window::calc_repeats ();
}
void window::get (float& l, float& b, float& r, float& t) {
l = left;
b = bottom;
r = right;
t = top;
}
void window::panx (int dir) {
float dpan = pan_x * dir;
left = left + dpan;
right = left + width;
mousex += dpan;
}
void window::pany (int dir) {
float dpan = pan_y * dir;
bottom = bottom + pan_y * dir;
top = bottom + height;
mousey += dpan;
}
void window::zoom (int dir) {
float dw = ZOOM_AMOUNT * width * dir, dh = dw / aspect_ratio, dw2 = dw / 2, dh2 = dh / 2;
float l = left - dw2;
float r = right + dw2;
float b = bottom - dh2;
float t = top + dh2;
float w = r - l, h = t - b;
if ((w > 0) && (h > 0)) set (l, b, r, t);
}
void window::locate_mouse () {
extern viewport view;
extern int mousex, mousey;
view2win (mousex, mousey, window::mousex, window::mousey, view, *this);
prev_mousex = mousex;
prev_mousey = mousey;
}
void window::update_mouse () {
extern int mousex, mousey;
mousex_prev = window::mousex;
mousey_prev = window::mousey;
window::mousex += (mousex - prev_mousex) * vwx;
window::mousey -= (mousey - prev_mousey) * vwy;
prev_mousex = mousex;
prev_mousey = mousey;
}
int window::diff_mouse (float& dx, float& dy) {
dx = mousex - mousex_prev;
dy = mousey - mousey_prev;
if (dx || dy) return 1; else return 0;
}
void window::calc_viewwin () {
extern viewport view;
vwx = width / view.xmax;
vwy = height / view.ymax;
locate_mouse ();
}
void window::calc_repeats () {
if (PAN_RATE > 0) PAN_REPEAT = 1. / PAN_RATE;
if (ZOOM_RATE > 0) ZOOM_REPEAT = 1. / ZOOM_RATE;
}
void window::calc () {
box<float>::calc ();
calc_repeats ();
calc_panxy ();
calc_viewwin ();
calc_handle_radius ();
}
void view2win (int vx, int vy, float& wx, float& wy, viewport& view, window& win) {
float xr = vx * view.xmax_1;
float yr = 1 - vy * view.ymax_1;
wx = win.left + xr * win.width;
wy = win.bottom + yr * win.height;
}
void win2view (float wx, float wy, int& vx, int& vy, window& win, viewport& view) {
float xr = (wx - win.left) * win.width_1;
float yr = (wy - win.bottom) * win.height_1;
vx = (int) (xr * view.xmax + 0.5);
vy = (int) (yr * view.ymax + 0.5);
}