Why doesn't mousePressed() work without setup() in p5.js? - mouseevent

In the p5 editor, I was trying to create a simple example that doesn't require a canvas, so I deleted the setup() and draw() functions. I realized that mousePressed() won't work without at least the setup() function being called. I can comment out createCanvas() and mousePressed() works just fine. Any ideas on why this is happening?
var luckyNum;
function mousePressed(){
luckyNum = int(random(0, 100));
createP("Your lucky number is " + luckyNum + "!");
}

The mousePressed() function works fine without draw(), but it does require setup().
Here's an example:
function setup() {
// empty
}
function mousePressed() {
background(random(255));
}
I'm not sure why this is. It's probably related to some internal initialization that only happens if p5.js detects a setup() function.
You might consider switching to pure JavaScript, since you don't seem to need many p5 features. You could attach a click listener to the <body> of your page and create a <p> element from there.

Related

Vaadin LoginOverlay

I am very new to both java and vaadin. Hope to be able to get some good tips on how I can improve my code.
I would like to rewrite the code below to use Vaadin´s -> LoginOverlay instead of the code below.
As I said, I'm trying to learn so I have used the code for this example: https://www.youtube.com/watch?v=oMKks5AjaSQ&t=1158s
However, LoginOverlay seems to be a better way to display its login part through. As in this example: https://www.youtube.com/watch?v=pteip-kZm4M
So my question is how can you write the code below as a LoginOverlay.
public class LoginView extends Div {
public LoginView(AuthService authService) {
setId("login-view");
var username = new TextField("Username");
var password = new PasswordField("Password");
add(
new H1("Welcome"),
username,
password,
new Button("Login", event -> {
try {
authService.authenticate(username.getValue(), password.getValue());
UI.getCurrent().navigate("home");
} catch (AuthService.AuthException e) {
Notification.show("Wrong credentials.");
}
}),
new RouterLink("Register", RegisterView.class)
);
}
}
I have only come this far to convert the code.
A clarification of the new part of the code. The code does not work. The part with loginOverlay.addLoginListener (event -> probably needs to be written in a different way.
I'm using IntelliJ 2020.3.4 if that is of any help.
public class LoginView2 extends Composite<LoginOverlay> {
public LoginView2(AuthService authService) {
setId("login-view");
LoginOverlay loginOverlay = getContent();
loginOverlay.setTitle("Welcom");
loginOverlay.setDescription("Manage your business tasks");
loginOverlay.setOpened(true);
loginOverlay.addLoginListener(event -> {try {
if(authService.authenticate(username.getValue(), password.getValue());
UI.getCurrent().navigate("home");
} catch (AuthService.AuthException e) {
Notification.show("Wrong credentials.");
}
}),
new RouterLink("Register", RegisterView.class);
}
}
}
}
Super grateful for all the help you can give.
Many thanks to everyone who makes stackoverflow so amazing.
Copy-pasting code snippets with little idea about what the code does is a recipe for disaster, especially when it comes to security.
You have all kinds of errors in your code: misplaced braces, using variables that do not exist, and a RouterLink far from where it belongs.
I understand you've got to start somewhere. I would recommend starting from code that actually compiles, and then gradually adding things, testing what you have so far at every step.
Here are some tips for your LoginView2:
Remove the whole loginOverlay.addLoginListener(...) code, including the authService.authenticate call and the RouterLink. Make sure that you can run the application at this point, and that you can see the login overlay.
Add back the login listener, but for now just show a notification in it. Test that you can run the application, and that if you click Login, your notification is displayed.
loginOverlay.addLoginListener(event -> {
Notification.show("This is working");
});
Implement the authentication. You have a call to authService.authenticate(...) inside an if-statement, but the method does not return anything. Instead, it throws an exception if the authentication fails, hence the try-catch. This means that inside the try { ... } block, any code you put after the authService.authenticate(...) call is only executed if it did not throw an exception, i.e. if the authentication was successful.
There are no username or password variables. The first YouTube video had defined these variables in the form of text fields. With the login overlay, it creates those fields for you, so how do you get the corresponding values from it?

How to modify a form in a background thread

