]> git.donarmstrong.com Git - xournal.git/commitdiff
Lasso selection tool; prepare for release 0.4.7
authorauroux <auroux>
Thu, 5 Jul 2012 01:38:24 +0000 (01:38 +0000)
committerauroux <auroux>
Thu, 5 Jul 2012 01:38:24 +0000 (01:38 +0000)
12 files changed:
AUTHORS
ChangeLog
NEWS
README
configure.in
html-doc/manual.html
src/xo-callbacks.c
src/xo-file.c
src/xo-misc.c
src/xo-selection.c
src/xo-selection.h
src/xournal.h

diff --git a/AUTHORS b/AUTHORS
index 7950cc0a06fdef3e495db9c55fdfdfcc18e4b654..ca2d6987156007456e4dd46d1b09e93134631204 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -5,9 +5,9 @@ The source code includes contributions by the following people:
 Alvaro, Kit Barnes, Eduardo de Barros Lima, Mathieu Bouchard, 
 Ole Joergen Broenner, Robert Buchholz, Vincenzo Ciancia, Luca de Cicco, 
 Michele Codutti, Robert Gerlach, Daniel German, Dirk Gerrits, Simon Guest,
 Alvaro, Kit Barnes, Eduardo de Barros Lima, Mathieu Bouchard, 
 Ole Joergen Broenner, Robert Buchholz, Vincenzo Ciancia, Luca de Cicco, 
 Michele Codutti, Robert Gerlach, Daniel German, Dirk Gerrits, Simon Guest,
-Lukasz Kaiser, Timo Kluck, David Kolibac, Danny Kukawka, Stefan Lembach
-Bob McElrath, Andy Neitzke, David Planella, Marco Poletti, Alex Ray
-Jean-Baptiste Rouquier, Victor Saase, Marco Souza, Mike Ter Louw, 
+Lukasz Kaiser, Ian Woo Kim, Timo Kluck, David Kolibac, Danny Kukawka
+Stefan Lembach, Bob McElrath, Andy Neitzke, David Planella, Marco Poletti
+Alex Ray, Jean-Baptiste Rouquier, Victor Saase, Marco Souza, Mike Ter Louw, 
 Uwe Winter, Lu Zhihe.
 
 (Let me know if you are missing from this list or if your name is 
 Uwe Winter, Lu Zhihe.
 
 (Let me know if you are missing from this list or if your name is 
index 43c50f0e56ef8d1f83dc5070ede9adec50413b96..9b72ce144a545517ffadb94b971c8c7ec56c77b8 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,7 +1,8 @@
-This version:
+Version 0.4.7 (July 4, 2012):
   - insert image tool (based on patches by Victor Saase and Simon Guest)
   - renamed "Journal" menu to "Page"
   - paste images and text directly from and to other applications
   - insert image tool (based on patches by Victor Saase and Simon Guest)
   - renamed "Journal" menu to "Page"
   - paste images and text directly from and to other applications
+  - lasso tool (based on patch by Ian Woo Kim)
 
 Version 0.4.6 (May 22, 2012):
   - win32 portability code (contributed by Dirk Gerrits)
 
 Version 0.4.6 (May 22, 2012):
   - win32 portability code (contributed by Dirk Gerrits)
diff --git a/NEWS b/NEWS
index ad92faf213608efbbd6b0379c6f482bec5254ece..37cbe88fe37fd54433af43e61c9590a9fcfc8a76 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,4 @@
-Version 0.4.6 (May 22, 2012)
-
-This release catches up with changes accumulated in the cvs repository.
+Version 0.4.7 (July 4, 2012)
 
 Installation:  see INSTALL
 User's manual: see html-doc/manual.html
 
 Installation:  see INSTALL
 User's manual: see html-doc/manual.html
diff --git a/README b/README
index ad92faf213608efbbd6b0379c6f482bec5254ece..37cbe88fe37fd54433af43e61c9590a9fcfc8a76 100644 (file)
--- a/README
+++ b/README
@@ -1,6 +1,4 @@
-Version 0.4.6 (May 22, 2012)
-
-This release catches up with changes accumulated in the cvs repository.
+Version 0.4.7 (July 4, 2012)
 
 Installation:  see INSTALL
 User's manual: see html-doc/manual.html
 
 Installation:  see INSTALL
 User's manual: see html-doc/manual.html
index 99d500bb64b838b1453fb8ec8e6686a1e82260af..1af1b0d92237f767005a9797763cf806f56e96ed 100644 (file)
@@ -1,7 +1,7 @@
 dnl Process this file with autoconf to produce a configure script.
 
 AC_INIT(configure.in)
 dnl Process this file with autoconf to produce a configure script.
 
 AC_INIT(configure.in)
-AM_INIT_AUTOMAKE(xournal, 0.4.6+image)
+AM_INIT_AUTOMAKE(xournal, 0.4.7)
 AM_CONFIG_HEADER(config.h)
 AM_MAINTAINER_MODE
 
 AM_CONFIG_HEADER(config.h)
 AM_MAINTAINER_MODE
 
index 8a257e683eccc8f7678297bdb2477ee02af87bce..743d81e73230c555f877b397fddc25a372f9d29a 100644 (file)
@@ -24,7 +24,7 @@
   Xournal User's Manual
 </h2>
 <p style="font-size: 0.95em; text-align: center; color: rgb(0,0,0)">
   Xournal User's Manual
 </h2>
 <p style="font-size: 0.95em; text-align: center; color: rgb(0,0,0)">
- Version 0.4.6
+ Version 0.4.7
 </p>
 <hr />
 <p>
 </p>
 <hr />
 <p>
@@ -148,6 +148,15 @@ the Tools menu):
   that the typesetting of the text may be slightly different in the
   printout.
 </p>
   that the typesetting of the text may be slightly different in the
   printout.
 </p>
+<h3 class="subsub"> The image tool</h3>
+<p>
+  To insert a new image (from a file on disk), click at the location 
+  where the upper-left corner is to be located. A file selection dialog
+  box pops up. Alternatively, images can be pasted directly from the
+  clipboard (without having to select the image tool). In both cases,
+  the newly inserted image is selected, and can be easily moved or resized
+  as with any selection.
+</p>
 <h3 class="subsub"><img src="pixmaps/ruler.png"> The ruler</h3>
 <p>
   The ruler is not a tool by itself, but rather a special operating mode
 <h3 class="subsub"><img src="pixmaps/ruler.png"> The ruler</h3>
 <p>
   The ruler is not a tool by itself, but rather a special operating mode
@@ -217,6 +226,13 @@ the Tools menu):
   or to a different journal) using the copy-paste toolbar buttons or the
   corresponding entries of the Edit menu.
 </p>
   or to a different journal) using the copy-paste toolbar buttons or the
   corresponding entries of the Edit menu.
 </p>
