mirror of
https://github.com/ruby-opencv/ruby-opencv
synced 2023-03-27 23:22:12 -04:00
fixed Window to handle MouseEvent with propriety
This commit is contained in:
parent
6be99de63c
commit
81714f0768
8 changed files with 182 additions and 59 deletions
|
@ -117,7 +117,7 @@ VALUE rb_event(VALUE self)
|
|||
VALUE
|
||||
rb_left_button_q(VALUE self)
|
||||
{
|
||||
return MOUSEEVENT(self)->flag & CV_EVENT_FLAG_LBUTTON ? Qtrue : Qfalse;
|
||||
return MOUSEEVENT(self)->flags & CV_EVENT_FLAG_LBUTTON ? Qtrue : Qfalse;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -126,7 +126,7 @@ rb_left_button_q(VALUE self)
|
|||
VALUE
|
||||
rb_right_button_q(VALUE self)
|
||||
{
|
||||
return MOUSEEVENT(self)->flag & CV_EVENT_FLAG_RBUTTON ? Qtrue : Qfalse;
|
||||
return MOUSEEVENT(self)->flags & CV_EVENT_FLAG_RBUTTON ? Qtrue : Qfalse;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -135,7 +135,7 @@ rb_right_button_q(VALUE self)
|
|||
VALUE
|
||||
rb_middle_button_q(VALUE self)
|
||||
{
|
||||
return MOUSEEVENT(self)->flag & CV_EVENT_FLAG_MBUTTON ? Qtrue : Qfalse;
|
||||
return MOUSEEVENT(self)->flags & CV_EVENT_FLAG_MBUTTON ? Qtrue : Qfalse;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -144,7 +144,7 @@ rb_middle_button_q(VALUE self)
|
|||
VALUE
|
||||
rb_ctrl_key_q(VALUE self)
|
||||
{
|
||||
return MOUSEEVENT(self)->flag & CV_EVENT_FLAG_CTRLKEY ? Qtrue : Qfalse;
|
||||
return MOUSEEVENT(self)->flags & CV_EVENT_FLAG_CTRLKEY ? Qtrue : Qfalse;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -153,7 +153,7 @@ rb_ctrl_key_q(VALUE self)
|
|||
VALUE
|
||||
rb_shift_key_q(VALUE self)
|
||||
{
|
||||
return MOUSEEVENT(self)->flag & CV_EVENT_FLAG_SHIFTKEY ? Qtrue : Qfalse;
|
||||
return MOUSEEVENT(self)->flags & CV_EVENT_FLAG_SHIFTKEY ? Qtrue : Qfalse;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -162,18 +162,18 @@ rb_shift_key_q(VALUE self)
|
|||
VALUE
|
||||
rb_alt_key_q(VALUE self)
|
||||
{
|
||||
return MOUSEEVENT(self)->flag & CV_EVENT_FLAG_ALTKEY ? Qtrue : Qfalse;
|
||||
return MOUSEEVENT(self)->flags & CV_EVENT_FLAG_ALTKEY ? Qtrue : Qfalse;
|
||||
}
|
||||
|
||||
VALUE
|
||||
new_object(int flag, int y, int x, int event)
|
||||
new_object(int event, int x, int y, int flags)
|
||||
{
|
||||
VALUE object = rb_allocate(rb_class());
|
||||
MouseEvent *mouseevent = MOUSEEVENT(object);
|
||||
mouseevent->point.x = x;
|
||||
mouseevent->point.y = y;
|
||||
mouseevent->event = event;
|
||||
mouseevent->flag = flag;
|
||||
mouseevent->flags = flags;
|
||||
return object;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ __NAMESPACE_BEGIN_MOUSEEVENT
|
|||
typedef struct MouseEvent {
|
||||
CvPoint point;
|
||||
int event;
|
||||
int flag;
|
||||
int flags;
|
||||
} MouseEvent;
|
||||
|
||||
VALUE rb_class();
|
||||
|
|
|
@ -409,6 +409,9 @@ define_ruby_module()
|
|||
rb_define_const(rb_module, "CV_FM_8POINT", INT2FIX(CV_FM_8POINT));
|
||||
rb_define_const(rb_module, "CV_FM_RANSAC", INT2FIX(CV_FM_RANSAC));
|
||||
rb_define_const(rb_module, "CV_FM_LMEDS", INT2FIX(CV_FM_LMEDS));
|
||||
|
||||
/* Flags of window */
|
||||
rb_define_const(rb_module, "CV_WINDOW_AUTOSIZE", INT2FIX(CV_WINDOW_AUTOSIZE));
|
||||
|
||||
VALUE inversion_method = rb_hash_new();
|
||||
/* {:lu, :svd, :svd_sym(:svd_symmetric)}: Inversion method */
|
||||
|
|
|
@ -30,8 +30,7 @@ GET_WINDOW_NAME(VALUE object)
|
|||
void *handle = DATA_PTR(object);
|
||||
if (!handle)
|
||||
rb_raise(rb_eStandardError, "window handle error");
|
||||
const char *window_name = cvGetWindowName(handle);
|
||||
return window_name;
|
||||
return (const char*)cvGetWindowName(handle);
|
||||
}
|
||||
|
||||
st_table *windows = st_init_numtable();
|
||||
|
@ -64,10 +63,10 @@ define_ruby_class()
|
|||
rb_define_singleton_method(rb_klass, "destroy_all", RUBY_METHOD_FUNC(rb_destroy_all), 0);
|
||||
rb_define_method(rb_klass, "resize", RUBY_METHOD_FUNC(rb_resize), -1);
|
||||
rb_define_method(rb_klass, "move", RUBY_METHOD_FUNC(rb_move), -1);
|
||||
rb_define_method(rb_klass, "show_image", RUBY_METHOD_FUNC(rb_show_image), 1);
|
||||
rb_define_method(rb_klass, "show_image", RUBY_METHOD_FUNC(rb_show_image), -1);
|
||||
rb_define_alias(rb_klass, "show", "show_image");
|
||||
rb_define_method(rb_klass, "set_trackbar", RUBY_METHOD_FUNC(rb_set_trackbar), -1);
|
||||
rb_define_method(rb_klass, "set_mouse_callback", RUBY_METHOD_FUNC(rb_set_mouse_callback), 0);
|
||||
rb_define_method(rb_klass, "set_mouse_callback", RUBY_METHOD_FUNC(rb_set_mouse_callback), -1);
|
||||
rb_define_alias(rb_klass, "on_mouse", "set_mouse_callback");
|
||||
}
|
||||
|
||||
|
@ -121,34 +120,26 @@ rb_aref(VALUE klass, VALUE name)
|
|||
|
||||
/*
|
||||
* call-seq:
|
||||
* new(<i>name[,autosize]</i>)
|
||||
* new(<i>name[,flags]</i>)
|
||||
*
|
||||
* Create new window named <i>name</i>.
|
||||
* If <i>autoresize</i> is true(default), window size automatically resize when image given.
|
||||
* If <i>flags</i> is CV_WINDOW_AUTOSIZE (default), window size automatically resize when image given.
|
||||
*/
|
||||
VALUE
|
||||
rb_initialize(int argc, VALUE *argv, VALUE self)
|
||||
{
|
||||
VALUE name, autosize;
|
||||
rb_scan_args(argc, argv, "11", &name, &autosize);
|
||||
VALUE name, flags;
|
||||
rb_scan_args(argc, argv, "11", &name, &flags);
|
||||
Check_Type(name, T_STRING);
|
||||
int mode;
|
||||
if (argc < 2)
|
||||
mode = CV_WINDOW_AUTOSIZE;
|
||||
else{
|
||||
switch (TYPE(autosize)) {
|
||||
case T_TRUE:
|
||||
mode = CV_WINDOW_AUTOSIZE;
|
||||
break;
|
||||
case T_FALSE:
|
||||
mode = 0;
|
||||
break;
|
||||
default:
|
||||
rb_raise(rb_eTypeError, "argument 2 (auto-size) should be true or false.");
|
||||
}
|
||||
int mode = CV_WINDOW_AUTOSIZE;
|
||||
if (argc == 2) {
|
||||
Check_Type(flags, T_FIXNUM);
|
||||
mode = FIX2INT(flags);
|
||||
}
|
||||
cvNamedWindow(StringValueCStr(name), mode);
|
||||
void *handle = cvGetWindowHandle(StringValueCStr(name));
|
||||
|
||||
char* name_str = StringValueCStr(name);
|
||||
cvNamedWindow(name_str, mode);
|
||||
void *handle = cvGetWindowHandle(name_str);
|
||||
if (st_lookup(windows, (st_data_t)handle, 0)) {
|
||||
rb_raise(rb_eStandardError, "window name should be unique.");
|
||||
}
|
||||
|
@ -217,7 +208,8 @@ rb_resize(int argc, VALUE *argv, VALUE self)
|
|||
size = cvSize(FIX2INT(argv[0]), FIX2INT(argv[1]));
|
||||
break;
|
||||
default:
|
||||
rb_raise(rb_eArgError, "wrong number of arguments (1 or 2)");
|
||||
rb_raise(rb_eArgError, "wrong number of arguments (1 or 2)");
|
||||
break;
|
||||
}
|
||||
cvResizeWindow(GET_WINDOW_NAME(self), size.width, size.height);
|
||||
return self;
|
||||
|
@ -242,7 +234,8 @@ rb_move(int argc, VALUE *argv, VALUE self)
|
|||
point = cvPoint(FIX2INT(argv[0]), FIX2INT(argv[1]));
|
||||
break;
|
||||
default:
|
||||
rb_raise(rb_eArgError, "wrong number of arguments (1 or 2)");
|
||||
rb_raise(rb_eArgError, "wrong number of arguments (1 or 2)");
|
||||
break;
|
||||
}
|
||||
cvMoveWindow(GET_WINDOW_NAME(self), point.x, point.y);
|
||||
return self;
|
||||
|
@ -252,22 +245,27 @@ rb_move(int argc, VALUE *argv, VALUE self)
|
|||
* call-seq:
|
||||
* show_image(<i>image</i>)
|
||||
*
|
||||
* Show the image. If the window was created with <i>autosize</i> = true then the image is shown
|
||||
* Show the image. If the window was created with <i>flags</i> = CV_WINDOW_AUTOSIZE then the image is shown
|
||||
* with its original size, otherwize the image is scaled to fit the window.
|
||||
*/
|
||||
VALUE
|
||||
rb_show_image(VALUE self, VALUE image)
|
||||
rb_show_image(int argc, VALUE *argv, VALUE self)
|
||||
{
|
||||
if (!rb_obj_is_kind_of(image, cCvMat::rb_class())) {
|
||||
rb_raise(rb_eTypeError, "argument should be %s.", rb_class2name(cCvMat::rb_class()));
|
||||
CvArr* image = NULL;
|
||||
if (argc > 0) {
|
||||
if (!rb_obj_is_kind_of(argv[0], cCvMat::rb_class()))
|
||||
rb_raise(rb_eTypeError, "argument should be %s.", rb_class2name(cCvMat::rb_class()));
|
||||
else
|
||||
image = CVARR(argv[0]);
|
||||
|
||||
st_table *holder;
|
||||
if (st_lookup(windows, (st_data_t)DATA_PTR(self), (st_data_t*)&holder)) {
|
||||
st_insert(holder, cCvMat::rb_class(), argv[0]);
|
||||
}else
|
||||
rb_raise(rb_eFatal, "invalid window operation.");
|
||||
}
|
||||
cvShowImage(GET_WINDOW_NAME(self), CVARR(image));
|
||||
st_table *holder;
|
||||
if (st_lookup(windows, (st_data_t)DATA_PTR(self), (st_data_t*)&holder)) {
|
||||
st_insert(holder, cCvMat::rb_class(), image);
|
||||
return self;
|
||||
}else
|
||||
rb_raise(rb_eFatal, "invalid window operation.");
|
||||
cvShowImage(GET_WINDOW_NAME(self), image);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
@ -291,7 +289,8 @@ rb_set_trackbar(int argc, VALUE *argv, VALUE self)
|
|||
}
|
||||
Trackbar *trackbar = TRACKBAR(instance);
|
||||
void *callback = (void *)alloc_callback(&trackbar_callback, trackbar->block);
|
||||
cvCreateTrackbar(trackbar->name, GET_WINDOW_NAME(self), &trackbar->val, trackbar->maxval, (CvTrackbarCallback)callback);
|
||||
cvCreateTrackbar(trackbar->name, GET_WINDOW_NAME(self), &(trackbar->val), trackbar->maxval,
|
||||
(CvTrackbarCallback)callback);
|
||||
st_table *holder;
|
||||
if (st_lookup(windows, (st_data_t)DATA_PTR(self), (st_data_t*)&holder)) {
|
||||
st_insert(holder, (st_data_t)&trackbar->name, (st_data_t)instance);
|
||||
|
@ -326,10 +325,13 @@ rb_set_trackbar(int argc, VALUE *argv, VALUE self)
|
|||
* OpenCV::GUI::wait_key
|
||||
*/
|
||||
VALUE
|
||||
rb_set_mouse_callback(VALUE self)
|
||||
{
|
||||
VALUE block = rb_block_given_p() ? rb_block_proc() : 0;
|
||||
if (!block) {rb_raise(rb_eArgError, "block not given.");}
|
||||
rb_set_mouse_callback(int argc, VALUE* argv, VALUE self)
|
||||
{
|
||||
if (!rb_block_given_p())
|
||||
rb_raise(rb_eArgError, "block not given.");
|
||||
|
||||
VALUE block = Qnil;
|
||||
rb_scan_args(argc, argv, "0&", &block);
|
||||
void *callback = (void *)alloc_callback(&mouse_callback, block);
|
||||
cvSetMouseCallback(GET_WINDOW_NAME(self), (CvMouseCallback)callback);
|
||||
st_table *holder;
|
||||
|
@ -353,11 +355,11 @@ void
|
|||
mouse_callback(VALUE block, va_alist ap)
|
||||
{
|
||||
va_start_void(ap);
|
||||
//VALUE ary = rb_ary_new2(4);
|
||||
//for (int i = 0; i < 4; i++)
|
||||
// rb_ary_store(ary, i, INT2FIX(va_arg_int(ap)));
|
||||
//rb_apply(block, rb_intern("call"), ary);
|
||||
rb_funcall(block, rb_intern("call"), 1, cMouseEvent::new_object(va_arg_int(ap),va_arg_int(ap),va_arg_int(ap),va_arg_int(ap)));
|
||||
int event = va_arg_int(ap);
|
||||
int x = va_arg_int(ap);
|
||||
int y = va_arg_int(ap);
|
||||
int flags = va_arg_int(ap);
|
||||
rb_funcall(block, rb_intern("call"), 1, cMouseEvent::new_object(event, x, y, flags));
|
||||
va_return_void(ap);
|
||||
}
|
||||
|
||||
|
|
|
@ -40,9 +40,9 @@ VALUE rb_destroy(VALUE self);
|
|||
VALUE rb_destroy_all(VALUE klass);
|
||||
VALUE rb_resize(int argc, VALUE *argv, VALUE self);
|
||||
VALUE rb_move(int argc, VALUE *argv, VALUE self);
|
||||
VALUE rb_show_image(VALUE self, VALUE image);
|
||||
VALUE rb_show_image(int argc, VALUE *argv, VALUE self);
|
||||
VALUE rb_set_trackbar(int argc, VALUE *argv, VALUE self);
|
||||
VALUE rb_set_mouse_callback(VALUE self);
|
||||
VALUE rb_set_mouse_callback(int argc, VALUE* argv, VALUE self);
|
||||
|
||||
void trackbar_callback(VALUE block, va_alist ap);
|
||||
void mouse_callback(VALUE block, va_alist ap);
|
||||
|
|
|
@ -72,7 +72,7 @@ else
|
|||
end
|
||||
|
||||
# Quick fix for 1.8.7
|
||||
$CFLAGS << "-I#{File.dirname(__FILE__)}/ext/opencv"
|
||||
$CFLAGS << " -I#{File.dirname(__FILE__)}/ext/opencv"
|
||||
|
||||
# step-final. create Makefile
|
||||
create_makefile("opencv", "./ext/opencv")
|
||||
|
|
|
@ -99,6 +99,9 @@ class TestOpenCV < OpenCVTestCase
|
|||
assert_equal(2, CV_FM_8POINT)
|
||||
assert_equal(8, CV_FM_RANSAC)
|
||||
assert_equal(4, CV_FM_LMEDS)
|
||||
|
||||
# Flags of window
|
||||
assert_equal(1, CV_WINDOW_AUTOSIZE)
|
||||
end
|
||||
|
||||
def test_symbols
|
||||
|
|
115
test/test_window.rb
Executable file
115
test/test_window.rb
Executable file
|
@ -0,0 +1,115 @@
|
|||
#!/usr/bin/env ruby
|
||||
# -*- mode: ruby; coding: utf-8-unix -*-
|
||||
require 'test/unit'
|
||||
require 'opencv'
|
||||
require File.expand_path(File.dirname(__FILE__)) + '/helper'
|
||||
|
||||
include OpenCV
|
||||
include GUI
|
||||
|
||||
# Tests for OpenCV::Window
|
||||
class TestWindow < OpenCVTestCase
|
||||
def setup
|
||||
@window1 = Window.new('window1')
|
||||
@window2 = Window.new('window2', CV_WINDOW_AUTOSIZE)
|
||||
@window3 = Window.new('window3', 0)
|
||||
end
|
||||
|
||||
def teardown
|
||||
Window::destroy_all
|
||||
end
|
||||
|
||||
def test_initialize
|
||||
[Window.new('w1'), Window.new('w2', CV_WINDOW_AUTOSIZE), Window.new('w3', 0)].each { |w|
|
||||
assert_not_nil(w)
|
||||
assert_equal(Window, w.class)
|
||||
}
|
||||
|
||||
assert_raise(TypeError) {
|
||||
Window.new('w4', 'foobar')
|
||||
}
|
||||
|
||||
assert_raise(StandardError) {
|
||||
Window.new('w5')
|
||||
Window.new('w5')
|
||||
}
|
||||
end
|
||||
|
||||
def test_alive
|
||||
assert(@window1.alive?)
|
||||
@window1.destroy
|
||||
assert(!(@window1.alive?))
|
||||
end
|
||||
|
||||
def test_destroy
|
||||
@window1.destroy
|
||||
assert(!(@window1.alive?))
|
||||
end
|
||||
|
||||
def test_destroy_all
|
||||
Window::destroy_all
|
||||
assert(!(@window1.alive?))
|
||||
assert(!(@window2.alive?))
|
||||
assert(!(@window3.alive?))
|
||||
end
|
||||
|
||||
def test_resize
|
||||
@window1.resize(CvSize.new(10, 20))
|
||||
@window2.resize(100, 200)
|
||||
assert_raise(ArgumentError) {
|
||||
@window3.resize
|
||||
}
|
||||
|
||||
# Uncomment the following lines to show the results
|
||||
# @window1.show(CvMat.new(10, 20))
|
||||
# @window2.show(CvMat.new(100, 200))
|
||||
# GUI::wait_key
|
||||
end
|
||||
|
||||
def test_move
|
||||
@window1.move(CvPoint.new(10, 20))
|
||||
@window2.move(100, 200)
|
||||
assert_raise(ArgumentError) {
|
||||
@window3.move
|
||||
}
|
||||
|
||||
# Uncomment the following lines to show the results
|
||||
# @window1.show(CvMat.new(10, 20))
|
||||
# @window2.show(CvMat.new(100, 200))
|
||||
# GUI::wait_key
|
||||
end
|
||||
|
||||
def test_show_image
|
||||
img = IplImage.load(FILENAME_CAT, CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR)
|
||||
@window1.show_image(img)
|
||||
@window2.show # Alias
|
||||
|
||||
# Uncomment the following lines to show the results
|
||||
# GUI::wait_key
|
||||
end
|
||||
|
||||
def test_set_trackbar
|
||||
tr1 = @window1.set_trackbar('trackbar1', 100) { |value|
|
||||
puts value
|
||||
}
|
||||
assert_equal(Trackbar, tr1.class)
|
||||
|
||||
trackbar2 = Trackbar.new('trackbar2', 10, 1) {}
|
||||
tr2 = @window2.set_trackbar(trackbar2)
|
||||
assert_equal(Trackbar, tr2.class)
|
||||
end
|
||||
|
||||
def test_set_mouseevent
|
||||
@window1.set_mouse_callback { |mouse|
|
||||
e = "#{mouse.x}, #{mouse.y} : #{mouse.event} : "
|
||||
e << "<L>" if mouse.left_button?
|
||||
e << "<R>" if mouse.right_button?
|
||||
e << "<M>" if mouse.middle_button?
|
||||
e << "[CTRL]" if mouse.ctrl_key?
|
||||
e << "[SHIFT]" if mouse.shift_key?
|
||||
e << "[ALT]" if mouse.alt_key?
|
||||
puts e
|
||||
}
|
||||
end
|
||||
end
|
||||
|
Loading…
Reference in a new issue