Subversion Repositories DIN Is Noise

Rev

Rev 1459 | Rev 1712 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

/*
* basic_editor.cc
* DIN Is Noise is copyright (c) 2006-2020 Jagannathan Sampath
* For more information, please visit https://dinisnoise.org/
*/



#include <fstream>
#include <iostream>
#include "main.h"
#include "input.h"
#include "font.h"
#include "console.h"
#include "basic_editor.h"
#include "solver.h"
#include "widget.h"
#include "ui_list.h"

using namespace std;

extern console cons;
extern std::string user_data_dir;
extern viewport view;
extern char BUFFER [];
extern int wheel;
extern int can_wheel ();
extern ui_list uis;

basic_editor::basic_editor () {
  snap_what = SNAP_NONE;
  edit_sustain = 0;
  kbkb_attack_editor = 0;
  lmb_clicked = 0;
  pan = zoom = 1;
  ed = 1;
  draw_guide = 0;
  ++ref;
}

basic_editor::~basic_editor () {
  if (--ref == 0) {
    if (gl_pts) {
      dlog << "cleared basic_editor::gl_pts @ " << gl_pts << endl;
      delete[] gl_pts;
    }
  }
}

void basic_editor::load (const std::string& fname) {
  ifstream file ((user_data_dir + fname).c_str (), ios::in);
  if (!file) return;
  load (file);

}

void basic_editor::load  (ifstream& file) {

  std::string ignore;

  file >> ignore >> name;

  float l, b, r,  t;
  file >> ignore >> l >> b >> r >> t;
  win.set (l, b, r, t);

  file >> ignore >> win_chunk.x >> win_chunk.y;
  file >> ignore >> obj_chunk.x >> obj_chunk.y;

  win_per_obj (win_chunk.x / obj_chunk.x, win_chunk.y / obj_chunk.y);
  obj_per_win (obj_chunk.x / win_chunk.x , obj_chunk.y / win_chunk.y);

  file >> ignore >> snap_what;
  set_snap (snap_what);

  file >> ignore >> win_resolution;
  float dummy1 = 0, dummy2 = 0;
  win2obj (win_resolution, dummy1, obj_resolution, dummy2);

}

void basic_editor::save (ofstream& file) {
  //file << "id " << id << endl;
  file << "editor " << name << endl;
  file << "window " << win.left << ' ' << win.bottom << ' ' << win.right << ' ' << win.top << endl;
  file << "win_chunk " << win_chunk.x << ' ' << win_chunk.y << endl;
  file << "obj_chunk " << obj_chunk.x << ' ' << obj_chunk.y << endl;
  file << "snap " << snap_what << endl;
  file << "win_resolution " << win_resolution << endl;
}

void basic_editor::calc_win_mouse () {
  win.update_mouse ();
}

int basic_editor::handle_input () {

  if (kbkb_attack_editor) {
    if (lmb) {
      if (lmb_clicked == 0) {
        if (edit_sustain) edit_sustain = 0;
        else {if (inbox (susbox, win.mousex, win.mousey)) edit_sustain = 1;}
        lmb_clicked = 1;
      }
    } else {
      if (edit_sustain) {
        float sx, sy; snap (sx, sy);
        float cx, cy; win2obj (sx, sy, cx, cy);
        _gotog.set (cx);
      }
      lmb_clicked = 0;
    }
  }

  // mouse capture
  if (mocap0.state == mocap::capturing) mocap0.add (win.mousex, win.mousey);

  // movement
  if (can_wheel()) do_zoom (-wheel * zoom);
  double pan_rept = window::PAN_REPEAT, zoom_rept = window::ZOOM_REPEAT;
  if  (keypressedd (SDLK_a, pan_rept, pan_rept)) do_panx (-pan);
  else if (keypressedd (SDLK_d, pan_rept, pan_rept)) do_panx (+pan);
  else if (keypressedd (SDLK_w, pan_rept, pan_rept)) do_pany (+pan);
  else if (keypressedd (SDLK_s, pan_rept, pan_rept)) do_pany (-pan);
  else if (keypressedd (SDLK_q, zoom_rept, zoom_rept)) do_zoom (+zoom);
  else if (keypressedd (SDLK_e, zoom_rept, zoom_rept)) do_zoom (-zoom);
  else if (keypressedd (SDLK_g)) draw_guide = !draw_guide;

  // snap
  else if (keypressed (SDLK_x)) set_snap (SNAP_X);
  else if (keypressed (SDLK_y)) set_snap (SNAP_Y);
  else if (keypressed (SDLK_b)) set_snap (SNAP_BOTH);
  else if (keypressed (SDLK_n)) set_snap (SNAP_NONE);

  else if (keypressedd (SDLK_F5)) {
    if (SHIFT) set_win_chunk (win_chunk.x, --win_chunk.y); else set_win_chunk (--win_chunk.x, win_chunk.y);
  } else if (keypressedd (SDLK_F6)) {
    if (SHIFT) set_win_chunk (win_chunk.x, ++win_chunk.y); else set_win_chunk (++win_chunk.x, win_chunk.y);
  }
  else if (keypressed (SDLK_F7)) {
    toggle_mouse_capture ();
  }

  return 1;
}