This might be a simple question but I can't figure it out.
I have a form called in my main function:
void Main() {
Mem = new MemoryManager();
Console::WriteLine("Thread Started");
Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);
FinalSolution::ControlPanel form;
Thread^ cLoop = gcnew Thread(gcnew ThreadStart(loop));
cLoop->Start();
Application::Run(%form);
}
All I want to do is, if someone presses a key in general (not just when the program is in focus), it changes the background to a different color.
I have tried a few things but nothing has worked so far. Here is the loop and I have indicated where I want it to happen.
void loop() {
while (true) {
if (GetAsyncKeyState(key)) {
//Here
form.button->BackColor = System::Drawing::Color::ForestGreen;
}
}
}
Of course the issue is that this function doesn't know what form is, but I don't know how to tell it.
Ended up just putting the loop directly in the form header and that solved the problem.

How to override dojo's domReady

I want to override dijit._CssStateMixin's domReady() method.
Is there any way to override that instead of changing the listener mechanism in Dojo.
I tried overriding _cssMouseEvent() method in simple javascript, but it still does invoke dijit's _cssMouseEvent() from domReady().
I have tried following approach:
dojoConfig = {
map: {
'dijit/_CssStateMixin': {
'dojo/domReady': 'app/noop'
}
}
};
I have added 'app' folder and then 'noop.js' inside that.
noop.js has nothing in it:
define([], function () {
return function () {};
});
Even after this I can see that dijit.js's _CssStateMaxin domReady() getting called from listener.apply (code snippet pasted below)
var addStopImmediate = function(listener){
return function(event){
if(!event.immediatelyStopped){// check to make sure it hasn't been stopped immediately
event.stopImmediatePropagation = stopImmediatePropagation;
return listener.apply(this, arguments);
}
};
}
If your ultimate goal is to prevent the domReady callback in dijit/_CssStateMixin from running, your simplest bet is likely to re-map dojo/domReady to a different module that doesn't call the callback at all, when loaded via dijit/_CssStateMixin.
NOTE: Stripping out these handlers might have adverse visual effects on Dijit widgets which inherit _CssStateMixin, since it may hinder the application of Dijit CSS classes related to hover and focus. But if your concern is that _CssStateMixin is hampering performance, it may at least be worth a try to confirm or deny your suspicion.
First we have to create a simple module that returns a function that does nothing, which we will later substitute for dojo/domReady when loaded by dijit/_CssStateMixin, so that it can still call domReady but it won't execute the callback it passes.
For simplicity's sake I'll assume you already have a custom package that you can easily add a module to; for this example I'll assume it's called app. Let's create app/noop:
define([], function () {
return function () {};
});
Now let's configure the loader to map app/noop in place of dojo/domReady specifically when loaded by dijit/_CssStateMixin:
var dojoConfig = {
...,
map: {
'dijit/_CssStateMixin': {
'dojo/domReady': 'app/noop'
}
},
...
};
Now the offending domReady callback should no longer be run.
If you're curious about map, you can read more about it in this SitePen FAQ.

time between mouse clicks processing.js

I want to get the time between successive mouse clicks in ms. This is what I have tried:
void setup(){
size(512,512);
background(100,100,0);
}
void draw(){
}
void mousePressed(){
println(new Date() - oldtime);
var oldtime=new Date();
}
The problem appears to be that processing.js does not remember the value of oldtime between calls to mousePressed().
On the first call, there has been no previous mouse click, oldtime is undefined, and the time should be NaN. But after the first click, oldtime is set, and so the above should work. I tried doing
var oldtime=new Date();
outside mousePressed() so that the first call would not be NaN, but no luck.
Thanks very much for any help.
===========================
The problem had to do with variable "scope". This works now
var oldtime=new Date();
void setup(){
size(512,512);
background(100,100,0);
}
void draw(){
}
void mousePressed(){
println(new Date() - oldtime);
oldtime=new Date();
}
There is a built in method/function for this called millis(), no need to use the Date class. There is also no reason to call var. I would also initialize your classes and variables in the setup method. Here is how these changes would look in your code in processing syntax:
int oldtime;
void setup(){
size(512,512);
background(100,100,0);
oldtime = millis()
}
void draw(){
}
void mousePressed(){
println(millis() - oldtime);
oldtime = millis()
}
If you are familiar with JavaScript you might find it beneficial use processing directly in javascript. That way it is easy to mix and match what you need and to use standard javascript debugging tools. There is a great tutorial on how to do this here:
http://processingjs.org/articles/jsQuickStart.html#javascriptonlyprocessingcode

