aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortamland <thomas.amland@gmail.com>2016-07-17 10:22:23 +0200
committerGitHub <noreply@github.com>2016-07-17 10:22:23 +0200
commitd071db22e1a68567b79d43093c3f7c67283fb707 (patch)
treefbcd9c55d06fd7c9faaf1780d852df89d6f6aa53
parent0dd39fccd851def055034c4f99cac6d6c116a208 (diff)
parent0a0b8065aed03f8c839c14d8e56e18174f3efb2b (diff)
Merge pull request #10060 from tamland/addon_screenshots
[addons] screeshot support
-rw-r--r--addons/skin.estouchy/addon.xml16
-rw-r--r--addons/skin.estouchy/resources/fanart.jpg (renamed from addons/skin.estouchy/fanart.jpg)bin59183 -> 59183 bytes
-rw-r--r--addons/skin.estouchy/resources/icon.png (renamed from addons/skin.estouchy/icon.png)bin6447 -> 6447 bytes
-rw-r--r--addons/skin.estouchy/resources/screenshot-01.jpgbin0 -> 233381 bytes
-rw-r--r--addons/skin.estouchy/resources/screenshot-02.jpgbin0 -> 117568 bytes
-rw-r--r--addons/skin.estouchy/resources/screenshot-03.jpgbin0 -> 447124 bytes
-rw-r--r--addons/skin.estouchy/resources/screenshot-04.jpgbin0 -> 358997 bytes
-rw-r--r--addons/skin.estouchy/resources/screenshot-05.jpgbin0 -> 186378 bytes
-rw-r--r--addons/skin.estouchy/resources/screenshot-06.jpgbin0 -> 123012 bytes
-rw-r--r--addons/skin.estouchy/resources/screenshot-07.jpgbin0 -> 432821 bytes
-rw-r--r--addons/skin.estouchy/resources/screenshot-08.jpgbin0 -> 411105 bytes
-rw-r--r--addons/skin.estouchy/resources/screenshot-09.jpgbin0 -> 341767 bytes
-rw-r--r--addons/skin.estouchy/resources/screenshot-10.jpgbin0 -> 477304 bytes
-rw-r--r--addons/skin.estouchy/resources/screenshot-11.jpgbin0 -> 292369 bytes
-rw-r--r--addons/skin.estouchy/resources/screenshot-12.jpgbin0 -> 243032 bytes
-rw-r--r--addons/skin.estuary/1080i/DialogAddonInfo.xml133
-rw-r--r--addons/skin.estuary/1080i/SlideShow.xml2
-rw-r--r--addons/skin.estuary/media/DefaultNoPreview.pngbin0 -> 515 bytes
-rwxr-xr-xtools/darwin/Support/CopyRootFiles-ios.command3
-rwxr-xr-xtools/darwin/Support/CopyRootFiles-osx.command3
-rw-r--r--xbmc/FileItem.cpp16
-rw-r--r--xbmc/FileItem.h3
-rw-r--r--xbmc/addons/Addon.h2
-rw-r--r--xbmc/addons/AddonBuilder.h1
-rw-r--r--xbmc/addons/AddonDatabase.cpp9
-rw-r--r--xbmc/addons/AddonManager.cpp49
-rw-r--r--xbmc/addons/GUIDialogAddonInfo.cpp23
-rw-r--r--xbmc/addons/IAddon.h2
-rw-r--r--xbmc/addons/Repository.cpp12
-rw-r--r--xbmc/guilib/GUIWindow.cpp10
-rw-r--r--xbmc/guilib/GUIWindow.h1
-rw-r--r--xbmc/interfaces/AnnouncementManager.cpp4
-rw-r--r--xbmc/interfaces/AnnouncementManager.h6
-rw-r--r--xbmc/pictures/GUIWindowSlideShow.cpp202
-rw-r--r--xbmc/pictures/GUIWindowSlideShow.h37
-rw-r--r--xbmc/pictures/SlideShowPicture.cpp25
36 files changed, 348 insertions, 211 deletions
diff --git a/addons/skin.estouchy/addon.xml b/addons/skin.estouchy/addon.xml
index de49fa667d..f227eb9ed5 100644
--- a/addons/skin.estouchy/addon.xml
+++ b/addons/skin.estouchy/addon.xml
@@ -74,5 +74,21 @@
<website></website>
<email></email>
<source>https://github.com/xbmc/skin.estouchy/</source>
+ <assets>
+ <icon>resources/icon.png</icon>
+ <fanart>resources/fanart.jpg</fanart>
+ <screenshot>resources/screenshot-01.jpg</screenshot>
+ <screenshot>resources/screenshot-02.jpg</screenshot>
+ <screenshot>resources/screenshot-03.jpg</screenshot>
+ <screenshot>resources/screenshot-04.jpg</screenshot>
+ <screenshot>resources/screenshot-05.jpg</screenshot>
+ <screenshot>resources/screenshot-06.jpg</screenshot>
+ <screenshot>resources/screenshot-07.jpg</screenshot>
+ <screenshot>resources/screenshot-08.jpg</screenshot>
+ <screenshot>resources/screenshot-09.jpg</screenshot>
+ <screenshot>resources/screenshot-10.jpg</screenshot>
+ <screenshot>resources/screenshot-11.jpg</screenshot>
+ <screenshot>resources/screenshot-12.jpg</screenshot>
+ </assets>
</extension>
</addon>
diff --git a/addons/skin.estouchy/fanart.jpg b/addons/skin.estouchy/resources/fanart.jpg
index 1f4d5d934f..1f4d5d934f 100644
--- a/addons/skin.estouchy/fanart.jpg
+++ b/addons/skin.estouchy/resources/fanart.jpg
Binary files differ
diff --git a/addons/skin.estouchy/icon.png b/addons/skin.estouchy/resources/icon.png
index 7714c72d65..7714c72d65 100644
--- a/addons/skin.estouchy/icon.png
+++ b/addons/skin.estouchy/resources/icon.png
Binary files differ
diff --git a/addons/skin.estouchy/resources/screenshot-01.jpg b/addons/skin.estouchy/resources/screenshot-01.jpg
new file mode 100644
index 0000000000..91ad9b5234
--- /dev/null
+++ b/addons/skin.estouchy/resources/screenshot-01.jpg
Binary files differ
diff --git a/addons/skin.estouchy/resources/screenshot-02.jpg b/addons/skin.estouchy/resources/screenshot-02.jpg
new file mode 100644
index 0000000000..e184527f50
--- /dev/null
+++ b/addons/skin.estouchy/resources/screenshot-02.jpg
Binary files differ
diff --git a/addons/skin.estouchy/resources/screenshot-03.jpg b/addons/skin.estouchy/resources/screenshot-03.jpg
new file mode 100644
index 0000000000..7b464acb45
--- /dev/null
+++ b/addons/skin.estouchy/resources/screenshot-03.jpg
Binary files differ
diff --git a/addons/skin.estouchy/resources/screenshot-04.jpg b/addons/skin.estouchy/resources/screenshot-04.jpg
new file mode 100644
index 0000000000..8075153def
--- /dev/null
+++ b/addons/skin.estouchy/resources/screenshot-04.jpg
Binary files differ
diff --git a/addons/skin.estouchy/resources/screenshot-05.jpg b/addons/skin.estouchy/resources/screenshot-05.jpg
new file mode 100644
index 0000000000..3fcfd51ad0
--- /dev/null
+++ b/addons/skin.estouchy/resources/screenshot-05.jpg
Binary files differ
diff --git a/addons/skin.estouchy/resources/screenshot-06.jpg b/addons/skin.estouchy/resources/screenshot-06.jpg
new file mode 100644
index 0000000000..614653db06
--- /dev/null
+++ b/addons/skin.estouchy/resources/screenshot-06.jpg
Binary files differ
diff --git a/addons/skin.estouchy/resources/screenshot-07.jpg b/addons/skin.estouchy/resources/screenshot-07.jpg
new file mode 100644
index 0000000000..05c5c87aa5
--- /dev/null
+++ b/addons/skin.estouchy/resources/screenshot-07.jpg
Binary files differ
diff --git a/addons/skin.estouchy/resources/screenshot-08.jpg b/addons/skin.estouchy/resources/screenshot-08.jpg
new file mode 100644
index 0000000000..e0ed056218
--- /dev/null
+++ b/addons/skin.estouchy/resources/screenshot-08.jpg
Binary files differ
diff --git a/addons/skin.estouchy/resources/screenshot-09.jpg b/addons/skin.estouchy/resources/screenshot-09.jpg
new file mode 100644
index 0000000000..245e995450
--- /dev/null
+++ b/addons/skin.estouchy/resources/screenshot-09.jpg
Binary files differ
diff --git a/addons/skin.estouchy/resources/screenshot-10.jpg b/addons/skin.estouchy/resources/screenshot-10.jpg
new file mode 100644
index 0000000000..113a857504
--- /dev/null
+++ b/addons/skin.estouchy/resources/screenshot-10.jpg
Binary files differ
diff --git a/addons/skin.estouchy/resources/screenshot-11.jpg b/addons/skin.estouchy/resources/screenshot-11.jpg
new file mode 100644
index 0000000000..a2c09d832e
--- /dev/null
+++ b/addons/skin.estouchy/resources/screenshot-11.jpg
Binary files differ
diff --git a/addons/skin.estouchy/resources/screenshot-12.jpg b/addons/skin.estouchy/resources/screenshot-12.jpg
new file mode 100644
index 0000000000..1dd782f040
--- /dev/null
+++ b/addons/skin.estouchy/resources/screenshot-12.jpg
Binary files differ
diff --git a/addons/skin.estuary/1080i/DialogAddonInfo.xml b/addons/skin.estuary/1080i/DialogAddonInfo.xml
index 8c15bbd80d..e236493cdd 100644
--- a/addons/skin.estuary/1080i/DialogAddonInfo.xml
+++ b/addons/skin.estuary/1080i/DialogAddonInfo.xml
@@ -8,37 +8,93 @@
<control type="group">
<include>OpenClose_Right</include>
<control type="button">
- <left>770</left>
- <top>162</top>
- <width>1040</width>
- <height>559</height>
+ <left>605</left>
+ <top>400</top>
+ <width>1235</width>
+ <height>375</height>
<label>-</label>
</control>
<control type="textbox">
- <left>840</left>
- <top>200</top>
- <width>900</width>
- <height>380</height>
+ <left>670</left>
+ <top>435</top>
+ <width>1050</width>
+ <height>300</height>
<font>font_textbox</font>
<label>$INFO[ListItem.AddonSummary,[B],[/B][CR]][COLOR=white]$INFO[ListItem.AddonDescription][/COLOR][COLOR=white][CR][/COLOR]</label>
<textcolor>button_focus</textcolor>
</control>
- <control type="textbox">
- <left>840</left>
- <top>610</top>
- <width>900</width>
- <height>70</height>
- <font>font_textbox</font>
- <label fallback="31008">$INFO[ListItem.AddonDisclaimer,$LOCALIZE[24052]: ]</label>
- <textcolor>button_focus</textcolor>
+ <control type="group">
+ <left>625</left>
+ <top>176</top>
+ <visible>Integer.IsEqual(Container(50).NumItems,0)</visible>
+ <control type="image">
+ <width>385</width>
+ <height>220</height>
+ <texture border="2" background="true">DefaultNoPreview.png</texture>
+ <aspectratio>scale</aspectratio>
+ <bordertexture colordiffuse="border_alpha">colors/black.png</bordertexture>
+ <bordersize>4</bordersize>
+ </control>
+ <control type="image">
+ <left>405</left>
+ <width>385</width>
+ <height>220</height>
+ <texture border="2" background="true">DefaultNoPreview.png</texture>
+ <aspectratio>scale</aspectratio>
+ <bordertexture colordiffuse="border_alpha">colors/black.png</bordertexture>
+ <bordersize>4</bordersize>
+ </control>
+ <control type="image">
+ <left>810</left>
+ <width>385</width>
+ <height>220</height>
+ <texture border="2" background="true">DefaultNoPreview.png</texture>
+ <aspectratio>scale</aspectratio>
+ <bordertexture colordiffuse="border_alpha">colors/black.png</bordertexture>
+ <bordersize>4</bordersize>
+ </control>
</control>
- <control type="image">
- <left>790</left>
- <top>600</top>
- <width>1000</width>
- <height>3</height>
- <texture colordiffuse="button_focus" border="2">dialogs/separator-grey.png</texture>
+ <control type="panel" id="50">
+ <left>625</left>
+ <top>176</top>
+ <width>1215</width>
+ <height>233</height>
+ <ondown>9000</ondown>
+ <onup>9000</onup>
+ <orientation>horizontal</orientation>
+ <itemlayout height="225" width="405">
+ <control type="image">
+ <width>385</width>
+ <height>220</height>
+ <texture border="2" fallback="DefaultAddonNone.png" background="true">$INFO[ListItem.Icon]</texture>
+ <aspectratio>scale</aspectratio>
+ <bordertexture colordiffuse="border_alpha">colors/black.png</bordertexture>
+ <bordersize>4</bordersize>
+ </control>
+ </itemlayout>
+ <focusedlayout height="225" width="405">
+ <control type="image">
+ <width>385</width>
+ <height>220</height>
+ <texture border="2" fallback="DefaultAddonNone.png" background="true">$INFO[ListItem.Icon]</texture>
+ <aspectratio>scale</aspectratio>
+ <bordertexture colordiffuse="border_alpha">colors/black.png</bordertexture>
+ <bordersize>4</bordersize>
+ </control>
+ <control type="image">
+ <width>385</width>
+ <height>220</height>
+ <texture border="8" colordiffuse="button_focus">buttons/thumbnail_focused.png</texture>
+ </control>
+ </focusedlayout>
</control>
+ <include content="LeftRightArrows">
+ <param name="list_id" value="50" />
+ <param name="left_posx" value="580" />
+ <param name="right_posx" value="1840" />
+ <param name="posy" value="280" />
+ <param name="visible" value="true" />
+ </include>
<control type="grouplist" id="9000">
<left>90</left>
<top>820</top>
@@ -46,7 +102,7 @@
<height>300</height>
<onleft>9000</onleft>
<onright>9000</onright>
- <onup>9000</onup>
+ <onup>50</onup>
<ondown>9000</ondown>
<align>center</align>
<itemgap>-18</itemgap>
@@ -97,11 +153,11 @@
</control>
<control type="group">
<include>OpenClose_Left</include>
- <left>120</left>
+ <top>158</top>
+ <left>80</left>
<control type="image">
- <top>162</top>
- <width>559</width>
- <height>559</height>
+ <width>505</width>
+ <height>505</height>
<aspectratio>scale</aspectratio>
<texture colordiffuse="border_alpha">colors/black.png</texture>
<bordertexture border="20">overlays/shadow.png</bordertexture>
@@ -109,13 +165,30 @@
</control>
<control type="image">
<left>24</left>
- <top>186</top>
- <width>511</width>
- <height>511</height>
+ <top>24</top>
+ <width>457</width>
+ <height>457</height>
<aspectratio aligny="top">scale</aspectratio>
<fadetime>300</fadetime>
<texture background="true" fallback="DefaultFolderSquare.png">$INFO[ListItem.Art(thumb)]</texture>
</control>
+ <control type="button">
+ <left>-3</left>
+ <top>490</top>
+ <width>511</width>
+ <height>128</height>
+ <label>-</label>
+ </control>
+ <control type="textbox">
+ <left>42</left>
+ <top>515</top>
+ <width>446</width>
+ <height>80</height>
+ <font>font_textbox</font>
+ <label fallback="31008">$INFO[ListItem.AddonDisclaimer,$LOCALIZE[24052]: ]</label>
+ <textcolor>button_focus</textcolor>
+ <autoscroll time="2000" delay="3000" repeat="5000">true</autoscroll>
+ </control>
<control type="group">
<visible>!String.IsEmpty(ListItem.AddonBroken)</visible>
<include>OpenClose_Fade</include>
diff --git a/addons/skin.estuary/1080i/SlideShow.xml b/addons/skin.estuary/1080i/SlideShow.xml
index 50b6429383..bfe6d61c65 100644
--- a/addons/skin.estuary/1080i/SlideShow.xml
+++ b/addons/skin.estuary/1080i/SlideShow.xml
@@ -1,5 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?>
<window>
- <defaultcontrol>2</defaultcontrol>
- <controls />
</window>
diff --git a/addons/skin.estuary/media/DefaultNoPreview.png b/addons/skin.estuary/media/DefaultNoPreview.png
new file mode 100644
index 0000000000..99ccbb5dba
--- /dev/null
+++ b/addons/skin.estuary/media/DefaultNoPreview.png
Binary files differ
diff --git a/tools/darwin/Support/CopyRootFiles-ios.command b/tools/darwin/Support/CopyRootFiles-ios.command
index 23f78bc1e5..971cac7d10 100755
--- a/tools/darwin/Support/CopyRootFiles-ios.command
+++ b/tools/darwin/Support/CopyRootFiles-ios.command
@@ -44,8 +44,7 @@ SYNCSKIN_A="${SKINSYNC} --exclude *.png --exclude *.jpg"
fi
${SYNCSKIN_A} "$SRCROOT/addons/skin.estouchy" "$TARGET_BUILD_DIR/$TARGET_NAME/AppData/AppHome/addons"
${SYNC} "$SRCROOT/addons/skin.estouchy/background" "$TARGET_BUILD_DIR/$TARGET_NAME/AppData/AppHome/addons/skin.estouchy"
-${SYNC} "$SRCROOT/addons/skin.estouchy/icon.png" "$TARGET_BUILD_DIR/$TARGET_NAME/AppData/AppHome/addons/skin.estouchy"
-${SYNC} "$SRCROOT/addons/skin.estouchy/fanart.jpg" "$TARGET_BUILD_DIR/$TARGET_NAME/AppData/AppHome/addons/skin.estouchy"
+${SYNC} "$SRCROOT/addons/skin.estouchy/resources" "$TARGET_BUILD_DIR/$TARGET_NAME/AppData/AppHome/addons/skin.estouchy"
# sync skin.estuary
SYNCSKIN_B=${SKINSYNC}
diff --git a/tools/darwin/Support/CopyRootFiles-osx.command b/tools/darwin/Support/CopyRootFiles-osx.command
index a4831eb3c0..2fb62b0582 100755
--- a/tools/darwin/Support/CopyRootFiles-osx.command
+++ b/tools/darwin/Support/CopyRootFiles-osx.command
@@ -39,8 +39,7 @@ ${SYNC} "$SRCROOT/addons/skin.estuary/icon.png" "$TARGET_BUILD_DIR/$TARGET_NAME
${SYNC} "$SRCROOT/addons/skin.estuary/fanart.jpg" "$TARGET_BUILD_DIR/$TARGET_NAME/Contents/Resources/$APP_NAME/addons/skin.estuary"
${SYNCSKIN} "$SRCROOT/addons/skin.estouchy" "$TARGET_BUILD_DIR/$TARGET_NAME/Contents/Resources/$APP_NAME/addons"
${SYNC} "$SRCROOT/addons/skin.estouchy/background" "$TARGET_BUILD_DIR/$TARGET_NAME/Contents/Resources/$APP_NAME/addons/skin.estouchy"
-${SYNC} "$SRCROOT/addons/skin.estouchy/icon.png" "$TARGET_BUILD_DIR/$TARGET_NAME/Contents/Resources/$APP_NAME/addons/skin.estouchy"
-${SYNC} "$SRCROOT/addons/skin.estouchy/fanart.jpg" "$TARGET_BUILD_DIR/$TARGET_NAME/Contents/Resources/$APP_NAME/addons/skin.estouchy"
+${SYNC} "$SRCROOT/addons/skin.estouchy/resources" "$TARGET_BUILD_DIR/$TARGET_NAME/Contents/Resources/$APP_NAME/addons/skin.estouchy"
${SYNC} "$SRCROOT/system" "$TARGET_BUILD_DIR/$TARGET_NAME/Contents/Resources/$APP_NAME"
${SYNC} "$SRCROOT/userdata" "$TARGET_BUILD_DIR/$TARGET_NAME/Contents/Resources/$APP_NAME"
diff --git a/xbmc/FileItem.cpp b/xbmc/FileItem.cpp
index 21a09f5b4a..eda5cc10dd 100644
--- a/xbmc/FileItem.cpp
+++ b/xbmc/FileItem.cpp
@@ -1808,15 +1808,21 @@ void CFileItemList::ClearItems()
m_map.clear();
}
-void CFileItemList::Add(const CFileItemPtr &pItem)
+void CFileItemList::Add(CFileItemPtr pItem)
{
CSingleLock lock(m_lock);
-
- m_items.push_back(pItem);
if (m_fastLookup)
- {
m_map.insert(MAPFILEITEMSPAIR(m_ignoreURLOptions ? CURL(pItem->GetPath()).GetWithoutOptions() : pItem->GetPath(), pItem));
- }
+ m_items.emplace_back(std::move(pItem));
+}
+
+void CFileItemList::Add(CFileItem&& item)
+{
+ CSingleLock lock(m_lock);
+ auto ptr = std::make_shared<CFileItem>(std::move(item));
+ if (m_fastLookup)
+ m_map.insert(MAPFILEITEMSPAIR(m_ignoreURLOptions ? CURL(ptr->GetPath()).GetWithoutOptions() : ptr->GetPath(), ptr));
+ m_items.emplace_back(std::move(ptr));
}
void CFileItemList::AddFront(const CFileItemPtr &pItem, int itemPosition)
diff --git a/xbmc/FileItem.h b/xbmc/FileItem.h
index 252f6c3d0b..1630072709 100644
--- a/xbmc/FileItem.h
+++ b/xbmc/FileItem.h
@@ -605,7 +605,8 @@ public:
const CFileItemPtr operator[] (const std::string& strPath) const;
void Clear();
void ClearItems();
- void Add(const CFileItemPtr &pItem);
+ void Add(CFileItemPtr item);
+ void Add(CFileItem&& item);
void AddFront(const CFileItemPtr &pItem, int itemPosition);
void Remove(CFileItem* pItem);
void Remove(int iItem);
diff --git a/xbmc/addons/Addon.h b/xbmc/addons/Addon.h
index fc2b14fd4a..515afe1283 100644
--- a/xbmc/addons/Addon.h
+++ b/xbmc/addons/Addon.h
@@ -74,6 +74,7 @@ public:
std::string icon;
std::string changelog;
std::string fanart;
+ std::vector<std::string> screenshots;
std::string disclaimer;
ADDONDEPS dependencies;
std::string broken;
@@ -109,6 +110,7 @@ public:
std::string ChangeLog() const override { return m_props.changelog; }
std::string FanArt() const override { return m_props.fanart; }
std::string Icon() const override { return m_props.icon; };
+ std::vector<std::string> Screenshots() const override { return m_props.screenshots; };
std::string Disclaimer() const override { return m_props.disclaimer; }
std::string Broken() const override { return m_props.broken; }
CDateTime InstallDate() const override { return m_props.installDate; }
diff --git a/xbmc/addons/AddonBuilder.h b/xbmc/addons/AddonBuilder.h
index 074f7ebe69..29663642d6 100644
--- a/xbmc/addons/AddonBuilder.h
+++ b/xbmc/addons/AddonBuilder.h
@@ -40,6 +40,7 @@ public:
void SetSource(std::string source) { m_props.source = std::move(source); }
void SetIcon(std::string icon) { m_props.icon = std::move(icon); }
void SetFanart(std::string fanart) { m_props.fanart = std::move(fanart); }
+ void SetScreenshots(std::vector<std::string> screenshots) { m_props.screenshots = std::move(screenshots); }
void SetChangelog(std::string changelog) { m_props.changelog = std::move(changelog); }
void SetBroken(std::string broken) { m_props.broken = std::move(broken); }
void SetPath(std::string path) { m_props.path = std::move(path); }
diff --git a/xbmc/addons/AddonDatabase.cpp b/xbmc/addons/AddonDatabase.cpp
index 6f49f14c28..0898f9b58d 100644
--- a/xbmc/addons/AddonDatabase.cpp
+++ b/xbmc/addons/AddonDatabase.cpp
@@ -50,6 +50,10 @@ static std::string SerializeMetadata(const IAddon& addon)
variant["fanart"] = addon.FanArt();
variant["icon"] = addon.Icon();
+ variant["screenshots"] = CVariant(CVariant::VariantTypeArray);
+ for (const auto& item : addon.Screenshots())
+ variant["screenshots"].push_back(item);
+
variant["extensions"] = CVariant(CVariant::VariantTypeArray);
variant["extensions"].push_back(ADDON::TranslateType(addon.Type(), false));
@@ -88,6 +92,11 @@ static void DeserializeMetadata(const std::string& document, CAddonBuilder& buil
builder.SetFanart(variant["fanart"].asString());
builder.SetIcon(variant["icon"].asString());
+ std::vector<std::string> screenshots;
+ for (auto it = variant["screenshots"].begin_array(); it != variant["screenshots"].end_array(); ++it)
+ screenshots.push_back(it->asString());
+ builder.SetScreenshots(std::move(screenshots));
+
builder.SetType(TranslateType(variant["extensions"][0].asString()));
ADDONDEPS deps;
diff --git a/xbmc/addons/AddonManager.cpp b/xbmc/addons/AddonManager.cpp
index 01984c3d03..67d845f20f 100644
--- a/xbmc/addons/AddonManager.cpp
+++ b/xbmc/addons/AddonManager.cpp
@@ -142,13 +142,6 @@ void CAddonMgr::FillCpluffMetadata(const cp_plugin_info_t* plugin, CAddonBuilder
if (plugin->provider_name)
builder.SetAuthor(plugin->provider_name);
- if (plugin->plugin_path && strcmp(plugin->plugin_path, "") != 0)
- {
- builder.SetPath(plugin->plugin_path);
- builder.SetIcon(URIUtils::AddFileToFolder(plugin->plugin_path, "icon.png"));
- builder.SetFanart(URIUtils::AddFileToFolder(plugin->plugin_path, "fanart.jpg"));
- }
-
{
ADDONDEPS dependencies;
for (unsigned int i = 0; i < plugin->num_imports; ++i)
@@ -185,10 +178,44 @@ void CAddonMgr::FillCpluffMetadata(const cp_plugin_info_t* plugin, CAddonBuilder
builder.SetBroken(CAddonMgr::GetInstance().GetExtValue(metadata->configuration, "broken"));
- if (CAddonMgr::GetInstance().GetExtValue(metadata->configuration, "nofanart") == "true")
- builder.SetFanart("");
- if (CAddonMgr::GetInstance().GetExtValue(metadata->configuration, "noicon") == "true")
- builder.SetIcon("");
+ if (plugin->plugin_path && strcmp(plugin->plugin_path, "") != 0)
+ {
+ builder.SetPath(plugin->plugin_path);
+
+ auto assets = CAddonMgr::GetInstance().GetExtElement(metadata->configuration, "assets");
+ if (assets)
+ {
+ std::string icon = CAddonMgr::GetInstance().GetExtValue(assets, "icon");
+ std::string fanart = CAddonMgr::GetInstance().GetExtValue(assets, "fanart");
+
+ if (!icon.empty())
+ builder.SetIcon(URIUtils::AddFileToFolder(plugin->plugin_path, icon));
+ if (!fanart.empty())
+ builder.SetFanart(URIUtils::AddFileToFolder(plugin->plugin_path, fanart));
+
+ std::vector<std::string> screenshots;
+ ELEMENTS elements;
+ if (CAddonMgr::GetInstance().GetExtElements(assets, "screenshot", elements))
+ {
+ for (const auto& elem : elements)
+ {
+ if (elem->value && strcmp(elem->value, "") != 0)
+ screenshots.emplace_back(URIUtils::AddFileToFolder(plugin->plugin_path, elem->value));
+ }
+ }
+ builder.SetScreenshots(std::move(screenshots));
+ }
+ else
+ {
+ //backwards compatibility
+ std::string icon = CAddonMgr::GetInstance().GetExtValue(metadata->configuration, "noicon") == "true" ? "" : "icon.png";
+ std::string fanart = CAddonMgr::GetInstance().GetExtValue(metadata->configuration, "nofanart") == "true" ? "" : "fanart.jpg";
+ if (!icon.empty())
+ builder.SetIcon(URIUtils::AddFileToFolder(plugin->plugin_path, icon));
+ if (!fanart.empty())
+ builder.SetFanart(URIUtils::AddFileToFolder(plugin->plugin_path, fanart));
+ }
+ }
}
}
diff --git a/xbmc/addons/GUIDialogAddonInfo.cpp b/xbmc/addons/GUIDialogAddonInfo.cpp
index ae5756a2de..e6c23b080e 100644
--- a/xbmc/addons/GUIDialogAddonInfo.cpp
+++ b/xbmc/addons/GUIDialogAddonInfo.cpp
@@ -36,6 +36,7 @@
#include "GUIUserMessages.h"
#include "guilib/GUIWindowManager.h"
#include "input/Key.h"
+#include "pictures/GUIWindowSlideShow.h"
#include "settings/Settings.h"
#include "utils/JobManager.h"
#include "utils/FileOperationJob.h"
@@ -55,6 +56,7 @@
#define CONTROL_BTN_SETTINGS 9
#define CONTROL_BTN_SELECT 12
#define CONTROL_BTN_AUTOUPDATE 13
+#define CONTROL_LIST_SCREENSHOTS 50
using namespace ADDON;
using namespace XFILE;
@@ -135,6 +137,17 @@ bool CGUIDialogAddonInfo::OnMessage(CGUIMessage& message)
OnToggleAutoUpdates();
return true;
}
+ else if (iControl == CONTROL_LIST_SCREENSHOTS)
+ {
+ if (message.GetParam1() == ACTION_SELECT_ITEM || message.GetParam1() == ACTION_MOUSE_LEFT_CLICK)
+ {
+ CGUIMessage msg(GUI_MSG_ITEM_SELECTED, GetID(), iControl);
+ OnMessage(msg);
+ int start = msg.GetParam1();
+ if (start >= 0 && start < m_item->GetAddonInfo()->Screenshots().size())
+ CGUIWindowSlideShow::RunSlideShow(m_item->GetAddonInfo()->Screenshots(), start);
+ }
+ }
}
break;
default:
@@ -198,6 +211,16 @@ void CGUIDialogAddonInfo::UpdateControls()
SET_CONTROL_LABEL(CONTROL_BTN_SELECT, CanUse() ? 21480 : (CanOpen() ? 21478 : 21479));
CONTROL_ENABLE_ON_CONDITION(CONTROL_BTN_SETTINGS, isInstalled && m_localAddon->HasSettings());
+
+ CFileItemList items;
+ for (const auto& screenshot : m_item->GetAddonInfo()->Screenshots())
+ {
+ auto item = std::make_shared<CFileItem>("");
+ item->SetArt("thumb", screenshot);
+ items.Add(std::move(item));
+ }
+ CGUIMessage msg(GUI_MSG_LABEL_BIND, GetID(), CONTROL_LIST_SCREENSHOTS, 0, 0, &items);
+ OnMessage(msg);
}
static const std::string LOCAL_CACHE = "\\0_local_cache"; // \0 to give it the lowest priority when sorting
diff --git a/xbmc/addons/IAddon.h b/xbmc/addons/IAddon.h
index 0cb5bbc4b1..1b1dfb3f76 100644
--- a/xbmc/addons/IAddon.h
+++ b/xbmc/addons/IAddon.h
@@ -26,6 +26,7 @@
#include <set>
#include <string>
#include <utility>
+#include <vector>
#include "XBDateTime.h"
class TiXmlElement;
@@ -106,6 +107,7 @@ namespace ADDON
virtual std::string LibPath() const =0;
virtual std::string ChangeLog() const =0;
virtual std::string FanArt() const =0;
+ virtual std::vector<std::string> Screenshots() const =0;
virtual std::string Author() const =0;
virtual std::string Icon() const =0;
virtual std::string Disclaimer() const =0;
diff --git a/xbmc/addons/Repository.cpp b/xbmc/addons/Repository.cpp
index 2f571646c7..86df11ba34 100644
--- a/xbmc/addons/Repository.cpp
+++ b/xbmc/addons/Repository.cpp
@@ -191,12 +191,14 @@ bool CRepositoryUpdateJob::DoWork()
AddonPtr oldAddon;
if (database.GetAddon(addon->ID(), oldAddon) && addon->Version() > oldAddon->Version())
{
- if (!addon->Icon().empty() || !addon->FanArt().empty())
+ if (!oldAddon->Icon().empty() || !oldAddon->FanArt().empty() || !oldAddon->Screenshots().empty())
CLog::Log(LOGDEBUG, "CRepository: invalidating cached art for '%s'", addon->ID().c_str());
- if (!addon->Icon().empty())
- textureDB.InvalidateCachedTexture(addon->Icon());
- if (!addon->FanArt().empty())
- textureDB.InvalidateCachedTexture(addon->Icon());
+ if (!oldAddon->Icon().empty())
+ textureDB.InvalidateCachedTexture(oldAddon->Icon());
+ if (!oldAddon->FanArt().empty())
+ textureDB.InvalidateCachedTexture(oldAddon->Icon());
+ for (const auto& path : oldAddon->Screenshots())
+ textureDB.InvalidateCachedTexture(path);
}
}
textureDB.CommitMultipleExecute();
diff --git a/xbmc/guilib/GUIWindow.cpp b/xbmc/guilib/GUIWindow.cpp
index 2f15256479..70f7063f62 100644
--- a/xbmc/guilib/GUIWindow.cpp
+++ b/xbmc/guilib/GUIWindow.cpp
@@ -55,7 +55,6 @@ CGUIWindow::CGUIWindow(int id, const std::string &xmlFile)
SetID(id);
SetProperty("xmlfile", xmlFile);
m_lastControlID = 0;
- m_isDialog = false;
m_needsScaling = true;
m_windowLoaded = false;
m_loadType = LOAD_EVERY_TIME;
@@ -187,14 +186,7 @@ bool CGUIWindow::Load(TiXmlElement* pRootElement)
while (pChild)
{
std::string strValue = pChild->Value();
- if (strValue == "type" && pChild->FirstChild())
- {
- // if we have are a window type (ie not a dialog), and we have <type>dialog</type>
- // then make this window act like a dialog
- if (!IsDialog() && strcmpi(pChild->FirstChild()->Value(), "dialog") == 0)
- m_isDialog = true;
- }
- else if (strValue == "previouswindow" && pChild->FirstChild())
+ if (strValue == "previouswindow" && pChild->FirstChild())
{
m_previousWindow = CButtonTranslator::TranslateWindow(pChild->FirstChild()->Value());
}
diff --git a/xbmc/guilib/GUIWindow.h b/xbmc/guilib/GUIWindow.h
index 19d800a38b..0b64939c11 100644
--- a/xbmc/guilib/GUIWindow.h
+++ b/xbmc/guilib/GUIWindow.h
@@ -244,7 +244,6 @@ protected:
bool m_needsScaling;
bool m_windowLoaded; // true if the window's xml file has been loaded
LOAD_TYPE m_loadType;
- bool m_isDialog; // true if we have a dialog, false otherwise.
bool m_dynamicResourceAlloc;
bool m_closing;
bool m_active; // true if window is active or dialog is running
diff --git a/xbmc/interfaces/AnnouncementManager.cpp b/xbmc/interfaces/AnnouncementManager.cpp
index 7e693aac91..9508cac002 100644
--- a/xbmc/interfaces/AnnouncementManager.cpp
+++ b/xbmc/interfaces/AnnouncementManager.cpp
@@ -100,13 +100,13 @@ void CAnnouncementManager::Announce(AnnouncementFlag flag, const char *sender, c
Announce(flag, sender, message, CFileItemPtr(), data);
}
-void CAnnouncementManager::Announce(AnnouncementFlag flag, const char *sender, const char *message, CFileItemPtr item)
+void CAnnouncementManager::Announce(AnnouncementFlag flag, const char *sender, const char *message, const std::shared_ptr<const CFileItem>& item)
{
CVariant data;
Announce(flag, sender, message, item, data);
}
-void CAnnouncementManager::Announce(AnnouncementFlag flag, const char *sender, const char *message, CFileItemPtr item, const CVariant &data)
+void CAnnouncementManager::Announce(AnnouncementFlag flag, const char *sender, const char *message, const std::shared_ptr<const CFileItem>& item, const CVariant &data)
{
CAnnounceData announcement;
announcement.flag = flag;
diff --git a/xbmc/interfaces/AnnouncementManager.h b/xbmc/interfaces/AnnouncementManager.h
index 978512487c..0ab56acbcc 100644
--- a/xbmc/interfaces/AnnouncementManager.h
+++ b/xbmc/interfaces/AnnouncementManager.h
@@ -47,8 +47,10 @@ namespace ANNOUNCEMENT
void Announce(AnnouncementFlag flag, const char *sender, const char *message);
void Announce(AnnouncementFlag flag, const char *sender, const char *message, const CVariant &data);
- void Announce(AnnouncementFlag flag, const char *sender, const char *message, CFileItemPtr item);
- void Announce(AnnouncementFlag flag, const char *sender, const char *message, CFileItemPtr item, const CVariant &data);
+ void Announce(AnnouncementFlag flag, const char *sender, const char *message,
+ const std::shared_ptr<const CFileItem>& item);
+ void Announce(AnnouncementFlag flag, const char *sender, const char *message,
+ const std::shared_ptr<const CFileItem>& item, const CVariant &data);
protected:
void Process();
diff --git a/xbmc/pictures/GUIWindowSlideShow.cpp b/xbmc/pictures/GUIWindowSlideShow.cpp
index e62255d619..2890113e6d 100644
--- a/xbmc/pictures/GUIWindowSlideShow.cpp
+++ b/xbmc/pictures/GUIWindowSlideShow.cpp
@@ -39,6 +39,7 @@
#include "guilib/Texture.h"
#include "windowing/WindowingFactory.h"
#include "guilib/LocalizeStrings.h"
+#include "TextureDatabase.h"
#include "threads/SingleLock.h"
#include "utils/log.h"
#include "utils/Variant.h"
@@ -56,7 +57,7 @@ using namespace KODI::MESSAGING;
#define MAX_ZOOM_FACTOR 10
#define MAX_PICTURE_SIZE 2048*2048
-#define IMMEDIATE_TRANSISTION_TIME 20
+#define IMMEDIATE_TRANSITION_TIME 1
#define PICTURE_MOVE_AMOUNT 0.02f
#define PICTURE_MOVE_AMOUNT_ANALOG 0.01f
@@ -66,12 +67,8 @@ using namespace KODI::MESSAGING;
#define ROTATION_SNAP_RANGE 10.0f
-#define FPS 25
-
-#define BAR_IMAGE 1
#define LABEL_ROW1 10
#define LABEL_ROW2 11
-#define LABEL_ROW2_EXTRA 12
#define CONTROL_PAUSE 13
static float zoomamount[10] = { 1.0f, 1.2f, 1.5f, 2.0f, 2.8f, 4.0f, 6.0f, 9.0f, 13.5f, 20.0f };
@@ -151,22 +148,15 @@ void CBackgroundPicLoader::LoadPic(int iPic, int iSlideNumber, const std::string
}
CGUIWindowSlideShow::CGUIWindowSlideShow(void)
- : CGUIWindow(WINDOW_SLIDESHOW, "SlideShow.xml")
+ : CGUIDialog(WINDOW_SLIDESHOW, "SlideShow.xml")
{
m_pBackgroundLoader = NULL;
- m_slides = new CFileItemList;
m_Resolution = RES_INVALID;
m_loadType = KEEP_IN_MEMORY;
m_bLoadNextPic = false;
Reset();
}
-CGUIWindowSlideShow::~CGUIWindowSlideShow(void)
-{
- Reset();
- delete m_slides;
-}
-
void CGUIWindowSlideShow::AnnouncePlayerPlay(const CFileItemPtr& item)
{
CVariant param;
@@ -191,14 +181,6 @@ void CGUIWindowSlideShow::AnnouncePlayerStop(const CFileItemPtr& item)
ANNOUNCEMENT::CAnnouncementManager::GetInstance().Announce(ANNOUNCEMENT::Player, "xbmc", "OnStop", item, param);
}
-void CGUIWindowSlideShow::AnnouncePlaylistRemove(int pos)
-{
- CVariant data;
- data["playlistid"] = PLAYLIST_PICTURE;
- data["position"] = pos;
- ANNOUNCEMENT::CAnnouncementManager::GetInstance().Announce(ANNOUNCEMENT::Playlist, "xbmc", "OnRemove", data);
-}
-
void CGUIWindowSlideShow::AnnouncePlaylistClear()
{
CVariant data;
@@ -252,8 +234,7 @@ void CGUIWindowSlideShow::Reset()
m_iCurrentPic = 0;
m_iDirection = 1;
m_iLastFailedNextSlide = -1;
- CSingleLock lock(m_slideSection);
- m_slides->Clear();
+ m_slides.clear();
AnnouncePlaylistClear();
m_Resolution = g_graphicsContext.GetVideoResolution();
}
@@ -287,7 +268,7 @@ void CGUIWindowSlideShow::OnDeinitWindow(int nextWindowID)
}
g_infoManager.ResetCurrentSlide();
- CGUIWindow::OnDeinitWindow(nextWindowID);
+ CGUIDialog::OnDeinitWindow(nextWindowID);
}
void CGUIWindowSlideShow::Add(const CFileItem *picture)
@@ -302,14 +283,14 @@ void CGUIWindowSlideShow::Add(const CFileItem *picture)
// then it is a picture and force tag generation
item->GetPictureInfoTag();
}
- AnnouncePlaylistAdd(item, m_slides->Size());
+ AnnouncePlaylistAdd(item, m_slides.size());
- m_slides->Add(item);
+ m_slides.emplace_back(std::move(item));
}
void CGUIWindowSlideShow::ShowNext()
{
- if (m_slides->Size() == 1)
+ if (m_slides.size() == 1)
return;
m_iDirection = 1;
@@ -322,7 +303,7 @@ void CGUIWindowSlideShow::ShowNext()
void CGUIWindowSlideShow::ShowPrevious()
{
- if (m_slides->Size() == 1)
+ if (m_slides.size() == 1)
return;
m_iDirection = -1;
@@ -336,9 +317,9 @@ void CGUIWindowSlideShow::ShowPrevious()
void CGUIWindowSlideShow::Select(const std::string& strPicture)
{
- for (int i = 0; i < m_slides->Size(); ++i)
+ for (int i = 0; i < m_slides.size(); ++i)
{
- const CFileItemPtr item = m_slides->Get(i);
+ const CFileItemPtr item = m_slides.at(i);
if (item->GetPath() == strPicture)
{
m_iDirection = 1;
@@ -358,21 +339,16 @@ void CGUIWindowSlideShow::Select(const std::string& strPicture)
}
}
-const CFileItemList &CGUIWindowSlideShow::GetSlideShowContents()
-{
- return *m_slides;
-}
-
void CGUIWindowSlideShow::GetSlideShowContents(CFileItemList &list)
{
- for (int index = 0; index < m_slides->Size(); index++)
- list.Add(CFileItemPtr(new CFileItem(*m_slides->Get(index))));
+ for (int index = 0; index < m_slides.size(); index++)
+ list.Add(CFileItemPtr(new CFileItem(*m_slides.at(index))));
}
-const CFileItemPtr CGUIWindowSlideShow::GetCurrentSlide()
+std::shared_ptr<const CFileItem> CGUIWindowSlideShow::GetCurrentSlide()
{
- if (m_iCurrentSlide >= 0 && m_iCurrentSlide < m_slides->Size())
- return m_slides->Get(m_iCurrentSlide);
+ if (m_iCurrentSlide >= 0 && m_iCurrentSlide < m_slides.size())
+ return m_slides.at(m_iCurrentSlide);
return CFileItemPtr();
}
@@ -385,8 +361,8 @@ void CGUIWindowSlideShow::StartSlideShow()
{
m_bSlideShow = true;
m_iDirection = 1;
- if (m_slides->Size())
- AnnouncePlayerPlay(m_slides->Get(m_iCurrentSlide));
+ if (m_slides.size())
+ AnnouncePlayerPlay(m_slides.at(m_iCurrentSlide));
}
void CGUIWindowSlideShow::SetDirection(int direction)
@@ -407,16 +383,16 @@ void CGUIWindowSlideShow::Process(unsigned int currentTime, CDirtyRegionList &re
// (unless we are the screensaver!)
if (m_bSlideShow && !m_bPause && !g_application.IsInScreenSaver())
g_application.ResetScreenSaver();
- int iSlides = m_slides->Size();
+ int iSlides = m_slides.size();
if (!iSlides) return ;
// if we haven't processed yet, we should mark the whole screen
if (!HasProcessed())
regions.push_back(CRect(0.0f, 0.0f, (float)g_graphicsContext.GetWidth(), (float)g_graphicsContext.GetHeight()));
- if (m_iCurrentSlide < 0 || m_iCurrentSlide >= m_slides->Size())
+ if (m_iCurrentSlide < 0 || m_iCurrentSlide >= m_slides.size())
m_iCurrentSlide = 0;
- if (m_iNextSlide < 0 || m_iNextSlide >= m_slides->Size())
+ if (m_iNextSlide < 0 || m_iNextSlide >= m_slides.size())
m_iNextSlide = GetNextSlide();
// Create our background loader if necessary
@@ -432,7 +408,7 @@ void CGUIWindowSlideShow::Process(unsigned int currentTime, CDirtyRegionList &re
}
bool bSlideShow = m_bSlideShow && !m_bPause && !m_bPlayingVideo;
- if (bSlideShow && m_slides->Get(m_iCurrentSlide)->HasProperty("unplayable"))
+ if (bSlideShow && m_slides.at(m_iCurrentSlide)->HasProperty("unplayable"))
{
m_iNextSlide = GetNextSlide();
if (m_iCurrentSlide == m_iNextSlide)
@@ -454,14 +430,14 @@ void CGUIWindowSlideShow::Process(unsigned int currentTime, CDirtyRegionList &re
}
else
{
- CLog::Log(LOGERROR, "Error loading the current image %d: %s", m_iCurrentSlide, m_slides->Get(m_iCurrentSlide)->GetPath().c_str());
- if (!m_slides->Get(m_iCurrentPic)->IsVideo())
+ CLog::Log(LOGERROR, "Error loading the current image %d: %s", m_iCurrentSlide, m_slides.at(m_iCurrentSlide)->GetPath().c_str());
+ if (!m_slides.at(m_iCurrentPic)->IsVideo())
{
// try next if we are in slideshow
- CLog::Log(LOGINFO, "set image %s unplayable", m_slides->Get(m_iCurrentSlide)->GetPath().c_str());
- m_slides->Get(m_iCurrentSlide)->SetProperty("unplayable", true);
+ CLog::Log(LOGINFO, "set image %s unplayable", m_slides.at(m_iCurrentSlide)->GetPath().c_str());
+ m_slides.at(m_iCurrentSlide)->SetProperty("unplayable", true);
}
- if (m_bLoadNextPic || (bSlideShow && !m_bPause && !m_slides->Get(m_iCurrentPic)->IsVideo()))
+ if (m_bLoadNextPic || (bSlideShow && !m_bPause && !m_slides.at(m_iCurrentPic)->IsVideo()))
{
// change to next item, wait loading.
m_iCurrentSlide = m_iNextSlide;
@@ -473,12 +449,12 @@ void CGUIWindowSlideShow::Process(unsigned int currentTime, CDirtyRegionList &re
}
else if (m_iNextSlide == m_pBackgroundLoader->SlideNumber())
{
- CLog::Log(LOGERROR, "Error loading the next image %d: %s", m_iNextSlide, m_slides->Get(m_iNextSlide)->GetPath().c_str());
+ CLog::Log(LOGERROR, "Error loading the next image %d: %s", m_iNextSlide, m_slides.at(m_iNextSlide)->GetPath().c_str());
// load next image failed, then skip to load next of next if next is not video.
- if (!m_slides->Get(m_iNextSlide)->IsVideo())
+ if (!m_slides.at(m_iNextSlide)->IsVideo())
{
- CLog::Log(LOGINFO, "set image %s unplayable", m_slides->Get(m_iNextSlide)->GetPath().c_str());
- m_slides->Get(m_iNextSlide)->SetProperty("unplayable", true);
+ CLog::Log(LOGINFO, "set image %s unplayable", m_slides.at(m_iNextSlide)->GetPath().c_str());
+ m_slides.at(m_iNextSlide)->SetProperty("unplayable", true);
// change to next item, wait loading.
m_iNextSlide = GetNextSlide();
}
@@ -490,7 +466,7 @@ void CGUIWindowSlideShow::Process(unsigned int currentTime, CDirtyRegionList &re
}
else
{ // Non-current and non-next slide, just ignore error.
- CLog::Log(LOGERROR, "Error loading the non-current non-next image %d/%d: %s", m_iNextSlide, m_pBackgroundLoader->SlideNumber(), m_slides->Get(m_iNextSlide)->GetPath().c_str());
+ CLog::Log(LOGERROR, "Error loading the non-current non-next image %d/%d: %s", m_iNextSlide, m_pBackgroundLoader->SlideNumber(), m_slides.at(m_iNextSlide)->GetPath().c_str());
m_bErrorMessage = false;
}
}
@@ -501,11 +477,9 @@ void CGUIWindowSlideShow::Process(unsigned int currentTime, CDirtyRegionList &re
return;
}
- CSingleLock lock(m_slideSection);
-
if (!m_Image[m_iCurrentPic].IsLoaded() && !m_pBackgroundLoader->IsLoading())
{ // load first image
- CFileItemPtr item = m_slides->Get(m_iCurrentSlide);
+ CFileItemPtr item = m_slides.at(m_iCurrentSlide);
std::string picturePath = GetPicturePath(item.get());
if (!picturePath.empty())
{
@@ -533,7 +507,7 @@ void CGUIWindowSlideShow::Process(unsigned int currentTime, CDirtyRegionList &re
if (m_iNextSlide != m_iCurrentSlide && m_Image[m_iCurrentPic].IsLoaded() && !m_Image[1 - m_iCurrentPic].IsLoaded() && !m_pBackgroundLoader->IsLoading() && m_iLastFailedNextSlide != m_iNextSlide)
{ // load the next image
m_iLastFailedNextSlide = -1;
- CFileItemPtr item = m_slides->Get(m_iNextSlide);
+ CFileItemPtr item = m_slides.at(m_iNextSlide);
std::string picturePath = GetPicturePath(item.get());
if (!picturePath.empty() && (!item->IsVideo() || !m_bSlideShow || m_bPause))
{
@@ -550,7 +524,7 @@ void CGUIWindowSlideShow::Process(unsigned int currentTime, CDirtyRegionList &re
}
}
- if (m_slides->Get(m_iCurrentSlide)->IsVideo() && bSlideShow)
+ if (m_slides.at(m_iCurrentSlide)->IsVideo() && bSlideShow)
{
if (!PlayVideo())
return;
@@ -568,10 +542,10 @@ void CGUIWindowSlideShow::Process(unsigned int currentTime, CDirtyRegionList &re
// Check if we should be transistioning immediately
if (m_bLoadNextPic && m_Image[m_iCurrentPic].IsLoaded())
{
- CLog::Log(LOGDEBUG, "Starting immediate transistion due to user wanting slide %s", m_slides->Get(m_iNextSlide)->GetPath().c_str());
+ CLog::Log(LOGDEBUG, "Starting immediate transistion due to user wanting slide %s", m_slides.at(m_iNextSlide)->GetPath().c_str());
if (m_Image[m_iCurrentPic].StartTransistion())
{
- m_Image[m_iCurrentPic].SetTransistionTime(1, IMMEDIATE_TRANSISTION_TIME); // only 20 frames for the transistion
+ m_Image[m_iCurrentPic].SetTransistionTime(1, IMMEDIATE_TRANSITION_TIME);
m_bLoadNextPic = false;
}
}
@@ -579,7 +553,7 @@ void CGUIWindowSlideShow::Process(unsigned int currentTime, CDirtyRegionList &re
// render the next image
if (m_Image[m_iCurrentPic].DrawNextImage())
{
- if (m_bSlideShow && !m_bPause && m_slides->Get(m_iNextSlide)->IsVideo())
+ if (m_bSlideShow && !m_bPause && m_slides.at(m_iNextSlide)->IsVideo())
{
// do not show thumb of video when playing slideshow
}
@@ -594,7 +568,7 @@ void CGUIWindowSlideShow::Process(unsigned int currentTime, CDirtyRegionList &re
}
// set the appropriate transistion time
m_Image[1 - m_iCurrentPic].SetTransistionTime(0, m_Image[m_iCurrentPic].GetTransistionTime(1));
- m_Image[1 - m_iCurrentPic].Pause(!m_bSlideShow || m_bPause || m_slides->Get(m_iNextSlide)->IsVideo());
+ m_Image[1 - m_iCurrentPic].Pause(!m_bSlideShow || m_bPause || m_slides.at(m_iNextSlide)->IsVideo());
m_Image[1 - m_iCurrentPic].Process(currentTime, regions);
}
else // next pic isn't loaded. We should hang around if it is in progress
@@ -612,10 +586,10 @@ void CGUIWindowSlideShow::Process(unsigned int currentTime, CDirtyRegionList &re
{
m_bLoadNextPic = false;
if (m_Image[m_iCurrentPic].IsFinished())
- CLog::Log(LOGDEBUG, "Image %s is finished rendering, switching to %s", m_slides->Get(m_iCurrentSlide)->GetPath().c_str(), m_slides->Get(m_iNextSlide)->GetPath().c_str());
+ CLog::Log(LOGDEBUG, "Image %s is finished rendering, switching to %s", m_slides.at(m_iCurrentSlide)->GetPath().c_str(), m_slides.at(m_iNextSlide)->GetPath().c_str());
else
// what if it's bg loading?
- CLog::Log(LOGDEBUG, "Image %s is not loaded, switching to %s", m_slides->Get(m_iCurrentSlide)->GetPath().c_str(), m_slides->Get(m_iNextSlide)->GetPath().c_str());
+ CLog::Log(LOGDEBUG, "Image %s is not loaded, switching to %s", m_slides.at(m_iCurrentSlide)->GetPath().c_str(), m_slides.at(m_iNextSlide)->GetPath().c_str());
if (m_Image[m_iCurrentPic].IsFinished() && m_iCurrentSlide == m_iNextSlide && m_Image[m_iCurrentPic].SlideNumber() == m_iNextSlide)
m_Image[m_iCurrentPic].Reset(GetDisplayEffect(m_iCurrentSlide));
@@ -639,7 +613,7 @@ void CGUIWindowSlideShow::Process(unsigned int currentTime, CDirtyRegionList &re
m_iCurrentSlide = m_iNextSlide;
m_iNextSlide = GetNextSlide();
}
- AnnouncePlayerPlay(m_slides->Get(m_iCurrentSlide));
+ AnnouncePlayerPlay(m_slides.at(m_iCurrentSlide));
m_iZoomFactor = 1;
m_fZoom = 1.0f;
@@ -647,14 +621,17 @@ void CGUIWindowSlideShow::Process(unsigned int currentTime, CDirtyRegionList &re
}
if (m_Image[m_iCurrentPic].IsLoaded())
- g_infoManager.SetCurrentSlide(*m_slides->Get(m_iCurrentSlide));
+ g_infoManager.SetCurrentSlide(*m_slides.at(m_iCurrentSlide));
RenderPause();
CGUIWindow::Process(currentTime, regions);
+ m_renderRegion.SetRect(0, 0, (float)g_graphicsContext.GetWidth(), (float)g_graphicsContext.GetHeight());
}
void CGUIWindowSlideShow::Render()
{
+ g_graphicsContext.Clear(0xff000000);
+
if (m_Image[m_iCurrentPic].IsLoaded())
m_Image[m_iCurrentPic].Render();
@@ -667,15 +644,15 @@ void CGUIWindowSlideShow::Render()
int CGUIWindowSlideShow::GetNextSlide()
{
- if (m_slides->Size() <= 1)
+ if (m_slides.size() <= 1)
return m_iCurrentSlide;
int step = m_iDirection >= 0 ? 1 : -1;
- int nextSlide = (m_iCurrentSlide + step + m_slides->Size()) % m_slides->Size();
+ int nextSlide = (m_iCurrentSlide + step + m_slides.size()) % m_slides.size();
while (nextSlide != m_iCurrentSlide)
{
- if (!m_slides->Get(nextSlide)->HasProperty("unplayable"))
+ if (!m_slides.at(nextSlide)->HasProperty("unplayable"))
return nextSlide;
- nextSlide = (nextSlide + step + m_slides->Size()) % m_slides->Size();
+ nextSlide = (nextSlide + step + m_slides.size()) % m_slides.size();
}
return m_iCurrentSlide;
}
@@ -770,13 +747,10 @@ bool CGUIWindowSlideShow::OnAction(const CAction &action)
}
}
break;
-
- case ACTION_PREVIOUS_MENU:
- case ACTION_NAV_BACK:
case ACTION_STOP:
- if (m_slides->Size())
- AnnouncePlayerStop(m_slides->Get(m_iCurrentSlide));
- g_windowManager.PreviousWindow();
+ if (m_slides.size())
+ AnnouncePlayerStop(m_slides.at(m_iCurrentSlide));
+ Close();
break;
case ACTION_NEXT_PICTURE:
@@ -811,9 +785,9 @@ bool CGUIWindowSlideShow::OnAction(const CAction &action)
case ACTION_PAUSE:
case ACTION_PLAYER_PLAY:
- if (m_slides->Size() == 0)
+ if (m_slides.size() == 0)
break;
- if (m_slides->Get(m_iCurrentSlide)->IsVideo())
+ if (m_slides.at(m_iCurrentSlide)->IsVideo())
{
if (!m_bPlayingVideo)
{
@@ -836,12 +810,12 @@ bool CGUIWindowSlideShow::OnAction(const CAction &action)
if (m_Image[m_iCurrentPic].DisplayEffectNeedChange(effect))
m_Image[m_iCurrentPic].Reset(effect);
}
- AnnouncePlayerPlay(m_slides->Get(m_iCurrentSlide));
+ AnnouncePlayerPlay(m_slides.at(m_iCurrentSlide));
}
else if (action.GetID() == ACTION_PAUSE)
{
m_bPause = true;
- AnnouncePlayerPause(m_slides->Get(m_iCurrentSlide));
+ AnnouncePlayerPause(m_slides.at(m_iCurrentSlide));
}
break;
@@ -900,7 +874,7 @@ bool CGUIWindowSlideShow::OnAction(const CAction &action)
break;
default:
- return CGUIWindow::OnAction(action);
+ return CGUIDialog::OnAction(action);
}
return true;
}
@@ -934,10 +908,10 @@ bool CGUIWindowSlideShow::OnMessage(CGUIMessage& message)
else
m_Resolution = g_graphicsContext.GetVideoResolution();
- CGUIWindow::OnMessage(message);
+ CGUIDialog::OnMessage(message);
// turn off slideshow if we only have 1 image
- if (m_slides->Size() <= 1)
+ if (m_slides.size() <= 1)
m_bSlideShow = false;
return true;
@@ -1016,7 +990,7 @@ bool CGUIWindowSlideShow::OnMessage(CGUIMessage& message)
m_iCurrentPic = 1 - m_iCurrentPic;
m_iCurrentSlide = m_iNextSlide;
m_iNextSlide = GetNextSlide();
- AnnouncePlayerPlay(m_slides->Get(m_iCurrentSlide));
+ AnnouncePlayerPlay(m_slides.at(m_iCurrentSlide));
m_iZoomFactor = 1;
m_fZoom = 1.0f;
m_fRotate = 0.0f;
@@ -1025,7 +999,7 @@ bool CGUIWindowSlideShow::OnMessage(CGUIMessage& message)
}
break;
}
- return CGUIWindow::OnMessage(message);
+ return CGUIDialog::OnMessage(message);
}
void CGUIWindowSlideShow::RenderPause()
@@ -1038,16 +1012,6 @@ void CGUIWindowSlideShow::RenderPause()
{
SET_CONTROL_HIDDEN(CONTROL_PAUSE);
}
- /*
- static DWORD dwCounter=0;
- dwCounter++;
- if (dwCounter > 25)
- {
- dwCounter=0;
- }
- if (!m_bPause) return;
- if (dwCounter <13) return;*/
-
}
void CGUIWindowSlideShow::Rotate(float fAngle, bool immediate /* = false */)
@@ -1108,7 +1072,7 @@ void CGUIWindowSlideShow::Move(float fX, float fY)
bool CGUIWindowSlideShow::PlayVideo()
{
- CFileItemPtr item = m_slides->Get(m_iCurrentSlide);
+ CFileItemPtr item = m_slides.at(m_iCurrentSlide);
if (!item || !item->IsVideo())
return false;
CLog::Log(LOGDEBUG, "Playing current video slide %s", item->GetPath().c_str());
@@ -1129,7 +1093,7 @@ bool CGUIWindowSlideShow::PlayVideo()
CSlideShowPic::DISPLAY_EFFECT CGUIWindowSlideShow::GetDisplayEffect(int iSlideNumber) const
{
- if (m_bSlideShow && !m_bPause && !m_slides->Get(iSlideNumber)->IsVideo())
+ if (m_bSlideShow && !m_bPause && !m_slides.at(iSlideNumber)->IsVideo())
return CSettings::GetInstance().GetBool(CSettings::SETTING_SLIDESHOW_DISPLAYEFFECTS) ? CSlideShowPic::EFFECT_RANDOM : CSlideShowPic::EFFECT_NONE;
else
return CSlideShowPic::EFFECT_NO_TIMEOUT;
@@ -1140,20 +1104,19 @@ void CGUIWindowSlideShow::OnLoadPic(int iPic, int iSlideNumber, const std::strin
if (pTexture)
{
// set the pic's texture + size etc.
- CSingleLock lock(m_slideSection);
- if (iSlideNumber >= m_slides->Size() || GetPicturePath(m_slides->Get(iSlideNumber).get()) != strFileName)
+ if (iSlideNumber >= m_slides.size() || GetPicturePath(m_slides.at(iSlideNumber).get()) != strFileName)
{ // throw this away - we must have cleared the slideshow while we were still loading
delete pTexture;
return;
}
- CLog::Log(LOGDEBUG, "Finished background loading slot %d, %d: %s", iPic, iSlideNumber, m_slides->Get(iSlideNumber)->GetPath().c_str());
+ CLog::Log(LOGDEBUG, "Finished background loading slot %d, %d: %s", iPic, iSlideNumber, m_slides.at(iSlideNumber)->GetPath().c_str());
m_Image[iPic].SetTexture(iSlideNumber, pTexture, GetDisplayEffect(iSlideNumber));
m_Image[iPic].SetOriginalSize(pTexture->GetOriginalWidth(), pTexture->GetOriginalHeight(), bFullSize);
m_Image[iPic].m_bIsComic = false;
- if (URIUtils::IsInRAR(m_slides->Get(m_iCurrentSlide)->GetPath()) || URIUtils::IsInZIP(m_slides->Get(m_iCurrentSlide)->GetPath())) // move to top for cbr/cbz
+ if (URIUtils::IsInRAR(m_slides.at(m_iCurrentSlide)->GetPath()) || URIUtils::IsInZIP(m_slides.at(m_iCurrentSlide)->GetPath())) // move to top for cbr/cbz
{
- CURL url(m_slides->Get(m_iCurrentSlide)->GetPath());
+ CURL url(m_slides.at(m_iCurrentSlide)->GetPath());
std::string strHostName = url.GetHostName();
if (URIUtils::HasExtension(strHostName, ".cbr|.cbz"))
{
@@ -1162,9 +1125,9 @@ void CGUIWindowSlideShow::OnLoadPic(int iPic, int iSlideNumber, const std::strin
}
}
}
- else if (iSlideNumber >= m_slides->Size() || GetPicturePath(m_slides->Get(iSlideNumber).get()) != strFileName)
+ else if (iSlideNumber >= m_slides.size() || GetPicturePath(m_slides.at(iSlideNumber).get()) != strFileName)
{ // Failed to load image. and not match values calling LoadPic, then something is changed, ignore.
- CLog::Log(LOGDEBUG, "CGUIWindowSlideShow::OnLoadPic(%d, %d, %s) on failure not match current state (cur %d, next %d, curpic %d, pic[0, 1].slidenumber=%d, %d, %s)", iPic, iSlideNumber, strFileName.c_str(), m_iCurrentSlide, m_iNextSlide, m_iCurrentPic, m_Image[0].SlideNumber(), m_Image[1].SlideNumber(), iSlideNumber >= m_slides->Size() ? "" : m_slides->Get(iSlideNumber)->GetPath().c_str());
+ CLog::Log(LOGDEBUG, "CGUIWindowSlideShow::OnLoadPic(%d, %d, %s) on failure not match current state (cur %d, next %d, curpic %d, pic[0, 1].slidenumber=%d, %d, %s)", iPic, iSlideNumber, strFileName.c_str(), m_iCurrentSlide, m_iNextSlide, m_iCurrentPic, m_Image[0].SlideNumber(), m_Image[1].SlideNumber(), iSlideNumber >= m_slides.size() ? "" : m_slides.at(iSlideNumber)->GetPath().c_str());
}
else
{ // Failed to load image. What should be done??
@@ -1176,7 +1139,7 @@ void CGUIWindowSlideShow::OnLoadPic(int iPic, int iSlideNumber, const std::strin
void CGUIWindowSlideShow::Shuffle()
{
- m_slides->Randomize();
+ std::random_shuffle(m_slides.begin(), m_slides.end());
m_iCurrentSlide = 0;
m_iNextSlide = GetNextSlide();
m_bShuffled = true;
@@ -1186,7 +1149,7 @@ void CGUIWindowSlideShow::Shuffle()
int CGUIWindowSlideShow::NumSlides() const
{
- return m_slides->Size();
+ return m_slides.size();
}
int CGUIWindowSlideShow::CurrentSlide() const
@@ -1203,7 +1166,6 @@ void CGUIWindowSlideShow::AddFromPath(const std::string &strPath,
{
// reset the slideshow
Reset();
- m_strExtensions = strExtensions;
if (bRecursive)
{
path_set recursivePaths;
@@ -1316,3 +1278,23 @@ std::string CGUIWindowSlideShow::GetPicturePath(CFileItem *item)
return picturePath;
}
+
+void CGUIWindowSlideShow::RunSlideShow(std::vector<std::string> paths, int start /* = 0*/)
+{
+ auto dialog = static_cast<CGUIWindowSlideShow*>(g_windowManager.GetWindow(WINDOW_SLIDESHOW));
+ if (dialog)
+ {
+ std::vector<CFileItemPtr> items;
+ for (const auto& path : paths)
+ items.push_back(std::make_shared<CFileItem>(CTextureUtils::GetWrappedImageURL(path), false));
+
+ dialog->Reset();
+ dialog->m_bPause = true;
+ dialog->m_bSlideShow = false;
+ dialog->m_iDirection = 1;
+ dialog->m_iCurrentSlide = start;
+ dialog->m_iNextSlide = (start + 1) % items.size();
+ dialog->m_slides = std::move(items);
+ dialog->Open();
+ }
+}
diff --git a/xbmc/pictures/GUIWindowSlideShow.h b/xbmc/pictures/GUIWindowSlideShow.h
index 8c00b2745e..4559124f28 100644
--- a/xbmc/pictures/GUIWindowSlideShow.h
+++ b/xbmc/pictures/GUIWindowSlideShow.h
@@ -21,7 +21,7 @@
*/
#include <set>
-#include "guilib/GUIWindow.h"
+#include "guilib/GUIDialog.h"
#include "threads/Thread.h"
#include "threads/CriticalSection.h"
#include "threads/Event.h"
@@ -59,21 +59,25 @@ private:
CGUIWindowSlideShow *m_pCallback;
};
-class CGUIWindowSlideShow : public CGUIWindow
+class CGUIWindowSlideShow : public CGUIDialog
{
public:
CGUIWindowSlideShow(void);
- virtual ~CGUIWindowSlideShow(void);
+ virtual ~CGUIWindowSlideShow() {};
+
+ bool OnMessage(CGUIMessage& message) override;
+ EVENT_RESULT OnMouseEvent(const CPoint &point, const CMouseEvent &event) override;
+ bool OnAction(const CAction &action) override;
+ void Render() override;
+ void Process(unsigned int currentTime, CDirtyRegionList &regions) override;
+ void OnDeinitWindow(int nextWindowID) override;
void Reset();
void Add(const CFileItem *picture);
bool IsPlaying() const;
- void ShowNext();
- void ShowPrevious();
void Select(const std::string& strPicture);
- const CFileItemList &GetSlideShowContents();
void GetSlideShowContents(CFileItemList &list);
- const CFileItemPtr GetCurrentSlide();
+ std::shared_ptr<const CFileItem> GetCurrentSlide();
void RunSlideShow(const std::string &strPath, bool bRecursive = false,
bool bRandom = false, bool bNotRandom = false,
const std::string &beginSlidePath="", bool startSlideShow = true,
@@ -88,12 +92,6 @@ public:
const std::string &strExtensions="");
void StartSlideShow();
bool InSlideShow() const;
- virtual bool OnMessage(CGUIMessage& message);
- virtual EVENT_RESULT OnMouseEvent(const CPoint &point, const CMouseEvent &event);
- virtual bool OnAction(const CAction &action);
- virtual void Render();
- virtual void Process(unsigned int currentTime, CDirtyRegionList &regions);
- virtual void OnDeinitWindow(int nextWindowID);
void OnLoadPic(int iPic, int iSlideNumber, const std::string &strFileName, CBaseTexture* pTexture, bool bFullSize);
int NumSlides() const;
int CurrentSlide() const;
@@ -101,8 +99,14 @@ public:
bool IsPaused() const { return m_bPause; }
bool IsShuffled() const { return m_bShuffled; }
int GetDirection() const { return m_iDirection; }
- void SetDirection(int direction); // -1: rewind, 1: forward
+
+ static void RunSlideShow(std::vector<std::string> paths, int start=0);
+
private:
+ void ShowNext();
+ void ShowPrevious();
+ void SetDirection(int direction); // -1: rewind, 1: forward
+
typedef std::set<std::string> path_set; // set to track which paths we're adding
void AddItems(const std::string &strPath, path_set *recursivePaths,
SortBy method = SortByLabel,
@@ -123,7 +127,6 @@ private:
void AnnouncePlayerPlay(const CFileItemPtr& item);
void AnnouncePlayerPause(const CFileItemPtr& item);
void AnnouncePlayerStop(const CFileItemPtr& item);
- void AnnouncePlaylistRemove(int pos);
void AnnouncePlaylistClear();
void AnnouncePlaylistAdd(const CFileItemPtr& item, int pos);
void AnnouncePropertyChanged(const std::string &strProperty, const CVariant &value);
@@ -143,7 +146,7 @@ private:
bool m_bPlayingVideo;
bool m_bErrorMessage;
- CFileItemList* m_slides;
+ std::vector<CFileItemPtr> m_slides;
CSlideShowPic m_Image[2];
@@ -153,7 +156,5 @@ private:
int m_iLastFailedNextSlide;
bool m_bLoadNextPic;
RESOLUTION m_Resolution;
- CCriticalSection m_slideSection;
- std::string m_strExtensions;
CPoint m_firstGesturePoint;
};
diff --git a/xbmc/pictures/SlideShowPicture.cpp b/xbmc/pictures/SlideShowPicture.cpp
index 7d77391014..f571d0472d 100644
--- a/xbmc/pictures/SlideShowPicture.cpp
+++ b/xbmc/pictures/SlideShowPicture.cpp
@@ -42,7 +42,7 @@
static float zoomamount[10] = { 1.0f, 1.2f, 1.5f, 2.0f, 2.8f, 4.0f, 6.0f, 9.0f, 13.5f, 20.0f };
-CSlideShowPic::CSlideShowPic()
+CSlideShowPic::CSlideShowPic() : m_alpha(0)
{
m_pImage = NULL;
m_bIsLoaded = false;
@@ -75,6 +75,7 @@ void CSlideShowPic::Close()
m_bDrawNextImage = false;
m_bTransistionImmediately = false;
m_bIsDirty = true;
+ m_alpha = 0;
#ifdef HAS_DX
SAFE_RELEASE(m_vb);
#endif
@@ -122,6 +123,18 @@ void CSlideShowPic::SetTexture_Internal(int iSlideNumber, CBaseTexture* pTexture
// initialize our transistion effect
m_transistionStart.type = transEffect;
m_transistionStart.start = 0;
+
+ // initialize our display effect
+ if (dispEffect == EFFECT_RANDOM)
+ {
+ if (((m_fWidth / m_fHeight) > 1.9) || ((m_fHeight / m_fWidth) > 1.9))
+ m_displayEffect = EFFECT_PANORAMA;
+ else
+ m_displayEffect = (DISPLAY_EFFECT)((rand() % (EFFECT_RANDOM - 1)) + 1);
+ }
+ else
+ m_displayEffect = dispEffect;
+
// the +1's make sure it actually occurs
float fadeTime = 0.2f;
if (m_displayEffect != EFFECT_NO_TIMEOUT)
@@ -148,16 +161,6 @@ void CSlideShowPic::SetTexture_Internal(int iSlideNumber, CBaseTexture* pTexture
m_fZoomAmount = 1;
m_fZoomLeft = 0;
m_fZoomTop = 0;
- // initialize our display effect
- if (dispEffect == EFFECT_RANDOM)
- {
- if (((m_fWidth / m_fHeight) > 1.9) || ((m_fHeight / m_fWidth) > 1.9))
- m_displayEffect = EFFECT_PANORAMA;
- else
- m_displayEffect = (DISPLAY_EFFECT)((rand() % (EFFECT_RANDOM - 1)) + 1);
- }
- else
- m_displayEffect = dispEffect;
m_fPosX = m_fPosY = 0.0f;
m_fPosZ = 1.0f;
m_fVelocityX = m_fVelocityY = m_fVelocityZ = 0.0f;