void UIBinding::_SetContextMenu(const ValueList& args, SharedValue result) { args.VerifyException("setContextMenu", "o|0"); SharedKObject argObj = args.GetObject(0, NULL); AutoMenu menu = NULL; if (!argObj.isNull()) { menu = argObj.cast<Menu>(); } this->SetContextMenu(menu); }
// A :method_missing method for finding KObject properties in Ruby static VALUE RubyKObjectMethodMissing(int argc, VALUE *argv, VALUE self) { SharedValue* dval = NULL; Data_Get_Struct(self, SharedValue, dval); SharedKObject object = (*dval)->ToObject(); // TODO: We should raise an exception instead if (object.isNull()) return Qnil; // This is the same error that ruby throws if (argc == 0 || !SYMBOL_P(argv[0])) { rb_raise(rb_eArgError, "no id given"); } // We need to determine the method that was invoked: // store the method name and arguments in separate variables VALUE r_name, args; rb_scan_args(argc, argv, "1*", &r_name, &args); const char* name = rb_id2name(SYM2ID(r_name)); // Check if this is an assignment SharedValue value = object->Get(name); if (name[strlen(name) - 1] == '=' && argc > 1) { char* mod_name = strdup(name); mod_name[strlen(mod_name) - 1] = '\0'; value = RubyUtils::ToKrollValue(argv[1]); object->Set(mod_name, value); free(mod_name); return argv[1]; } else if (value->IsUndefined()) // raise a method missing error { VALUE selfString = rb_obj_as_string(self); rb_raise(rb_eNoMethodError, "undefined method `%s' for %s", name, RubyUtils::ToString(selfString)); } else if (value->IsMethod()) // actually call a method { return RubyUtils::GenericKMethodCall(value->ToMethod(), args); } else // Plain old access { return RubyUtils::ToRubyValue(value); } }
void UIBinding::_SetMenu(const ValueList& args, SharedValue result) { args.VerifyException("setMenu", "o|0"); SharedKObject argObj = args.GetObject(0, NULL); AutoMenu menu = NULL; if (!argObj.isNull()) { menu = argObj.cast<Menu>(); } this->SetMenu(menu); // platform-specific impl // Notify all windows that the app menu has changed. std::vector<AutoUserWindow>::iterator i = openWindows.begin(); while (i != openWindows.end()) { (*i++)->AppMenuChanged(); } }
void MonkeyBinding::EvaluateUserScript( SharedKObject event, std::string& url, SharedKObject windowObject, std::string& scriptSource) { static Logger *logger = Logger::Get("Monkey"); // I got a castle in brooklyn, that's where i dwell // Word, brother. if (!windowObject->Get("eval")->IsMethod()) { logger->Error("Found a window object without an " "eval function (%s) -- aborting", url.c_str()); return; } SharedKObject target = event->GetObject("target"); if (!windowObject->Get(GLOBAL_NS_VARNAME)->IsObject() && !target.isNull() && target->Get("insertAPI")->IsMethod()) { logger->Info("Forcing Titanium API into: %s\n", url.c_str()); target->CallNS("insertAPI", Value::NewObject(windowObject)); } SharedKMethod evalFunction = windowObject->GetMethod("eval"); logger->Info("Loading userscript for %s\n", url.c_str()); try { evalFunction->Call(Value::NewString(scriptSource)); } catch (ValueException &ex) { SharedString ss = ex.DisplayString(); int line = -1; if (ex.GetValue()->IsObject() && ex.GetValue()->ToObject()->Get("line")->IsNumber()) { line = ex.GetValue()->ToObject()->Get("line")->ToInt(); } logger->Error( "Exception generated evaluating user script for %s " "(line %i): %s", url.c_str(), line, ss->c_str()); } }
// A :method method for pulling methods off of KObjects in Ruby static VALUE RubyKObjectMethod(int argc, VALUE *argv, VALUE self) { SharedValue* dval = NULL; Data_Get_Struct(self, SharedValue, dval); SharedKObject object = (*dval)->ToObject(); // TODO: We should raise an exception instead if (object.isNull()) return Qnil; if (argc < 1) return Qnil; VALUE meth_name = argv[0]; const char* name = rb_id2name(SYM2ID(meth_name)); SharedValue v = object->Get(name); if (v->IsMethod()) { return RubyUtils::ToRubyValue(v); } else { return Qnil; } }
void UserWindow::FireEvent(UserWindowEvent event_type, SharedKObject event) { std::string name; switch (event_type) { case FOCUSED: { name = "focused"; break; } case UNFOCUSED: { name = "unfocused"; break; } case OPEN: { name = "open"; break; } case OPENED: { name = "opened"; break; } case CLOSE: { name = "close"; break; } case CLOSED: { name = "closed"; break; } case HIDDEN: { name = "hidden"; break; } case SHOWN: { name = "shown"; break; } case FULLSCREENED: { name = "fullscreened"; break; } case UNFULLSCREENED: { name = "unfullscreened"; break; } case MAXIMIZED: { name = "maximized"; break; } case MINIMIZED: { name = "minimized"; break; } case RESIZED: { name = "resized"; break; } case MOVED: { name = "moved"; break; } case INIT: { name = "page.init"; break; } case LOAD: { name = "page.load"; break; } case CREATE: { name = "create"; break; } } std::string en = std::string("ti.UI.window.") + name; if (event.isNull()) { event = new StaticBoundObject(); } event->Set("window", Value::NewObject(this->shared_this)); this->api->Call(en.c_str(), Value::NewObject(event)); // If we don't have listeners here, we can just bail. if (this->listeners.size() == 0) { return; } ValueList args; args.push_back(Value::NewString(name)); args.push_back(Value::NewObject(event)); std::vector<Listener>::iterator it = this->listeners.begin(); while (it != this->listeners.end()) { SharedKMethod callback = (*it).callback; try { this->host->InvokeMethodOnMainThread(callback,args,false); } catch(std::exception &e) { std::cerr << "Caught exception dispatching window event callback: " << event << ", Error: " << e.what() << std::endl; } it++; } }