home
products
contribute
download
documentation
forum
Home
Forums
New posts
Search forums
What's new
New posts
All posts
Latest activity
Members
Registered members
Current visitors
Donate
Log in
Register
What's new
Search
Search
Search titles only
By:
New posts
Search forums
Search titles only
By:
Menu
Log in
Register
Navigation
Install the app
Install
More options
Contact us
Close Menu
Forums
MediaPortal 2
Skins and Design
Skinning contest: One month to go
Contact us
RSS
JavaScript is disabled. For a better experience, please enable JavaScript in your browser before proceeding.
You are using an out of date browser. It may not display this or other websites correctly.
You should upgrade or use an
alternative browser
.
Reply to thread
Message
<blockquote data-quote="FreakyJ" data-source="post: 681466" data-attributes="member: 106003"><p><strong>AW: Skinning contest: One month to go</strong></p><p></p><p>First of all thanks for your detailed help <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite2" alt=";)" title="Wink ;)" loading="lazy" data-shortname=";)" /></p><p></p><p>At first I tried to understand the ResourceWrapper, but I still don't get the point oO</p><p>In the file ShowPlaylist.xaml you are using the following line (for example):</p><p></p><p>[code]</p><p><ResourceWrapper x:Key="Contents_Element"></p><p>[/code]</p><p></p><p>I I don't find any reference in a .cs file to this "resource"... Also there is no reference in any .xaml file to "Contents_Element".</p><p></p><p>I think your example above make sense... If I'm right the example above should work like this (the <SomeUIElement> is maybe a bit confusing.., but I know that it is a placeholder for an element^^ But it can destroy my theory xD):</p><p></p><p>[code]</p><p><SomeUIElement></p><p> <Resources></p><p> <ResourceWrapper x:Key="BlackColor" Resource="#FF000000"/></p><p> </Resources></p><p></SomeUIElement></p><p></p><p><label color="BlackColor" content="string" /></p><p>[/code]</p><p></p><p>I didn't tried it yet, just tried to understand it in theory, because I'm still struggling at a more basic point and think I should understand this first before I will come to this back, but later on more on my little second problem^^</p><p></p><p>But what is the exact function of the ResourceWrapper in the ShowPlaylist.xaml file? Maybe I get the point if you could explain it <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite2" alt=";)" title="Wink ;)" loading="lazy" data-shortname=";)" /></p><p>Sure, you told me that I can use it if there is nor xml element like <string>, but why do you need it in the ShowPlaylist.xaml?! You have a <grid> element, which is "wrapping" all the stuff...</p><p></p><p>//------------------</p><p></p><p>Now to my little second problem, which is a bit more basic^^</p><p></p><p>First of all my xaml file:</p><p></p><p>[code]<DockPanel Name="FastParticleBackground.Window1"</p><p>xmlns="www.team-mediaportal.com/2008/mpf/directx"</p><p>xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"</p><p>Context="{Model Id=5726DA5A-70D5-458f-AF67-611293D97912}" LastChildFill="False"></p><p> <Grid></p><p> <Grid.Background></p><p> <RadialGradientBrush Center="0.54326,0.45465" RadiusX="0.602049" RadiusY="1.02049" GradientOrigin="0.4326,0.45465"></p><p> <GradientStop Color="#57ffe6" Offset="0"/></p><p> <GradientStop Color="#008ee7" Offset="0.718518495559692"/></p><p> <GradientStop Color="#2c0072" Offset="1"/></p><p> </RadialGradientBrush></p><p> </Grid.Background></p><p> <Canvas x:Name="ParticleHost"></p><p> <Ellipse RenderTransformOrigin="0.5,0.5" Width="5" Height="5" Fill="White"></p><p> <Ellipse.RenderTransform></p><p> <TransformGroup></p><p> <TranslateTransform X="{Binding TranslateTransform0_X}" Y="{Binding TranslateTransform0_Y}"/></p><p> </TransformGroup></p><p> </Ellipse.RenderTransform></p><p> </Ellipse></p><p> </Canvas></p><p> <Label Content="{Binding HelloString}" Margin="10"</p><p> HorizontalAlignment="Left" VerticalAlignment="Center"/></p><p> </Grid></p><p></DockPanel>[/code]</p><p></p><p>the model.cs (still ugly stuff, I know, but I'm still in the try and error state^^ so there is no chance of a clean code xD)</p><p></p><p>[code]#region Copyright (C) 2007-2010 Team MediaPortal</p><p></p><p>/*</p><p> Copyright (C) 2007-2010 Team MediaPortal</p><p> https://www.team-mediaportal.com</p><p></p><p> This file is part of MediaPortal 2</p><p></p><p> MediaPortal 2 is free software: you can redistribute it and/or modify</p><p> it under the terms of the GNU General Public License as published by</p><p> the Free Software Foundation, either version 3 of the License, or</p><p> (at your option) any later version.</p><p></p><p> MediaPortal 2 is distributed in the hope that it will be useful,</p><p> but WITHOUT ANY WARRANTY; without even the implied warranty of</p><p> MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</p><p> GNU General Public License for more details.</p><p></p><p> You should have received a copy of the GNU General Public License</p><p> along with MediaPortal 2. If not, see <http://www.gnu.org/licenses/>.</p><p>*/</p><p></p><p>#endregion</p><p></p><p>using MediaPortal.Core.General;</p><p>using MediaPortal.UI.Presentation.Models;</p><p></p><p>using MediaPortal.UI.SkinEngine.MpfElements;</p><p>using MediaPortal.UI.SkinEngine.SkinManagement;</p><p>using MediaPortal.UI.SkinEngine.Xaml;</p><p>using MediaPortal.UI.SkinEngine.Xaml.Interfaces;</p><p>using MediaPortal.UI.SkinEngine.Controls.Visuals;</p><p>using MediaPortal.UI.SkinEngine.MpfElements.Resources;</p><p></p><p>using System;</p><p>using System.Collections.Generic;</p><p>using System.Linq;</p><p>using System.Text;</p><p>using System.Windows;</p><p>using System.Windows.Data;</p><p>using System.Windows.Documents;</p><p>using System.Windows.Input;</p><p>using System.Windows.Media;</p><p>using System.Windows.Media.Imaging;</p><p>using System.Windows.Navigation;</p><p></p><p>using System.Windows.Threading;</p><p>//using System.Windows.Media;</p><p>using System.Windows.Media.Media3D;</p><p>using System.Windows.Media.Effects;</p><p>using System.Windows.Shapes;</p><p>using System.Collections;</p><p>using System;</p><p>using System.Windows;</p><p></p><p>namespace Models.HelloWorld</p><p>{</p><p> /// <summary></p><p> /// Example for a simple model.</p><p> /// The screenfile to this model is located at:</p><p> /// /Skins/default/screens/hello_world.xaml</p><p> /// </summary></p><p> /// <remarks></p><p> /// <para></p><p> /// Models are used for providing data from the system to the skin and for executing actions (commands)</p><p> /// which are triggered by the Skin, for example by clicking a button.</p><p> /// </para></p><p> /// <para></p><p> /// All public properties can be data-bound by the skin, for example the <see cref="HelloString"/> property.</p><p> /// Note that properties, which are updated by the model and whose new value should be propagated to the</p><p> /// skin, must be backed by an instance of <see cref="AbstractProperty"/>. That instance must be made available</p><p> /// to the skin engine by publishing it under the same name as the actual property plus "Property", see for example</p><p> /// <see cref="HelloStringProperty"/>.</p><p> /// </para></p><p> /// <para></p><p> /// You can also consider to implement the interface <see cref="IWorkflowModel"/>, which makes it</p><p> /// possible to attend the screenflow = workflow of the user session. When that interface is implemented and this</p><p> /// model is registered in a workflow state as backing workflow model, the model will get notifications when the</p><p> /// GUI navigation switches to or away from its workflow state.</p><p> /// </para></p><p> /// <para></p><p> /// To make an UI model known by the system (and thus loadable by the skin), it is necessary to register it</p><p> /// in the <c>plugin.xml</c> file.</p><p> /// </para></p><p> /// </remarks></p><p> public class Model</p><p> {</p><p> // ListItem</p><p> public List<Particle> particleList = new List<Particle>();</p><p> </p><p> /// <summary></p><p> /// This is a localized string resource. Localized string resources always look like this:</p><p> /// <example></p><p> /// [Section.Name]</p><p> /// </example></p><p> /// Localized resources must be present at least in the english language, as this is the default.</p><p> /// In the english language file of this hello world plugin, you'll find the translation of this string.</p><p> /// The language file is located at: /Language/strings_en.xml</p><p> /// </summary></p><p> protected const string HELLOWORLD_RESOURCE = "[HelloWorld.HelloWorldText]";</p><p> protected const string TranslateTransform0_X_RESOURCE = "20";</p><p> protected const string TranslateTransform0_Y_RESOURCE = "20";</p><p></p><p> /// <summary></p><p> /// Another localized string resource.</p><p> /// </summary></p><p> protected const string COMMAND_TRIGGERED_RESOURCE = "[HelloWorld.ButtonTextCommandExecuted]";</p><p></p><p> /// <summary></p><p> /// This property holds a string that we will modify in this tutorial.</p><p> /// </summary></p><p> private readonly AbstractProperty _helloStringProperty;</p><p> private readonly AbstractProperty _TranslateTransform0_XProperty;</p><p> private readonly AbstractProperty _TranslateTransform0_YProperty;</p><p></p><p> /// <summary></p><p> /// Constructor... this one is called by the WorkflowManager when this model is loaded due to a screen reference.</p><p> /// </summary></p><p> public Model()</p><p> {</p><p> // In models, properties will always be WProperty instances. When using SProperties for screen databinding,</p><p> // the system might run into memory leaks.</p><p> _helloStringProperty = new WProperty(typeof(string), HELLOWORLD_RESOURCE);</p><p> _TranslateTransform0_XProperty = new WProperty(typeof(string), TranslateTransform0_X_RESOURCE);</p><p> _TranslateTransform0_YProperty = new WProperty(typeof(string), TranslateTransform0_Y_RESOURCE);</p><p> //_ParticleHost = new WProperty(typeof(string), ParticleHost);</p><p></p><p> Window_Loaded();</p><p> }</p><p> </p><p> /// <summary></p><p> /// This sample property will be accessed by the hello_world screen. Note that the data type must be the same</p><p> /// as in the instantiation of our backing property <see cref="_helloStringProperty"/>.</p><p> /// </summary></p><p> public string HelloString</p><p> {</p><p> get { return (string) _helloStringProperty.GetValue(); }</p><p> set { _helloStringProperty.SetValue(value); }</p><p> }</p><p></p><p> public string TranslateTransform0_X</p><p> {</p><p> get { return (string)_TranslateTransform0_XProperty.GetValue(); }</p><p> set { _TranslateTransform0_XProperty.SetValue(value); }</p><p> }</p><p></p><p> public string TranslateTransform0_Y</p><p> {</p><p> get { return (string)_TranslateTransform0_YProperty.GetValue(); }</p><p> set { _TranslateTransform0_YProperty.SetValue(value); }</p><p> }</p><p></p><p> /// <summary></p><p> /// This is the dependency property for our sample string. It is needed to propagate changes to the skin.</p><p> /// </summary></p><p> /// <remarks></p><p> /// <para></p><p> /// If the screen databinds to the <see cref="HelloString"/> property in a binding mode which will propagate data</p><p> /// changes from the model to the skin, the SkinEngine will attach a change handler to this property.</p><p> /// </para></p><p> /// <para></p><p> /// In other words: Every property <c>Xyz</c>, which should be able to be attached to, must be present also as</p><p> /// <c>XyzProperty</c>.</p><p> /// Only if <c>XyzProperty</c> is present in the model, value changes can be propagated to the skin.</p><p> /// </remarks></p><p> public AbstractProperty HelloStringProperty</p><p> {</p><p> get { return _helloStringProperty; }</p><p> }</p><p></p><p> public AbstractProperty TranslateTransform0_XProperty</p><p> {</p><p> get { return _TranslateTransform0_XProperty; }</p><p> }</p><p></p><p> public AbstractProperty TranslateTransform0_YProperty</p><p> {</p><p> get { return _TranslateTransform0_YProperty; }</p><p> }</p><p></p><p> /// <summary></p><p> /// Method which will be called from our screen. We will change the value of our HelloWorld string here.</p><p> /// </summary></p><p> public void ChangeHelloWorldString()</p><p> {</p><p> HelloString = COMMAND_TRIGGERED_RESOURCE;</p><p> }</p><p></p><p> DispatcherTimer timer = new DispatcherTimer();</p><p> Random random = new Random(DateTime.Now.Millisecond);</p><p></p><p> // Some general values </p><p> double MaxSize = 30;</p><p> double NumberOfParticles = 25;</p><p> int Width = 800;</p><p> int Height = 600;</p><p> /*double VerticalVelocity = 0.4;</p><p> double HorizontalVelocity = -2.2;</p><p> double elapsed = 0.1;*/</p><p> </p><p> public void Window_Loaded()</p><p> {</p><p> for (int i = 0; i < NumberOfParticles; i++)</p><p> {</p><p> CreateParticle();</p><p> }</p><p></p><p> timer.Interval = TimeSpan.FromMilliseconds(33.33);</p><p> timer.Tick += new EventHandler(timer_Tick);</p><p> timer.Start();</p><p></p><p> HelloString = "EXECUTED";</p><p> }</p><p> </p><p> void timer_Tick(object sender, EventArgs e)</p><p> {</p><p> // I control "particle" from their ellipse representation </p><p> //foreach (Ellipse ellipse in ParticleHost.Children)</p><p> //{</p><p> /*var p = ellipse.Tag as Particle;</p><p> var t = ellipse.RenderTransform as TranslateTransform;</p><p></p><p> // Update location </p><p> t.X += p.Velocity.X;</p><p> t.Y += p.Velocity.Y;</p><p></p><p></p><p> // Check if the particle is too high </p><p> if (t.Y < -MaxSize)</p><p> {</p><p> t.Y = Height + MaxSize;</p><p> }</p><p></p><p> // Check if the particle has gone outside </p><p> if (t.X < -MaxSize || t.X > Width + MaxSize)</p><p> {</p><p> t.X = random.NextDouble() * Width;</p><p> t.Y = Height + MaxSize;</p><p> }</p><p></p><p> // Brush & Effect </p><p> //ellipse.Fill = p.Brush;</p><p> ellipse.Fill = (Brush)Brushes.White.Clone();</p><p> // Comment this line to deactivate the Blur Effect </p><p> ellipse.Effect = p.Blur;*/</p><p> //}</p><p></p><p> //----------------------------</p><p></p><p> foreach (Particle particle in particleList)</p><p> {</p><p> TranslateTransform0_X = (ToDouble(TranslateTransform0_X) + particle.Velocity.X).ToString();</p><p> TranslateTransform0_Y = (ToDouble(TranslateTransform0_Y) + particle.Velocity.Y).ToString();</p><p></p><p> HelloString = "Transform X to " + TranslateTransform0_X;</p><p></p><p> // Check if the particle is too high </p><p> if (ToDouble(TranslateTransform0_Y) < -MaxSize)</p><p> {</p><p> TranslateTransform0_Y = (Height + MaxSize).ToString();</p><p> }</p><p></p><p> // Check if the particle has gone outside </p><p> if (ToDouble(TranslateTransform0_X) < -MaxSize || ToDouble(TranslateTransform0_X) > Width + MaxSize)</p><p> {</p><p> TranslateTransform0_X = (random.NextDouble() * Width).ToString();</p><p> TranslateTransform0_Y = (Height + MaxSize).ToString();</p><p> }</p><p> }</p><p> }</p><p> </p><p> private void CreateParticle()</p><p> {</p><p> </p><p> </p><p> // Brush (White) </p><p> var brush = System.Windows.Media.Brushes.White.Clone();</p><p> // Opacity (0.2 <= 1) </p><p> brush.Opacity = 0.2 + random.NextDouble() * 0.8;</p><p> // Blur effect </p><p> var blur = new BlurEffect();</p><p> blur.RenderingBias = RenderingBias.Performance;</p><p> // Radius (1 <= 40) </p><p> blur.Radius = 1 + random.NextDouble() * 39;</p><p> // Ellipse </p><p> var ellipse = new Ellipse();</p><p> // Size (from 15% to 95% of MaxSize) </p><p> ellipse.Width = ellipse.Height = MaxSize * 0.15 + random.NextDouble() * MaxSize * 0.8;</p><p> // Starting location of the ellipse (anywhere in the scree</p><p></p><p> // extraTags adden</p><p> var p = new Particle();</p><p></p><p> // Speed</p><p> double speed = RandomWithVariance(20, 15);</p><p> double velocityMultiplier = (random.NextDouble() + 0.25) * speed;</p><p> double vX = (1.0 - (random.NextDouble() * 2.0)) * velocityMultiplier;</p><p> // Only going from the bottom of the screen to the top (for now)</p><p> double vY = -Math.Abs((1.0 - (random.NextDouble() * 2.0)) * velocityMultiplier);</p><p></p><p> p.Velocity = p.Velocity = new Point(vX, vY);</p><p> p.Blur = blur;</p><p> ellipse.Tag = p;</p><p> </p><p></p><p> //this.ParticleHost.Children.Add(ellipse);</p><p></p><p> TranslateTransform t;</p><p></p><p> t = new TranslateTransform();</p><p> ellipse.RenderTransform = t;</p><p> ellipse.RenderTransformOrigin = new Point(0.5, 0.5);</p><p> </p><p> //t.X = RandomWithVariance(Width / 2, Width / 2);</p><p> //t.Y = Height;</p><p></p><p> //----------------------------------------</p><p></p><p> // add particle to list</p><p> particleList.Add(p);</p><p></p><p> // set position</p><p> TranslateTransform0_X = RandomWithVariance(Width / 2, Width / 2).ToString();</p><p> TranslateTransform0_Y = Height.ToString();</p><p> }</p><p></p><p></p><p> private double RandomWithVariance(double midvalue, double variance)</p><p> {</p><p> double min = Math.Max(midvalue - (variance / 2), 0);</p><p> double max = midvalue + (variance / 2);</p><p> double value = min + ((max - min) * random.NextDouble());</p><p> return value;</p><p> }</p><p></p><p> #region helper functions</p><p></p><p> /// <summary></p><p> /// Wandelt in String in Double um</p><p> /// </summary></p><p> /// <param name="In"></param></p><p> /// <returns></returns></p><p> public static double ToDouble(string In)</p><p> {</p><p> In = In.Replace(",", ".");</p><p></p><p> return double.Parse(In, System.Globalization.CultureInfo.InvariantCulture);</p><p> }</p><p></p><p> /// <summary></p><p> /// Wandelt String in Double um mit Default falls es nicht möglich ist</p><p> /// </summary></p><p> /// <param name="In"></param></p><p> /// <param name="Default"></param></p><p> /// <returns></returns></p><p> public static double ToDouble(string In, double Default)</p><p> {</p><p> double dblOut;</p><p></p><p> In = In.Replace(",", ".");</p><p></p><p> try</p><p> {</p><p> dblOut = double.Parse(In, System.Globalization.CultureInfo.InvariantCulture);</p><p> }</p><p> catch</p><p> {</p><p> dblOut = Default;</p><p> }</p><p></p><p> return dblOut;</p><p> }</p><p></p><p> /// <summary></p><p> /// Wandelt einen String in Double um (Default = 0 oder es wird eine Exception ausgelöst)</p><p> /// </summary></p><p> /// <param name="In">String</param></p><p> /// <param name="UseExceptions">True (Exception wird ausgelöst) oder False (Default 0 wird verwendet)</param></p><p> /// <returns></returns></p><p> public static double ToDouble(string In, bool UseExceptions)</p><p> {</p><p> double dblOut;</p><p></p><p> In = In.Replace(",", ".");</p><p></p><p> try</p><p> {</p><p> dblOut = double.Parse(In, System.Globalization.CultureInfo.InvariantCulture);</p><p> }</p><p> catch (Exception ex)</p><p> {</p><p> if (UseExceptions)</p><p> throw ex;</p><p> else</p><p> dblOut = 0;</p><p> }</p><p></p><p> return dblOut;</p><p> }</p><p></p><p> #endregion</p><p> }</p><p>}</p><p>[/code]</p><p></p><p>hello-world-actions-xml</p><p></p><p>[code]<?xml version="1.0" encoding="utf-8"?></p><p><!-- Hello world workflow state actions --></p><p><Workflow DescriptorVersion="1.0"></p><p> <MenuActions></p><p> <!-- This is the workflow action which will be shown in the main menu in the home screen.</p><p> A PushNavigationTransition is a static action which is always visible in one or more defined</p><p> workflow states. When executed, the given target state will be pushed onto the workflow navigation stack.</p><p> There are also other action types which can be used at this place, for example it is possible to</p><p> make the action visible and invisible programmatically when using a workflow contributor action.</p><p></p><p> The action's name is only needed for debugging purposes and won't be shown to the user.</p><p></p><p> The DisplayCategory is used to group actions together. There is no detailed definition which groups</p><p> are present but the idea is that each plugin developer uses its own display categories to group its actions</p><p> together. There are also some common display categories which can be reused here. Use the first letter</p><p> as an indicator for the sort ordering, for example "z" for actions which should be posed at the end,</p><p> "a" for the beginning, etc.</p><p></p><p> The SortOrder is used for finer grained sorting inside a display category. We suggest to use a single, lower-case</p><p> letter here.</p><p></p><p> The SourceState attribute is needed to tell the system in which states the action should be visible.</p><p> Use the state's id here. You can also use a star ("*"). In that case, the action will be shown in each</p><p> state.</p><p></p><p> The TargetState attribute must always contain an id of a valid target state where the sytem will navigate to</p><p> when this action is executed.</p><p></p><p> The DisplayTitle will be shown in the main menu for this action. --></p><p> <PushNavigationTransition Id="EA48BD6E-60D3-45b2-9C35-1AB437CC72FB"</p><p> Name="Home->HelloWorld"</p><p> DisplayCategory="z-HelloWorld"</p><p> SortOrder="a"</p><p> SourceState="7F702D9C-F2DD-42da-9ED8-0BA92F07787F"</p><p> TargetState="D5CD9D35-1B36-4ede-8BED-A4FB658F27BD"</p><p> DisplayTitle="[HelloWorld.MenuEntry]"/></p><p> </MenuActions></p><p></Workflow>[/code]</p><p></p><p>hallo-world-states.xml</p><p></p><p>[code]<?xml version="1.0" encoding="utf-8"?></p><p><!-- Hello world workflow states --></p><p><Workflow DescriptorVersion="1.0"></p><p> <States></p><p> <!-- This is the workflow state which corresponds to the hello world screen. Each workflow state corresponds to</p><p> a certain UI state. The id is needed to be able to reference the state, for example in the action which</p><p> navigates to this state, see in file hello-world-actions.xml.</p><p></p><p> The name of the state is only needed for debug reasons and will not be shown to the user.</p><p></p><p> The MainScreen will automatically be shown by the workflow manager when switching to the state.</p><p> It is also possible to set the screen programmatically when using a workflow model.</p><p></p><p> The DisplayLabel is the string which is shown in the Navigation bar for this state. --></p><p> <WorkflowState Id="D5CD9D35-1B36-4ede-8BED-A4FB658F27BD"</p><p> Name="HelloWorldMain" MainScreen="hello_world"</p><p> DisplayLabel="[HelloWorld.StateDisplayLabel]"/> <!-- No workflow model --></p><p> </States></p><p></Workflow>[/code]</p><p></p><p>puuuhhh, a lot of stuff^^</p><p></p><p>If I'm executing the source above I will get the error "Error loading skin resource.." (log attached)</p><p>And in the log I find this line:</p><p></p><p></p><p>the id is the same as from the standard hallo world plugin... but the strange thing is if I change the first lines in the helloworld.xaml to this (removing the context="ID"):</p><p></p><p>[CODE]<DockPanel Name="FastParticleBackground.Window1"</p><p>xmlns="www.team-mediaportal.com/2008/mpf/directx"</p><p>xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">[/CODE]</p><p></p><p>I can "open" my plugin, but I don't see the label and the ellipse doesn't move... but I think it should work...</p><p>The question is now: What is the context="ID" for in the first lines?! Do I need it?</p><p></p><p>I will try still more debugging an maybe I will get further information <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite2" alt=";)" title="Wink ;)" loading="lazy" data-shortname=";)" /></p></blockquote><p></p>
[QUOTE="FreakyJ, post: 681466, member: 106003"] [b]AW: Skinning contest: One month to go[/b] First of all thanks for your detailed help ;) At first I tried to understand the ResourceWrapper, but I still don't get the point oO In the file ShowPlaylist.xaml you are using the following line (for example): [code] <ResourceWrapper x:Key="Contents_Element"> [/code] I I don't find any reference in a .cs file to this "resource"... Also there is no reference in any .xaml file to "Contents_Element". I think your example above make sense... If I'm right the example above should work like this (the <SomeUIElement> is maybe a bit confusing.., but I know that it is a placeholder for an element^^ But it can destroy my theory xD): [code] <SomeUIElement> <Resources> <ResourceWrapper x:Key="BlackColor" Resource="#FF000000"/> </Resources> </SomeUIElement> <label color="BlackColor" content="string" /> [/code] I didn't tried it yet, just tried to understand it in theory, because I'm still struggling at a more basic point and think I should understand this first before I will come to this back, but later on more on my little second problem^^ But what is the exact function of the ResourceWrapper in the ShowPlaylist.xaml file? Maybe I get the point if you could explain it ;) Sure, you told me that I can use it if there is nor xml element like <string>, but why do you need it in the ShowPlaylist.xaml?! You have a <grid> element, which is "wrapping" all the stuff... //------------------ Now to my little second problem, which is a bit more basic^^ First of all my xaml file: [code]<DockPanel Name="FastParticleBackground.Window1" xmlns="www.team-mediaportal.com/2008/mpf/directx" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Context="{Model Id=5726DA5A-70D5-458f-AF67-611293D97912}" LastChildFill="False"> <Grid> <Grid.Background> <RadialGradientBrush Center="0.54326,0.45465" RadiusX="0.602049" RadiusY="1.02049" GradientOrigin="0.4326,0.45465"> <GradientStop Color="#57ffe6" Offset="0"/> <GradientStop Color="#008ee7" Offset="0.718518495559692"/> <GradientStop Color="#2c0072" Offset="1"/> </RadialGradientBrush> </Grid.Background> <Canvas x:Name="ParticleHost"> <Ellipse RenderTransformOrigin="0.5,0.5" Width="5" Height="5" Fill="White"> <Ellipse.RenderTransform> <TransformGroup> <TranslateTransform X="{Binding TranslateTransform0_X}" Y="{Binding TranslateTransform0_Y}"/> </TransformGroup> </Ellipse.RenderTransform> </Ellipse> </Canvas> <Label Content="{Binding HelloString}" Margin="10" HorizontalAlignment="Left" VerticalAlignment="Center"/> </Grid> </DockPanel>[/code] the model.cs (still ugly stuff, I know, but I'm still in the try and error state^^ so there is no chance of a clean code xD) [code]#region Copyright (C) 2007-2010 Team MediaPortal /* Copyright (C) 2007-2010 Team MediaPortal https://www.team-mediaportal.com This file is part of MediaPortal 2 MediaPortal 2 is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. MediaPortal 2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with MediaPortal 2. If not, see <http://www.gnu.org/licenses/>. */ #endregion using MediaPortal.Core.General; using MediaPortal.UI.Presentation.Models; using MediaPortal.UI.SkinEngine.MpfElements; using MediaPortal.UI.SkinEngine.SkinManagement; using MediaPortal.UI.SkinEngine.Xaml; using MediaPortal.UI.SkinEngine.Xaml.Interfaces; using MediaPortal.UI.SkinEngine.Controls.Visuals; using MediaPortal.UI.SkinEngine.MpfElements.Resources; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Threading; //using System.Windows.Media; using System.Windows.Media.Media3D; using System.Windows.Media.Effects; using System.Windows.Shapes; using System.Collections; using System; using System.Windows; namespace Models.HelloWorld { /// <summary> /// Example for a simple model. /// The screenfile to this model is located at: /// /Skins/default/screens/hello_world.xaml /// </summary> /// <remarks> /// <para> /// Models are used for providing data from the system to the skin and for executing actions (commands) /// which are triggered by the Skin, for example by clicking a button. /// </para> /// <para> /// All public properties can be data-bound by the skin, for example the <see cref="HelloString"/> property. /// Note that properties, which are updated by the model and whose new value should be propagated to the /// skin, must be backed by an instance of <see cref="AbstractProperty"/>. That instance must be made available /// to the skin engine by publishing it under the same name as the actual property plus "Property", see for example /// <see cref="HelloStringProperty"/>. /// </para> /// <para> /// You can also consider to implement the interface <see cref="IWorkflowModel"/>, which makes it /// possible to attend the screenflow = workflow of the user session. When that interface is implemented and this /// model is registered in a workflow state as backing workflow model, the model will get notifications when the /// GUI navigation switches to or away from its workflow state. /// </para> /// <para> /// To make an UI model known by the system (and thus loadable by the skin), it is necessary to register it /// in the <c>plugin.xml</c> file. /// </para> /// </remarks> public class Model { // ListItem public List<Particle> particleList = new List<Particle>(); /// <summary> /// This is a localized string resource. Localized string resources always look like this: /// <example> /// [Section.Name] /// </example> /// Localized resources must be present at least in the english language, as this is the default. /// In the english language file of this hello world plugin, you'll find the translation of this string. /// The language file is located at: /Language/strings_en.xml /// </summary> protected const string HELLOWORLD_RESOURCE = "[HelloWorld.HelloWorldText]"; protected const string TranslateTransform0_X_RESOURCE = "20"; protected const string TranslateTransform0_Y_RESOURCE = "20"; /// <summary> /// Another localized string resource. /// </summary> protected const string COMMAND_TRIGGERED_RESOURCE = "[HelloWorld.ButtonTextCommandExecuted]"; /// <summary> /// This property holds a string that we will modify in this tutorial. /// </summary> private readonly AbstractProperty _helloStringProperty; private readonly AbstractProperty _TranslateTransform0_XProperty; private readonly AbstractProperty _TranslateTransform0_YProperty; /// <summary> /// Constructor... this one is called by the WorkflowManager when this model is loaded due to a screen reference. /// </summary> public Model() { // In models, properties will always be WProperty instances. When using SProperties for screen databinding, // the system might run into memory leaks. _helloStringProperty = new WProperty(typeof(string), HELLOWORLD_RESOURCE); _TranslateTransform0_XProperty = new WProperty(typeof(string), TranslateTransform0_X_RESOURCE); _TranslateTransform0_YProperty = new WProperty(typeof(string), TranslateTransform0_Y_RESOURCE); //_ParticleHost = new WProperty(typeof(string), ParticleHost); Window_Loaded(); } /// <summary> /// This sample property will be accessed by the hello_world screen. Note that the data type must be the same /// as in the instantiation of our backing property <see cref="_helloStringProperty"/>. /// </summary> public string HelloString { get { return (string) _helloStringProperty.GetValue(); } set { _helloStringProperty.SetValue(value); } } public string TranslateTransform0_X { get { return (string)_TranslateTransform0_XProperty.GetValue(); } set { _TranslateTransform0_XProperty.SetValue(value); } } public string TranslateTransform0_Y { get { return (string)_TranslateTransform0_YProperty.GetValue(); } set { _TranslateTransform0_YProperty.SetValue(value); } } /// <summary> /// This is the dependency property for our sample string. It is needed to propagate changes to the skin. /// </summary> /// <remarks> /// <para> /// If the screen databinds to the <see cref="HelloString"/> property in a binding mode which will propagate data /// changes from the model to the skin, the SkinEngine will attach a change handler to this property. /// </para> /// <para> /// In other words: Every property <c>Xyz</c>, which should be able to be attached to, must be present also as /// <c>XyzProperty</c>. /// Only if <c>XyzProperty</c> is present in the model, value changes can be propagated to the skin. /// </remarks> public AbstractProperty HelloStringProperty { get { return _helloStringProperty; } } public AbstractProperty TranslateTransform0_XProperty { get { return _TranslateTransform0_XProperty; } } public AbstractProperty TranslateTransform0_YProperty { get { return _TranslateTransform0_YProperty; } } /// <summary> /// Method which will be called from our screen. We will change the value of our HelloWorld string here. /// </summary> public void ChangeHelloWorldString() { HelloString = COMMAND_TRIGGERED_RESOURCE; } DispatcherTimer timer = new DispatcherTimer(); Random random = new Random(DateTime.Now.Millisecond); // Some general values double MaxSize = 30; double NumberOfParticles = 25; int Width = 800; int Height = 600; /*double VerticalVelocity = 0.4; double HorizontalVelocity = -2.2; double elapsed = 0.1;*/ public void Window_Loaded() { for (int i = 0; i < NumberOfParticles; i++) { CreateParticle(); } timer.Interval = TimeSpan.FromMilliseconds(33.33); timer.Tick += new EventHandler(timer_Tick); timer.Start(); HelloString = "EXECUTED"; } void timer_Tick(object sender, EventArgs e) { // I control "particle" from their ellipse representation //foreach (Ellipse ellipse in ParticleHost.Children) //{ /*var p = ellipse.Tag as Particle; var t = ellipse.RenderTransform as TranslateTransform; // Update location t.X += p.Velocity.X; t.Y += p.Velocity.Y; // Check if the particle is too high if (t.Y < -MaxSize) { t.Y = Height + MaxSize; } // Check if the particle has gone outside if (t.X < -MaxSize || t.X > Width + MaxSize) { t.X = random.NextDouble() * Width; t.Y = Height + MaxSize; } // Brush & Effect //ellipse.Fill = p.Brush; ellipse.Fill = (Brush)Brushes.White.Clone(); // Comment this line to deactivate the Blur Effect ellipse.Effect = p.Blur;*/ //} //---------------------------- foreach (Particle particle in particleList) { TranslateTransform0_X = (ToDouble(TranslateTransform0_X) + particle.Velocity.X).ToString(); TranslateTransform0_Y = (ToDouble(TranslateTransform0_Y) + particle.Velocity.Y).ToString(); HelloString = "Transform X to " + TranslateTransform0_X; // Check if the particle is too high if (ToDouble(TranslateTransform0_Y) < -MaxSize) { TranslateTransform0_Y = (Height + MaxSize).ToString(); } // Check if the particle has gone outside if (ToDouble(TranslateTransform0_X) < -MaxSize || ToDouble(TranslateTransform0_X) > Width + MaxSize) { TranslateTransform0_X = (random.NextDouble() * Width).ToString(); TranslateTransform0_Y = (Height + MaxSize).ToString(); } } } private void CreateParticle() { // Brush (White) var brush = System.Windows.Media.Brushes.White.Clone(); // Opacity (0.2 <= 1) brush.Opacity = 0.2 + random.NextDouble() * 0.8; // Blur effect var blur = new BlurEffect(); blur.RenderingBias = RenderingBias.Performance; // Radius (1 <= 40) blur.Radius = 1 + random.NextDouble() * 39; // Ellipse var ellipse = new Ellipse(); // Size (from 15% to 95% of MaxSize) ellipse.Width = ellipse.Height = MaxSize * 0.15 + random.NextDouble() * MaxSize * 0.8; // Starting location of the ellipse (anywhere in the scree // extraTags adden var p = new Particle(); // Speed double speed = RandomWithVariance(20, 15); double velocityMultiplier = (random.NextDouble() + 0.25) * speed; double vX = (1.0 - (random.NextDouble() * 2.0)) * velocityMultiplier; // Only going from the bottom of the screen to the top (for now) double vY = -Math.Abs((1.0 - (random.NextDouble() * 2.0)) * velocityMultiplier); p.Velocity = p.Velocity = new Point(vX, vY); p.Blur = blur; ellipse.Tag = p; //this.ParticleHost.Children.Add(ellipse); TranslateTransform t; t = new TranslateTransform(); ellipse.RenderTransform = t; ellipse.RenderTransformOrigin = new Point(0.5, 0.5); //t.X = RandomWithVariance(Width / 2, Width / 2); //t.Y = Height; //---------------------------------------- // add particle to list particleList.Add(p); // set position TranslateTransform0_X = RandomWithVariance(Width / 2, Width / 2).ToString(); TranslateTransform0_Y = Height.ToString(); } private double RandomWithVariance(double midvalue, double variance) { double min = Math.Max(midvalue - (variance / 2), 0); double max = midvalue + (variance / 2); double value = min + ((max - min) * random.NextDouble()); return value; } #region helper functions /// <summary> /// Wandelt in String in Double um /// </summary> /// <param name="In"></param> /// <returns></returns> public static double ToDouble(string In) { In = In.Replace(",", "."); return double.Parse(In, System.Globalization.CultureInfo.InvariantCulture); } /// <summary> /// Wandelt String in Double um mit Default falls es nicht möglich ist /// </summary> /// <param name="In"></param> /// <param name="Default"></param> /// <returns></returns> public static double ToDouble(string In, double Default) { double dblOut; In = In.Replace(",", "."); try { dblOut = double.Parse(In, System.Globalization.CultureInfo.InvariantCulture); } catch { dblOut = Default; } return dblOut; } /// <summary> /// Wandelt einen String in Double um (Default = 0 oder es wird eine Exception ausgelöst) /// </summary> /// <param name="In">String</param> /// <param name="UseExceptions">True (Exception wird ausgelöst) oder False (Default 0 wird verwendet)</param> /// <returns></returns> public static double ToDouble(string In, bool UseExceptions) { double dblOut; In = In.Replace(",", "."); try { dblOut = double.Parse(In, System.Globalization.CultureInfo.InvariantCulture); } catch (Exception ex) { if (UseExceptions) throw ex; else dblOut = 0; } return dblOut; } #endregion } } [/code] hello-world-actions-xml [code]<?xml version="1.0" encoding="utf-8"?> <!-- Hello world workflow state actions --> <Workflow DescriptorVersion="1.0"> <MenuActions> <!-- This is the workflow action which will be shown in the main menu in the home screen. A PushNavigationTransition is a static action which is always visible in one or more defined workflow states. When executed, the given target state will be pushed onto the workflow navigation stack. There are also other action types which can be used at this place, for example it is possible to make the action visible and invisible programmatically when using a workflow contributor action. The action's name is only needed for debugging purposes and won't be shown to the user. The DisplayCategory is used to group actions together. There is no detailed definition which groups are present but the idea is that each plugin developer uses its own display categories to group its actions together. There are also some common display categories which can be reused here. Use the first letter as an indicator for the sort ordering, for example "z" for actions which should be posed at the end, "a" for the beginning, etc. The SortOrder is used for finer grained sorting inside a display category. We suggest to use a single, lower-case letter here. The SourceState attribute is needed to tell the system in which states the action should be visible. Use the state's id here. You can also use a star ("*"). In that case, the action will be shown in each state. The TargetState attribute must always contain an id of a valid target state where the sytem will navigate to when this action is executed. The DisplayTitle will be shown in the main menu for this action. --> <PushNavigationTransition Id="EA48BD6E-60D3-45b2-9C35-1AB437CC72FB" Name="Home->HelloWorld" DisplayCategory="z-HelloWorld" SortOrder="a" SourceState="7F702D9C-F2DD-42da-9ED8-0BA92F07787F" TargetState="D5CD9D35-1B36-4ede-8BED-A4FB658F27BD" DisplayTitle="[HelloWorld.MenuEntry]"/> </MenuActions> </Workflow>[/code] hallo-world-states.xml [code]<?xml version="1.0" encoding="utf-8"?> <!-- Hello world workflow states --> <Workflow DescriptorVersion="1.0"> <States> <!-- This is the workflow state which corresponds to the hello world screen. Each workflow state corresponds to a certain UI state. The id is needed to be able to reference the state, for example in the action which navigates to this state, see in file hello-world-actions.xml. The name of the state is only needed for debug reasons and will not be shown to the user. The MainScreen will automatically be shown by the workflow manager when switching to the state. It is also possible to set the screen programmatically when using a workflow model. The DisplayLabel is the string which is shown in the Navigation bar for this state. --> <WorkflowState Id="D5CD9D35-1B36-4ede-8BED-A4FB658F27BD" Name="HelloWorldMain" MainScreen="hello_world" DisplayLabel="[HelloWorld.StateDisplayLabel]"/> <!-- No workflow model --> </States> </Workflow>[/code] puuuhhh, a lot of stuff^^ If I'm executing the source above I will get the error "Error loading skin resource.." (log attached) And in the log I find this line: the id is the same as from the standard hallo world plugin... but the strange thing is if I change the first lines in the helloworld.xaml to this (removing the context="ID"): [CODE]<DockPanel Name="FastParticleBackground.Window1" xmlns="www.team-mediaportal.com/2008/mpf/directx" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">[/CODE] I can "open" my plugin, but I don't see the label and the ellipse doesn't move... but I think it should work... The question is now: What is the context="ID" for in the first lines?! Do I need it? I will try still more debugging an maybe I will get further information ;) [/QUOTE]
Insert quotes…
Verification
Post reply
Forums
MediaPortal 2
Skins and Design
Skinning contest: One month to go
Contact us
RSS
Top
Bottom