[longomatch] Add support for players subsitutions
- From: Andoni Morales Alastruey <amorales src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [longomatch] Add support for players subsitutions
- Date: Wed, 24 Sep 2014 20:32:44 +0000 (UTC)
commit aff71e30df100c131145e6bac2b89ac458f2f2c8
Author: Andoni Morales Alastruey <ylatuya gmail com>
Date: Mon Sep 22 21:25:07 2014 +0200
Add support for players subsitutions
LongoMatch.Core/Common/Constants.cs | 1 +
LongoMatch.Core/Common/Enums.cs | 9 +
LongoMatch.Core/Common/EventsBroker.cs | 10 +
LongoMatch.Core/Common/Exceptions.cs | 6 +
LongoMatch.Core/Handlers/Handlers.cs | 2 +-
LongoMatch.Core/Store/EventType.cs | 23 ++
LongoMatch.Core/Store/Player.cs | 2 +-
.../Store/Playlists/PlaylistPlayElement.cs | 2 +-
LongoMatch.Core/Store/Project.cs | 125 +++++++++++-
LongoMatch.Core/Store/TimeNode.cs | 6 +-
LongoMatch.Core/Store/TimelineEvent.cs | 167 ++++++++++++----
LongoMatch.Core/StyleConf.cs | 3 +
LongoMatch.Drawing/CanvasObjects/BenchObject.cs | 1 +
LongoMatch.Drawing/CanvasObjects/ButtonObject.cs | 35 ++++
LongoMatch.Drawing/CanvasObjects/FieldObject.cs | 40 +++--
.../CanvasObjects/PlayersTaggerObject.cs | 194 ++++++++++++++++--
LongoMatch.Drawing/CanvasObjects/TimeNodeObject.cs | 5 +
LongoMatch.Drawing/Widgets/TeamTagger.cs | 35 +++-
LongoMatch.GUI.Multimedia/Gui/PlayerBin.cs | 12 +-
LongoMatch.GUI.Multimedia/gtk-gui/objects.xml | 2 +-
LongoMatch.GUI/Gui/Component/CodingWidget.cs | 11 +
LongoMatch.GUI/Gui/Component/TeamTemplateEditor.cs | 11 +-
LongoMatch.GUI/Gui/Dialog/SubstitutionsEditor.cs | 216 ++++++++++++++++++++
LongoMatch.GUI/Gui/GUIToolkit.cs | 20 ++-
LongoMatch.GUI/Gui/Menu/PlaysMenu.cs | 40 +++--
LongoMatch.GUI/Gui/Panel/NewProjectPanel.cs | 31 +++-
LongoMatch.GUI/Gui/TreeView/PlaysTreeView.cs | 32 +++-
LongoMatch.GUI/LongoMatch.GUI.csproj | 2 +
LongoMatch.GUI/Makefile.am | 2 +
.../LongoMatch.Gui.Dialog.SubstitutionsEditor.cs | 140 +++++++++++++
LongoMatch.GUI/gtk-gui/gui.stetic | 157 ++++++++++++++
LongoMatch.GUI/gtk-gui/objects.xml | 100 +++++-----
LongoMatch.Migration/LongoMatch.Migration.csproj | 3 -
LongoMatch.Services/Services/EventsManager.cs | 17 ++
LongoMatch.Services/Services/ProjectsManager.cs | 1 +
po/POTFILES.in | 1 +
36 files changed, 1293 insertions(+), 171 deletions(-)
---
diff --git a/LongoMatch.Core/Common/Constants.cs b/LongoMatch.Core/Common/Constants.cs
index 2ae737f..4bc0db1 100644
--- a/LongoMatch.Core/Common/Constants.cs
+++ b/LongoMatch.Core/Common/Constants.cs
@@ -126,5 +126,6 @@ Xavier Queralt Mateu (ca)";
public static Guid PenaltyCardID = new Guid ("da4df338-3392-11e4-be8d-0811963e3880");
public static Guid ScoreID = new Guid ("dc4df338-3392-11e4-be8d-0811963e3880");
+ public static Guid SubsID = new Guid ("db4df338-3392-11e4-be8d-0811963e3880");
}
}
diff --git a/LongoMatch.Core/Common/Enums.cs b/LongoMatch.Core/Common/Enums.cs
index f4d5dd6..9c36cf4 100644
--- a/LongoMatch.Core/Common/Enums.cs
+++ b/LongoMatch.Core/Common/Enums.cs
@@ -258,5 +258,14 @@ namespace LongoMatch.Core.Common
Sorted = 8,
Focused = 16
}
+
+ public enum SubstitutionReason {
+ PlayersSubstitution,
+ PositionChange,
+ BenchPositionChange,
+ Injury,
+ TemporalExclusion,
+ Exclusion,
+ }
}
diff --git a/LongoMatch.Core/Common/EventsBroker.cs b/LongoMatch.Core/Common/EventsBroker.cs
index 0a1eb18..2644d90 100644
--- a/LongoMatch.Core/Common/EventsBroker.cs
+++ b/LongoMatch.Core/Common/EventsBroker.cs
@@ -22,6 +22,7 @@ using LongoMatch.Core.Store;
using LongoMatch.Core.Store.Playlists;
using LongoMatch.Core.Interfaces;
using LongoMatch.Core.Interfaces.GUI;
+using LongoMatch.Core.Store.Templates;
namespace LongoMatch.Core.Common
{
@@ -39,6 +40,7 @@ namespace LongoMatch.Core.Common
public event TagEventHandler TagEventEvent;
public event DuplicateEventsHandler DuplicateEventsEvent;
public event TeamsTagsChangedHandler TeamTagsChanged;
+ public event PlayersSubstitutionHandler PlayerSubstitutionEvent;
/* Playlist */
public event RenderPlaylistHandler RenderPlaylist;
@@ -377,6 +379,14 @@ namespace LongoMatch.Core.Common
public void EmitPressButton (DashboardButton button) {
}
+
+ public void EmitSubstitutionEvent (TeamTemplate team, Player p1, Player p2,
+ SubstitutionReason reason, Time time)
+ {
+ if (PlayerSubstitutionEvent != null) {
+ PlayerSubstitutionEvent (team, p1, p2, reason, time);
+ }
+ }
}
}
diff --git a/LongoMatch.Core/Common/Exceptions.cs b/LongoMatch.Core/Common/Exceptions.cs
index 0f5abcf..a07707d 100644
--- a/LongoMatch.Core/Common/Exceptions.cs
+++ b/LongoMatch.Core/Common/Exceptions.cs
@@ -37,5 +37,11 @@ namespace LongoMatch.Core.Common
{
}
}
+
+ public class SubstitutionException: Exception {
+ public SubstitutionException (string error): base (error)
+ {
+ }
+ }
}
diff --git a/LongoMatch.Core/Handlers/Handlers.cs b/LongoMatch.Core/Handlers/Handlers.cs
index 18f46ab..a3e92ee 100644
--- a/LongoMatch.Core/Handlers/Handlers.cs
+++ b/LongoMatch.Core/Handlers/Handlers.cs
@@ -105,7 +105,7 @@ namespace LongoMatch.Core.Handlers
public delegate void PlayerPropertiesHandler (Player player);
public delegate void PlayersPropertiesHandler (List<Player> players);
/* Players selection */
- public delegate void PlayersSubstitutionHandler (Player p1,Player p2,TeamTemplate team);
+ public delegate void PlayersSubstitutionHandler (TeamTemplate team, Player p1, Player p2,
SubstitutionReason reason, Time time);
public delegate void PlayersSelectionChangedHandler (List<Player> players);
/* A list of projects have been selected */
public delegate void ProjectsSelectedHandler (List<ProjectDescription> projects);
diff --git a/LongoMatch.Core/Store/EventType.cs b/LongoMatch.Core/Store/EventType.cs
index 9ad9a33..d937e23 100644
--- a/LongoMatch.Core/Store/EventType.cs
+++ b/LongoMatch.Core/Store/EventType.cs
@@ -166,5 +166,28 @@ namespace LongoMatch.Core.Store
return ID.GetHashCode ();
}
}
+
+ [Serializable]
+ public class SubstitutionEventType: EventType
+ {
+ public SubstitutionEventType ()
+ {
+ ID = Constants.SubsID;
+ Name = Catalog.GetString ("Substitution");
+ }
+
+ public override bool Equals (object obj)
+ {
+ SubstitutionEventType sc = obj as SubstitutionEventType;
+ if (sc == null)
+ return false;
+ return sc.ID == ID;
+ }
+
+ public override int GetHashCode ()
+ {
+ return ID.GetHashCode ();
+ }
+ }
}
diff --git a/LongoMatch.Core/Store/Player.cs b/LongoMatch.Core/Store/Player.cs
index 5f150cf..99c4271 100644
--- a/LongoMatch.Core/Store/Player.cs
+++ b/LongoMatch.Core/Store/Player.cs
@@ -148,7 +148,7 @@ namespace LongoMatch.Core.Store
} else {
displayName = Name + " " + LastName;
}
- return String.Format("{0} - {1}", Number, displayName);
+ return String.Format("{0}-{1}", Number, displayName);
}
#endregion
diff --git a/LongoMatch.Core/Store/Playlists/PlaylistPlayElement.cs
b/LongoMatch.Core/Store/Playlists/PlaylistPlayElement.cs
index 66adaae..3ab650b 100644
--- a/LongoMatch.Core/Store/Playlists/PlaylistPlayElement.cs
+++ b/LongoMatch.Core/Store/Playlists/PlaylistPlayElement.cs
@@ -61,7 +61,7 @@ namespace LongoMatch.Core.Store.Playlists
[JsonIgnore]
public string Description {
get {
- return Title;
+ return Title + " " + Play.Start.ToSecondsString () + " " +
Play.Stop.ToSecondsString ();
}
}
diff --git a/LongoMatch.Core/Store/Project.cs b/LongoMatch.Core/Store/Project.cs
index ec173e0..0b8390f 100644
--- a/LongoMatch.Core/Store/Project.cs
+++ b/LongoMatch.Core/Store/Project.cs
@@ -49,6 +49,7 @@ namespace LongoMatch.Core.Store
public class Project : IComparable, IIDObject
{
ProjectDescription description;
+ SubstitutionEventType subsType;
#region Constructors
public Project() {
@@ -160,6 +161,19 @@ namespace LongoMatch.Core.Store
}
}
+ [JsonIgnore]
+ public SubstitutionEventType SubstitutionsEventType {
+ get {
+ if (subsType == null) {
+ subsType = EventTypes.OfType<SubstitutionEventType> ().FirstOrDefault
();
+ if (subsType == null) {
+ subsType = new SubstitutionEventType ();
+ subsType.SortMethod = SortMethodType.SortByStartTime;
+ }
+ }
+ return subsType;
+ }
+ }
#endregion
#region Public Methods
@@ -262,10 +276,117 @@ namespace LongoMatch.Core.Store
public void UpdateEventTypes ()
{
- IEnumerable<EventType> types = Dashboard.List.OfType<EventButton>().Select(b =>
b.EventType);
+ IEnumerable<EventType> types = Dashboard.List.OfType<EventButton> ().Select (b =>
b.EventType);
EventTypes.AddRange (types.Except (EventTypes));
- types = Timeline.Select (t => t.EventType).Distinct().Except (EventTypes);
+ types = Timeline.Select (t => t.EventType).Distinct ().Except (EventTypes);
EventTypes.AddRange (types.Except (EventTypes));
+ if (!EventTypes.Contains (SubstitutionsEventType)) {
+ EventTypes.Add (SubstitutionsEventType);
+ }
+ }
+
+ public SubstitutionEvent SubsitutePlayer (TeamTemplate template, Player playerIn, Player
playerOut,
+ SubstitutionReason reason, Time subsTime)
+ {
+ Team team;
+ LineupEvent lineup;
+ SubstitutionEvent se;
+
+ if (template == LocalTeamTemplate) {
+ team = Team.LOCAL;
+ } else {
+ team = Team.VISITOR;
+ }
+ lineup = Timeline.OfType<LineupEvent> ().FirstOrDefault ();
+ if (lineup == null) {
+ throw new SubstitutionException (Catalog.GetString ("No lineup events
found"));
+ }
+ if (subsTime < lineup.EventTime) {
+ throw new SubstitutionException (Catalog.GetString ("A substitution can't
happen before the lineup event"));
+ }
+ se = new SubstitutionEvent ();
+ se.EventType = SubstitutionsEventType;
+ se.In = playerIn;
+ se.Out = playerOut;
+ se.Reason = reason;
+ se.EventTime = subsTime;
+ se.Team = team;
+ Timeline.Add (se);
+ return se;
+ }
+
+ public void CurrentLineup (Time currentTime,
+ out List<Player> homeFieldPlayers,
+ out List<Player> homeBenchPlayers,
+ out List<Player> awayFieldPlayers,
+ out List<Player> awayBenchPlayers)
+ {
+ TeamTemplate homeTeam, awayTeam;
+ LineupEvent lineup;
+ List<Player> homeTeamPlayers, awayTeamPlayers;
+
+ lineup = Timeline.OfType <LineupEvent> ().FirstOrDefault ();
+ if (lineup == null) {
+ lineup = CreateLineupEvent ();
+ }
+
+ homeTeamPlayers = lineup.HomeStartingPlayers.Concat (lineup.HomeBenchPlayers).ToList
();
+ awayTeamPlayers = lineup.AwayStartingPlayers.Concat (lineup.AwayBenchPlayers).ToList
();
+
+ foreach (SubstitutionEvent ev in Timeline.OfType<SubstitutionEvent> ().
+ Where (e => e.EventTime <= currentTime)) {
+ if (ev.In != null && ev.Out != null) {
+ if (ev.Team == Team.LOCAL) {
+ homeTeamPlayers.Swap (ev.In, ev.Out);
+ } else {
+ awayTeamPlayers.Swap (ev.In, ev.Out);
+ }
+ }
+ }
+
+ homeTeam = new TeamTemplate {
+ Formation = LocalTeamTemplate.Formation,
+ List = homeTeamPlayers
+ };
+ awayTeam = new TeamTemplate {
+ Formation = VisitorTeamTemplate.Formation,
+ List = awayTeamPlayers
+ };
+
+ homeFieldPlayers = homeTeam.StartingPlayersList;
+ homeBenchPlayers = homeTeam.BenchPlayersList;
+ awayFieldPlayers = awayTeam.StartingPlayersList;
+ awayBenchPlayers = awayTeam.BenchPlayersList;
+ }
+
+ public bool LineupChanged (Time start, Time stop)
+ {
+ return Timeline.OfType<SubstitutionEvent> ().
+ Count (s => s.EventTime > start && s.EventTime <= stop) > 0;
+ }
+
+ public LineupEvent CreateLineupEvent ()
+ {
+ Time startTime;
+ LineupEvent lineup;
+
+ if (Periods.Count == 0) {
+ startTime = new Time (0);
+ } else {
+ startTime = Periods[0].PeriodNode.Start;
+ }
+
+ lineup = new LineupEvent {
+ Name = Catalog.GetString ("Lineup ") + LocalTeamTemplate.TeamName,
+ EventType = SubstitutionsEventType,
+ HomeStartingPlayers = LocalTeamTemplate.StartingPlayersList,
+ HomeBenchPlayers = LocalTeamTemplate.BenchPlayersList,
+ AwayStartingPlayers = VisitorTeamTemplate.StartingPlayersList,
+ AwayBenchPlayers = VisitorTeamTemplate.BenchPlayersList,
+ EventTime = startTime};
+ Timeline.Add (lineup);
+
+ return lineup;
}
public List<TimelineEvent> EventsByType (EventType evType) {
diff --git a/LongoMatch.Core/Store/TimeNode.cs b/LongoMatch.Core/Store/TimeNode.cs
index 759dae0..c288984 100644
--- a/LongoMatch.Core/Store/TimeNode.cs
+++ b/LongoMatch.Core/Store/TimeNode.cs
@@ -45,7 +45,7 @@ namespace LongoMatch.Core.Store
/// <summary>
/// A short description of the time node
/// </summary>
- public string Name {
+ public virtual string Name {
get;
set;
}
@@ -53,7 +53,7 @@ namespace LongoMatch.Core.Store
/// <summary>
/// Start Time
/// </summary>
- public Time Start {
+ public virtual Time Start {
get {
return start;
}
@@ -68,7 +68,7 @@ namespace LongoMatch.Core.Store
/// <summary>
/// Stop time
/// </summary>
- public Time Stop {
+ public virtual Time Stop {
get {
return stop;
}
diff --git a/LongoMatch.Core/Store/TimelineEvent.cs b/LongoMatch.Core/Store/TimelineEvent.cs
index 5420138..e1476cb 100644
--- a/LongoMatch.Core/Store/TimelineEvent.cs
+++ b/LongoMatch.Core/Store/TimelineEvent.cs
@@ -17,7 +17,6 @@
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
//
//
-
using System;
using System.Collections.Generic;
using System.Linq;
@@ -28,7 +27,6 @@ using Newtonsoft.Json;
namespace LongoMatch.Core.Store
{
-
/// <summary>
/// Represents a Play in the game.
/// </summary>
@@ -38,22 +36,21 @@ namespace LongoMatch.Core.Store
{
#region Constructors
- public TimelineEvent() {
- Drawings = new List<FrameDrawing>();
+ public TimelineEvent ()
+ {
+ Drawings = new List<FrameDrawing> ();
Players = new List<Player> ();
- Tags = new List<Tag>();
+ Tags = new List<Tag> ();
Rate = 1.0f;
ID = Guid.NewGuid ();
}
#endregion
-
#region Properties
-
public Guid ID {
get;
set;
}
-
+
/// <summary>
/// Category in which this play is tagged
/// </summary>
@@ -86,20 +83,20 @@ namespace LongoMatch.Core.Store
get;
set;
}
-
/* FIXME: Keep this until we support multiple drawings */
[JsonIgnore]
public FrameDrawing KeyFrameDrawing {
get {
- if(Drawings.Count > 0)
- return Drawings.First();
+ if (Drawings.Count > 0)
+ return Drawings.First ();
else
return null;
- } set {
+ }
+ set {
if (Drawings.Count == 0)
Drawings.Add (value);
else
- Drawings[0] = value;
+ Drawings [0] = value;
}
}
@@ -117,7 +114,7 @@ namespace LongoMatch.Core.Store
get;
set;
}
-
+
public Team Team {
get;
set;
@@ -127,7 +124,7 @@ namespace LongoMatch.Core.Store
get;
set;
}
-
+
public Coordinates FieldPosition {
get;
set;
@@ -137,19 +134,19 @@ namespace LongoMatch.Core.Store
get;
set;
}
-
+
public Coordinates GoalPosition {
get;
set;
}
-
+
[JsonIgnore]
public virtual string Description {
get {
return
- Name + "\n" +
- TagsDescription () + "\n" +
- Start.ToMSecondsString() + " - " + Stop.ToMSecondsString();
+ (Name + "\n" +
+ TagsDescription () + "\n" +
+ TimesDesription ());
}
}
@@ -160,14 +157,25 @@ namespace LongoMatch.Core.Store
}
}
#endregion
-
#region Public methods
-
- public string TagsDescription () {
+ public string TagsDescription ()
+ {
return String.Join ("-", Tags.Select (t => t.Value));
}
- public void AddDefaultPositions () {
+ public string TimesDesription ()
+ {
+ if (Start != null && Stop != null) {
+ return Start.ToMSecondsString () + " - " + Stop.ToMSecondsString ();
+ } else if (EventType != null) {
+ return EventTime.ToMSecondsString ();
+ } else {
+ return "";
+ }
+ }
+
+ public void AddDefaultPositions ()
+ {
if (EventType.TagFieldPosition) {
if (FieldPosition == null) {
FieldPosition = new Coordinates ();
@@ -194,8 +202,9 @@ namespace LongoMatch.Core.Store
}
}
}
-
- public Coordinates CoordinatesInFieldPosition (FieldPositionType pos) {
+
+ public Coordinates CoordinatesInFieldPosition (FieldPositionType pos)
+ {
switch (pos) {
case FieldPositionType.Field:
return FieldPosition;
@@ -206,8 +215,9 @@ namespace LongoMatch.Core.Store
}
return null;
}
-
- public void UpdateCoordinates (FieldPositionType pos, List<Point> points) {
+
+ public void UpdateCoordinates (FieldPositionType pos, List<Point> points)
+ {
Coordinates co = new Coordinates ();
co.Points = points;
@@ -223,14 +233,14 @@ namespace LongoMatch.Core.Store
break;
}
}
-
- public override string ToString()
+
+ public override string ToString ()
{
return Description;
}
#endregion
}
-
+
[Serializable]
public class PenaltyCardEvent: TimelineEvent
{
@@ -246,7 +256,7 @@ namespace LongoMatch.Core.Store
}
}
}
-
+
[Serializable]
public class ScoreEvent: TimelineEvent
{
@@ -261,15 +271,102 @@ namespace LongoMatch.Core.Store
return Score != null ? Score.Color : EventType.Color;
}
}
-
+
[JsonIgnore]
public override string Description {
get {
return String.Format ("{0} - {1}\n{2}\n{3}\n", Score.Points, Name,
- TagsDescription (), Start.ToMSecondsString(),
- Stop.ToMSecondsString());
+ TagsDescription (), Start.ToMSecondsString (),
+ Stop.ToMSecondsString ());
}
}
}
+ [Serializable]
+ public class StatEvent: TimelineEvent
+ {
+ public override Time Start {
+ get {
+ return EventTime;
+ }
+ set {
+ EventTime = value;
+ }
+ }
+
+ public override Time Stop {
+ get {
+ return EventTime;
+ }
+ set {
+ EventTime = value;
+ }
+ }
+ }
+
+ [Serializable]
+ public class SubstitutionEvent: StatEvent
+ {
+ public Player In {
+ get;
+ set;
+ }
+
+ public Player Out {
+ get;
+ set;
+ }
+
+ public override string Name {
+ get {
+ return Reason.ToString();
+ }
+ set {
+ }
+ }
+
+ public SubstitutionReason Reason {
+ get;
+ set;
+ }
+
+ [JsonIgnore]
+ public override string Description {
+ get {
+ string desc = "";
+ if (In != null && Out != null) {
+ desc = String.Format ("{0} ⟲ {1}", In, Out);
+ } else if (In != null) {
+ desc = "↷ " + In;
+ } else if (Out != null) {
+ desc = "↶ " + Out;
+ }
+ return desc += "\n" + EventTime.ToMSecondsString ();
+ }
+ }
+ }
+
+ [Serializable]
+ public class LineupEvent: StatEvent
+ {
+ public List<Player> HomeStartingPlayers {
+ get;
+ set;
+ }
+
+ public List<Player> HomeBenchPlayers {
+ get;
+ set;
+ }
+
+ public List<Player> AwayStartingPlayers {
+ get;
+ set;
+ }
+
+ public List<Player> AwayBenchPlayers {
+ get;
+ set;
+ }
+ }
}
diff --git a/LongoMatch.Core/StyleConf.cs b/LongoMatch.Core/StyleConf.cs
index 68714f3..b8b41a5 100644
--- a/LongoMatch.Core/StyleConf.cs
+++ b/LongoMatch.Core/StyleConf.cs
@@ -87,6 +87,9 @@ namespace LongoMatch.Core.Common
public const int PlayerNumberOffset = 17;
public const int PlayerArrowOffset = 14;
public const int PlayerArrowSize = 20;
+
+ public const string SubsLock = "hicolor/scalable/actions/longomatch-player-swap-lock.svg";
+ public const string SubsUnlock = "hicolor/scalable/actions/longomatch-player-swap-unlock.svg";
public const int NotebookTabIconSize = 18;
public const int NotebookTabSize = NotebookTabIconSize + 14;
diff --git a/LongoMatch.Drawing/CanvasObjects/BenchObject.cs b/LongoMatch.Drawing/CanvasObjects/BenchObject.cs
index d8093db..8f69de2 100644
--- a/LongoMatch.Drawing/CanvasObjects/BenchObject.cs
+++ b/LongoMatch.Drawing/CanvasObjects/BenchObject.cs
@@ -101,6 +101,7 @@ namespace LongoMatch.Drawing.CanvasObjects
foreach (PlayerObject po in BenchPlayers) {
po.Playing = false;
po.SubstitutionMode = SubstitutionMode;
+ po.Size = PlayersSize;
po.Draw (tk, area);
}
diff --git a/LongoMatch.Drawing/CanvasObjects/ButtonObject.cs
b/LongoMatch.Drawing/CanvasObjects/ButtonObject.cs
index bf3251d..3dacc69 100644
--- a/LongoMatch.Drawing/CanvasObjects/ButtonObject.cs
+++ b/LongoMatch.Drawing/CanvasObjects/ButtonObject.cs
@@ -24,6 +24,13 @@ namespace LongoMatch.Drawing.CanvasObjects
{
public class ButtonObject: CanvasButtonObject, IMovableObject
{
+ const int BORDER_SIZE = 4;
+
+ public ButtonObject () {
+ BackgroundColor = Config.Style.PaletteBackground;
+ BorderColor = Config.Style.PaletteBackgroundDark;
+ }
+
public virtual Point Position {
get;
set;
@@ -39,6 +46,11 @@ namespace LongoMatch.Drawing.CanvasObjects
set;
}
+ public string Text {
+ get;
+ set;
+ }
+
public virtual Color BorderColor {
get;
set;
@@ -59,6 +71,16 @@ namespace LongoMatch.Drawing.CanvasObjects
}
}
+ public Image BackgroundImage {
+ get;
+ set;
+ }
+
+ public Image BackgroundImageActive {
+ get;
+ set;
+ }
+
public TagMode Mode {
get;
set;
@@ -146,7 +168,20 @@ namespace LongoMatch.Drawing.CanvasObjects
public override void Draw (IDrawingToolkit tk, Area area)
{
+ Point pos = new Point (Position.X + BORDER_SIZE / 2, Position.Y + BORDER_SIZE / 2);
+
tk.Begin ();
+ DrawButton (tk);
+ DrawSelectionArea (tk);
+
+ if (Active && BackgroundImageActive != null) {
+ tk.DrawImage (pos, Width - BORDER_SIZE, Height - BORDER_SIZE,
BackgroundImageActive, true);
+ } else if (BackgroundImage != null) {
+ tk.DrawImage (pos, Width - BORDER_SIZE, Height - BORDER_SIZE,
BackgroundImage, true);
+ }
+ if (Text != null) {
+ tk.DrawText (Position, Width, Height, Text);
+ }
tk.End ();
}
}
diff --git a/LongoMatch.Drawing/CanvasObjects/FieldObject.cs b/LongoMatch.Drawing/CanvasObjects/FieldObject.cs
index b18ef3e..659e846 100644
--- a/LongoMatch.Drawing/CanvasObjects/FieldObject.cs
+++ b/LongoMatch.Drawing/CanvasObjects/FieldObject.cs
@@ -28,8 +28,6 @@ namespace LongoMatch.Drawing.CanvasObjects
{
int[] homeFormation;
int[] awayFormation;
- List<PlayerObject> homePlayingPlayers;
- List<PlayerObject> awayPlayingPlayers;
int playerSize;
Image background;
@@ -58,6 +56,16 @@ namespace LongoMatch.Drawing.CanvasObjects
set;
}
+ public List<PlayerObject> HomePlayingPlayers {
+ get;
+ set;
+ }
+
+ public List<PlayerObject> AwayPlayingPlayers {
+ get;
+ set;
+ }
+
public void LoadTeams (Image backgroundImg, int[] homeF, int[] awayF,
List<PlayerObject> homeT, List<PlayerObject> awayT,
int size, int nteams)
@@ -65,8 +73,8 @@ namespace LongoMatch.Drawing.CanvasObjects
background = backgroundImg;
homeFormation = homeF;
awayFormation = awayF;
- homePlayingPlayers = homeT;
- awayPlayingPlayers = awayT;
+ HomePlayingPlayers = homeT;
+ AwayPlayingPlayers = awayT;
playerSize = size;
NTeams = nteams;
Update ();
@@ -75,10 +83,10 @@ namespace LongoMatch.Drawing.CanvasObjects
public void Update ()
{
if (homeFormation != null) {
- UpdateTeam (homePlayingPlayers, homeFormation, Team.LOCAL);
+ UpdateTeam (HomePlayingPlayers, homeFormation, Team.LOCAL);
}
if (awayFormation != null) {
- UpdateTeam (awayPlayingPlayers, awayFormation, Team.VISITOR);
+ UpdateTeam (AwayPlayingPlayers, awayFormation, Team.VISITOR);
}
}
@@ -135,15 +143,19 @@ namespace LongoMatch.Drawing.CanvasObjects
if (background != null) {
tk.DrawImage (background);
}
- if (homePlayingPlayers != null) {
- foreach (PlayerObject po in homePlayingPlayers) {
+ if (HomePlayingPlayers != null) {
+ foreach (PlayerObject po in HomePlayingPlayers) {
po.Playing = true;
+ po.SubstitutionMode = SubstitutionMode;
+ po.Size = playerSize;
po.Draw (tk, area);
}
}
- if (awayPlayingPlayers != null) {
- foreach (PlayerObject po in awayPlayingPlayers) {
+ if (AwayPlayingPlayers != null) {
+ foreach (PlayerObject po in AwayPlayingPlayers) {
po.Playing = true;
+ po.SubstitutionMode = SubstitutionMode;
+ po.Size = playerSize;
po.Draw (tk, area);
}
}
@@ -156,15 +168,15 @@ namespace LongoMatch.Drawing.CanvasObjects
point = Utils.ToUserCoords (point, Position, 1, 1);
- if (homePlayingPlayers != null) {
- foreach (PlayerObject po in homePlayingPlayers) {
+ if (HomePlayingPlayers != null) {
+ foreach (PlayerObject po in HomePlayingPlayers) {
selection = po.GetSelection (point, precision);
if (selection != null)
break;
}
}
- if (selection == null && awayPlayingPlayers != null) {
- foreach (PlayerObject po in awayPlayingPlayers) {
+ if (selection == null && AwayPlayingPlayers != null) {
+ foreach (PlayerObject po in AwayPlayingPlayers) {
selection = po.GetSelection (point, precision);
if (selection != null)
break;
diff --git a/LongoMatch.Drawing/CanvasObjects/PlayersTaggerObject.cs
b/LongoMatch.Drawing/CanvasObjects/PlayersTaggerObject.cs
index 1761776..26e5acf 100644
--- a/LongoMatch.Drawing/CanvasObjects/PlayersTaggerObject.cs
+++ b/LongoMatch.Drawing/CanvasObjects/PlayersTaggerObject.cs
@@ -38,30 +38,39 @@ namespace LongoMatch.Drawing.CanvasObjects
*/
public event PlayersSubstitutionHandler PlayersSubstitutionEvent;
public event PlayersSelectionChangedHandler PlayersSelectionChangedEvent;
+ const int SUBSTITUTION_BUTTONS_HEIGHT = 40;
+ const int SUBSTITUTION_BUTTONS_WIDTH = 60;
+ ButtonObject subPlayers, subInjury;
/* Cached surfaces reused by player objects */
ISurface backgroundSurface, homeNumberSurface, awayNumberSurface, photoSurface;
ISurface homeInSurface, homeOutSurface, awayInSurface, awayOutSurface;
TeamTemplate homeTeam, awayTeam;
Image background;
+ Dictionary<Player, PlayerObject> playerToPlayerObject;
List<PlayerObject> homePlayingPlayers, awayPlayingPlayers;
List<PlayerObject> homeBenchPlayers, awayBenchPlayers;
List <PlayerObject> homePlayers, awayPlayers;
BenchObject homeBench, awayBench;
PlayerObject clickedPlayer, substitutionPlayer;
+ ButtonObject clickedButton;
FieldObject field;
int NTeams;
Point offset;
bool substitutionMode;
double scaleX, scaleY;
+ Time lastTime, currentTime;
public PlayersTaggerObject ()
{
Position = new Point (0, 0);
homeBench = new BenchObject ();
awayBench = new BenchObject ();
+ playerToPlayerObject = new Dictionary<Player, PlayerObject>();
field = new FieldObject ();
SelectedPlayers = new List<Player> ();
+ lastTime = null;
LoadSurfaces ();
+ LoadSubsButtons ();
}
protected override void Dispose (bool disposing)
@@ -78,9 +87,36 @@ namespace LongoMatch.Drawing.CanvasObjects
awayOutSurface.Dispose ();
homeInSurface.Dispose ();
awayInSurface.Dispose ();
+ subPlayers.Dispose ();
+ subInjury.Dispose ();
base.Dispose (disposing);
}
+ public Time CurrentTime {
+ get {
+ return currentTime;
+ }
+ set {
+ currentTime = value;
+ if (lastTime == null) {
+ UpdateLineup ();
+ } else if (currentTime != lastTime && Project != null) {
+ Time start, stop;
+ if (lastTime < currentTime) {
+ start = lastTime;
+ stop = currentTime;
+ } else {
+ start = currentTime;
+ stop = lastTime;
+ }
+ if (Project.LineupChanged (start, stop)) {
+ UpdateLineup ();
+ }
+ }
+ lastTime = currentTime;
+ }
+ }
+
public Point Position {
get;
set;
@@ -106,6 +142,11 @@ namespace LongoMatch.Drawing.CanvasObjects
set;
}
+ public Project Project {
+ get;
+ set;
+ }
+
public bool SubstitutionMode {
get {
return substitutionMode;
@@ -115,6 +156,16 @@ namespace LongoMatch.Drawing.CanvasObjects
homeBench.SubstitutionMode = awayBench.SubstitutionMode =
field.SubstitutionMode = value;
}
}
+
+ public bool ShowSubsitutionButtons {
+ get;
+ set;
+ }
+
+ public bool ShowInjurySubsitutionButton {
+ get;
+ set;
+ }
public List<Player> SelectedPlayers {
get;
@@ -196,14 +247,13 @@ namespace LongoMatch.Drawing.CanvasObjects
public void LoadTeams (TeamTemplate homeTeam, TeamTemplate awayTeam, Image background)
{
int[] homeF = null, awayF = null;
- int playerSize, benchPlayerSize, colSize, border, benchWidth, playersPerRow;
+ int playerSize, colSize, border;
this.homeTeam = homeTeam;
this.awayTeam = awayTeam;
this.background = background;
NTeams = 0;
-
if (background != null) {
field.Height = background.Height;
field.Width = background.Width;
@@ -253,6 +303,23 @@ namespace LongoMatch.Drawing.CanvasObjects
Update ();
}
+ void UpdateLineup ()
+ {
+ List<Player> homeFieldL, awayFieldL, homeBenchL, awayBenchL;
+ Project.CurrentLineup (currentTime, out homeFieldL, out homeBenchL,
+ out awayFieldL, out awayBenchL);
+ homePlayingPlayers = homeFieldL.Select (p => playerToPlayerObject [p]).ToList ();
+ homeBenchPlayers = homeBenchL.Select (p => playerToPlayerObject [p]).ToList ();
+ awayPlayingPlayers = awayFieldL.Select (p => playerToPlayerObject [p]).ToList ();
+ awayBenchPlayers = awayBenchL.Select (p => playerToPlayerObject [p]).ToList ();
+ homeBench.BenchPlayers = homeBenchPlayers;
+ awayBench.BenchPlayers = awayBenchPlayers;
+ field.HomePlayingPlayers = homePlayingPlayers;
+ field.AwayPlayingPlayers = awayPlayingPlayers;
+ Update ();
+ EmitRedrawEvent (this, new Area (Position, Width, Height));
+ }
+
void BenchWidth (int colSize, int height, int playerSize)
{
int maxPlayers, playersPerColumn, playersPerRow;
@@ -297,11 +364,11 @@ namespace LongoMatch.Drawing.CanvasObjects
awayPlayers = null;
}
}
+ playerToPlayerObject.Clear ();
}
ISurface CreateSurface (string name)
{
-
return Config.DrawingToolkit.CreateSurface (Path.Combine (Config.ImagesDir, name));
}
@@ -317,6 +384,20 @@ namespace LongoMatch.Drawing.CanvasObjects
awayInSurface = CreateSurface (StyleConf.PlayerAwayIn);
}
+ void LoadSubsButtons () {
+ subPlayers = new ButtonObject ();
+ string path = Path.Combine (Config.IconsDir, StyleConf.SubsUnlock);
+ subPlayers.BackgroundImageActive = Image.LoadFromFile (path);
+ path = Path.Combine (Config.IconsDir, StyleConf.SubsLock);
+ subPlayers.BackgroundImage = Image.LoadFromFile (path);
+ subPlayers.Toggle = true;
+ subPlayers.ClickedEvent += HandleSubsClicked;
+ subInjury = new ButtonObject ();
+ subInjury.Toggle = true;
+ subInjury.ClickedEvent += HandleSubsClicked;
+ subInjury.Visible = false;
+ }
+
void Substitute (PlayerObject p1, PlayerObject p2,
List<PlayerObject> playingPlayers,
List<PlayerObject> benchPlayers)
@@ -402,13 +483,44 @@ namespace LongoMatch.Drawing.CanvasObjects
SubstitutionMode = SubstitutionMode,
Photo = photoSurface
};
- po.ClickedEvent += HandleClickedEvent;
+ po.ClickedEvent += HandlePlayerClickedEvent;
playerObjects.Add (po);
+ playerToPlayerObject.Add (p, po);
}
return playerObjects;
}
- void HandleClickedEvent (CanvasObject co)
+ void EmitSubsitutionEvent (PlayerObject player1, PlayerObject player2)
+ {
+ TeamTemplate team;
+ List<PlayerObject> bench, field;
+
+ if (substitutionPlayer.Team == Team.LOCAL) {
+ team = homeTeam;
+ bench = homeBenchPlayers;
+ } else {
+ team = awayTeam;
+ bench = awayBenchPlayers;
+ }
+ if (PlayersSubstitutionEvent != null) {
+ if (bench.Contains (player1) && bench.Contains (player2)) {
+ PlayersSubstitutionEvent (team, player1.Player, player2.Player,
+ SubstitutionReason.BenchPositionChange,
CurrentTime);
+ } else if (!bench.Contains (player1) && !bench.Contains (player2)) {
+ PlayersSubstitutionEvent (team, player1.Player, player2.Player,
+ SubstitutionReason.PositionChange,
CurrentTime);
+ } else if (bench.Contains (player1)) {
+ PlayersSubstitutionEvent (team, player1.Player, player2.Player,
+ SubstitutionReason.PlayersSubstitution,
CurrentTime);
+ } else {
+ PlayersSubstitutionEvent (team, player2.Player, player1.Player,
+ SubstitutionReason.PlayersSubstitution,
CurrentTime);
+ }
+ }
+ ResetSelection ();
+ }
+
+ void HandlePlayerClickedEvent (ICanvasObject co)
{
PlayerObject player = co as PlayerObject;
@@ -417,16 +529,9 @@ namespace LongoMatch.Drawing.CanvasObjects
substitutionPlayer = player;
} else {
if (substitutionPlayer.Team == player.Team) {
- TeamTemplate team;
- if (substitutionPlayer.Team == Team.LOCAL) {
- team = homeTeam;
- } else {
- team = awayTeam;
- }
- if (PlayersSubstitutionEvent != null) {
- PlayersSubstitutionEvent (substitutionPlayer.Player,
- player.Player, team);
- }
+ EmitSubsitutionEvent (player, substitutionPlayer);
+ } else {
+ player.Active = false;
}
}
} else {
@@ -441,10 +546,44 @@ namespace LongoMatch.Drawing.CanvasObjects
}
}
+ bool ButtonClickPressed (Point point, ButtonModifier modif, params ButtonObject[] buttons)
+ {
+ Selection sel;
+
+ if (!ShowSubsitutionButtons) {
+ return false;
+ }
+
+ foreach (ButtonObject button in buttons) {
+ if (!button.Visible)
+ continue;
+ sel = button.GetSelection (point, 0);
+ if (sel != null) {
+ clickedButton = sel.Drawable as ButtonObject;
+ (sel.Drawable as ICanvasObject).ClickPressed (point, modif);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ void HandleSubsClicked (ICanvasObject co)
+ {
+ ResetSelection ();
+ if (PlayersSelectionChangedEvent != null) {
+ PlayersSelectionChangedEvent (SelectedPlayers);
+ }
+ SubstitutionMode = !SubstitutionMode;
+ }
+
public override void ClickPressed (Point point, ButtonModifier modif)
{
Selection selection = null;
+ if (ButtonClickPressed (point, modif, subPlayers, subInjury)) {
+ return;
+ }
+
if (!SubstitutionMode && SelectionMode != MultiSelectionMode.Multiple) {
if (SelectionMode == MultiSelectionMode.Single || modif ==
ButtonModifier.None) {
ResetSelection ();
@@ -474,7 +613,10 @@ namespace LongoMatch.Drawing.CanvasObjects
public override void ClickReleased ()
{
- if (clickedPlayer != null) {
+ if (clickedButton != null) {
+ clickedButton.ClickReleased ();
+ clickedButton = null;
+ } else if (clickedPlayer != null) {
clickedPlayer.ClickReleased ();
} else {
ResetSelection ();
@@ -493,10 +635,28 @@ namespace LongoMatch.Drawing.CanvasObjects
width = homeBench.Width * NTeams + field.Width +
2 * NTeams * Config.Style.TeamTaggerBenchBorder;
height = field.Height;
- Image.ScaleFactor ((int)width, (int)height, (int)Width, (int)Height,
+ Image.ScaleFactor ((int)width, (int)height, (int)Width,
+ (int)Height - SUBSTITUTION_BUTTONS_HEIGHT,
out scaleX, out scaleY, out offset);
+ offset.Y += SUBSTITUTION_BUTTONS_HEIGHT;
tk.Begin ();
tk.Clear (Config.Style.PaletteBackground);
+
+ /* Draw substitution buttons */
+ if (ShowSubsitutionButtons) {
+ subPlayers.Position = new Point (Width / 2 - SUBSTITUTION_BUTTONS_WIDTH / 2,
+ offset.Y - SUBSTITUTION_BUTTONS_HEIGHT);
+ subPlayers.Width = SUBSTITUTION_BUTTONS_WIDTH;
+ subPlayers.Height = SUBSTITUTION_BUTTONS_HEIGHT;
+ subPlayers.Draw (tk, area);
+
+ //subInjury.Position = new Point (100, 0);
+ //subInjury.Width = 100;
+ //subInjury.Height = SUBSTITUTION_BUTTONS_HEIGHT;
+ //subInjury.Draw (tk, area);
+ }
+
+
tk.TranslateAndScale (Position + offset, new Point (scaleX, scaleY));
homeBench.Draw (tk, area);
awayBench.Draw (tk, area);
diff --git a/LongoMatch.Drawing/CanvasObjects/TimeNodeObject.cs
b/LongoMatch.Drawing/CanvasObjects/TimeNodeObject.cs
index 2f0bada..24add6d 100644
--- a/LongoMatch.Drawing/CanvasObjects/TimeNodeObject.cs
+++ b/LongoMatch.Drawing/CanvasObjects/TimeNodeObject.cs
@@ -122,6 +122,11 @@ namespace LongoMatch.Drawing.CanvasObjects
}
newTime = Utils.PosToTime (p, SecondsPerPixel);
+ if (TimeNode is StatEvent) {
+ TimeNode.EventTime = newTime;
+ return;
+ }
+
switch (sel.Position) {
case SelectionPosition.Left:
{
diff --git a/LongoMatch.Drawing/Widgets/TeamTagger.cs b/LongoMatch.Drawing/Widgets/TeamTagger.cs
index 99b7d13..6126fbd 100644
--- a/LongoMatch.Drawing/Widgets/TeamTagger.cs
+++ b/LongoMatch.Drawing/Widgets/TeamTagger.cs
@@ -33,10 +33,9 @@ namespace LongoMatch.Drawing.Widgets
{
public event PlayersSelectionChangedHandler PlayersSelectionChangedEvent;
+ public event PlayersSubstitutionHandler PlayersSubstitutionEvent;
public event PlayersPropertiesHandler ShowMenuEvent;
PlayersTaggerObject tagger;
- MultiSelectionMode prevMode;
- bool inSubs;
public TeamTagger (IWidget widget): base (widget)
{
@@ -46,6 +45,7 @@ namespace LongoMatch.Drawing.Widgets
tagger.SelectionMode = MultiSelectionMode.Single;
tagger.PlayersSubstitutionEvent += HandlePlayersSubstitutionEvent;
tagger.PlayersSelectionChangedEvent += HandlePlayersSelectionChangedEvent;
+ ShowSubstitutionButtons = true;
ObjectsCanMove = false;
AddObject (tagger);
}
@@ -67,6 +67,12 @@ namespace LongoMatch.Drawing.Widgets
tagger.Reload ();
widget.ReDraw ();
}
+
+ public Project Project {
+ set {
+ tagger.Project = value;
+ }
+ }
public bool Compact {
set {
@@ -74,12 +80,24 @@ namespace LongoMatch.Drawing.Widgets
}
}
+ public Time CurrentTime {
+ set {
+ tagger.CurrentTime = value;
+ }
+ }
+
public bool SubstitutionMode {
set {
tagger.SubstitutionMode = value;
}
}
+ public bool ShowSubstitutionButtons {
+ set {
+ tagger.ShowSubsitutionButtons = value;
+ }
+ }
+
public new MultiSelectionMode SelectionMode {
set {
tagger.SelectionMode = value;
@@ -104,6 +122,11 @@ namespace LongoMatch.Drawing.Widgets
widget.ReDraw ();
}
+ public void Substitute (Player p1, Player p2, TeamTemplate team)
+ {
+ tagger.Substitute (p1, p2, team);
+ }
+
protected override void ShowMenu (Point coords)
{
List<Player> players = tagger.SelectedPlayers;
@@ -122,18 +145,18 @@ namespace LongoMatch.Drawing.Widgets
}
}
-
void HandleSizeChangedEvent ()
{
tagger.Width = widget.Width;
tagger.Height = widget.Height;
}
- void HandlePlayersSubstitutionEvent (Player p1, Player p2, TeamTemplate team)
+ void HandlePlayersSubstitutionEvent (TeamTemplate team, Player p1, Player p2,
SubstitutionReason reason, Time time)
{
- team.List.Swap (p1, p2);
- tagger.Substitute (p1, p2, team);
widget.ReDraw ();
+ if (PlayersSubstitutionEvent != null) {
+ PlayersSubstitutionEvent (team, p1, p2, reason, time);
+ }
}
void HandlePlayersSelectionChangedEvent (List<Player> players)
diff --git a/LongoMatch.GUI.Multimedia/Gui/PlayerBin.cs b/LongoMatch.GUI.Multimedia/Gui/PlayerBin.cs
index 5b8dfdc..21848d5 100644
--- a/LongoMatch.GUI.Multimedia/Gui/PlayerBin.cs
+++ b/LongoMatch.GUI.Multimedia/Gui/PlayerBin.cs
@@ -251,12 +251,18 @@ namespace LongoMatch.Gui
}
}
- public void LoadPlay (MediaFile file, TimelineEvent play, Time seekTime, bool playing)
+ public void LoadPlay (MediaFile file, TimelineEvent evt, Time seekTime, bool playing)
{
loadedPlaylist = null;
loadedPlaylistElement = null;
- loadedPlay = play;
- LoadSegment (file, play.Start, play.Stop, seekTime, playing, play.Rate);
+ loadedPlay = evt;
+ if (evt.Start != null && evt.Start != null) {
+ LoadSegment (file, evt.Start, evt.Stop, seekTime, playing, evt.Rate);
+ } else if (evt.EventTime != null) {
+ Seek (evt.EventTime, true);
+ } else {
+ Log.Error ("Event does not have timing info: " + evt);
+ }
}
public void Close ()
diff --git a/LongoMatch.GUI.Multimedia/gtk-gui/objects.xml b/LongoMatch.GUI.Multimedia/gtk-gui/objects.xml
index b8d3ed6..28c8a06 100644
--- a/LongoMatch.GUI.Multimedia/gtk-gui/objects.xml
+++ b/LongoMatch.GUI.Multimedia/gtk-gui/objects.xml
@@ -40,10 +40,10 @@
</itemgroups>
<signals>
<itemgroup label="VideoWindow Signals">
+ <signal name="ReadyEvent" />
<signal name="ExposeEvent" />
<signal name="ButtonPressEvent" />
<signal name="ScrollEvent" />
- <signal name="ReadyEvent" />
</itemgroup>
</signals>
</object>
diff --git a/LongoMatch.GUI/Gui/Component/CodingWidget.cs b/LongoMatch.GUI/Gui/Component/CodingWidget.cs
index 5830a7a..f3aafa6 100644
--- a/LongoMatch.GUI/Gui/Component/CodingWidget.cs
+++ b/LongoMatch.GUI/Gui/Component/CodingWidget.cs
@@ -26,6 +26,7 @@ using LongoMatch.Drawing.Widgets;
using LongoMatch.Drawing.Cairo;
using LongoMatch.Gui.Helpers;
using Mono.Unix;
+using LongoMatch.Core.Store.Templates;
namespace LongoMatch.Gui.Component
{
@@ -62,6 +63,7 @@ namespace LongoMatch.Gui.Component
teamtagger = new TeamTagger (new WidgetWrapper (teamsdrawingarea));
teamtagger.SelectionMode = MultiSelectionMode.Multiple;
teamtagger.PlayersSelectionChangedEvent += HandlePlayersSelectionChangedEvent;
+ teamtagger.PlayersSubstitutionEvent += HandlePlayersSubstitutionEvent;
teamtagger.Compact = true;
teamsdrawingarea.HeightRequest = 200;
@@ -110,8 +112,10 @@ namespace LongoMatch.Gui.Component
if (project != null) {
buttonswidget.Template = project.Dashboard;
}
+ teamtagger.Project = project;
teamtagger.LoadTeams (project.LocalTeamTemplate, project.VisitorTeamTemplate,
project.Dashboard.FieldBackground);
+ teamtagger.CurrentTime = new Time (0);
if (projectType == ProjectType.FileProject) {
timeline.SetProject (project, filter);
}
@@ -229,6 +233,7 @@ namespace LongoMatch.Gui.Component
if (projectType != ProjectType.FileProject) {
timeline.CurrentTime = currentTime;
buttonswidget.CurrentTime = currentTime;
+ teamtagger.CurrentTime = currentTime;
}
}
@@ -237,6 +242,7 @@ namespace LongoMatch.Gui.Component
if (projectType == ProjectType.FileProject) {
timeline.CurrentTime = currentTime;
buttonswidget.CurrentTime = currentTime;
+ teamtagger.CurrentTime = currentTime;
}
}
@@ -258,6 +264,11 @@ namespace LongoMatch.Gui.Component
Config.EventsBroker.EmitNewEvent (play);
}
+ void HandlePlayersSubstitutionEvent (TeamTemplate team, Player p1, Player p2,
+ SubstitutionReason reason, Time time)
+ {
+ Config.EventsBroker.EmitSubstitutionEvent (team, p1, p2, reason, time);
+ }
}
}
diff --git a/LongoMatch.GUI/Gui/Component/TeamTemplateEditor.cs
b/LongoMatch.GUI/Gui/Component/TeamTemplateEditor.cs
index 294a175..bbf5658 100644
--- a/LongoMatch.GUI/Gui/Component/TeamTemplateEditor.cs
+++ b/LongoMatch.GUI/Gui/Component/TeamTemplateEditor.cs
@@ -52,12 +52,13 @@ namespace LongoMatch.Gui.Component
teamtagger = new TeamTagger (new WidgetWrapper (drawingarea));
teamtagger.SelectionMode = MultiSelectionMode.MultipleWithModifier;
teamtagger.PlayersSelectionChangedEvent += HandlePlayersSelectionChangedEvent;
+ teamtagger.PlayersSubstitutionEvent += HandlePlayersSubstitutionEvent;
ConnectSignals ();
ClearPlayer ();
}
-
+
protected override void OnDestroyed ()
{
teamtagger.Dispose ();
@@ -340,6 +341,14 @@ namespace LongoMatch.Gui.Component
Edited = true;
}
}
+
+ void HandlePlayersSubstitutionEvent (TeamTemplate team, Player p1, Player p2,
+ SubstitutionReason reason, Time time)
+ {
+ team.List.Swap (p1, p2);
+ teamtagger.Substitute (p1, p2, team);
+ }
+
}
}
diff --git a/LongoMatch.GUI/Gui/Dialog/SubstitutionsEditor.cs
b/LongoMatch.GUI/Gui/Dialog/SubstitutionsEditor.cs
new file mode 100644
index 0000000..c7a0b74
--- /dev/null
+++ b/LongoMatch.GUI/Gui/Dialog/SubstitutionsEditor.cs
@@ -0,0 +1,216 @@
+//
+// Copyright (C) 2014 Andoni Morales Alastruey
+//
+// This program 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 2 of the License, or
+// (at your option) any later version.
+//
+// This program 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 this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+using System;
+using System.Linq;
+using LongoMatch.Drawing.Widgets;
+using LongoMatch.Drawing.Cairo;
+using LongoMatch.Core.Store;
+using System.Collections.Generic;
+using LongoMatch.Core.Store.Templates;
+using LongoMatch.Core.Common;
+using LongoMatch.Drawing;
+using LongoMatch.Drawing.CanvasObjects;
+using LongoMatch.Core.Interfaces.Drawing;
+
+namespace LongoMatch.Gui.Dialog
+{
+ public partial class SubstitutionsEditor : Gtk.Dialog
+ {
+ TeamTagger tagger;
+ SelectionCanvas incanvas, outcanvas;
+ PlayerObject inpo, outpo;
+ Player inPlayer, outPlayer, selectedPlayer;
+ TeamTemplate homeTeam, awayTeam;
+ LineupEvent lineup;
+ SubstitutionEvent substitution;
+ const int PLAYER_SIZE = 100;
+
+ public SubstitutionsEditor ()
+ {
+ this.Build ();
+ tagger = new TeamTagger (new WidgetWrapper (drawingarea));
+ tagger.PlayersSelectionChangedEvent += HandlePlayersSelectionChangedEvent;
+ tagger.PlayersSubstitutionEvent += HandlePlayersSubstitutionEvent;
+ incanvas = new SelectionCanvas (new WidgetWrapper (drawingarea2));
+ outcanvas = new SelectionCanvas (new WidgetWrapper (drawingarea3));
+ inpo = new PlayerObject ();
+ outpo = new PlayerObject ();
+ inpo.ClickedEvent += HandleClickedEvent;
+ outpo.ClickedEvent += HandleClickedEvent;
+ inpo.Size = PLAYER_SIZE;
+ outpo.Size = PLAYER_SIZE;
+ inpo.Position = new Point (PLAYER_SIZE / 2, PLAYER_SIZE / 2);
+ outpo.Position = new Point (PLAYER_SIZE / 2, PLAYER_SIZE / 2);
+ incanvas.AddObject (inpo);
+ outcanvas.AddObject (outpo);
+ drawingarea2.WidthRequest = drawingarea2.HeightRequest = PLAYER_SIZE;
+ drawingarea3.WidthRequest = drawingarea3.HeightRequest = PLAYER_SIZE;
+ }
+
+ public void SaveChanges ()
+ {
+ if (lineup != null) {
+ lineup.HomeStartingPlayers = homeTeam.StartingPlayersList;
+ lineup.HomeBenchPlayers = homeTeam.BenchPlayersList;
+ lineup.AwayStartingPlayers = awayTeam.StartingPlayersList;
+ lineup.AwayBenchPlayers = awayTeam.BenchPlayersList;
+ } else {
+ substitution.In = inPlayer;
+ substitution.Out = outPlayer;
+ }
+ }
+
+ public void Load (Project project, StatEvent evt)
+ {
+ if (evt is LineupEvent) {
+ LoadLineup (project, evt as LineupEvent);
+ } else {
+ LoadSubstitution (project, evt as SubstitutionEvent);
+ }
+ }
+
+ public void LoadLineup (Project project, LineupEvent lineup)
+ {
+ this.lineup = lineup;
+ playershbox.Visible = false;
+ tagger.SubstitutionMode = true;
+ tagger.ShowSubstitutionButtons = false;
+ LoadTeams (project, lineup.HomeStartingPlayers, lineup.HomeBenchPlayers,
+ lineup.AwayStartingPlayers, lineup.AwayBenchPlayers);
+ }
+
+ public void LoadSubstitution (Project project, SubstitutionEvent substitution)
+ {
+ TeamTemplate team;
+ List<Player> hfp, hbp, afp, abp;
+
+ this.substitution = substitution;
+ project.CurrentLineup (substitution.EventTime, out hfp, out hbp, out afp, out abp);
+ if (substitution.Team == Team.LOCAL) {
+ team = homeTeam;
+ } else {
+ team = awayTeam;
+ }
+ playershbox.Visible = true;
+ tagger.SubstitutionMode = false;
+ tagger.ShowSubstitutionButtons = false;
+ tagger.SelectionMode = MultiSelectionMode.Single;
+ LoadTeams (project, hfp, hbp, null, null);
+ SwitchPlayer (substitution.In, substitution.Out);
+ }
+
+ void LoadTeams (Project project, List<Player> homeFieldPlayers, List<Player> homeBenchPlayers,
+ List<Player> awayFieldPlayers, List<Player> awayBenchPlayers)
+ {
+ List<Player> homeTeamPlayers, awayTeamPlayers;
+
+ homeTeamPlayers = homeFieldPlayers.Concat (homeBenchPlayers).ToList ();
+ homeTeam = new TeamTemplate {
+ ID = project.LocalTeamTemplate.ID,
+ Formation = project.LocalTeamTemplate.Formation,
+ List = homeTeamPlayers
+ };
+
+ if (awayFieldPlayers != null) {
+ awayTeamPlayers = awayFieldPlayers.Concat (awayBenchPlayers).ToList ();
+ awayTeam = new TeamTemplate {
+ ID = project.VisitorTeamTemplate.ID,
+ Formation = project.VisitorTeamTemplate.Formation,
+ List = awayTeamPlayers
+ };
+ } else {
+ awayTeam = null;
+ }
+
+ tagger.LoadTeams (homeTeam, awayTeam, project.Dashboard.FieldBackground);
+ }
+
+ void SwitchPlayer (Player inPlayer, Player outPlayer)
+ {
+ if (inPlayer != null) {
+ this.inPlayer = inPlayer;
+ inpo.Player = inPlayer;
+ inpo.Active = false;
+ drawingarea2.QueueDraw ();
+ tagger.ResetSelection ();
+ } else {
+ inframe.Visible = false;
+ }
+ if (outPlayer != null) {
+ this.outPlayer = outPlayer;
+ outpo.Player = outPlayer;
+ outpo.Active = false;
+ drawingarea3.QueueDraw ();
+ tagger.ResetSelection ();
+ } else {
+ outframe.Visible = false;
+ }
+ selectedPlayer = null;
+ }
+
+ void HandlePlayersSelectionChangedEvent (List<Player> players)
+ {
+ if (players.Count == 1) {
+ selectedPlayer = players [0];
+ if (inpo.Active) {
+ SwitchPlayer (selectedPlayer, outPlayer);
+ } else if (outpo.Active) {
+ SwitchPlayer (inPlayer, selectedPlayer);
+ }
+ } else {
+ selectedPlayer = null;
+ }
+ }
+
+ void HandlePlayersSubstitutionEvent (TeamTemplate team, Player p1, Player p2,
SubstitutionReason reason, Time time)
+ {
+ tagger.Substitute (p1, p2, team);
+ if (team.ID == homeTeam.ID) {
+ homeTeam.List.Swap (p1, p2);
+ } else {
+ awayTeam.List.Swap (p1, p2);
+ }
+ }
+
+ void HandleClickedEvent (ICanvasObject co)
+ {
+ PlayerObject po = co as PlayerObject;
+ Player player = po.Player;
+
+ if (po == inpo) {
+ if (outpo.Active) {
+ outpo.Active = false;
+ drawingarea3.QueueDraw ();
+ }
+ if (selectedPlayer != null) {
+ SwitchPlayer (selectedPlayer, outPlayer);
+ }
+ } else {
+ if (inpo.Active) {
+ inpo.Active = false;
+ drawingarea2.QueueDraw ();
+ }
+ if (selectedPlayer != null) {
+ SwitchPlayer (inPlayer, selectedPlayer);
+ }
+ }
+ }
+
+ }
+}
+
diff --git a/LongoMatch.GUI/Gui/GUIToolkit.cs b/LongoMatch.GUI/Gui/GUIToolkit.cs
index 3491562..b7077a7 100644
--- a/LongoMatch.GUI/Gui/GUIToolkit.cs
+++ b/LongoMatch.GUI/Gui/GUIToolkit.cs
@@ -226,11 +226,21 @@ namespace LongoMatch.Gui
sd.Destroy();
}
- public void EditPlay (TimelineEvent play, Project project, bool editTags, bool editPos, bool
editPlayers, bool editNotes) {
- PlayEditor dialog = new PlayEditor ();
- dialog.LoadPlay (play, project, editTags, editPos, editPlayers, editNotes);
- dialog.Run();
- dialog.Destroy();
+ public void EditPlay (TimelineEvent play, Project project, bool editTags, bool editPos, bool
editPlayers, bool editNotes)
+ {
+ if (play is StatEvent) {
+ SubstitutionsEditor dialog = new SubstitutionsEditor ();
+ dialog.Load (project, play as StatEvent);
+ if (dialog.Run () == (int)ResponseType.Ok) {
+ dialog.SaveChanges ();
+ }
+ dialog.Destroy ();
+ } else {
+ PlayEditor dialog = new PlayEditor ();
+ dialog.LoadPlay (play, project, editTags, editPos, editPlayers, editNotes);
+ dialog.Run();
+ dialog.Destroy();
+ }
}
public void DrawingTool (Image image, TimelineEvent play, FrameDrawing drawing) {
diff --git a/LongoMatch.GUI/Gui/Menu/PlaysMenu.cs b/LongoMatch.GUI/Gui/Menu/PlaysMenu.cs
index fbcab43..bb4dd7b 100644
--- a/LongoMatch.GUI/Gui/Menu/PlaysMenu.cs
+++ b/LongoMatch.GUI/Gui/Menu/PlaysMenu.cs
@@ -60,6 +60,8 @@ namespace LongoMatch.Gui.Menus
private void ShowMenu (Project project, List<TimelineEvent> plays, EventType eventType, Time
time,
List<EventType> eventTypes, bool editableName)
{
+ bool isLineup = false, isSubstitution = false;
+
this.plays = plays;
this.eventType = eventType;
this.time = time;
@@ -73,17 +75,28 @@ namespace LongoMatch.Gui.Menus
newPlay.Visible = false;
}
- if (plays == null)
+ if (plays == null) {
plays = new List<TimelineEvent> ();
-
- edit.Visible = editableName;
- snapshot.Visible = plays.Count == 1;
- moveCat.Visible = plays.Count == 1 && eventTypes != null;
- drawings.Visible = plays.Count == 1 && plays [0].Drawings.Count > 0;
- del.Visible = plays.Count > 0;
- addPLN.Visible = plays.Count > 0;
- render.Visible = plays.Count > 0;
- duplicate.Visible = plays.Count > 0;
+ } else if (plays.Count == 1) {
+ isLineup = plays [0] is LineupEvent;
+ isSubstitution = plays [0] is SubstitutionEvent;
+ }
+
+ if (isLineup || isSubstitution) {
+ edit.Visible = true;
+ del.Visible = isSubstitution;
+ snapshot.Visible = moveCat.Visible = drawings.Visible =
+ addPLN.Visible = render.Visible = duplicate.Visible = false;
+ } else {
+ edit.Visible = editableName;
+ snapshot.Visible = plays.Count == 1;
+ moveCat.Visible = plays.Count == 1 && eventTypes != null;
+ drawings.Visible = plays.Count == 1 && plays [0].Drawings.Count > 0;
+ del.Visible = plays.Count > 0;
+ addPLN.Visible = plays.Count > 0;
+ render.Visible = plays.Count > 0;
+ duplicate.Visible = plays.Count > 0;
+ }
if (plays.Count > 0) {
string label = String.Format ("{0} ({1})", Catalog.GetString ("Delete"),
plays.Count);
@@ -209,9 +222,10 @@ namespace LongoMatch.Gui.Menus
void HandleNePlayActivated (object sender, EventArgs e)
{
- Config.EventsBroker.EmitNewTag (eventType, null, null,
- time - new Time {Seconds = 10},
- time + new Time {Seconds = 10});
+ Config.EventsBroker.EmitNewTag (eventType,
+ eventTime: time,
+ start: time - new Time {Seconds = 10},
+ stop: time + new Time {Seconds = 10});
}
void EmitRenderPlaylist (List<TimelineEvent> plays)
diff --git a/LongoMatch.GUI/Gui/Panel/NewProjectPanel.cs b/LongoMatch.GUI/Gui/Panel/NewProjectPanel.cs
index fd39e2b..460f396 100644
--- a/LongoMatch.GUI/Gui/Panel/NewProjectPanel.cs
+++ b/LongoMatch.GUI/Gui/Panel/NewProjectPanel.cs
@@ -142,6 +142,8 @@ namespace LongoMatch.Gui.Panel
teamtagger = new TeamTagger (new WidgetWrapper (drawingarea));
teamtagger.ShowMenuEvent += HandleShowMenuEvent;
teamtagger.SubstitutionMode = true;
+ teamtagger.ShowSubstitutionButtons = false;
+ teamtagger.PlayersSubstitutionEvent += HandlePlayersSubstitutionEvent;
teams = Config.TeamTemplatesProvider.Templates;
hometeamscombobox.Load (teams);
hometeamscombobox.Changed += (sender, e) => {
@@ -364,6 +366,19 @@ namespace LongoMatch.Gui.Panel
captureSettings.EncodingSettings = encSettings;
return true;
}
+
+ void StartProject ()
+ {
+ if (CreateProject ()) {
+ if (projectType == ProjectType.EditProject) {
+ projectType = ProjectType.FileProject;
+ Config.EventsBroker.EmitCreateThumbnails (project);
+ } else {
+ project.CreateLineupEvent ();
+ }
+ Config.EventsBroker.EmitOpenNewProject (project, projectType,
captureSettings);
+ }
+ }
void HandleEntryChanged (object sender, EventArgs e)
{
@@ -429,17 +444,12 @@ namespace LongoMatch.Gui.Panel
if (projectType == ProjectType.CaptureProject ||
projectType == ProjectType.FakeCaptureProject ||
projectType == ProjectType.URICaptureProject) {
+ project.CreateLineupEvent ();
Config.EventsBroker.EmitOpenNewProject (project, projectType,
captureSettings);
return;
}
} else if (notebook1.Page == PROJECT_PERIODS) {
- if (CreateProject ()) {
- if (projectType == ProjectType.EditProject) {
- projectType = ProjectType.FileProject;
- Config.EventsBroker.EmitCreateThumbnails (project);
- }
- Config.EventsBroker.EmitOpenNewProject (project, projectType,
captureSettings);
- }
+ StartProject ();
return;
}
@@ -466,6 +476,13 @@ namespace LongoMatch.Gui.Panel
menu.ShowAll ();
menu.Popup ();
}
+
+ void HandlePlayersSubstitutionEvent (TeamTemplate team, Player p1, Player p2,
+ SubstitutionReason reason, Time time)
+ {
+ team.List.Swap (p1, p2);
+ teamtagger.Substitute (p1, p2, team);
+ }
}
}
diff --git a/LongoMatch.GUI/Gui/TreeView/PlaysTreeView.cs b/LongoMatch.GUI/Gui/TreeView/PlaysTreeView.cs
index e39c1d1..b2550e8 100644
--- a/LongoMatch.GUI/Gui/TreeView/PlaysTreeView.cs
+++ b/LongoMatch.GUI/Gui/TreeView/PlaysTreeView.cs
@@ -194,17 +194,33 @@ namespace LongoMatch.Gui.Component
Model.SetSortFunc(0, SortFunction);
}
- override protected bool SelectFunction(TreeSelection selection, TreeModel model, TreePath
path, bool selected) {
- // Don't allow multiselect for categories
- if(!selected && selection.GetSelectedRows().Length > 0) {
- if(selection.GetSelectedRows().Length == 1 &&
- GetValueFromPath(selection.GetSelectedRows()[0]) is EventType)
+ override protected bool SelectFunction (TreeSelection selection, TreeModel model, TreePath
path, bool selected)
+ {
+ TreePath[] selectedRows;
+
+ selectedRows = selection.GetSelectedRows ();
+ if (!selected && selectedRows.Length > 0) {
+ object currentSelected;
+ object firstSelected;
+
+ firstSelected = GetValueFromPath (selectedRows [0]);
+ // No multiple selection for event types and substitution events
+ if (selectedRows.Length == 1) {
+ if (firstSelected is EventType) {
+ return false;
+ } else if (firstSelected is StatEvent) {
+ return false;
+ }
+ }
+
+ currentSelected = GetValueFromPath (path);
+ if (currentSelected is EventType || currentSelected is StatEvent) {
return false;
- return !(GetValueFromPath(path) is EventType);
+ }
+ return true;
}
// Always unselect
- else
- return true;
+ return true;
}
override protected bool OnButtonPressEvent(Gdk.EventButton evnt)
diff --git a/LongoMatch.GUI/LongoMatch.GUI.csproj b/LongoMatch.GUI/LongoMatch.GUI.csproj
index 8538bf2..d11093c 100644
--- a/LongoMatch.GUI/LongoMatch.GUI.csproj
+++ b/LongoMatch.GUI/LongoMatch.GUI.csproj
@@ -183,6 +183,8 @@
<Compile Include="gtk-gui\LongoMatch.Gui.Panel.PanelHeader.cs" />
<Compile Include="Gui\Dialog\PlayEditor.cs" />
<Compile Include="gtk-gui\LongoMatch.Gui.Dialog.PlayEditor.cs" />
+ <Compile Include="Gui\Dialog\SubstitutionsEditor.cs" />
+ <Compile Include="gtk-gui\LongoMatch.Gui.Dialog.SubstitutionsEditor.cs" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="gtk-gui\gui.stetic">
diff --git a/LongoMatch.GUI/Makefile.am b/LongoMatch.GUI/Makefile.am
index 27b9801..652bf61 100644
--- a/LongoMatch.GUI/Makefile.am
+++ b/LongoMatch.GUI/Makefile.am
@@ -54,6 +54,7 @@ SOURCES = Gui/Cairo.cs \
Gui/Dialog/ShortcutsHelpDialog.cs \
Gui/Dialog/SnapshotsDialog.cs \
Gui/Dialog/StatsViewer.cs \
+ Gui/Dialog/SubstitutionsEditor.cs \
Gui/Dialog/UpdateDialog.cs \
Gui/Dialog/VideoConversionTool.cs \
Gui/Dialog/VideoEditionProperties.cs \
@@ -125,6 +126,7 @@ SOURCES = Gui/Cairo.cs \
gtk-gui/LongoMatch.Gui.Dialog.ShortcutsHelpDialog.cs \
gtk-gui/LongoMatch.Gui.Dialog.SnapshotsDialog.cs \
gtk-gui/LongoMatch.Gui.Dialog.StatsViewer.cs \
+ gtk-gui/LongoMatch.Gui.Dialog.SubstitutionsEditor.cs \
gtk-gui/LongoMatch.Gui.Dialog.UpdateDialog.cs \
gtk-gui/LongoMatch.Gui.Dialog.VideoConversionTool.cs \
gtk-gui/LongoMatch.Gui.Dialog.VideoEditionProperties.cs \
diff --git a/LongoMatch.GUI/gtk-gui/LongoMatch.Gui.Dialog.SubstitutionsEditor.cs
b/LongoMatch.GUI/gtk-gui/LongoMatch.Gui.Dialog.SubstitutionsEditor.cs
new file mode 100644
index 0000000..22b33ca
--- /dev/null
+++ b/LongoMatch.GUI/gtk-gui/LongoMatch.Gui.Dialog.SubstitutionsEditor.cs
@@ -0,0 +1,140 @@
+
+// This file has been generated by the GUI designer. Do not modify.
+namespace LongoMatch.Gui.Dialog
+{
+ public partial class SubstitutionsEditor
+ {
+ private global::Gtk.VBox vbox2;
+ private global::Gtk.HBox playershbox;
+ private global::Gtk.Frame inframe;
+ private global::Gtk.Alignment GtkAlignment2;
+ private global::Gtk.DrawingArea drawingarea2;
+ private global::Gtk.Label GtkLabel2;
+ private global::Gtk.Frame outframe;
+ private global::Gtk.Alignment GtkAlignment3;
+ private global::Gtk.DrawingArea drawingarea3;
+ private global::Gtk.Label GtkLabel3;
+ private global::Gtk.DrawingArea drawingarea;
+ private global::Gtk.Button buttonCancel;
+ private global::Gtk.Button buttonOk;
+
+ protected virtual void Build ()
+ {
+ global::Stetic.Gui.Initialize (this);
+ // Widget LongoMatch.Gui.Dialog.SubstitutionsEditor
+ this.Name = "LongoMatch.Gui.Dialog.SubstitutionsEditor";
+ this.Icon = global::Stetic.IconLoader.LoadIcon (this, "longomatch",
global::Gtk.IconSize.Menu);
+ this.WindowPosition = ((global::Gtk.WindowPosition)(4));
+ this.DestroyWithParent = true;
+ this.Gravity = ((global::Gdk.Gravity)(5));
+ this.SkipPagerHint = true;
+ this.SkipTaskbarHint = true;
+ // Internal child LongoMatch.Gui.Dialog.SubstitutionsEditor.VBox
+ global::Gtk.VBox w1 = this.VBox;
+ w1.Name = "dialog1_VBox";
+ w1.BorderWidth = ((uint)(2));
+ // Container child dialog1_VBox.Gtk.Box+BoxChild
+ this.vbox2 = new global::Gtk.VBox ();
+ this.vbox2.Name = "vbox2";
+ this.vbox2.Spacing = 6;
+ // Container child vbox2.Gtk.Box+BoxChild
+ this.playershbox = new global::Gtk.HBox ();
+ this.playershbox.Name = "playershbox";
+ this.playershbox.Spacing = 6;
+ // Container child playershbox.Gtk.Box+BoxChild
+ this.inframe = new global::Gtk.Frame ();
+ this.inframe.Name = "inframe";
+ this.inframe.ShadowType = ((global::Gtk.ShadowType)(0));
+ // Container child inframe.Gtk.Container+ContainerChild
+ this.GtkAlignment2 = new global::Gtk.Alignment (0F, 0F, 1F, 1F);
+ this.GtkAlignment2.Name = "GtkAlignment2";
+ this.GtkAlignment2.LeftPadding = ((uint)(12));
+ // Container child GtkAlignment2.Gtk.Container+ContainerChild
+ this.drawingarea2 = new global::Gtk.DrawingArea ();
+ this.drawingarea2.Name = "drawingarea2";
+ this.GtkAlignment2.Add (this.drawingarea2);
+ this.inframe.Add (this.GtkAlignment2);
+ this.GtkLabel2 = new global::Gtk.Label ();
+ this.GtkLabel2.Name = "GtkLabel2";
+ this.GtkLabel2.LabelProp = global::Mono.Unix.Catalog.GetString ("<b>Player in</b>");
+ this.GtkLabel2.UseMarkup = true;
+ this.inframe.LabelWidget = this.GtkLabel2;
+ this.playershbox.Add (this.inframe);
+ global::Gtk.Box.BoxChild w4 = ((global::Gtk.Box.BoxChild)(this.playershbox
[this.inframe]));
+ w4.Position = 0;
+ w4.Fill = false;
+ // Container child playershbox.Gtk.Box+BoxChild
+ this.outframe = new global::Gtk.Frame ();
+ this.outframe.Name = "outframe";
+ this.outframe.ShadowType = ((global::Gtk.ShadowType)(0));
+ // Container child outframe.Gtk.Container+ContainerChild
+ this.GtkAlignment3 = new global::Gtk.Alignment (0F, 0F, 1F, 1F);
+ this.GtkAlignment3.Name = "GtkAlignment3";
+ this.GtkAlignment3.LeftPadding = ((uint)(12));
+ // Container child GtkAlignment3.Gtk.Container+ContainerChild
+ this.drawingarea3 = new global::Gtk.DrawingArea ();
+ this.drawingarea3.Name = "drawingarea3";
+ this.GtkAlignment3.Add (this.drawingarea3);
+ this.outframe.Add (this.GtkAlignment3);
+ this.GtkLabel3 = new global::Gtk.Label ();
+ this.GtkLabel3.Name = "GtkLabel3";
+ this.GtkLabel3.LabelProp = global::Mono.Unix.Catalog.GetString ("<b>Player out</b>");
+ this.GtkLabel3.UseMarkup = true;
+ this.outframe.LabelWidget = this.GtkLabel3;
+ this.playershbox.Add (this.outframe);
+ global::Gtk.Box.BoxChild w7 = ((global::Gtk.Box.BoxChild)(this.playershbox
[this.outframe]));
+ w7.Position = 1;
+ w7.Fill = false;
+ this.vbox2.Add (this.playershbox);
+ global::Gtk.Box.BoxChild w8 = ((global::Gtk.Box.BoxChild)(this.vbox2
[this.playershbox]));
+ w8.Position = 0;
+ w8.Expand = false;
+ // Container child vbox2.Gtk.Box+BoxChild
+ this.drawingarea = new global::Gtk.DrawingArea ();
+ this.drawingarea.Name = "drawingarea";
+ this.vbox2.Add (this.drawingarea);
+ global::Gtk.Box.BoxChild w9 = ((global::Gtk.Box.BoxChild)(this.vbox2
[this.drawingarea]));
+ w9.Position = 1;
+ w1.Add (this.vbox2);
+ global::Gtk.Box.BoxChild w10 = ((global::Gtk.Box.BoxChild)(w1 [this.vbox2]));
+ w10.Position = 0;
+ // Internal child LongoMatch.Gui.Dialog.SubstitutionsEditor.ActionArea
+ global::Gtk.HButtonBox w11 = this.ActionArea;
+ w11.Name = "dialog1_ActionArea";
+ w11.Spacing = 10;
+ w11.BorderWidth = ((uint)(5));
+ w11.LayoutStyle = ((global::Gtk.ButtonBoxStyle)(4));
+ // Container child dialog1_ActionArea.Gtk.ButtonBox+ButtonBoxChild
+ this.buttonCancel = new global::Gtk.Button ();
+ this.buttonCancel.CanDefault = true;
+ this.buttonCancel.CanFocus = true;
+ this.buttonCancel.Name = "buttonCancel";
+ this.buttonCancel.UseStock = true;
+ this.buttonCancel.UseUnderline = true;
+ this.buttonCancel.Label = "gtk-cancel";
+ this.AddActionWidget (this.buttonCancel, -6);
+ global::Gtk.ButtonBox.ButtonBoxChild w12 =
((global::Gtk.ButtonBox.ButtonBoxChild)(w11 [this.buttonCancel]));
+ w12.Expand = false;
+ w12.Fill = false;
+ // Container child dialog1_ActionArea.Gtk.ButtonBox+ButtonBoxChild
+ this.buttonOk = new global::Gtk.Button ();
+ this.buttonOk.CanDefault = true;
+ this.buttonOk.CanFocus = true;
+ this.buttonOk.Name = "buttonOk";
+ this.buttonOk.UseStock = true;
+ this.buttonOk.UseUnderline = true;
+ this.buttonOk.Label = "gtk-ok";
+ this.AddActionWidget (this.buttonOk, -5);
+ global::Gtk.ButtonBox.ButtonBoxChild w13 =
((global::Gtk.ButtonBox.ButtonBoxChild)(w11 [this.buttonOk]));
+ w13.Position = 1;
+ w13.Expand = false;
+ w13.Fill = false;
+ if ((this.Child != null)) {
+ this.Child.ShowAll ();
+ }
+ this.DefaultWidth = 726;
+ this.DefaultHeight = 404;
+ this.Show ();
+ }
+ }
+}
diff --git a/LongoMatch.GUI/gtk-gui/gui.stetic b/LongoMatch.GUI/gtk-gui/gui.stetic
index e1c9b2b..e599757 100644
--- a/LongoMatch.GUI/gtk-gui/gui.stetic
+++ b/LongoMatch.GUI/gtk-gui/gui.stetic
@@ -10825,4 +10825,161 @@ You can continue with the current capture, cancel it or save your project.
</widget>
</child>
</widget>
+ <widget class="Gtk.Dialog" id="LongoMatch.Gui.Dialog.SubstitutionsEditor" design-size="726 404">
+ <property name="MemberName" />
+ <property name="Icon">stock:longomatch Menu</property>
+ <property name="WindowPosition">CenterOnParent</property>
+ <property name="DestroyWithParent">True</property>
+ <property name="Gravity">Center</property>
+ <property name="SkipPagerHint">True</property>
+ <property name="SkipTaskbarHint">True</property>
+ <property name="Buttons">2</property>
+ <property name="HelpButton">False</property>
+ <child internal-child="VBox">
+ <widget class="Gtk.VBox" id="dialog1_VBox">
+ <property name="MemberName" />
+ <property name="BorderWidth">2</property>
+ <child>
+ <widget class="Gtk.VBox" id="vbox2">
+ <property name="MemberName" />
+ <property name="Spacing">6</property>
+ <child>
+ <widget class="Gtk.HBox" id="playershbox">
+ <property name="MemberName" />
+ <property name="Spacing">6</property>
+ <child>
+ <widget class="Gtk.Frame" id="inframe">
+ <property name="MemberName" />
+ <property name="ShadowType">None</property>
+ <child>
+ <widget class="Gtk.Alignment" id="GtkAlignment2">
+ <property name="MemberName" />
+ <property name="Xalign">0</property>
+ <property name="Yalign">0</property>
+ <property name="LeftPadding">12</property>
+ <child>
+ <widget class="Gtk.DrawingArea" id="drawingarea2">
+ <property name="MemberName" />
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="Gtk.Label" id="GtkLabel2">
+ <property name="MemberName" />
+ <property name="LabelProp" translatable="yes"><b>Player in</b></property>
+ <property name="UseMarkup">True</property>
+ </widget>
+ <packing>
+ <property name="type">label_item</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="Position">0</property>
+ <property name="AutoSize">False</property>
+ <property name="Fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="Gtk.Frame" id="outframe">
+ <property name="MemberName" />
+ <property name="ShadowType">None</property>
+ <child>
+ <widget class="Gtk.Alignment" id="GtkAlignment3">
+ <property name="MemberName" />
+ <property name="Xalign">0</property>
+ <property name="Yalign">0</property>
+ <property name="LeftPadding">12</property>
+ <child>
+ <widget class="Gtk.DrawingArea" id="drawingarea3">
+ <property name="MemberName" />
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="Gtk.Label" id="GtkLabel3">
+ <property name="MemberName" />
+ <property name="LabelProp" translatable="yes"><b>Player
out</b></property>
+ <property name="UseMarkup">True</property>
+ </widget>
+ <packing>
+ <property name="type">label_item</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="Position">1</property>
+ <property name="AutoSize">False</property>
+ <property name="Fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="Position">0</property>
+ <property name="AutoSize">False</property>
+ <property name="Expand">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="Gtk.DrawingArea" id="drawingarea">
+ <property name="MemberName" />
+ </widget>
+ <packing>
+ <property name="Position">1</property>
+ <property name="AutoSize">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="Position">0</property>
+ <property name="AutoSize">True</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ <child internal-child="ActionArea">
+ <widget class="Gtk.HButtonBox" id="dialog1_ActionArea">
+ <property name="MemberName" />
+ <property name="Spacing">10</property>
+ <property name="BorderWidth">5</property>
+ <property name="Size">2</property>
+ <property name="LayoutStyle">End</property>
+ <child>
+ <widget class="Gtk.Button" id="buttonCancel">
+ <property name="MemberName" />
+ <property name="CanDefault">True</property>
+ <property name="CanFocus">True</property>
+ <property name="UseStock">True</property>
+ <property name="Type">StockItem</property>
+ <property name="StockId">gtk-cancel</property>
+ <property name="ResponseId">-6</property>
+ <property name="label">gtk-cancel</property>
+ </widget>
+ <packing>
+ <property name="Expand">False</property>
+ <property name="Fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="Gtk.Button" id="buttonOk">
+ <property name="MemberName" />
+ <property name="CanDefault">True</property>
+ <property name="CanFocus">True</property>
+ <property name="UseStock">True</property>
+ <property name="Type">StockItem</property>
+ <property name="StockId">gtk-ok</property>
+ <property name="ResponseId">-5</property>
+ <property name="label">gtk-ok</property>
+ </widget>
+ <packing>
+ <property name="Position">1</property>
+ <property name="Expand">False</property>
+ <property name="Fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
</stetic-interface>
\ No newline at end of file
diff --git a/LongoMatch.GUI/gtk-gui/objects.xml b/LongoMatch.GUI/gtk-gui/objects.xml
index b57a19f..3c0644f 100644
--- a/LongoMatch.GUI/gtk-gui/objects.xml
+++ b/LongoMatch.GUI/gtk-gui/objects.xml
@@ -1,8 +1,33 @@
<objects attr-sync="on">
+ <object type="LongoMatch.Gui.Component.CategoryProperties" palette-category="General"
allow-children="false" base-type="Gtk.Bin">
+ <itemgroups>
+ <itemgroup label="CategoryProperties Properties">
+ <property name="Edited" />
+ </itemgroup>
+ </itemgroups>
+ <signals>
+ <itemgroup label="CategoryProperties Signals">
+ <signal name="HotKeyChanged" />
+ <signal name="EditedEvent" />
+ </itemgroup>
+ </signals>
+ </object>
<object type="LongoMatch.Gui.Popup.TransparentDrawingArea" palette-category="General"
allow-children="false" base-type="Gtk.Window">
<itemgroups />
<signals />
</object>
+ <object type="LongoMatch.Gui.Component.DashboardWidget" palette-category="General" allow-children="false"
base-type="Gtk.Bin">
+ <itemgroups>
+ <itemgroup label="DashboardWidget Properties">
+ <property name="Edited" />
+ </itemgroup>
+ </itemgroups>
+ <signals>
+ <itemgroup label="DashboardWidget Signals">
+ <signal name="NewTagEvent" />
+ </itemgroup>
+ </signals>
+ </object>
<object type="LongoMatch.Gui.Component.NotesWidget" palette-category="General" allow-children="false"
base-type="Gtk.Bin">
<itemgroups />
<signals />
@@ -40,19 +65,6 @@
</itemgroup>
</signals>
</object>
- <object type="LongoMatch.Gui.Component.CategoryProperties" palette-category="General"
allow-children="false" base-type="Gtk.Bin">
- <itemgroups>
- <itemgroup label="CategoryProperties Properties">
- <property name="Edited" />
- </itemgroup>
- </itemgroups>
- <signals>
- <itemgroup label="CategoryProperties Signals">
- <signal name="HotKeyChanged" />
- <signal name="EditedEvent" />
- </itemgroup>
- </signals>
- </object>
<object type="LongoMatch.Gui.Component.PlaysListTreeWidget" palette-category="General"
allow-children="false" base-type="Gtk.Bin">
<itemgroups />
<signals />
@@ -125,6 +137,10 @@
</itemgroups>
<signals />
</object>
+ <object type="LongoMatch.Gui.Component.Stats.SubCategoryViewer" palette-category="General"
allow-children="false" base-type="Gtk.Bin">
+ <itemgroups />
+ <signals />
+ </object>
<object type="LongoMatch.Gui.Component.Stats.CategoriesViewer" palette-category="General"
allow-children="false" base-type="Gtk.Bin">
<itemgroups />
<signals />
@@ -149,30 +165,6 @@
<itemgroups />
<signals />
</object>
- <object type="LongoMatch.Gui.Component.TeamTemplateEditor" palette-category="General"
allow-children="false" base-type="Gtk.Bin">
- <itemgroups>
- <itemgroup label="TeamTemplateEditor Properties">
- <property name="Edited" />
- </itemgroup>
- </itemgroups>
- <signals>
- <itemgroup label="TeamTemplateEditor Signals">
- <signal name="TemplateSaved" />
- </itemgroup>
- </signals>
- </object>
- <object type="LongoMatch.Gui.Component.Stats.SubCategoryViewer" palette-category="General"
allow-children="false" base-type="Gtk.Bin">
- <itemgroups />
- <signals />
- </object>
- <object type="LongoMatch.Gui.Component.Timeline" palette-category="General" allow-children="false"
base-type="Gtk.Bin">
- <itemgroups />
- <signals />
- </object>
- <object type="LongoMatch.Gui.Component.PlaysPositionViewer" palette-category="General"
allow-children="false" base-type="Gtk.Bin">
- <itemgroups />
- <signals />
- </object>
<object type="LongoMatch.Gui.Component.AnalysisComponent" palette-category="General"
allow-children="false" base-type="Gtk.Bin">
<itemgroups />
<signals />
@@ -209,6 +201,18 @@
</itemgroup>
</signals>
</object>
+ <object type="LongoMatch.Gui.Component.TeamTemplateEditor" palette-category="General"
allow-children="false" base-type="Gtk.Bin">
+ <itemgroups>
+ <itemgroup label="TeamTemplateEditor Properties">
+ <property name="Edited" />
+ </itemgroup>
+ </itemgroups>
+ <signals>
+ <itemgroup label="TeamTemplateEditor Signals">
+ <signal name="TemplateSaved" />
+ </itemgroup>
+ </signals>
+ </object>
<object type="LongoMatch.Gui.Panel.ProjectsManagerPanel" palette-category="General" allow-children="false"
base-type="Gtk.Bin">
<itemgroups />
<signals>
@@ -233,6 +237,10 @@
</itemgroup>
</signals>
</object>
+ <object type="LongoMatch.Gui.Component.Timeline" palette-category="General" allow-children="false"
base-type="Gtk.Bin">
+ <itemgroups />
+ <signals />
+ </object>
<object type="LongoMatch.Gui.Component.CodingWidget" palette-category="General" allow-children="false"
base-type="Gtk.Bin">
<itemgroups>
<itemgroup label="CodingWidget Properties">
@@ -249,6 +257,10 @@
<itemgroups />
<signals />
</object>
+ <object type="LongoMatch.Gui.Component.PlaysPositionViewer" palette-category="General"
allow-children="false" base-type="Gtk.Bin">
+ <itemgroups />
+ <signals />
+ </object>
<object type="LongoMatch.Gui.Component.TeamsComboBox" palette-category="General" allow-children="false"
base-type="Gtk.ComboBox">
<itemgroups />
<signals />
@@ -286,18 +298,6 @@
</itemgroup>
</signals>
</object>
- <object type="LongoMatch.Gui.Component.DashboardWidget" palette-category="General" allow-children="false"
base-type="Gtk.Bin">
- <itemgroups>
- <itemgroup label="DashboardWidget Properties">
- <property name="Edited" />
- </itemgroup>
- </itemgroups>
- <signals>
- <itemgroup label="DashboardWidget Signals">
- <signal name="NewTagEvent" />
- </itemgroup>
- </signals>
- </object>
<object type="LongoMatch.Gui.Panel.PanelHeader" palette-category="General" allow-children="false"
base-type="Gtk.Bin">
<itemgroups />
<signals>
@@ -348,10 +348,10 @@
</itemgroups>
<signals>
<itemgroup label="VideoWindow Signals">
+ <signal name="ReadyEvent" />
<signal name="ExposeEvent" />
<signal name="ButtonPressEvent" />
<signal name="ScrollEvent" />
- <signal name="ReadyEvent" />
</itemgroup>
</signals>
</object>
diff --git a/LongoMatch.Migration/LongoMatch.Migration.csproj
b/LongoMatch.Migration/LongoMatch.Migration.csproj
index 8df3f24..a65bb88 100644
--- a/LongoMatch.Migration/LongoMatch.Migration.csproj
+++ b/LongoMatch.Migration/LongoMatch.Migration.csproj
@@ -110,11 +110,8 @@
<Compile Include="Common\SerializableObject.cs" />
<Compile Include="Common\ConsoleCrayon.cs" />
<Compile Include="Common\Config.cs" />
- <Compile Include="Tests\CateogiresTest.cs" />
<Compile Include="Core\Templates\SubCategoryTemplate.cs" />
- <Compile Include="Tests\TestTeam.cs" />
<Compile Include="Converter.cs" />
- <Compile Include="Tests\TestProject.cs" />
<Compile Include="DataBase.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
diff --git a/LongoMatch.Services/Services/EventsManager.cs b/LongoMatch.Services/Services/EventsManager.cs
index e41be47..07da40b 100644
--- a/LongoMatch.Services/Services/EventsManager.cs
+++ b/LongoMatch.Services/Services/EventsManager.cs
@@ -27,6 +27,7 @@ using Mono.Unix;
using System.IO;
using LongoMatch.Core.Interfaces.Multimedia;
using LongoMatch.Core.Store.Playlists;
+using LongoMatch.Core.Store.Templates;
namespace LongoMatch.Services
{
@@ -93,6 +94,7 @@ namespace LongoMatch.Services
Config.EventsBroker.DuplicateEventsEvent += OnDuplicatePlays;
Config.EventsBroker.SnapshotSeries += OnSnapshotSeries;
Config.EventsBroker.EventLoadedEvent += HandlePlayLoaded;
+ Config.EventsBroker.PlayerSubstitutionEvent += HandlePlayerSubstitutionEvent;
Config.EventsBroker.ShowProjectStatsEvent += HandleShowProjectStatsEvent;
Config.EventsBroker.TagSubcategoriesChangedEvent +=
HandleTagSubcategoriesChangedEvent;
@@ -105,6 +107,21 @@ namespace LongoMatch.Services
Config.EventsBroker.ShowFullScreenEvent += HandleShowFullScreenEvent;
}
+ void HandlePlayerSubstitutionEvent (TeamTemplate team, Player p1, Player p2,
SubstitutionReason reason, Time time)
+ {
+ if (openedProject != null) {
+ TimelineEvent evt;
+
+ try {
+ evt = openedProject.SubsitutePlayer (team, p1, p2, reason, time);
+ analysisWindow.AddPlay (evt);
+ filter.Update ();
+ } catch (SubstitutionException ex) {
+ guiToolkit.ErrorMessage (ex.Message);
+ }
+ }
+ }
+
void HandleShowFullScreenEvent (bool fullscreen)
{
guiToolkit.FullScreen = fullscreen;
diff --git a/LongoMatch.Services/Services/ProjectsManager.cs b/LongoMatch.Services/Services/ProjectsManager.cs
index 573dfa4..55858b5 100644
--- a/LongoMatch.Services/Services/ProjectsManager.cs
+++ b/LongoMatch.Services/Services/ProjectsManager.cs
@@ -358,6 +358,7 @@ namespace LongoMatch.Services
Log.Debug ("Importing fake live project");
ToolsManager.AddVideoFile (project, true);
}
+ project.UpdateEventTypes ();
SetProject (project, ProjectType.FileProject, new CaptureSettings ());
}
diff --git a/po/POTFILES.in b/po/POTFILES.in
index a6a6751..cbbf346 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -39,6 +39,7 @@ LongoMatch.GUI/gtk-gui/LongoMatch.Gui.Dialog.PlayEditor.cs
LongoMatch.GUI/gtk-gui/LongoMatch.Gui.Dialog.RenderingJobsDialog.cs
LongoMatch.GUI/gtk-gui/LongoMatch.Gui.Dialog.SnapshotsDialog.cs
LongoMatch.GUI/gtk-gui/LongoMatch.Gui.Dialog.StatsViewer.cs
+LongoMatch.GUI/gtk-gui/LongoMatch.Gui.Dialog.SubstitutionsEditor.cs
LongoMatch.GUI/gtk-gui/LongoMatch.Gui.Dialog.UpdateDialog.cs
LongoMatch.GUI/gtk-gui/LongoMatch.Gui.Dialog.VideoConversionTool.cs
LongoMatch.GUI/gtk-gui/LongoMatch.Gui.Dialog.VideoEditionProperties.cs
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]