Skip to content

Commit

Permalink
for #383 - work in progress.
Browse files Browse the repository at this point in the history
  • Loading branch information
Cecil committed Dec 8, 2017
1 parent 2375f6a commit 3230544
Show file tree
Hide file tree
Showing 6 changed files with 122 additions and 17 deletions.
29 changes: 22 additions & 7 deletions Tests/events/event4.rb
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
class TestWidget < Shoes::Widget
def initialize()

attr_accessor :click_blk

def initialize(&blk)
@click_blk = blk
self.width = 200; self.height = 200 ## note that you do need this
flow width: 190, height: 200 do ###### explicit slot
background coral
para "user defined widget"
click {|btn,x,y,mods| puts "widget clicked btn: #{btn} at #{x},#{y} with #{mods}"}
end
end

def click(btn,x,y,mods)
puts "TW click called, sending.."
@click_blk.call(btn,x,y,mods)
end
end

Shoes.app do
Shoes.app height: 700 do
stack do
tagline "Clicks for non-native widgets"
flow do
Expand All @@ -20,14 +28,21 @@ def initialize()
@img.click {|btn,x,y,mods| @eb.append "Image clicked btn: #{btn} at #{x},#{y} with #{mods}\n"}
@svg = svg "#{DIR}/samples/good/paris.svg", width: 200, height: 200, group: "#diamond_4"
@svg.click {|btn,x,y,mods| @eb.append "Svg clicked btn: #{btn} at #{x},#{y} with #{mods}\n"}
@plt = plot 200, 200, title: "Test plot"
# click only works on TimeSeries plots
@plt = plot 200, 200, title: "Test plot", chart: "timeseries"
@plt.click {|btn,x,y,mods| @eb.append "Plot clicked btn: #{btn} at #{x},#{y} with #{mods}\n"}
@tw = test_widget

#@tw = test_widget {|btn,x,y,mods| @eb.append "User Widget: #{btn} at #{x},#{y} with #{mods}\n"}
end
@eb = edit_box width: 500, height: 200
end

event do |evt|
puts "event called #{evt.type} at #{evt.x},#{evt.y} mods: #{evt.modifiers}"
evt.accept = $ck.checked?
$stderr.puts "event called: #{evt.type} at #{evt.x},#{evt.y} mods: #{evt.modifiers}"
if evt.object
$stderr.puts " for non-native: #{evt.object}"
end
evt.accept = true #$ck.checked?
end