+<h3 class="subsub"><img src="pixmaps/lasso.png"> Lasso selection</h3>
+<p>
+  This tool lets you select an irregular shaped region of the current layer.
+  All the items which are entirely contained within the given region
+  are selected. As with the rectangle selection tool, the selection can be moved,
+  resized, copied and pasted.
+</p>
 <h3 class="subsub"><img src="pixmaps/stretch.png"> Vertical space</h3>
 <p>
   This tool lets you insert or remove vertical space within the page:
 <h3 class="subsub"><img src="pixmaps/stretch.png"> Vertical space</h3>
 <p>
   This tool lets you insert or remove vertical space within the page:
@@ -702,10 +718,11 @@ Xournal is written by Denis Auroux
 The source code includes contributions by the following people: 
 Alvaro, Kit Barnes, Eduardo de Barros Lima, Mathieu Bouchard, 
 Ole J&oslash;rgen Br&oslash;nner, Robert Buchholz, Vincenzo Ciancia, Luca de Cicco, 
 The source code includes contributions by the following people: 
 Alvaro, Kit Barnes, Eduardo de Barros Lima, Mathieu Bouchard, 
 Ole J&oslash;rgen Br&oslash;nner, Robert Buchholz, Vincenzo Ciancia, Luca de Cicco, 
