Skip to content

Commit

Permalink
for #383 - many fixes for replay attempt
Browse files Browse the repository at this point in the history
* replay effort will stall soon. It may not be possible.
  • Loading branch information
Cecil committed Dec 20, 2017
1 parent 15d90b6 commit 0867507
Show file tree
Hide file tree
Showing 10 changed files with 299 additions and 8 deletions.
32 changes: 32 additions & 0 deletions Tests/events/button.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
Shoes.app do

stack do
para "Native button test"
flow do
@btn1 = button "button 1", width: 75 do
@eb.append "button 1 clicked\n"
end
@btn2 = button "button 2" do
@eb.append "button 2 clicked\n"
end
flow do
@ck2 = check checked: true do
@eb.append "Happy: "
@eb.append "feeling good\n" if @r1.checked?
@eb.append "feeling something\n" if @r2.checked?
@eb.append "feeling low\n" if @r3.checked?
end
para "Happy?"
end
stack do
flow {@r1 = radio :happy; para "Estatic"}
flow {@r2 = radio :happy; para "So-So"}
flow {@r3 = radio :happy; para "Not really"}
end
end
@eb = edit_box width: 500, height: 350
end
click do |btn,x,y,mods|
@eb.append "click #{btn}, x: #{x}, y: #{y}. mods: #{mods}\n"
end
end
40 changes: 40 additions & 0 deletions Tests/events/button.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
---
:context:
:app: "/home/ccoupe/Projects/shoes3/Tests/events/button.rb"
:time: 2017-12-18 23:46:58.596135799 -07:00
:events:
- :time: 2.380615873
:button: 1
:x: 0
:y: 35
:modifiers:
:object: !ruby/object:Shoes::Types::Button {}
:type: :btn_activate
- :time: 3.780337516
:button: 1
:x: 75
:y: 35
:modifiers:
:object: !ruby/object:Shoes::Types::Button {}
:type: :btn_activate
- :time: 6.24463253
:button: 1
:x: 0
:y: 100
:modifiers:
:object: !ruby/object:Shoes::Types::Radio {}
:type: :btn_activate
- :time: 6.244678214
:button: 1
:x: 0
:y: 135
:modifiers:
:object: !ruby/object:Shoes::Types::Radio {}
:type: :btn_activate
- :time: 8.060630508
:button: 1
:x: 0
:y: 65
:modifiers:
:object: !ruby/object:Shoes::Types::Check {}
:type: :btn_activate
3 changes: 3 additions & 0 deletions Tests/events/capture.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@
events << { time: (Time.now - base_t), button: evt.button, x: evt.x, y: evt.y,
modifiers: evt.modifiers, object: evt.object, type: evt.type}
evt.accept = true
when :btn_activate
events << { time: (Time.now - base_t), button: evt.button, x: evt.x, y: evt.y,
modifiers: evt.modifiers, object: evt.object, type: evt.type}
else
evt.accept = true
end
Expand Down
47 changes: 47 additions & 0 deletions Tests/events/chipmunk.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
---
:context:
:app: "/home/ccoupe/Projects/shoes3/minlin/samples/simple/chipmunk.rb"
:time: 2017-12-17 21:37:26.497452015 -07:00
:events:
- :time: 3.111306338
:button: 1
:x: 19
:y: 59
:modifiers: shift
:object: &1 !ruby/object:Shoes::Types::Shape {}
:type: :click
- :time: 6.447366351
:button: 1
:x: 82
:y: 52
:modifiers: control
:object: &3 !ruby/object:Shoes::Types::Shape {}
:type: :click
- :time: 10.895925171
:button: 1
:x: 112
:y: 49
:modifiers: shift
:object: &2 !ruby/object:Shoes::Types::Shape {}
:type: :click
- :time: 15.735470191
:button: 1
:x: 17
:y: 52
:modifiers: control_shift
:object: *1
:type: :click
- :time: 19.503386712
:button: 1
:x: 109
:y: 52
:modifiers: control_shift
:object: *2
:type: :click
- :time: 22.647864317
:button: 1
:x: 82
:y: 54
:modifiers:
:object: *3
:type: :click
26 changes: 26 additions & 0 deletions Tests/events/event1.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
:context:
:app: "/home/ccoupe/Projects/shoes3/Tests/events/event1.rb"
:time: 2017-12-18 19:14:17.527820709 -07:00
:events:
- :time: 2.084820129
:button: 1
:x: 379
:y: 55
:modifiers:
:object:
:type: :click
- :time: 3.299109652
:button: 1
:x: 0
:y: 70
:modifiers:
:object: !ruby/object:Shoes::Types::Button {}
:type: :btn_activate
- :time: 4.835090063
:button: 1
:x: 75
:y: 70
:modifiers:
:object: !ruby/object:Shoes::Types::Button {}
:type: :btn_activate
21 changes: 18 additions & 3 deletions Tests/events/replay.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
require 'yaml'
Shoes.app do
yaml_path = ""
if ARGV.length > 1
tp = ARGV[1]
if tp[0] != '/'
yaml_path = "#{DIR}/../#{tp}"
else
yaml_path = tp
end
end
stack do
tagline "Replay Clicks for another app"
para "Load events from"
flow do
@sv = edit_line width: 450
@sv.text = "#{Dir.getwd}/chipmunk.yaml"
@sv.text = yaml_path
button "Change" do
path = ask_open_file
@sv.text = path if path
Expand All @@ -31,11 +40,17 @@
# note this creates as many simulaneous timers as events
# not pretty
w2 = Shoes.APPS[-1]
base_t = nil
@events.each_index do |r|
ev = @events[r]
if r == 0
# chop first delay - minor improvement
base_t = ev[:time]
puts "base_t #{base_t}"
end
t = ev[:time]
timer(t) do
puts "wait for #{t}"
timer(t-base_t) do
puts "wait for #{t-base_t}"
puts " move to #{ev[:x]}, #{ev[:y]} and click "
w2.replay_event(ev)
end
Expand Down
75 changes: 73 additions & 2 deletions shoes/app.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "shoes/types/text.h"
#include "shoes/types/text_link.h"
#include "shoes/types/textblock.h"
#include "shoes/types/native.h"
#include "shoes/types/event.h"

