• yueqiw

    @sreyemnayr I tried your re-worked script and it worked well.
    I used #import pythonista\n rather than #\input texinfo\n
    To make it run faster I prepend 10 strings in each iteration, e.g.f.write("#import pythonista\n" * 10 + source) and set counter to increment by 10.

    posted in Pythonista read more
  • yueqiw

    Check out the neuroscience game I created in Pythonista:
    https://github.com/yueqiw/ophys-game-ios

    It's been a while since I posted questions related to this, but I want to thank @JonB, @cvp and others for the help on getting the movie to play in WebView and setting up a game Scene on top of that.

    posted in Pythonista read more
  • yueqiw

    Just figured out the solution!

    It's very simple. Just need to call glClearColor(0, 0, 0, 0) and glClear(GL_COLOR_BUFFER_BIT) at every frame by in draw()

    class ChristmasScene(Scene):
        def setup(self):
            objv = ObjCInstance(self.view)
            objv.glkView().setOpaque_(False)
            sp = SpriteNode('emj:Christmas_Tree', anchor_point=(0,0), position=(500,300), parent=self))
        def draw(self):
            glClearColor(0, 0, 0, 0)
            glClear(GL_COLOR_BUFFER_BIT)
    
    # The rest of the code is the same as the most recent reply. No need to set up a separate delegate. 
    

    For this to work, the WebView has to be a subview of the SceneView. Adding WebView and SceneView as subviews of the same SuperView does not work well. Hope this doesn't break other drawing steps. Thanks again @JonB and @cvp for the help! Previous code examples from @omz and @Cethric also helped a lot for me to understand how things work.

    posted in Pythonista read more
  • yueqiw

    Update: Now I add webview as a background subview of the SceneView, by gameview.add_subview(webview) and webview.send_to_back().

    As long as the GLKView in the front has glClearColor(0, 0, 0, 0) in its glkView_drawInRect_() delegate method, the GLKView will be transparent.

    However, as you can see from the following code, once I plug in a new delegate to the GLKView of SceneView, its connection to Scene is also lost (I got the transparent background, but no longer able to draw SpriteNode on it.)

    from objc_util import *
    from scene import *
    import ui
    
    glClearColor = c.glClearColor
    glClearColor.restype = None
    glClearColor.argtypes = [c_float, c_float, c_float, c_float]
    glClear = c.glClear
    glClear.restype = None
    glClear.argtypes = [c_uint]
    GL_COLOR_BUFFER_BIT = 0x00004000
    
    def glkView_drawInRect_(_self, _cmd, view, rect):
        glClearColor(1, 0, 0, 0.3)
        glClear(GL_COLOR_BUFFER_BIT)
    
    MyGLViewDelegate = create_objc_class('MyGLViewDelegate', methods=[glkView_drawInRect_], protocols=['GLKViewDelegate'])
    
    class ChristmasScene(Scene):
        def setup(self):
            objv = ObjCInstance(self.view)
    
            delegate = MyGLViewDelegate.alloc().init()
            objv.glkView().setDelegate_(delegate)
            objv.glkView().setOpaque_(False)
            
            sp = SpriteNode('emj:Christmas_Tree', anchor_point=(0,0), position=(500,300), parent=self)
            
    w, h = ui.get_window_size()
    webview = ui.WebView(frame=(w/4,0,w/2,h))
    webview.load_url('http://google.com')
    gameview = SceneView()
    gameview.scene = ChristmasScene()
    
    gameview.add_subview(webview)
    webview.send_to_back()
    
    gameview.present('full_screen')
    
    
    

    posted in Pythonista read more
  • yueqiw

    @cvp @JonB Thanks a lot! I'll see if the mask layer is good enough for my purpose.

    I'm trying to implement some GLKit similar to this: https://forum.omz-software.com/topic/2066/python-opengles
    @omz Any suggestion?

    posted in Pythonista read more
  • yueqiw

    @cvp Thanks for trying! I'm stuck at the point where I couldn't find a way to access scene.background_color from ObjC.

    posted in Pythonista read more
  • yueqiw

    @scj643 Thanks! I'll get a slack in case I need more help.

    I thought I wouldn't have to use objc, but I just run into another problem that might need some objc: https://forum.omz-software.com/topic/3926/transparent-scene-background-using-objc_utils

    posted in Pythonista read more
  • yueqiw

    I tried to use objc_utils to change the background color, but have not figured out a solution. This is what I've tried so far:

    from objc_util import ObjCInstance, ObjCClass
    import objc_util
    
    UIColor = ObjCClass('UIColor')
    clear_color = UIColor.color(red=0.0, green=0.0, blue=0.0, alpha=0.0)
    
    objv = ObjCInstance(self.view)
    objv.backgroundColor = clear_color  
    # this make the **View** background of SceneView transparent, but does not alter the **Scene** background. 
    
    v1 = objv.subviews()[0]   # A GLKView instance
    v1.alpha = 0.2
    # this makes both the background and the content of the scene transparent
    v1.backgroundColor = clear_color
    # this does not do anything
    

    I need some help on how to set the background of SceneView() to be transparent, so that I can see the content of the WebView beneath it. Thanks!

    I saw some threads on how to make background transparent in Objective-C using glClearColor: http://stackoverflow.com/questions/10636176/opengl-es-2-0-glkit-with-transparent-background . But I'm not sure how to do it in Pythonista.

    posted in Pythonista read more
  • yueqiw

    I'm trying to overlay a SceneView on top of a WebView. The goal is to have the WebView show mp4 video using html while the Scene in SceneView renders game objects and processes touch events. (I got the mp4 and html part working.)

    However, the Scene always have a solid background_color that blocks the webview content and I cannot make the Scene background transparent.

    Here is a toy example:

    from scene import *
    import ui
    
    class GameScene(Scene):
        def setup(self):
            self.background_color = None  
            # the background_color here only accepts RGB but not RGBA
            self.view.alpha = 0.2   
            # this changes the alpha of the entire SceneView, making both the background and the contents transparent. 
            sp = SpriteNode('emj:Christmas_Tree', anchor_point=(0,0), position=(100,100), parent=self)
            
    w, h = ui.get_window_size()
    frame = (0,0,w,h)
    v = ui.View(frame=frame)
    
    webview = ui.WebView(frame=(w/4,0,w/2,h))
    webview.load_url('http://google.com')
    v.add_subview(webview)
    
    gameview = SceneView()
    gameview.scene = GameScene()
    gameview.frame = (w/4, 0, w/2, h/2)
    v.add_subview(gameview)
    
    # overlay SceneView() on top of WebView()
    gameview.bring_to_front()
    v.present('full_screen')
    

    Thanks!

    posted in Pythonista read more
  • yueqiw

    @JonB

    The view has to be presented, and maybe onscreen, already for this to work, which might be why it didnt work for you(if you called evaljs before present).

    You are correct! Simply putting webview.eval_js('document.getElementById("myvideo").play();') after v.present() solved the problem -- Now it autoplays without any trigger.

    I did try webview.load_url(absfilepath), and as you said, it does not give much programatical control.

    Thanks a lot for the help!

    posted in Pythonista read more
  • yueqiw

    @JonB I tried pause and other things to make sure the video is properly loaded. My conclusion is that the video has to be triggered by some kind of user input, either by the iOS playback controls or any kind of button click (a button in html/js or a button in ui.Button() with eval_js(). I'm not exactly sure how the system prevents autoplay internally (maybe a older version of iOS Webkit), but now I've decided to go with a button trigger.

    posted in Pythonista read more
  • yueqiw

    @scj643 Thanks! I'll definitely install the library and try it out. I don't have experience using Objective-C, though.

    posted in Pythonista read more
  • yueqiw

    @cvp Thanks for the suggestion! I didn't know that ui.WebView() can inherit the methods of ui.View(). Now looks like there are a lot more things I can do with WebView.

    I ended up adding a button so that the background video (without playback control) starts playing after clicking the "start game" button. This is done by using eval_js() in the button_tapped() function

    The html template contains the following video tag:

    <video id="myvideo" preload="auto">
        <source src="{{FPATH}}" type="video/mp4">
    </video>
    

    The Python code load html and uses eval_js() to start video play after clicking the button.

    v = ui.View()
    webview = ui.WebView()
    v.add_subview(webview)
    
    html = TEMPLATE.replace('{{FPATH}}', absfilepath)
    webview.load_html(html)
    
    def button_tapped(sender):
        webview.eval_js('document.getElementById("myvideo").play();')
    
    button = ui.Button(title="Start Game")
    button.action = button_tapped
    v.add_subview(button)
    
    v.frame = (0,0,500,500)
    webview.frame = (0,0,500,500)
    v.present()
    

    So it looks like the user has to click on something to play any kind of video. Because simply calling webview.eval_js('document.getElementById("myvideo").play();') outside the button_tapped() function does not make the video play.

    posted in Pythonista read more
  • yueqiw

    I'm new to Pythonista and really like it. I'm trying to play .mp4 videos in ui.WebView(), but I cannot set the video to autoplay with playback controls hidden. The goal is to (1) program the video to start playing by itself and (2) disable/hide the playback control, so that it looks like background video.

    I tried two approaches. First by load_html() :
    webview = ui.WebView()
    html = TEMPLATE.replace('{{FPATH}}', absfilepath)
    webview.load_html(html)
    webview.present()
    

    The html has the following lines:

    <video autoplay>
        <source src="{{FPATH}}" type="video/mp4">
    </video>
    

    The video does not play when I set it to autoplay, It only plays when I use <video autoplay controls>, but in this case, I need to click the play button to start playing.

    It looks like the iOS WebKit now allows autoplay for videos without soundtrack. https://webkit.org/blog/6784/new-video-policies-for-ios/
    However, my video does not contain soundtrack, but it still cannot autoplay, even after I use <video muted autoplay>.

    Is there any solution to this?

    The second approach I tried is load_url()

    I tried webview.load_url(absfilepath) to load the .mp4 files directly onto WebView. It works and autoplays, but it always comes with playback controls. The video can be stopped by tapping on the screen and does not look like background video. Is there any way to hide the playback controls?

    Thanks!

    posted in Pythonista read more
Internal error.

Oops! Looks like something went wrong!