void basic_editor::set_win_chunk (int x, int y) {

  if (x < 1) x = 1;
  if (y < 1) y = 1;

  win_chunk.x = x;
  win_chunk.y = y;

  float wx = win_chunk.x / obj_chunk.x, wy = win_chunk.y / obj_chunk.y;
  win_per_obj (wx, wy);
  obj_per_win (1.0f/wx, 1.0f/wy);

}

int basic_editor::is_snapx () {
  return ((snap_what == SNAP_X) || (snap_what == SNAP_BOTH));
}

int basic_editor::is_snapy () {
  return ((snap_what == SNAP_Y) || (snap_what == SNAP_BOTH));
}

void basic_editor::snap (float& x, float& y) {
  x = win.mousex;
  y = win.mousey;
  if (SHIFT) { // x stays, wont snap
    if (shft_clk.noted == 0) shft_clk.note (x, y);
    x = shft_clk.pt.x;
    do_snapy (y);
    ctrl_clk.noted = 0;
  } else if (CTRL) { // y stays, wont snap
    if (ctrl_clk.noted == 0) ctrl_clk.note (x, y);
    y = ctrl_clk.pt.y;
    do_snapx (x);
    shft_clk.noted = 0;
  } else { // both may snap
    do_snapx (x);
    do_snapy (y);
    ctrl_clk.noted = 0;
    shft_clk.noted = 0;
  }
}

void basic_editor::do_snapx (float& x) {
  if (is_snapx()) {
    float s = win.mousex / win_chunk.x;
    if (s < 0) s -= 0.5; else s += 0.5;
    x = (int) s * win_chunk.x;
  }
}

void basic_editor::do_snapy (float& y) {
  if (is_snapy()) {
    float s = win.mousey / win_chunk.y;
    if (s < 0) s -= 0.5; else s += 0.5;
    y = (int) s * win_chunk.y;
  }
}

void basic_editor::project () {
  glMatrixMode (GL_PROJECTION);
  glPushMatrix ();
    glLoadIdentity ();
    glOrtho (win.left, win.right, win.bottom, win.top, -1, 1);
     
  glMatrixMode (GL_MODELVIEW);
    glPushMatrix ();
      glLoadIdentity ();
}

void basic_editor::unproject () {
  glMatrixMode (GL_MODELVIEW);
  glPopMatrix ();
  glMatrixMode (GL_PROJECTION);
  glPopMatrix ();
}

void basic_editor::draw  () {
  // must always be wrapped by project, unproject
  draw_snaps ();
}

void basic_editor::draw_cursor () {

  if (hide_cursor) return;

  glMatrixMode (GL_PROJECTION);
  glPushMatrix ();
    glLoadIdentity ();
      glOrtho (0, view.xmax, 0, view.ymax, 0, 1);

    float wx, wy; snap (wx, wy);
    win2obj (wx, wy, cursor_x, cursor_y);
    int vx, vy; win2view (wx, wy, vx, vy, win, view);

    /*int spacing, dummy;
    float whx = win.left+win.handle_radius, why = win.bottom;
    win2view (whx, why, spacing, dummy, win, view); */


    const int spacing = 12;
    int vxs = vx + spacing;
    if (draw_guide) {
      glColor3f (0.20f, 0.20f, 0.20f);
      gl_pts[0]=0; gl_pts[1]=vy;
      gl_pts[2]=vx - spacing; gl_pts[3]=vy;
      gl_pts[4]=vxs; gl_pts[5]=vy;
      gl_pts[6]=view.xmax; gl_pts[7]=vy;
      gl_pts[8]=vx; gl_pts[9]=0;
      gl_pts[10]=vx; gl_pts[11]=vy - spacing;
      gl_pts[12]=vx; gl_pts[13]=vy + spacing;
      gl_pts[14]=vx; gl_pts[15]=view.ymax;
      glVertexPointer (2, GL_FLOAT, 0, gl_pts);
      glDrawArrays (GL_LINES, 0, 8);
    }


    glColor3f (1, 1, 1);
    sprintf (BUFFER, " %.3f, %.3f", cursor_x, cursor_y);
    draw_string (BUFFER, vxs, vy);

    extern int line_height;
    if (edit_sustain) {
      vy -= line_height;
      extern gotog _gotog;
      sprintf (BUFFER, " sustain @ %.3f", _gotog.g);
      draw_string (BUFFER, vx, vy);
    }

    if (cursor_mesg != "") {
      glColor3f (1, 1, 0.5);
      vy -= line_height;
      draw_string (cursor_mesg, vx, vy);
    }

  glPopMatrix ();
}