static void shoes_app_mark(shoes_app *app) {
Expand Down Expand Up @@ -776,7 +777,64 @@ shoes_code shoes_app_keyup(shoes_app *app, VALUE key) {
return SHOES_OK;
}

#if 0
// replay -- testing - just clicks
debug_value(VALUE obj) {
switch (TYPE(obj)) {
case T_NIL:
break;
case T_OBJECT:
break;
case T_CLASS:
break;
case T_MODULE:
break;
case T_FLOAT:
break;
case T_STRING:
break;
case T_REGEXP:
break;
case T_ARRAY:
break;
case T_HASH:
break;
case T_STRUCT: // (Ruby) structure
break;
case T_BIGNUM: // multi precision integer
break;
case T_FIXNUM: // Fixnum(31bit or 63bit integer)
break;
case T_COMPLEX: // complex number
break;
case T_RATIONAL: // rational number
break;
case T_FILE: // IO
break;
case T_TRUE: // true
break;
case T_FALSE: // false
break;
case T_DATA: // data
break;
case T_SYMBOL: // symbol
break;
case T_ICLASS: // included module
break;
case T_MATCH: // MatchData object
break;
case T_UNDEF: // undefined
break;
case T_NODE: // syntax tree node
break;
case T_ZOMBIE: // object awaiting finalization
break;
default:
break;
}
}
#endif

VALUE shoes_app_replay_event(VALUE self, VALUE evh) {
shoes_app *self_t;
Data_Get_Struct(self, shoes_app, self_t);
Expand All @@ -787,10 +845,23 @@ VALUE shoes_app_replay_event(VALUE self, VALUE evh) {
mods = shoes_hash_get(evh, rb_intern("modifiers"));
type = shoes_hash_get(evh, rb_intern("type"));
vobj = shoes_hash_get(evh, rb_intern("object"));
if (SYM2ID(type) == s_click) {// TODO: figure symbol/id for type == click
// using app->canvas
ID typeid = SYM2ID(type);
// using app->canvas
if (typeid == s_click) {
shoes_canvas_send_click(self_t->canvas, NUM2INT(btn), NUM2INT(vx), NUM2INT(vy), mods);
return Qtrue;
} else if (typeid == s_btn_activate) {
// TODO figure out whether it's a button/checkbox/radio and how
// to call the shoes code
VALUE button = Qnil;
int x = NUM2INT(vx);
int y = NUM2INT(vy);
//debug_value(vobj); // it's not one of the documented types.
shoes_event_find_native(self_t->canvas, x+4, y+4, &button);
if (! NIL_P(button)) {
shoes_control_send(button, s_click);
}
return Qtrue;
} else
return Qnil;
}
Expand Down
1 change: 1 addition & 0 deletions shoes/types/button.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,4 @@ VALUE shoes_canvas_button(int argc, VALUE *argv, VALUE self) {

return button;
}

47 changes: 46 additions & 1 deletion shoes/types/event.c
Original file line number Diff line number Diff line change
Expand Up @@ -214,9 +214,54 @@ VALUE shoes_event_find_psuedo (VALUE self, int x, int y, VALUE *hitobj) {

return Qnil;
}
extern VALUE cButton, cCheck, cRadio;
/*
* This is called by event replay to find if there is a native widget at x,y
*/
VALUE shoes_event_find_native (VALUE self, int x, int y, VALUE *hitobj) {
long i;
int ox = x, oy = y;
VALUE v = Qnil; // v is t/f, Qtrue/Qnil
shoes_canvas *self_t;
Data_Get_Struct(self, shoes_canvas, self_t);

if (ORIGIN(self_t->place)) {
oy = y + self_t->slot->scrolly;
ox = x - self_t->place.ix + self_t->place.dx;
oy = oy - (self_t->place.iy + self_t->place.dy);
if (oy < self_t->slot->scrolly || ox < 0 || oy > self_t->slot->scrolly + self_t->place.ih || ox > self_t->place.iw)
return Qnil;
}
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)) {
// TODO: something
VALUE click = ATTR(self_t->attr, click);
if (!NIL_P(click)) {
if (ORIGIN(self_t->place))
y += self_t->slot->scrolly;
//shoes_safe_block(self, click, rb_ary_new3(4, INT2NUM(button), INT2NUM(x), INT2NUM(y), mods));
}
}

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, cCanvas)) {
v = shoes_event_find_native(ele, ox, oy, hitobj);
} else if (rb_obj_is_kind_of(ele, cNative)) {
v = shoes_control_is_here(ele, ox,oy);
*hitobj = ele;
}