Metro c++ async programming and UI updating. My technique?

The problem: I'm crashing when I want to render my incoming data which was retrieved asynchronously.
The app starts and displays some dialog boxes using XAML. Once the user fills in their data and clicks the login button, the XAML class has in instance of a worker class that does the HTTP stuff for me (asynchronously using IXMLHTTPRequest2). When the app has successfully logged in to the web server, my .then() block fires and I make a callback to my main xaml class to do some rendering of the assets.
I am always getting crashes in the delegate though (the main XAML class), which leads me to believe that I cannot use this approach (pure virtual class and callbacks) to update my UI. I think I am inadvertently trying to do something illegal from an incorrect thread which is a byproduct of the async calls.
Is there a better or different way that I should be notifying the main XAML class that it is time for it to update it's UI? I am coming from an iOS world where I could use NotificationCenter.
Now, I saw that Microsoft has it's own Delegate type of thing here: http://msdn.microsoft.com/en-us/library/windows/apps/hh755798.aspx
Do you think that if I used this approach instead of my own callbacks that it would no longer crash?
Let me know if you need more clarification or what not.
Here is the jist of the code:
public interface class ISmileServiceEvents
{
public: // required methods
virtual void UpdateUI(bool isValid) abstract;
};
// In main XAML.cpp which inherits from an ISmileServiceEvents
void buttonClick(...){
_myUser->LoginAndGetAssets(txtEmail->Text, txtPass->Password);
}
void UpdateUI(String^ data) // implements ISmileServiceEvents
{
// This is where I would render my assets if I could.
// Cannot legally do much here. Always crashes.
// Follow the rest of the code to get here.
}
// In MyUser.cpp
void LoginAndGetAssets(String^ email, String^ password){
Uri^ uri = ref new URI(MY_SERVER + "login.json");
String^ inJSON = "some json input data here"; // serialized email and password with other data
// make the HTTP request to login, then notify XAML that it has data to render.
_myService->HTTPPostAsync(uri, json).then([](String^ outputJson){
String^ assets = MyParser::Parse(outputJSON);
// The Login has returned and we have our json output data
if(_delegate)
{
_delegate->UpdateUI(assets);
}
});
}
// In MyService.cpp
task<String^> MyService::HTTPPostAsync(Uri^ uri, String^ json)
{
return _httpRequest.PostAsync(uri,
json->Data(),
_cancellationTokenSource.get_token()).then([this](task<std::wstring> response)
{
try
{
if(_httpRequest.GetStatusCode() != 200) SM_LOG_WARNING("Status code=", _httpRequest.GetStatusCode());
String^ j = ref new String(response.get().c_str());
return j;
}
catch (Exception^ ex) .......;
return ref new String(L"");
}, task_continuation_context::use_current());
}
Edit: BTW, the error I get when I go to update the UI is:
"An invalid parameter was passed to a function that considers invalid parameters fatal."
In this case I am just trying to execute in my callback is
txtBox->Text = data;
It appears you are updating the UI thread from the wrong context. You can use task_continuation_context::use_arbitrary() to allow you to update the UI. See the "Controlling the Execution Thread" example in this document (the discussion of marshaling is at the bottom).
So, it turns out that when you have a continuation, if you don't specify a context after the lambda function, that it defaults to use_arbitrary(). This is in contradiction to what I learned in an MS video.
However by adding use_currrent() to all of the .then blocks that have anything to do with the GUI, my error goes away and everything is able to render properly.
My GUI calls a service which generates some tasks and then calls to an HTTP class that does asynchronous stuff too. Way back in the HTTP classes I use use_arbitrary() so that it can run on secondary threads. This works fine. Just be sure to use use_current() on anything that has to do with the GUI.
Now that you have my answer, if you look at the original code you will see that it already contains use_current(). This is true, but I left out a wrapping function for simplicity of the example. That is where I needed to add use_current().