-Michele Codutti, Robert Gerlach, Daniel German, Dirk Gerrits,
-Lukasz Kaiser, Timo Kluck, David Kolibac, Danny Kukawka, Stefan Lembach, 
-Bob McElrath,  Andy Neitzke, David Planella, Marco Poletti, Alex Ray, 
-Jean-Baptiste Rouquier, Marco Souza, Mike Ter Louw, Uwe Winter, Lu Zhihe.
+Michele Codutti, Robert Gerlach, Daniel German, Dirk Gerrits, Simon Guest,
+Lukasz Kaiser, Ian Woo Kim, Timo Kluck, David Kolibac, Danny Kukawka, 
+Stefan Lembach, Bob McElrath, Andy Neitzke, David Planella, Marco Poletti, 
+Alex Ray, Jean-Baptiste Rouquier, Victor Saase, Marco Souza, Mike Ter Louw, 
+Uwe Winter, Lu Zhihe.
 </p>
 <p style="font-size:0.9em">(Let me know if you are missing from this list or
 if your name is mis-spelled)</p>
 </p>
 <p style="font-size:0.9em">(Let me know if you are missing from this list or
 if your name is mis-spelled)</p>
@@ -734,6 +751,15 @@ Bug reports and suggestions can also be submitted on Xournal's
 <a name="changelog"></a>
 <h2 class="subtitle">Version history</h2>
 <p>
 <a name="changelog"></a>
 <h2 class="subtitle">Version history</h2>
 <p>
+Version 0.4.7 (July 4, 2012):
+<ul>
+     <li>insert image tool (based on patches by Victor Saase and Simon Guest)
+</li><li>renamed "Journal" menu to "Page"
+</li><li>paste images and text directly from and to other applications
+</li><li>lasso tool (based on patch by Ian Woo Kim)
+</ul>
+</p>
+<p>
 Version 0.4.6 (May 22, 2012):
 <ul>
      <li>win32 portability code (contributed by Dirk Gerrits)
 Version 0.4.6 (May 22, 2012):
 <ul>
      <li>win32 portability code (contributed by Dirk Gerrits)
@@ -1080,6 +1106,15 @@ The contents of the text are encoded in UTF-8, with the characters
 no extraneous whitespace should be inserted between the enclosing tags
 and the text itself).
 </p>
 no extraneous whitespace should be inserted between the enclosing tags
 and the text itself).
 </p>
+<p>Starting with version 0.4.7, layers can also contain image items.
+The format of an image item is:
+<pre>&lt;image left="..." top="..." right="..." bottom="..."&gt;... data ...&lt;/image&gt;
+</pre>
+The <i>left</i>, <i>top</i>, <i>right</i> and <i>bottom</i> attributes
+specify the bounding box to which the image is scaled, in page coordinates
+(measured in points from the top-left corner). The data is in base64-encoded
+PNG format (though any other base64-encoded format that can be loaded by
+gdk-pixbuf is currently accepted).
 <hr />
 <a name="installation"></a>
 <h2 class="subtitle">Installation issues</h2>
 <hr />
 <a name="installation"></a>
 <h2 class="subtitle">Installation issues</h2>
index 8c6f098a1cdc88566305da6b6181386ad3960a0d..50672f6b14737a2edbf462266894798a12ffbd1d 100644 (file)
@@ -33,6 +33,7 @@
 #include "xo-misc.h"
 #include "xo-file.h"
 #include "xo-paint.h"
 #include "xo-misc.h"
 #include "xo-file.h"
 #include "xo-paint.h"
+#include "xo-selection.h"
 #include "xo-print.h"
 #include "xo-shapes.h"
 
 #include "xo-print.h"
 #include "xo-shapes.h"
 
@@ -1807,7 +1808,25 @@ void
 on_toolsSelectRegion_activate          (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
 on_toolsSelectRegion_activate          (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
-
+  if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_RADIO_MENU_ITEM) {
+    if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem)))
+      return;
+  } else {
+    if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem)))
+      return;
+  }
+  
+  if (ui.cur_mapping != 0 && !ui.button_switch_mapping) return; // not user-generated
+  if (ui.toolno[ui.cur_mapping] == TOOL_SELECTREGION) return;
+  
+  ui.cur_mapping = 0; // don't use switch_mapping() (refreshes buttons too soon)
+  end_text();
+  ui.toolno[ui.cur_mapping] = TOOL_SELECTREGION;
+  update_mapping_linkings(-1);
+  update_tool_buttons();
+  update_tool_menu();
+  update_color_menu();
+  update_cursor();
 }
 
 
 }
 
 
@@ -2520,6 +2539,9 @@ on_canvas_button_press_event           (GtkWidget       *widget,
     do_eraser((GdkEvent *)event, ui.cur_brush->thickness/2,
                ui.cur_brush->tool_options == TOOLOPT_ERASER_STROKES);
   }
     do_eraser((GdkEvent *)event, ui.cur_brush->thickness/2,
                ui.cur_brush->tool_options == TOOLOPT_ERASER_STROKES);
   }
+  else if (ui.toolno[mapping] == TOOL_SELECTREGION) {
+    start_selectregion((GdkEvent *)event);
+  }
   else if (ui.toolno[mapping] == TOOL_SELECTRECT) {
     start_selectrect((GdkEvent *)event);
   }
   else if (ui.toolno[mapping] == TOOL_SELECTRECT) {
     start_selectrect((GdkEvent *)event);
   }
@@ -2564,6 +2586,9 @@ on_canvas_button_release_event         (GtkWidget       *widget,
   else if (ui.cur_item_type == ITEM_ERASURE) {
     finalize_erasure();
   }
   else if (ui.cur_item_type == ITEM_ERASURE) {
     finalize_erasure();
   }
+  else if (ui.cur_item_type == ITEM_SELECTREGION) {
+    finalize_selectregion();
+  }
   else if (ui.cur_item_type == ITEM_SELECTRECT) {
     finalize_selectrect();
   }
   else if (ui.cur_item_type == ITEM_SELECTRECT) {
     finalize_selectrect();
   }
@@ -2756,6 +2781,9 @@ on_canvas_motion_notify_event          (GtkWidget       *widget,
     else if (ui.cur_item_type == ITEM_ERASURE) {
       finalize_erasure();
     }
     else if (ui.cur_item_type == ITEM_ERASURE) {
       finalize_erasure();
     }
+    else if (ui.cur_item_type == ITEM_SELECTREGION) {
+      finalize_selectregion();
+    }
     else if (ui.cur_item_type == ITEM_SELECTRECT) {
       finalize_selectrect();
     }
     else if (ui.cur_item_type == ITEM_SELECTRECT) {
       finalize_selectrect();
     }
@@ -2779,6 +2807,9 @@ on_canvas_motion_notify_event          (GtkWidget       *widget,
     do_eraser((GdkEvent *)event, ui.cur_brush->thickness/2,
                ui.cur_brush->tool_options == TOOLOPT_ERASER_STROKES);
   }
     do_eraser((GdkEvent *)event, ui.cur_brush->thickness/2,
                ui.cur_brush->tool_options == TOOLOPT_ERASER_STROKES);
   }
+  else if (ui.cur_item_type == ITEM_SELECTREGION) {
+    continue_selectregion((GdkEvent *)event);
+  }
   else if (ui.cur_item_type == ITEM_SELECTRECT) {
     get_pointer_coords((GdkEvent *)event, pt);
     ui.selection->bbox.right = pt[0];
   else if (ui.cur_item_type == ITEM_SELECTRECT) {
     get_pointer_coords((GdkEvent *)event, pt);
     ui.selection->bbox.right = pt[0];
index 129ba87873f8cf920491278c554178bfb9cccbf9..082d399f36c3d4d26ae9bc7970d9a685ae091cb6 100644 (file)
@@ -45,7 +45,7 @@
 #include "xo-paint.h"
 #include "xo-image.h"
 
 #include "xo-paint.h"
 #include "xo-image.h"
 
-const char *tool_names[NUM_TOOLS] = {"pen", "eraser", "highlighter", "text", "", "selectrect", "vertspace", "hand", "image"};
+const char *tool_names[NUM_TOOLS] = {"pen", "eraser", "highlighter", "text", "selectregion", "selectrect", "vertspace", "hand", "image"};
 const char *color_names[COLOR_MAX] = {"black", "blue", "red", "green",
    "gray", "lightblue", "lightgreen", "magenta", "orange", "yellow", "white"};
 const char *bgtype_names[3] = {"solid", "pixmap", "pdf"};
 const char *color_names[COLOR_MAX] = {"black", "blue", "red", "green",
    "gray", "lightblue", "lightgreen", "magenta", "orange", "yellow", "white"};
 const char *bgtype_names[3] = {"solid", "pixmap", "pdf"};
@@ -1709,7 +1709,7 @@ void save_config_to_file(void)
     g_strdup_printf("%d", PDFTOPPM_PRINTING_DPI));
 
   update_keyval("tools", "startup_tool",
     g_strdup_printf("%d", PDFTOPPM_PRINTING_DPI));
 
   update_keyval("tools", "startup_tool",
-    _(" selected tool at startup (pen, eraser, highlighter, selectrect, vertspace, hand)"),
+    _(" selected tool at startup (pen, eraser, highlighter, selectregion, selectrect, vertspace, hand, image)"),
     g_strdup(tool_names[ui.startuptool]));
   update_keyval("tools", "pen_color",
     _(" default pen color"),
     g_strdup(tool_names[ui.startuptool]));
   update_keyval("tools", "pen_color",
     _(" default pen color"),
@@ -1746,7 +1746,7 @@ void save_config_to_file(void)
     _(" default highlighter is in shape recognizer mode (true/false)"),
     g_strdup(ui.default_brushes[TOOL_HIGHLIGHTER].recognizer?"true":"false"));
   update_keyval("tools", "btn2_tool",
     _(" default highlighter is in shape recognizer mode (true/false)"),
     g_strdup(ui.default_brushes[TOOL_HIGHLIGHTER].recognizer?"true":"false"));
   update_keyval("tools", "btn2_tool",
-    _(" button 2 tool (pen, eraser, highlighter, text, selectrect, vertspace, hand)"),
+    _(" button 2 tool (pen, eraser, highlighter, text, selectregion, selectrect, vertspace, hand, image)"),
     g_strdup(tool_names[ui.toolno[1]]));
   update_keyval("tools", "btn2_linked",
     _(" button 2 brush linked to primary brush (true/false) (overrides all other settings)"),
     g_strdup(tool_names[ui.toolno[1]]));
   update_keyval("tools", "btn2_linked",
     _(" button 2 brush linked to primary brush (true/false) (overrides all other settings)"),
@@ -1774,7 +1774,7 @@ void save_config_to_file(void)
     _(" button 2 eraser mode (eraser only)"),
     g_strdup_printf("%d", ui.brushes[1][TOOL_ERASER].tool_options));
   update_keyval("tools", "btn3_tool",
     _(" button 2 eraser mode (eraser only)"),
     g_strdup_printf("%d", ui.brushes[1][TOOL_ERASER].tool_options));
   update_keyval("tools", "btn3_tool",
-    _(" button 3 tool (pen, eraser, highlighter, text, selectrect, vertspace, hand)"),
+    _(" button 3 tool (pen, eraser, highlighter, text, selectregion, selectrect, vertspace, hand, image)"),
     g_strdup(tool_names[ui.toolno[2]]));
   update_keyval("tools", "btn3_linked",
     _(" button 3 brush linked to primary brush (true/false) (overrides all other settings)"),
     g_strdup(tool_names[ui.toolno[2]]));
   update_keyval("tools", "btn3_linked",
     _(" button 3 brush linked to primary brush (true/false) (overrides all other settings)"),
index bd65f1afbede9a8a3a9cde569a3c0a197a1cb581..3d866cf37da202002da89588a5711ceeb5d1f6e3 100644 (file)
@@ -2082,8 +2082,8 @@ void allow_all_accels(void)
       "can-activate-accel", G_CALLBACK(can_accel), NULL);
   g_signal_connect((gpointer) GET_COMPONENT("toolsText"),
       "can-activate-accel", G_CALLBACK(can_accel), NULL);
       "can-activate-accel", G_CALLBACK(can_accel), NULL);
   g_signal_connect((gpointer) GET_COMPONENT("toolsText"),
       "can-activate-accel", G_CALLBACK(can_accel), NULL);
-/*  g_signal_connect((gpointer) GET_COMPONENT("toolsSelectRegion"),
-      "can-activate-accel", G_CALLBACK(can_accel), NULL);  */
+  g_signal_connect((gpointer) GET_COMPONENT("toolsSelectRegion"),
+      "can-activate-accel", G_CALLBACK(can_accel), NULL);
   g_signal_connect((gpointer) GET_COMPONENT("toolsSelectRectangle"),
       "can-activate-accel", G_CALLBACK(can_accel), NULL);
   g_signal_connect((gpointer) GET_COMPONENT("toolsVerticalSpace"),
   g_signal_connect((gpointer) GET_COMPONENT("toolsSelectRectangle"),
       "can-activate-accel", G_CALLBACK(can_accel), NULL);
   g_signal_connect((gpointer) GET_COMPONENT("toolsVerticalSpace"),
@@ -2145,10 +2145,6 @@ void hide_unimplemented(void)
 {
   gtk_widget_hide(GET_COMPONENT("filePrintOptions"));
   gtk_widget_hide(GET_COMPONENT("journalFlatten"));  
 {
   gtk_widget_hide(GET_COMPONENT("filePrintOptions"));
   gtk_widget_hide(GET_COMPONENT("journalFlatten"));  
-  gtk_widget_hide(GET_COMPONENT("toolsSelectRegion"));
-  gtk_widget_hide(GET_COMPONENT("buttonSelectRegion"));
-  gtk_widget_hide(GET_COMPONENT("button2SelectRegion"));
-  gtk_widget_hide(GET_COMPONENT("button3SelectRegion"));
   gtk_widget_hide(GET_COMPONENT("helpIndex")); 
 
   /* config file only works with glib 2.6 and beyond */
   gtk_widget_hide(GET_COMPONENT("helpIndex")); 
 
   /* config file only works with glib 2.6 and beyond */
index 9b35864566acb5769e9902767bc60cee841bdd61..5816bb6fd6d8c291a7a73ae977dcdfaae3dd4918 100644 (file)
@@ -22,6 +22,8 @@
 #include <gtk/gtk.h>
 #include <libgnomecanvas/libgnomecanvas.h>
 #include <libart_lgpl/art_vpath_dash.h>
 #include <gtk/gtk.h>
 #include <libgnomecanvas/libgnomecanvas.h>
 #include <libart_lgpl/art_vpath_dash.h>
+#include <libart_lgpl/art_svp_point.h>
+#include <libart_lgpl/art_svp_vpath.h>
 
 #include "xournal.h"
 #include "xo-callbacks.h"
 
 #include "xournal.h"
 #include "xo-callbacks.h"
@@ -74,7 +76,6 @@ void finalize_selectrect(void)
   double x1, x2, y1, y2;
   GList *itemlist;
   struct Item *item;
   double x1, x2, y1, y2;
   GList *itemlist;
   struct Item *item;
-
   
   ui.cur_item_type = ITEM_NONE;
 
   
   ui.cur_item_type = ITEM_NONE;
 
@@ -119,6 +120,156 @@ void finalize_selectrect(void)
   update_font_button();
 }
 
   update_font_button();
 }
 
+
+void start_selectregion(GdkEvent *event)
+{
+  double pt[2];
+  reset_selection();
+  
+  ui.cur_item_type = ITEM_SELECTREGION;
+  ui.selection = g_new(struct Selection, 1);
+  ui.selection->type = ITEM_SELECTREGION;
+  ui.selection->items = NULL;
+  ui.selection->layer = ui.cur_layer;
+
+  get_pointer_coords(event, pt);
+  ui.selection->bbox.left = ui.selection->bbox.right = pt[0];
+  ui.selection->bbox.top = ui.selection->bbox.bottom = pt[1];
+  
+  realloc_cur_path(1);
+  ui.cur_path.num_points = 1;
+  ui.cur_path.coords[0] = ui.cur_path.coords[2] = pt[0];
+  ui.cur_path.coords[1] = ui.cur_path.coords[3] = pt[1];
+  ui.selection->canvas_item = gnome_canvas_item_new(ui.cur_layer->group,
+      gnome_canvas_polygon_get_type(), "width-pixels", 1, 
+      "outline-color-rgba", 0x000000ff,
+      "fill-color-rgba", 0x80808040,
+      NULL);
+  make_dashed(ui.selection->canvas_item);
+  update_cursor();
+}
+
+void continue_selectregion(GdkEvent *event)
+{
+  double *pt;
+  
+  realloc_cur_path(ui.cur_path.num_points+1);
+  pt = ui.cur_path.coords + 2*ui.cur_path.num_points;
+  get_pointer_coords(event, pt);
+  if (hypot(pt[0]-pt[-2], pt[1]-pt[-1]) < PIXEL_MOTION_THRESHOLD/ui.zoom)
+    return; // not a meaningful motion
+  ui.cur_path.num_points++;
+  if (ui.cur_path.num_points>2)
+    gnome_canvas_item_set(ui.selection->canvas_item, 
+     "points", &ui.cur_path, NULL);
+}
+
+/* check whether a point, resp. an item, is inside a lasso selection */
+
+gboolean hittest_point(ArtSVP *lassosvp, double x, double y)
+{
+  return art_svp_point_wind(lassosvp, x, y)%2;
+}
+
+gboolean hittest_item(ArtSVP *lassosvp, struct Item *item)
+{
+  int i;
+  
+  if (item->type == ITEM_STROKE) {
+    for (i=0; i<item->path->num_points; i++)
+      if (!hittest_point(lassosvp, item->path->coords[2*i], item->path->coords[2*i+1])) 
+        return FALSE;
+    return TRUE;
+  }
+  else 
+    return (hittest_point(lassosvp, item->bbox.left, item->bbox.top) &&
+            hittest_point(lassosvp, item->bbox.right, item->bbox.top) &&
+            hittest_point(lassosvp, item->bbox.left, item->bbox.bottom) &&
+            hittest_point(lassosvp, item->bbox.right, item->bbox.bottom));
+}
+
+void finalize_selectregion(void)
+{
+  GList *itemlist;
+  struct Item *item;
+  ArtVpath *vpath;
+  ArtSVP *lassosvp;
+  int i, n;
+  double *pt;
+  
+  ui.cur_item_type = ITEM_NONE;
+  
+  // build SVP for the lasso path
+  n = ui.cur_path.num_points;
+  vpath = g_malloc((n+2)*sizeof(ArtVpath));
+  for (i=0; i<n; i++) { 
+    vpath[i].x = ui.cur_path.coords[2*i];
+    vpath[i].y = ui.cur_path.coords[2*i+1];
+  }
+  vpath[n].x = vpath[0].x; vpath[n].y = vpath[0].y;
+  vpath[0].code = ART_MOVETO;
+  for (i=1; i<=n; i++) vpath[i].code = ART_LINETO;
+  vpath[n+1].code = ART_END;
+  lassosvp = art_svp_from_vpath(vpath);
+  g_free(vpath);
+
+  // see which items we selected
+  for (itemlist = ui.selection->layer->items; itemlist!=NULL; itemlist = itemlist->next) {
+    item = (struct Item *)itemlist->data;
+    if (hittest_item(lassosvp, item)) {
+      // update the selection bbox
+      if (ui.selection->items==NULL || ui.selection->bbox.left>item->bbox.left)
+        ui.selection->bbox.left = item->bbox.left;
+      if (ui.selection->items==NULL || ui.selection->bbox.right<item->bbox.right)
+        ui.selection->bbox.right = item->bbox.right;
+      if (ui.selection->items==NULL || ui.selection->bbox.top>item->bbox.top)
+        ui.selection->bbox.top = item->bbox.top;
+      if (ui.selection->items==NULL || ui.selection->bbox.bottom<item->bbox.bottom)
+        ui.selection->bbox.bottom = item->bbox.bottom;
+      // add the item
+      ui.selection->items = g_list_append(ui.selection->items, item); 
+    }
+  }
+  art_svp_free(lassosvp);
+  
+  if (ui.selection->items == NULL) {
+    // if we clicked inside a text zone or image?
+    pt = ui.cur_path.coords; 
+    item = click_is_in_text_or_image(ui.selection->layer, pt[0], pt[1]);
+    if (item!=NULL) {
+      for (i=0; i<n; i++, pt+=2) {
+        if (pt[0]<item->bbox.left || pt[0]>item->bbox.right || pt[1]<item->bbox.top || pt[1]>item->bbox.bottom)
+          { item = NULL; break; }
+      }
+    }
+    if (item!=NULL) {
+      ui.selection->items = g_list_append(ui.selection->items, item);
+      g_memmove(&(ui.selection->bbox), &(item->bbox), sizeof(struct BBox));
+    }
+  }
+
+  if (ui.selection->items == NULL) reset_selection();
+  else { // make a selection rectangle instead of the lasso shape
+    gtk_object_destroy(GTK_OBJECT(ui.selection->canvas_item));
+    ui.selection->canvas_item = gnome_canvas_item_new(ui.cur_layer->group,
+      gnome_canvas_rect_get_type(), "width-pixels", 1, 
+      "outline-color-rgba", 0x000000ff,
+      "fill-color-rgba", 0x80808040,
+      "x1", ui.selection->bbox.left, "x2", ui.selection->bbox.right, 
+      "y1", ui.selection->bbox.top, "y2", ui.selection->bbox.bottom, NULL);
+    make_dashed(ui.selection->canvas_item);
+    ui.selection->type = ITEM_SELECTRECT;
+  }
+
+  update_cursor();
+  update_copy_paste_enabled();
+  update_font_button();
+}
+
+
+/*** moving/resizing the selection ***/
+
 gboolean start_movesel(GdkEvent *event)
 {
   double pt[2];
 gboolean start_movesel(GdkEvent *event)
 {
   double pt[2];
@@ -127,7 +278,7 @@ gboolean start_movesel(GdkEvent *event)
   if (ui.cur_layer != ui.selection->layer) return FALSE;
   
   get_pointer_coords(event, pt);
   if (ui.cur_layer != ui.selection->layer) return FALSE;
   
   get_pointer_coords(event, pt);
-  if (ui.selection->type == ITEM_SELECTRECT) {
+  if (ui.selection->type == ITEM_SELECTRECT || ui.selection->type == ITEM_SELECTREGION) {
     if (pt[0]<ui.selection->bbox.left || pt[0]>ui.selection->bbox.right ||
         pt[1]<ui.selection->bbox.top  || pt[1]>ui.selection->bbox.bottom)
       return FALSE;
     if (pt[0]<ui.selection->bbox.left || pt[0]>ui.selection->bbox.right ||
         pt[1]<ui.selection->bbox.top  || pt[1]>ui.selection->bbox.bottom)
       return FALSE;
@@ -154,7 +305,7 @@ gboolean start_resizesel(GdkEvent *event)
 
   get_pointer_coords(event, pt);
 
 
   get_pointer_coords(event, pt);
 
-  if (ui.selection->type == ITEM_SELECTRECT) {
+  if (ui.selection->type == ITEM_SELECTRECT || ui.selection->type == ITEM_SELECTREGION) {
     resize_margin = RESIZE_MARGIN/ui.zoom;
     hmargin = (ui.selection->bbox.right-ui.selection->bbox.left)*0.3;
     if (hmargin>resize_margin) hmargin = resize_margin;
     resize_margin = RESIZE_MARGIN/ui.zoom;
     hmargin = (ui.selection->bbox.right-ui.selection->bbox.left)*0.3;
     if (hmargin>resize_margin) hmargin = resize_margin;
index bf5bce4ac39d7e72b6fd32ab3f1c5950ca6c227c..df1006ab45f51dd6b34a46aab48e8e8b58a34478 100644 (file)
@@ -16,6 +16,9 @@
 
 void start_selectrect(GdkEvent *event);
 void finalize_selectrect(void);
 
 void start_selectrect(GdkEvent *event);
 void finalize_selectrect(void);
+void start_selectregion(GdkEvent *event);
+void finalize_selectregion(void);
+void continue_selectregion(GdkEvent *event);
 
 gboolean start_movesel(GdkEvent *event);
 void start_vertspace(GdkEvent *event);
 
 gboolean start_movesel(GdkEvent *event);
 void start_vertspace(GdkEvent *event);
index 9f801cc7154fe2a0ce7ebf49d8ebe4c320a6d606..9d9064e34c00a0ab96be2204b4fd9d34efccbe2d 100644 (file)
@@ -207,6 +207,7 @@ typedef struct Item {
 #define ITEM_RESIZESEL 22
 #define ITEM_RECOGNIZER 23
 #define ITEM_IMAGE 24
 #define ITEM_RESIZESEL 22
 #define ITEM_RECOGNIZER 23
 #define ITEM_IMAGE 24
+#define ITEM_SELECTREGION 25
 
 typedef struct Layer {
   GList *items; // the items on the layer, from bottom to top
 
 typedef struct Layer {
   GList *items; // the items on the layer, from bottom to top
@@ -230,7 +231,7 @@ typedef struct Journal {
 } Journal;
 
 typedef struct Selection {
 } Journal;
 
 typedef struct Selection {
-  int type;  // ITEM_SELECTRECT, ITEM_MOVESEL_VERT
+  int type;  // ITEM_SELECTRECT, ITEM_MOVESEL_VERT, ITEM_SELECTREGION
   BBox bbox; // the rectangle bbox of the selection
   struct Layer *layer; // the layer on which the selection lives
   double anchor_x, anchor_y, last_x, last_y; // for selection motion
   BBox bbox; // the rectangle bbox of the selection
   struct Layer *layer; // the layer on which the selection lives
   double anchor_x, anchor_y, last_x, last_y; // for selection motion