// helper for creating key events
if (!NIL_P(v))
return v;
}
}

return Qnil;
}


VALUE shoes_event_type(VALUE self) {
Expand Down
15 changes: 13 additions & 2 deletions shoes/types/native.c
Original file line number Diff line number Diff line change
Expand Up @@ -179,12 +179,12 @@ void shoes_control_send(VALUE self, ID event) {
shoes_safe_block(app->canvas, evtproc, rb_ary_new3(1, evt));
shoes_event *tevent;
Data_Get_Struct(evt, shoes_event, tevent);
sendevt = tevent->accept;
sendevt = shoes_event_contrain_TF(tevent->accept);
} else
fprintf(stderr, "shoes_control_send: doesn't have event - but it should\n");
}
if ((sendevt == Qtrue) && !NIL_P(self_t->attr)) {
// TODO: bug here
// TODO: bug here for replay
click = rb_hash_aref(self_t->attr, ID2SYM(event));
if (!NIL_P(click))
shoes_safe_block(self_t->parent, click, rb_ary_new3(1, self));
Expand Down Expand Up @@ -214,6 +214,17 @@ void shoes_control_show_ref(SHOES_CONTROL_REF ref) {
if (ref != NULL) shoes_native_control_show(ref);
}

// called by low level when feeding events
VALUE shoes_control_is_here(VALUE self, int x, int y) {
shoes_control *ctl;
Data_Get_Struct(self, shoes_control, ctl);
if (IS_INSIDE(ctl, x, y))
return Qtrue;
else
return Qnil;
}


// canvas
VALUE shoes_canvas_hide(VALUE self) {
shoes_canvas *self_t;
Expand Down

0 comments on commit 0867507

Please sign in to comment.