Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ScreenshotEvent #2602

Closed
wants to merge 7 commits into from
Closed

Add ScreenshotEvent #2602

wants to merge 7 commits into from

Conversation

shadowfacts
Copy link
Contributor

Adds ScreenshotEvent.Pre and ScreenshotEvent.Post which are fired respectively before and after screenshots are taken.

Pre can be used to change the screenshot file and cancel the event.

Post can be used to perform actions on the screenshot after it has been saved.

This was tested successfully using:

import net.minecraftforge.client.event.ScreenshotEvent;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;

import java.io.File;

@Mod(modid = "ScreenshotEventTest")
public class ScreenshotTest
{

    @Mod.EventHandler
    public void preInit(FMLPreInitializationEvent event) {
        MinecraftForge.EVENT_BUS.register(this);
    }

    @SubscribeEvent
    public void onScreenshotPre(ScreenshotEvent.Pre event) {
        event.setScreenshotFile(new File(event.getScreenshotFile().getParentFile(), "Screenshot_test.png"));
    }

    @SubscribeEvent
    public void onScreenshotPost(ScreenshotEvent.Post event) {
        System.out.println("Screenshot saved to: " + event.getScreenshotFile().getName());
    }

}

@williewillus
Copy link
Contributor

Maybe provide the BufferedImage if people want to change/use that for whatever reason?

}

+ net.minecraftforge.client.event.ScreenshotEvent.Pre preEvent = net.minecraftforge.client.ForgeHooksClient.onScreenshotPre(file2);
+ if (preEvent.isCanceled()) return preEvent.getCancelReason();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can make this 2 lines, and so much cleaner by moving code to the forge class.

@shadowfacts
Copy link
Contributor Author

@LexManos I don't see how it would be possible to move all that code into ForgeClientHooks. As far as I can tell, all the code that can be in there, is. I need 4 things from the pre event:

  • If it's canceled
    • If so, the cancellation message
  • The File to use
  • The BufferedImage

There's no way to return all three things from ForgeClientHooks.onScreenshotPre.

@kashike
Copy link
Contributor

kashike commented Mar 20, 2016

The indentation is weird throughout this PR

@shadowfacts
Copy link
Contributor Author

Fixed the indentation issues and a couple incorrect braces that I missed before.

@LexManos
Copy link
Member

Humm, im not quite sure why you need to return a completely new buffered image from the event.
You should really only have one event tho.
It should take in a reference to a buffered image. let people manipulate it and move on.
You should also send in and let people modify the file path HOWEVER they should be able to set it to null and disable the whole 'save to file' feature.

Something along the lines of:
file = Forge.onScreenshot(image, file); if (file == null) return;

Not quite sure why it needs a text return but meh.

@shadowfacts
Copy link
Contributor Author

cancelReason is required because that method returns an ITextComponent and if I returned null on cancellation, it would cause a NPE to be thrown later on because MC isn't expecting null.

@shadowfacts
Copy link
Contributor Author

Also, yes it could be simplified to one line but this:

net.minecraftforge.client.event.ScreenshotEvent.Pre preEvent = net.minecraftforge.client.ForgeHooksClient.onScreenshotPre(bufferedimage, file2); if (preEvent.isCanceled()) return preEvent.getCancelReason();

is very messy and difficult to read.

@shadowfacts
Copy link
Contributor Author

I've removed setImage and simplified the patch down to 3 lines total.

@Cancelable
public static class Pre extends ScreenshotEvent
{
private BufferedImage image;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be final now that the setter is gone.

@shadowfacts
Copy link
Contributor Author

@kashike image is now final

@LexManos
Copy link
Member

Github killed my newline, the if was supposed to be on a separate one.
The point is, we try and keep the patches as small as possible, AND we try and keep as few references to Forge classes from the patches.

And again, i'm still not even convinced that there needs to be a pre/post event to this. Not EVERY event needs a pre/post.

@shadowfacts
Copy link
Contributor Author

@LexManos The reason I made it this way is my ShadowTweaks mod adds a couple of things pertaining to screenshots:

  1. The ability to change the screenshot directory (this requires an event to be fired before the screenshot is saved in order to change the file)
  2. The ability to upload a screenshot to Imgur after it's taken (this requires an event to be fired after the screenshot is taken and saved)

If you have a way to make both these work, I would gladly use that, but this is the only solution I've been able to come up with.

@LexManos
Copy link
Member

Fire one event.
To Change the file path: Change the file path
To Upload the image: Encode the bufferedimage and upload it from MEMORY not file.
If you want you could prevent it saving to file by setting the path to null.

@shadowfacts
Copy link
Contributor Author

I rewrote it to only use one event which reduced the path to 2 lines.

This code was used to test it:

import net.minecraft.util.text.TextComponentString;
import net.minecraftforge.client.event.ScreenshotEvent;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;

import java.io.File;

/**
 * @author shadowfacts
 */
@Mod(modid = "ScreenshotEventTest")
public class ScreenshotTest
{

    @Mod.EventHandler
    public void preInit(FMLPreInitializationEvent event) {
        MinecraftForge.EVENT_BUS.register(this);
    }

    @SubscribeEvent
    public void onScreenshotPre(ScreenshotEvent event) {
//        event.setScreenshotFile(new File(event.getScreenshotFile().getParentFile(), "Screenshot_test2.png"));
        event.setCancelReason(new TextComponentString("Testerino"));
        event.setCanceled(true);
    }

}

@BlayTheNinth
Copy link
Contributor

Why is it specifically a "CancelReason" and not just a "ResultMessage" or something that gets returned in place of the actual message as long as its not null? I can see myself needing that if I were to implement TwelveIterationMods/EiraIRC#343 ([Upload & Share] Link in Screenshot Message) without hacks.

... of course I could just cancel it and then perform the ImageIO save-to-file myself, but I feel it'd be cleaner to just widen cancelReason to a general result chat component.

@shadowfacts
Copy link
Contributor Author

Added ScreenshotEvent#resultMessage

@shadowfacts
Copy link
Contributor Author

Anything else?

@shadowfacts shadowfacts mentioned this pull request May 5, 2016
@shadowfacts
Copy link
Contributor Author

Replaced by #2828.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants