[project @ 4]
[mussa.git] / mussa_gui_conn.cc
index 75a757a59c43baefa422c3f14b5244ed9af40399..aeff03ec514d9d8adad132f465c9d001be607034 100644 (file)
@@ -25,6 +25,11 @@ ConnView::setup(string name, int sq_num, int win_len,
   x_scale_factor = (float) seq_lens[0] / x_max;
   cout << "scale factor is " << x_scale_factor << endl;
   y_seq_incre = (y_max-20) / (seq_num - 1);
+
+  dragging = false;
+  selected = false;
+
+  highlight.clear();
 }
 
 
@@ -38,10 +43,10 @@ ConnView::scale_paths()
 
   scaled_pathz.clear();
 
-  for(pathz_i = P->pathz.begin(); pathz_i != P->pathz.end(); ++pathz_i)
+  for(pathz_i = P->refined_pathz.begin(); pathz_i != P->refined_pathz.end(); ++pathz_i)
   {
     a_path = *pathz_i;
-    for(i2 = 0; i2 < seq_num; i2++)
+    for(i2 = 0; i2 <= seq_num; i2++)
       a_path[i2] = (int) (a_path[i2] / x_scale_factor);
     scaled_pathz.push_back(a_path);
   }
@@ -54,30 +59,108 @@ void
 ConnView::draw()
 {
   list<vector<int> >::iterator i;
-  int i2, y_loc, x_loc;
+  int i2, i3, y_loc, x_loc, x_start, x_end;
   vector<int> a_path;
+  list<annot>::iterator annot_i;
+  int window_size;
+  bool rc_color;
+  int path_start, path_end;
+  list<bool>::iterator highlight_i;
+
+
+  // clear drawing area and set background to white
+  fl_color(FL_WHITE);
+  fl_rectf(x(), y(), w(), h());
+
+  // determine which paths to highlight
+  highlight.clear();
+  for(i = scaled_pathz.begin(); i != scaled_pathz.end(); ++i)
+  {
+    a_path = *i;
+    // determine if path falls within the selected region and mark it for
+    // highlighted color
+    path_start = abs(a_path[1]);
+    path_end = path_start + a_path[0];
+    if ( ( (path_start >= drag_start) && (path_end <= drag_end) ) ||
+         ( (path_start < drag_start) && (path_end > drag_end) ) ||
+         ( (path_start < drag_start) && (path_end > drag_start) ) ||
+         ( (path_start < drag_end) && (path_end > drag_end) )          )
+      highlight.push_back(true);
+    else
+      highlight.push_back(false);
+  }
 
-  fl_color(FL_RED);
   fl_line_style(FL_SOLID, 1, NULL);
+  // draw non-highlight paths (ie not in the selection box)
+  highlight_i = highlight.begin();
+  for(i = scaled_pathz.begin(); i != scaled_pathz.end(); ++i)
+  {
+    a_path = *i;
+    y_loc = 10;
+
+    // get window size to determine line width
+    window_size = a_path[0];
+    // make sure width is at least 1  - might be zero to my slack rounding
+    if (window_size == 0)
+      window_size = 1;
+
+    if (!(*highlight_i))
+      for(i2 = seq_num; i2 > 1; i2--)
+      {
+        // RC case handling
+        // ugh, an xor...only want blue if one of the nodes is rc
+        if ( ((a_path[i2] < 0) || (a_path[i2-1] < 0)) &&
+             !((a_path[i2] < 0) && (a_path[i2-1] < 0)) )
+          fl_color(FL_CYAN);
+        else
+          fl_color(FL_MAGENTA);
+          
+        fl_polygon((int)abs(a_path[i2]), y_loc + 3,
+                   (int)abs(a_path[i2])+window_size, y_loc + 3,
+                   (int)abs(a_path[i2-1])+window_size, y_loc + y_seq_incre - 3,
+                   (int)abs(a_path[i2-1]), y_loc + y_seq_incre - 3);
 
+        y_loc += y_seq_incre;
+      }
+    ++highlight_i;
+  }
+
+  // draw highlighted paths (ie in or partially in selection)
+  // drawing these separately and after other paths so they are on top
+  highlight_i = highlight.begin();
   for(i = scaled_pathz.begin(); i != scaled_pathz.end(); ++i)
   {
     a_path = *i;
     y_loc = 10;
-    for(i2 = seq_num - 1; i2 > 0; i2--)
-    {
-      // RC case handling
-      // ugh, and xor...only want blue if one of the nodes is rc
-      if ( ((a_path[i2] < 0) || (a_path[i2-1] < 0)) &&
-           !((a_path[i2] < 0) && (a_path[i2-1] < 0)) )
-        fl_color(FL_BLUE);
-
-      fl_line((int)abs(a_path[i2]),y_loc,(int)abs(a_path[i2-1]),y_loc + y_seq_incre);
-      y_loc += y_seq_incre;
-      fl_color(FL_RED);
-    }
+
+    // get window size to determine line width
+    window_size = a_path[0];
+    // make sure width is at least 1  - might be zero to my slack rounding
+    if (window_size == 0)
+      window_size = 1;
+
+    if (*highlight_i)
+      for(i2 = seq_num; i2 > 1; i2--)
+      {
+        // RC case handling
+        // ugh, an xor...only want blue if one of the nodes is rc
+        if ( ((a_path[i2] < 0) || (a_path[i2-1] < 0)) &&
+             !((a_path[i2] < 0) && (a_path[i2-1] < 0)) )
+          fl_color(FL_BLUE);
+        else
+          fl_color(FL_RED);
+          
+        fl_polygon((int)abs(a_path[i2]), y_loc + 3,
+                   (int)abs(a_path[i2])+window_size, y_loc + 3,
+                   (int)abs(a_path[i2-1])+window_size, y_loc + y_seq_incre - 3,
+                   (int)abs(a_path[i2-1]), y_loc + y_seq_incre - 3);
+
+        y_loc += y_seq_incre;
+      }
+    ++highlight_i;
   }
 
+  // draw sequence representation lines
   fl_color(FL_BLACK);
   fl_line_style(FL_SOLID, 3, NULL);
   y_loc = 10;
@@ -87,21 +170,116 @@ ConnView::draw()
     fl_line(0,y_loc,x_loc,y_loc);
     y_loc += y_seq_incre;
   }