end
3 changes: 2 additions & 1 deletion shoes/app.c
Original file line number Diff line number Diff line change
Expand Up @@ -591,7 +591,8 @@ shoes_code shoes_app_click(shoes_app *app, int button, int x, int y, int mods) {
*/
if (app->use_event_handler) {
//fprintf(stderr, "have event_handler, creating event...\n");
VALUE evt = shoes_event_new(cShoesEvent, s_click, Qnil, x, y, button, modifiers);
VALUE evt = shoes_event_create_event(app, s_click, button, x, y, modifiers);
//VALUE evt = shoes_event_new(cShoesEvent, s_click, Qnil, x, y, button, modifiers);
shoes_canvas *canvas;
Data_Get_Struct(app->canvas, shoes_canvas, canvas);
VALUE event = ATTR(canvas->attr, event);
Expand Down
1 change: 0 additions & 1 deletion shoes/plot/plot.c
Original file line number Diff line number Diff line change
Expand Up @@ -745,7 +745,6 @@ VALUE shoes_plot_motion(VALUE self, int x, int y, char *touch) {
// called by shoes_canvas_send_click --> shoes_canvas_send_click2
VALUE shoes_plot_send_click(VALUE self, int button, int x, int y) {
VALUE v = Qnil;

if (button > 0) {
GET_STRUCT(plot, self_t);
v = shoes_plot_motion(self, x, y, NULL);
Expand Down
98 changes: 93 additions & 5 deletions shoes/types/event.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

#include "shoes/types/event.h"

#include "shoes/types/svg.h"

VALUE cShoesEvent;

Expand Down Expand Up @@ -36,7 +36,7 @@ void shoes_event_free(shoes_event *event) {
RUBY_CRITICAL(free(event));
}

// users should not create events but something has to be visible
// users should not create events but something has to be visible.
// click calls here.
VALUE shoes_event_new(VALUE klass, ID type, VALUE widget, int x, int y, int btn, VALUE mods) {
shoes_event *event;
Expand All @@ -52,9 +52,9 @@ VALUE shoes_event_new(VALUE klass, ID type, VALUE widget, int x, int y, int btn,
event->modifiers = mods;
return obj;
}

// Or here
VALUE shoes_event_new_widget(VALUE klass, ID type, VALUE widget, int btn, int x,
int y, int w, int h) {
int y, int w, int h, VALUE modifiers) {
shoes_event *event;
VALUE obj = shoes_event_alloc(klass);
Data_Get_Struct(obj, shoes_event, event);
Expand All @@ -67,7 +67,7 @@ VALUE shoes_event_new_widget(VALUE klass, ID type, VALUE widget, int btn, int x,
event->width = w;
event->height = h;
event->key = Qnil;
event->modifiers = Qnil;
event->modifiers = modifiers;
return obj;
}

Expand Down Expand Up @@ -107,6 +107,94 @@ VALUE shoes_canvas_shoesevent(int argc, VALUE *argv, VALUE self) {
return ev;
}

/* Need to detect if this is a click on pseudo widget (img,svg,plot.user-widget)
* or a slot click handler before we pass it to shoes_canvas_send_click/click2
* We create different event objects for the user specified handler to deal with
*/
extern ID cTextBlock, cImage, cShape, cCanvas;

VALUE shoes_event_create_event(shoes_app *app, ID etype, int button, int x, int y, VALUE modifiers) {
VALUE ps;
VALUE ps_widget = shoes_event_find_psuedo (app->canvas, x, y);
VALUE evt;
if (NIL_P(ps_widget)) {
evt = shoes_event_new(cShoesEvent, s_click, Qnil, x, y, button, modifiers);
} else {
int w, h; // get from ?
evt = shoes_event_new_widget(cShoesEvent, s_click, ps_widget, button, x, y, w, h, modifiers);
}
return evt;
}

/*
* Yes it does seem to be expensive but events happen at user speed (slow)
* Recursive when it finds a new slot (canvas)
* Beware all these non-widgets are canvas based! Return Qnil if no non-natives
* match the x,y. Return the matching non-native (not it's containing canvas/slot)
*/
VALUE shoes_event_find_psuedo (VALUE self, int x, int y) {
long i;
int ox = x, oy = y;
shoes_canvas *self_t;
Data_Get_Struct(self, shoes_canvas, self_t);
VALUE v = Qnil; // Returned object (svg,image, ...) a non native widget
if (ATTR(self_t->attr, hidden) != Qtrue) {
if (self_t->app->canvas == self) // when we are the app's slot
y -= self_t->slot->scrolly;

if (IS_INSIDE(self_t, x, y)) {
if (ORIGIN(self_t->place))
y += self_t->slot->scrolly;
for (i = RARRAY_LEN(self_t->contents) - 1; i >= 0; i--) {
VALUE ele = rb_ary_entry(self_t->contents, i);
if (rb_obj_is_kind_of(ele, cTextBlock)) {
fprintf(stderr, "found cTextblock\n");
//v = ele;
} else if (rb_obj_is_kind_of(ele, cImage)) {
// TODO: assumes image, has .place in the same spot as canvas (it does)
shoes_image *img;
Data_Get_Struct(ele, shoes_image, img);
if (IS_INSIDE(img, x, y)) {
fprintf(stderr, "found cImage at click\n");
return ele;
}
} else if (rb_obj_is_kind_of(ele, cSvg)) {
// TODO: assumes svg, has .place in the same spot as canvas (it does)
shoes_svg *svg;
Data_Get_Struct(ele, shoes_svg, svg);
if (IS_INSIDE(svg, x, y)) {
fprintf(stderr, "found cSvg at click\n");
return ele;
}
} else if (rb_obj_is_kind_of(ele, cPlot)) {
// TODO: assumes plot, has .place in the same spot as canvas (it does)
Data_Get_Struct(ele, shoes_canvas, self_t);
if (IS_INSIDE(self_t, x, y)) {
fprintf(stderr, "found cPlot at click\n");
return ele;
}
} else if (rb_obj_is_kind_of(ele, cShape)) {
fprintf(stderr, "found cShape\n");
//v = ele;
} else if (rb_obj_is_kind_of(ele, cCanvas)) {
shoes_canvas *cvs;
Data_Get_Struct(ele, shoes_canvas, cvs);
if (IS_INSIDE(cvs, x, y)) {
fprintf(stderr, "recurse canvas\n");
v = shoes_event_find_psuedo(ele, ox, oy);
}
} else {
v = Qnil;
}
if (! NIL_P(v))
return v;
}
}
}
return Qnil;
}



VALUE shoes_event_type(VALUE self) {
shoes_event *event;
Expand Down
6 changes: 4 additions & 2 deletions shoes/types/event.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,9 @@ void shoes_event_free(shoes_event *event);
VALUE shoes_event_new(VALUE klass, ID type, VALUE widget, int x, int y,
int btn, VALUE modifiers);
VALUE shoes_event_alloc(VALUE klass);
VALUE shoes_event_create_event(shoes_app *app, ID action, int button, int x, int y, VALUE modifiers);
VALUE shoes_canvas_shoesevent(int argc, VALUE *argv, VALUE self);
VALUE shoes_event_new_widget(VALUE klass, ID type, VALUE widget, int btn, int x,
int y, int w, int h);
VALUE shoes_event_new_widget(VALUE klass, ID type, VALUE widget, int btn, int x, \
int y, int w, int h, VALUE modifiers);
VALUE shoes_event_find_psuedo (VALUE self, int x, int y);
#endif
2 changes: 1 addition & 1 deletion shoes/types/native.c
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ void shoes_control_send(VALUE self, ID event) {
y = self_t->place.y;
h = self_t->place.h;
w = self_t->place.w;
VALUE evt = shoes_event_new_widget(cShoesEvent, s_click, self, 1, x, y, w, h);
VALUE evt = shoes_event_new_widget(cShoesEvent, event, self, 1, x, y, w, h, Qnil);
shoes_safe_block(app->canvas, evtproc, rb_ary_new3(1, evt));
shoes_event *tevent;
Data_Get_Struct(evt, shoes_event, tevent);
Expand Down

0 comments on commit 3230544

Please sign in to comment.