Seek by clicking on video progress bar (1 Viewer)

morpheus_xx

Lead Dev MP2
  • Team MediaPortal
  • March 24, 2007
    11,400
    6,972
    Germany Germany
    Country flag
    To be honest, my EventHandlerExtension can be replaced by CommandStencilExtension.
    Yes, I think the CommandStencil would fit for our needs.

    Current XAML implementation can be seen here: https://github.com/MediaPortal/Medi...ult/screens/FullscreenContentDVD.xaml#L38-L44

    In code the UIC does override OnMouseMove of UIElement: https://github.com/MediaPortal/Medi...ements/Controls/UserInputCapture.cs#L126-L128

    Does this match to your approach?
     

    osre

    Retired Team Member
  • Premium Supporter
  • December 14, 2014
    766
    386
    Germany Germany
    Country flag
    My approach is an exact clone of WPF (syntax wise) except to use a CommandStencil instead of the method name from the code behind class.
    There are no extra CommandStencil properties needed in anyclass that get executed from On... methods.
    I simply create an delegate from the CommandStencil and add it to the event.

    I create an GUITest page with MouseDown event.
     

    osre

    Retired Team Member
  • Premium Supporter
  • December 14, 2014
    766
    386
    Germany Germany
    Country flag
    Ok, it's working now:

    my XAML lokks like this:
    XML:
    <?xml version="1.0" encoding="utf-8"?>
    <Screen
        xmlns="www.team-mediaportal.com/2008/mpf/directx"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    
      <Screen.Resources>
        <Model x:Key="Model" Id="F4FC1599-F412-40d0-82BF-46FC352E93BE"/>
        <!-- GUI-Test-Model -->
      </Screen.Resources>
    
      <Grid x:Name="Grid"
            PreviewMouseDown="{CommandStencil Source={StaticResource Model}, Path=PreviewMouseDownHandler}"
            MouseDown="{CommandStencil Source={StaticResource Model}, Path=MouseDownHandler}">
        <Grid.ColumnDefinitions>
          <ColumnDefinition Width="*"/>
          <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
          <RowDefinition Height="*"/>
          <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
       
        <Border Grid.Column="0" Grid.Row="0" Margin="20" Background="Yellow"
                PreviewMouseDown="{CommandStencil Source={StaticResource Model}, Path=PreviewMouseDownHandler}"
                MouseDown="{CommandStencil Source={StaticResource Model}, Path=MouseDownHandler}"
                x:Name="Yellow">
          <StackPanel Margin="10">
            <Border Margin="10" Background="Red" x:Name="RenInYellow"
                    PreviewMouseDown="{CommandStencil Source={StaticResource Model}, Path=PreviewMouseDownHandler}"
                    MouseDown="{CommandStencil Source={StaticResource Model}, Path=MouseDownHandler}">
              <Label HorizontalAlignment="Center" VerticalAlignment="Center"
                     Content="Red in yellow"/>
            </Border>
            <Border Margin="10" Background="Green" x:Name="GreenInYellow"
                    PreviewMouseDown="{CommandStencil Source={StaticResource Model}, Path=PreviewMouseDownHandler}"
                    MouseDown="{CommandStencil Source={StaticResource Model}, Path=MouseDownHandler}">
              <Label HorizontalAlignment="Center" VerticalAlignment="Center"
                     Content="Green in yellow"/>
            </Border>
          </StackPanel>
        </Border>
      </Grid>
    
    </Screen>
    The model looks like this:
    Code:
    public void PreviewMouseDownHandler(object sender, MouseButtonEventArgs e)
        {
          Debug.Print("PreviewMouseDownHandler sender={0}; Source={1}; OriginalSource={2}", sender, e.Source, e.OriginalSource);
        }
    
        public void MouseDownHandler(object sender, MouseButtonEventArgs e)
        {
          Debug.Print("MouseDownHandler sender={0}; Source={1}; OriginalSource={2}", sender, e.Source, e.OriginalSource);
        }
    When I click on the yellow area I get this output:
    Code:
    PreviewMouseDownHandler sender=Grid, Name: 'Grid', ElementState: Running; Source=Grid, Name: 'Grid', ElementState: Running; OriginalSource=StackPanel, ElementState: Running
    PreviewMouseDownHandler sender=Border, Name: 'Yellow', ElementState: Running; Source=Border, Name: 'Yellow', ElementState: Running; OriginalSource=StackPanel, ElementState: Running
    MouseDownHandler sender=Border, Name: 'Yellow', ElementState: Running; Source=Border, Name: 'Yellow', ElementState: Running; OriginalSource=StackPanel, ElementState: Running
    MouseDownHandler sender=Grid, Name: 'Grid', ElementState: Running; Source=Grid, Name: 'Grid', ElementState: Running; OriginalSource=StackPanel, ElementState: Running
    My "Hit testing" seems to return the StackPanel, even that it is transparent, and the Yellow Border should be the original source.
    Currently I missuse the OnMouseMove method for hittesting :whistle:

    When I click on the green area I get this:
    Code:
    PreviewMouseDownHandler sender=Grid, Name: 'Grid', ElementState: Running; Source=Grid, Name: 'Grid', ElementState: Running; OriginalSource=Border, Name: 'GreenInYellow', ElementState: Running
    PreviewMouseDownHandler sender=Border, Name: 'Yellow', ElementState: Running; Source=Border, Name: 'Yellow', ElementState: Running; OriginalSource=Border, Name: 'GreenInYellow', ElementState: Running
    PreviewMouseDownHandler sender=Border, Name: 'GreenInYellow', ElementState: Running; Source=Border, Name: 'GreenInYellow', ElementState: Running; OriginalSource=Border, Name: 'GreenInYellow', ElementState: Running
    MouseDownHandler sender=Border, Name: 'GreenInYellow', ElementState: Running; Source=Border, Name: 'GreenInYellow', ElementState: Running; OriginalSource=Border, Name: 'GreenInYellow', ElementState: Running
    MouseDownHandler sender=Border, Name: 'Yellow', ElementState: Running; Source=Border, Name: 'Yellow', ElementState: Running; OriginalSource=Border, Name: 'GreenInYellow', ElementState: Running
    MouseDownHandler sender=Grid, Name: 'Grid', ElementState: Running; Source=Grid, Name: 'Grid', ElementState: Running; OriginalSource=Border, Name: 'GreenInYellow', ElementState: Running
    The events in UIElement are defined like this (without the class handlers):
    Code:
       public static readonly RoutedEvent PreviewMouseDownEvent = EventManager.RegisterRoutedEvent(
          "PreviewMouseDown", RoutingStrategy.Tunnel, typeof(MouseButtonEventHandler), typeof(UIElement));
    
        // Provide CLR accessors for the event
        public event MouseButtonEventHandler PreviewMouseDown
        {
          add { AddHandler(PreviewMouseDownEvent, value); }
          remove { RemoveHandler(PreviewMouseDownEvent, value); }
        }
      public static readonly RoutedEvent MouseDownEvent = EventManager.RegisterRoutedEvent(
          "MouseDown", RoutingStrategy.Bubble, typeof(MouseButtonEventHandler), typeof(UIElement));
    
        // Provide CLR accessors for the event
        public event MouseButtonEventHandler MouseDown
        {
          add { AddHandler(MouseDownEvent, value); }
          remove { RemoveHandler(MouseDownEvent, value); }
        }
    For anyone who knows WPF, this should be straight forward.
    What's missing you might ask:
    - Proper event invocation
    - Hit testing
    - Adding all the events (and invoke them)
    That's it I guess.
     

    morpheus_xx

    Lead Dev MP2
  • Team MediaPortal
  • March 24, 2007
    11,400
    6,972
    Germany Germany
    Country flag
    One thing we need to consider here: the life time of resources is quite complicated in MPF. We have a "DeepCopy" logic to make sure that resources can be freed when they are no longer needed.

    There are following types of "resource lifetimes" (I hope this list is complete, as Albert wrote the logic):
    • Style resources: remain in memory as long as application runs
    • Screens: remain active once Workflow is in its state. After workflow transitions into a new workflow state, resources of former screen can be GCed
    When you deal with static event handler registration this could potentially introduce references that avoid proper GC. This needs to be checked thoroughly
     

    osre

    Retired Team Member
  • Premium Supporter
  • December 14, 2014
    766
    386
    Germany Germany
    Country flag
    The event handlers are not registered statically. It's the event definition that is registered statically. Same as in WPF.
    The event handlers are added directly to the UIElement (or subclasses).
    Only class handlers are registered globally, but only once per class, not per instance.
     

    osre

    Retired Team Member
  • Premium Supporter
  • December 14, 2014
    766
    386
    Germany Germany
    Country flag
    I think the basics are finished now.
    I have added (Preview)MouseDown and (Preview)MouseUp events to UIElement.
    The events get routed correctly through the InputManager dispatcher (I made a generic implementation for all routed events).
    Also hit testing is now performed correctly.
    In XAML event handler can be attached by the CommandStencil markup extension.
    I have currently two open topics, I have to look into:
    - Qualified event names in XAML (like Button.Click="... in an StackPanel)
    - Event triggers are most likely not useable with routed events so far.

    More events should be implemented as well, but specially with the key events I have to check that nothing gets broken.
    I'll make a code review and upload my changes, fro MP dev review then.
     

    osre

    Retired Team Member
  • Premium Supporter
  • December 14, 2014
    766
    386
    Germany Germany
    Country flag
    I have recognized some "confusion" with types for Point, Size, ...
    In some classes the WinFoms System.Darwing.PointF, ... are used (like InputManager)
    In other classes the (UIElement, ...) the SharpDX.Vector2 is used by defining "using PointF = SharpDX.Vector2;"
    This brings a bit confusion and unnecessary conversions with it.
    What is the intended type to use?
    From my point of view both are not my 1st choice:
    When using the WinFoms type, any plugin who needs to interact must reference WinForms (not a big deal, but not really necessary).
    When using SharpDX types, then every Plugin needs to reference SharpDX, which might be a bit more of a problem, if the renderer should be exchangeable.
    I would recommend to create some MP2 own types for these (like WPF does). By this a point can be called Point, ... Only in the rare classes where WinForms interop is needed, the name Point is a bit "ugly" b/c WinFoms has also a Point with in coordinates.
     

    osre

    Retired Team Member
  • Premium Supporter
  • December 14, 2014
    766
    386
    Germany Germany
    Country flag
    I started to implement the Qualified event names. The XAML parser runs into the attached properties section (as expected). I thought I could use part of the logic there (even the comments mention events already, so I guess it's intended).
    For my 1st try I added "UIElement.MouseDown=..." to my XAML screen.
    When it comes to resolving the type name UIElement the code runs into "MpfNamespaceHandler" which uses Mpf.ObjectClassRegistrations.
    This dictionary contains only non abstract types, which makes sense since it's used for which types can be instantiated in XAML.
    I think a nice extension would be to have abstract classes too, and have an optional parameter if abstract types are wanted as well.
    Also the dictionary could be filled automatically, using reflection.
    Do you think it's ok to implement changes like this to MpfNamespaceHandler?
    Currently I'm stuck here, because events from abstract classes must be able to use.
     

    morpheus_xx

    Lead Dev MP2
  • Team MediaPortal
  • March 24, 2007
    11,400
    6,972
    Germany Germany
    Country flag
    I have recognized some "confusion" with types for Point, Size, ...
    In some classes the WinFoms System.Darwing.PointF, ... are used (like InputManager)
    In other classes the (UIElement, ...) the SharpDX.Vector2 is used by defining "using PointF = SharpDX.Vector2;"
    For now I'd like to use the SharpDX.Vector2. The reason is, that I'm currently reworking the renderer to D2D. A global change would be better placed into (or after) this task.

    I think a nice extension would be to have abstract classes too, and have an optional parameter if abstract types are wanted as well.
    Yes, good idea. Go for it.
     

    Users Who Are Viewing This Thread (Users: 0, Guests: 1)

    OP Similar threads Forum Replies Date
    mrmojo666 seek video over lan very slow for big and highbitrates videos General Support 11
    B MP 1.23 First time click TV or Recorded TV fails, 2nd ... it will work General Support 5
    N [Finished] [MP2-781] Enable one-click deletion of grouped TV recordings MediaPortal 2 70
    P Clicking on channel in epg goes nothing General 2
    CanadianEh MP TV server rebuild with Colossus 2 - Kodi clients receive PMT error when playing videos recoreded by Colossus 2 TV-Server 1
    Rob Hexenmeister Skinning Online Videos question OnlineVideos 2
    A [solved] How to Play All Videos in a List watch/edit Videos 3
    O 1.25.0 Codecs and Video Format for PlayStation 2 Codecs, External Players 0
    g0rsq Info box randomly popping up when watching TV or other video MediaPortal 2 Newcomers Forum 1
    I Video Playback Stuttering General Support 45
    B some videos jerky Television (MyTV frontend and TV-Server) 0
    B MP 2.2.3 Error playing videos from NAS Submit: Bug Reports 2
    T Kurze Tonaussetzter bei Videos und TV Allgemeines Supportforum 1
    mrmojo666 [Tv Server Plugin ]Direct Show Video Control Plugin 0.0.0.1 for Hauppauge PVR cards MediaPortal 1 Plugins 0
    ajs [Proposal] Video embedded cover MediaPortal 1 1
    G [solved] Black Screen on all videos after upgrading to either 1.23 or 1.24 from 1.22 General Support 4
    H random black screen live tv and videos (amended) General Support 0
    404 [solved] Live TV...video and audio freeze General Support 20
    R kein Ton bei TV, Video, Aufnahme, Musik Allgemeines Support- und Diskussionsforum 0
    U [solved] Dynamic Refresh Rate for 23fps video Watch / Listen Media 1
    J Debug OnlineVideos, How To? OnlineVideos 1
    A MP2.2.2, understanding movies/videos/tv and WTV recordings. General 16
    C Problem playing videos created on IPhone X and Samsung S9 General Support 2
    H [solved] Video database genres, sort titles and collection thumbnails Newcomers Forum 12
    M How to Watch my videos from my Media Portal to My TV without TV Tuner Newcomers Forum 1
    Similar threads

























    Top Bottom