void basic_editor::update_snaps () {
  int l, b, r, t;
  if (is_snapx()) {
    l = (int)(win.left / win_chunk.x);
    startx = l * win_chunk.x;
    r = (int)(win.right / win_chunk.x);
    endx = r * win_chunk.x;
    xlines.clear ();
    nxpts = 0;
    while (startx <= endx) {
      xlines.push_back (startx);
      xlines.push_back (win.bottom);
      xlines.push_back (startx);
      xlines.push_back (win.top);
      startx += win_chunk.x;
      nxpts += 2;
    }
  }
  if (is_snapy ()) {
    b = (int)(win.bottom / win_chunk.y);
    starty = b * win_chunk.y;
    t = (int)(win.top / win_chunk.y);
    endy = t * win_chunk.y;
    ylines.clear ();
    nypts = 0;
    while (starty <= endy) {
      ylines.push_back (win.left);
      ylines.push_back (starty);
      ylines.push_back (win.right);
      ylines.push_back (starty);
      starty += win_chunk.y;
      nypts += 2;
    }
  }
}

void basic_editor::draw_snaps () {
  //
  // draw snap lines
  //
  static const float sr = 0.1f, sg = sr, sb = sg; // snap color
  glColor3f (sr, sg, sb);
  if (is_snapx()) { // lines along y
    glVertexPointer (2, GL_INT, 0, xlines.data ());
    glDrawArrays (GL_LINES, 0, nxpts);
   
  }
  if (is_snapy()) { // lines along x
    glVertexPointer (2, GL_INT, 0, ylines.data ());
    glDrawArrays (GL_LINES, 0, nypts);
  }
}

void basic_editor::calc_visual_params () {
  if (kbkb_attack_editor) susbox (susx - win.handle_radius, win.top - win.sus_handle_radius, susx + win.handle_radius, win.top);
  tb.refresh (this);
  update_snaps ();
}

void basic_editor::update_sustain (float f) {
  float ox = f, oy = 0;
  obj2win (ox, oy, susx, susy);
  calc_visual_params ();
}

void basic_editor::do_panx (int dir) {
  win.panx (dir);
  calc_visual_params ();
}

void basic_editor::do_pany (int dir) {
  win.pany (dir);
  calc_visual_params ();
}

void basic_editor::do_zoom (int dir) {
  win.zoom (dir);
  calc_visual_params ();
}

void basic_editor::set_snap (int what) {
  snap_what = what;
  update_snaps ();
  ::set_snap (what);
}

void basic_editor::start_mouse_capture () {
  mocap0.clear ();
  mocap0.state = mocap::capturing;
  cons << GREEN << "Capturing mouse" << eol;
}

void basic_editor::stop_mouse_capture () {
  if (mocap0.state == mocap::capturing) {
    mocap0.finish (this);
    cons << GREEN << "Captured mouse!" << eol;
  }
}

void basic_editor::toggle_mouse_capture () {
  if (mocap0.state != mocap::capturing) start_mouse_capture (); else stop_mouse_capture ();
}

void basic_editor::obj2win (const float& ox, const float& oy, float& wx, float& wy) {
  wx = win_per_obj.x * ox;
  wy = win_per_obj.y * oy;
}

void basic_editor::obj2win (const point<float>& v, float& wx, float& wy) {
  obj2win (v.x, v.y, wx, wy);
}

void basic_editor::win2obj (const float& wx, const float& wy, float& ox, float& oy) {
  ox = obj_per_win.x * wx;
  oy = obj_per_win.y * wy;
}

void basic_editor::obj2view (const float& ox, const float& oy, int& vx, int& vy) {
  float wx, wy;
  obj2win (ox, oy, wx, wy);
  win2view (wx, wy, vx, vy, win, view);
}

void basic_editor::view2obj (const int& vx, const int& vy, float& ox, float& oy) {
  float wx, wy;
  view2win (vx, vy, wx, wy, view, win);
  win2obj (wx, wy, ox, oy);
}

void basic_editor::obj2mouse (const float& ox, const float& oy) {
  int vx, vy;
  obj2view (ox, oy, vx, vy);
  warp_mouse (vx, view.ymax - vy);
}

click_point_t::click_point_t () : noted (0) {}
void click_point_t::note (float x, float y) {
  pt.x = x;
  pt.y = y;
  noted = 1;
}