Re: Problems with AnimationCtrl in a CustomTreeCtrl

Andrea Gavana <[email protected]> Wed, 25 Apr 2018 11:21:20 +0000
Newsgroups gmane.comp.python.wxpython.devel
Message-ID <CAEf70bz71xUg5ETO-UaHXoAHw7oSH4jQV4FH6OaVXJzgcVOWTg@mail.gmail.com>
Hi,

On Mon, 23 Apr 2018 at 22.09, Hélio Guilherme <[email protected]>
wrote:

> Dear Experts,
>
> I wanted to use GIF animations to show when Test is Running or Paused on
> my fork of Robot Framework IDE (RIDE).
>
> I did not find a way to attach the GIFs to the Tree Item, only managed to
> attach them to the Tree object.
>
> This would be really easy to do, if SetItemImage would play animated GIFs
> (even better if APNGs). It accepts GIFs but it does not animate.
>
> For the CustomTreeCtrl Item I only managed to get the X,Y for the checkbox
> element, and then add an offset to overlap the BMP for the state of the
> Item (it represents a Test Case).
>
> I recorded my application to show you my problem. See it at
> https://youtu.be/sjthvz2Fslg
>
> In the recording we can see:
> - When we scroll the Tree, the animated icon, moves accordingly - OK.
> - When we start the animation, the initial position is always as the first
> time the Tree is rendered - Not OK.
> - The animation is visible even when the Item is hidden - Not OK.
>
> (Users will not notice these bugs if they don't scroll or expand/collapse
> tree nodes ;) )
>
> As you can also see in the code, the Destroy commands for the Animation
> were not as effective as I would expect (or am I missing something?).
>
> Please give me some hints on how to get this perfect. Thanks.
> (You are welcome to help me fixing bugs or improving the code.)
>
> Here is the relevant piece of code (available on branch `gificons` at
> https://github.com/HelioGuilherme66/RIDE/blob/gificons/src/robotide/ui/tree.py
> ):
>
>    def _test_result(self, message):
>         wx.CallAfter(self._set_icon_from_execution_results, message.item)
>
>     def _set_icon_from_execution_results(self, controller):
>         node = self._controller.find_node_by_controller(controller)
>         if not node:
>             return
>         # Expand the node - Nice to have
>         # root = self.GetRootItem()
>         # self.Expand(root)  # node.GetParent())
>         # self.Expand(node)
>         img_index = self._get_icon_index_for(controller)
>         # print("DEBUG setIcon img_index=%d" % (img_index))
>         if self._animctrl:
>             self._animctrl.Stop()
>             self._animctrl.Animation.Destroy()
>             self._animctrl.Destroy()
>             self._animctrl = None
>         if img_index in (RUNNING_IMAGE_INDEX, PAUSED_IMAGE_INDEX):
>             from wx.adv import Animation, AnimationCtrl
>             import os
>             _BASE = os.path.join(os.path.dirname(__file__), '..',
> 'widgets')
>             if img_index == RUNNING_IMAGE_INDEX:
>                 img = os.path.join(_BASE, 'robot-running.gif')
>             else:
>                 img = os.path.join(_BASE, 'robot-pause.gif')
>             ani = Animation(img)
>             obj = self
>             rect = (node.GetX()+20, node.GetY()+1) # DEBUG Can't get item
> window
>             self._animctrl = AnimationCtrl(obj, -1, ani, rect)
>             self._animctrl.SetBackgroundColour(obj.GetBackgroundColour())
>             self._animctrl.Play()
>         else:
>             self.SetItemImage(node, img_index)
>
>     def _get_icon_index_for(self, controller):
>         if not self._execution_results:
>             return ROBOT_IMAGE_INDEX
>         if self._execution_results.is_paused(controller):
>             return PAUSED_IMAGE_INDEX
>         if self._execution_results.is_running(controller):
>             return RUNNING_IMAGE_INDEX
>         if self._execution_results.has_passed(controller):
>             return PASSED_IMAGE_INDEX
>         if self._execution_results.has_failed(controller):
>             return FAILED_IMAGE_INDEX
>         return ROBOT_IMAGE_INDEX
>
>
>

I see two ways to do this:

1. CustomTreeCtrl has a method called SetItemWindow, you can use it to
associate any non-top level window to any item in the tree. In your case,
you can assign an AnimationCtrl which will play your gifs .

2. If you can split the gif into its composing static images, you may add
all those images to the CustomTreeCtrl wx.ImageList and then, in a timer,
call SetItemImage on the item you wish to have your gif “played”.

Andrea.






> --
> You received this message because you are subscribed to the Google Groups
> "wxPython-dev" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups "wxPython-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
For more options, visit https://groups.google.com/d/optout.