+
+  // draw annotations
+  fl_color(FL_GREEN);
+  fl_line_style(FL_SOLID, 9, NULL);
+  y_loc = 10;
+  for(i2 = seq_num - 1; i2 >= 0; i2--)
+  {
+    for(annot_i = (*S)[i2].annots.begin(); annot_i != (*S)[i2].annots.end(); ++annot_i)
+    {
+      x_start = (int)(annot_i->start / x_scale_factor);
+      x_end = (int)(annot_i->end / x_scale_factor);
+      fl_line(x_start,y_loc,x_end,y_loc);
+    }
+    y_loc += y_seq_incre;
+  }
+
+  // draw selection box
+  if (selected)
+  {
+    fl_color(FL_BLACK);
+    fl_line_style(FL_SOLID, 2, NULL);
+    fl_rect(drag_start, y_loc - y_seq_incre-8, drag_end-drag_start, 16);
+  }
+}
+
+
+
+int
+ConnView::handle(int e)
+{
+  int return_value;
+
+  switch(e)
+  {
+  case FL_PUSH:
+    if (Fl::event_button3())
+    {
+      spawnSeq();
+      return_value = 1;
+    }
+    break;
+  case FL_DRAG:
+    if (!dragging)
+    {
+      drag_start = Fl::event_x() -x();
+      dragging = true;
+      selected = false;
+      return_value = 1;
+    }
+    fl_color(FL_CYAN);
+    fl_line_style(FL_SOLID, 1, NULL);
+    fl_overlay_rect(drag_start, y_seq_incre*(seq_num-1), Fl::event_x()-drag_start, 16);
+    
+    break;
+  case FL_RELEASE:
+    if (dragging)
+    {
+      drag_end = Fl::event_x() - x();
+      dragging = false;
+      selected = true;
+      redraw();
+      return_value = 1;
+    }
+    break;
+  default:
+    return_value = Fl_Widget::handle(e);
+  }
+
+  return return_value;
 }
 
+
 void
 ConnView::spawnSeq()
 {
-  int seq_box_x;
+  list<vector<int> > selected_paths;
+  list<vector<int> >::iterator pathz_i;
+  int i2, i3, y_loc, x_loc, x_start, x_end;
+  vector<int> a_path;
+  list<bool>::iterator highlight_i;
+
+  // make new list of connections that are highlighted
+  selected_paths.clear();
+  highlight_i = highlight.begin();
+  for(pathz_i = P->refined_pathz.begin(); pathz_i != P->refined_pathz.end(); ++pathz_i)
+  {
+    if (*highlight_i)
+    {
+      a_path = *pathz_i;
+      selected_paths.push_back(a_path);
+      //cout << "bing ";
+    }
+    /*
+    else
+      cout << "bang ";
+    */
+    ++highlight_i;
+  }
+
+  //cout << endl;
 
   Fl_Window *seq_window = new Fl_Window(x_max, y_max, "Mussa Sequence");
-  Fl_Scroll *scroll_seq = new Fl_Scroll(0, 0, x_max, y_max);
 
-  seq_box_x = 32000; 
-    //seq_lens[0]*14;
-  SeqView *seq_box = new SeqView(0, 0, seq_box_x, y_max-20);
-  seq_box->setup(ana_name, seq_num, window, S, P, seq_lens);
+
+  SeqView *seq_box = new SeqView(0, 0, x_max, y_max);
+  seq_box->setup(ana_name, seq_num, S, selected_paths, seq_lens);
+  seq_box->debug_draw();
 
   seq_window->end();
   seq_window->show();
 }
+
+