Initial check in for SlideShowSaver. Currently, it shows a slide show of images from the folder chosen by the user. There are no fancy transitions yet.

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@10394 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Matthew Wilber 2004-12-11 22:05:17 +00:00
parent 07892552b0
commit 34d0fe82c4
10 changed files with 1942 additions and 0 deletions

View File

@ -0,0 +1,18 @@
SubDir OBOS_TOP src add-ons screen_savers slideshowsaver ;
ScreenSaver SlideShowSaver :
# LiveSettings
LiveSetting.cpp
LiveSettings.cpp
# SlideShowSaver classes
SlideShowSaver.cpp
SlideShowConfigView.cpp ;
LinkSharedOSLibs SlideShowSaver : be screensaver tracker translation ;
Package haiku-screensavers-cvs :
SlideShowSaver :
boot home config add-ons screen_savers ;

View File

@ -0,0 +1,198 @@
/*****************************************************************************/
// LiveSetting
// Written by Michael Wilber
//
// LiveSetting.cpp
//
// This class stores the default value for an individual setting and provides
// functions which read and write the setting to BMessages.
//
//
// Copyright (C) Haiku
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
/*****************************************************************************/
#include "LiveSetting.h"
void
LiveSetting::Init(uint32 id, const char *name, const LiveSettingType dataType)
{
fId = id;
fName = name;
fDataType = dataType;
}
LiveSetting::LiveSetting(uint32 id, const char *name, bool val)
{
Init(id, name, LIVE_SETTING_BOOL);
fBoolVal = val;
}
LiveSetting::LiveSetting(uint32 id, const char *name, int32 val)
{
Init(id, name, LIVE_SETTING_INT32);
fInt32Val = val;
}
LiveSetting::LiveSetting(uint32 id, const char *name, const char *val)
{
Init(id, name, LIVE_SETTING_STRING);
fCharpVal = val;
}
bool
LiveSetting::AddReplaceValue(BMessage *msgTo, BMessage *msgFrom /*= NULL*/) const
{
bool bResult = false;
switch (fDataType) {
case LIVE_SETTING_BOOL:
{
bool bVal;
if (GetValue(msgFrom, bVal) == true)
return AddReplaceValue(msgTo, bVal);
}
case LIVE_SETTING_INT32:
{
int32 iVal;
if (GetValue(msgFrom, iVal) == true)
return AddReplaceValue(msgTo, iVal);
}
case LIVE_SETTING_STRING:
{
BString str;
if (GetValue(msgFrom, str) == true)
return AddReplaceValue(msgTo, str);
}
default:
break;
}
return bResult;
}
bool
LiveSetting::AddReplaceValue(BMessage *msgTo, bool val) const
{
if (msgTo == NULL)
return false;
bool bResult = false;
bool dummy;
if (msgTo->FindBool(fName, &dummy) == B_OK) {
if (msgTo->ReplaceBool(fName, val) == B_OK)
bResult = true;
} else {
if (msgTo->AddBool(fName, val) == B_OK)
bResult = true;
}
return bResult;
}
bool
LiveSetting::AddReplaceValue(BMessage *msgTo, int32 val) const
{
if (msgTo == NULL)
return false;
bool bResult = false;
int32 dummy;
if (msgTo->FindInt32(fName, &dummy) == B_OK) {
if (msgTo->ReplaceInt32(fName, val) == B_OK)
bResult = true;
} else {
if (msgTo->AddInt32(fName, val) == B_OK)
bResult = true;
}
return bResult;
}
bool
LiveSetting::AddReplaceValue(BMessage *msgTo, const BString &val) const
{
if (msgTo == NULL)
return false;
bool bResult = false;
BString dummy;
if (msgTo->FindString(fName, &dummy) == B_OK) {
if (msgTo->ReplaceString(fName, val) == B_OK)
bResult = true;
} else {
if (msgTo->AddString(fName, val) == B_OK)
bResult = true;
}
return bResult;
}
bool
LiveSetting::GetValue(BMessage *msgFrom, bool &val) const
{
if (fDataType != LIVE_SETTING_BOOL)
return false;
bool bResult = false;
if (msgFrom == NULL) {
val = fBoolVal;
bResult = true;
} else if (msgFrom->FindBool(fName, &val) == B_OK)
bResult = true;
return bResult;
}
bool
LiveSetting::GetValue(BMessage *msgFrom, int32 &val) const
{
if (fDataType != LIVE_SETTING_INT32)
return false;
bool bResult = false;
if (msgFrom == NULL) {
val = fInt32Val;
bResult = true;
} else if (msgFrom->FindInt32(fName, &val) == B_OK)
bResult = true;
return bResult;
}
bool
LiveSetting::GetValue(BMessage *msgFrom, BString &val) const
{
if (fDataType != LIVE_SETTING_STRING)
return false;
bool bResult = false;
if (msgFrom == NULL) {
val = fCharpVal;
bResult = true;
} else if (msgFrom->FindString(fName, &val) == B_OK)
bResult = true;
return bResult;
}

View File

@ -0,0 +1,83 @@
/*****************************************************************************/
// LiveSetting
// Written by Michael Wilber
//
// LiveSetting.h
//
// This class stores the default value for an individual setting and provides
// functions which read and write the setting to BMessages.
//
//
// Copyright (C) Haiku
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
/*****************************************************************************/
#ifndef LIVE_SETTING_H
#define LIVE_SETTING_H
#include <Locker.h>
#include <Path.h>
#include <Message.h>
#include <String.h>
#include <vector>
#include "LiveSettingsObserver.h"
class LiveSetting {
public:
LiveSetting(uint32 id, const char *name, bool val);
LiveSetting(uint32 id, const char *name, int32 val);
LiveSetting(uint32 id, const char *name, const char *val);
~LiveSetting() { }
uint32 GetId() const { return fId; }
const char *GetName() const { return fName; }
bool AddReplaceValue(BMessage *msgTo, BMessage *msgFrom = NULL) const;
bool AddReplaceValue(BMessage *msgTo, bool val) const;
bool AddReplaceValue(BMessage *msgTo, int32 val) const;
bool AddReplaceValue(BMessage *msgTo, const BString &val) const;
bool GetValue(BMessage *msgFrom, bool &val) const;
bool GetValue(BMessage *msgFrom, int32 &val) const;
bool GetValue(BMessage *msgFrom, BString &val) const;
private:
enum LiveSettingType {
LIVE_SETTING_BOOL = 0,
LIVE_SETTING_INT32,
LIVE_SETTING_STRING
};
void Init(uint32 id, const char *name, const LiveSettingType dataType);
uint32 fId;
const char *fName;
LiveSettingType fDataType;
union {
bool fBoolVal;
int32 fInt32Val;
const char *fCharpVal;
};
};
#endif // #ifndef LIVE_SETTING_H

View File

@ -0,0 +1,479 @@
/*****************************************************************************/
// LiveSettings
// Written by Michael Wilber
//
// LiveSettings.cpp
//
// This class manages (saves/loads/locks/unlocks) a collection of BMessage
// based settings. This class allows you to share settings between different
// classes in different threads and receive notifications when the settings
// change. This class makes it easy to share settings between a Translator
// and its config panel or a Screen Saver and its config panel.
//
//
// Copyright (C) Haiku
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
/*****************************************************************************/
#include <string.h>
#include <File.h>
#include <FindDirectory.h>
#include "LiveSettings.h"
// ---------------------------------------------------------------
// Constructor
//
// Sets the default settings, location for the settings file
// and sets the reference count to 1
//
// Preconditions:
//
// Parameters:
//
// Postconditions:
//
// Returns:
// ---------------------------------------------------------------
LiveSettings::LiveSettings(const char *settingsFile,
LiveSetting *defaults, int32 defCount)
: fLock("LiveSettings Lock")
{
if (find_directory(B_USER_SETTINGS_DIRECTORY, &fSettingsPath))
fSettingsPath.SetTo("/tmp");
fSettingsPath.Append(settingsFile);
fRefCount = 1;
if (defCount > 0) {
fDefaults = defaults;
fDefCount = defCount;
} else {
fDefaults = NULL;
fDefCount = 0;
}
// Add Default Settings
// (Used when loading from the settings file or from
// a BMessage fails)
const LiveSetting *defs = fDefaults;
for (int32 i = 0; i < fDefCount; i++)
defs[i].AddReplaceValue(&fSettingsMsg);
}
// ---------------------------------------------------------------
// Acquire
//
// Returns a pointer to the LiveSettings and increments
// the reference count.
//
// Preconditions:
//
// Parameters:
//
// Postconditions:
//
// Returns: pointer to this LiveSettings object
// ---------------------------------------------------------------
LiveSettings *
LiveSettings::Acquire()
{
LiveSettings *psettings = NULL;
fLock.Lock();
fRefCount++;
psettings = this;
fLock.Unlock();
return psettings;
}
// ---------------------------------------------------------------
// Release
//
// Decrements the reference count and deletes the
// LiveSettings if the reference count is zero.
//
// Preconditions:
//
// Parameters:
//
// Postconditions:
//
// Returns: pointer to this LiveSettings object if
// the reference count is greater than zero, returns NULL
// if the reference count is zero and the LiveSettings
// object has been deleted
// ---------------------------------------------------------------
LiveSettings *
LiveSettings::Release()
{
LiveSettings *psettings = NULL;
fLock.Lock();
fRefCount--;
if (fRefCount > 0) {
psettings = this;
fLock.Unlock();
} else
delete this;
// delete this object and
// release locks
return psettings;
}
// ---------------------------------------------------------------
// Destructor
//
// Does nothing!
//
// Preconditions:
//
// Parameters:
//
// Postconditions:
//
// Returns:
// ---------------------------------------------------------------
LiveSettings::~LiveSettings()
{
fObservers.clear();
}
// returns true if observer was added sucessfully,
// false if observer already in the list or error
bool
LiveSettings::AddObserver(LiveSettingsObserver *observer)
{
fLock.Lock();
bool bAdd = true;
ObserverList::iterator I = fObservers.begin();
while (I != fObservers.end()) {
if (*I == observer) {
bAdd = false;
break;
}
I++;
}
if (bAdd == true)
fObservers.push_back(observer);
fLock.Unlock();
return bAdd;
}
// returns true if observer was removed successfully,
// false if observer not found or error
bool
LiveSettings::RemoveObserver(LiveSettingsObserver *observer)
{
fLock.Lock();
bool bRemove = false;
ObserverList::iterator I = fObservers.begin();
while (I != fObservers.end()) {
if (*I == observer) {
bRemove = true;
break;
}
I++;
}
if (bRemove == true)
fObservers.erase(I);
fLock.Unlock();
return bRemove;
}
void
LiveSettings::NotifySettingChanged(uint32 setting)
{
fLock.Lock();
ObserverList listCopy = fObservers;
fLock.Unlock();
ObserverList::iterator I = listCopy.begin();
while (I != listCopy.end()) {
(*I)->SettingChanged(setting);
I++;
}
}
// ---------------------------------------------------------------
// LoadSettings
//
// Loads the settings by reading them from the default
// settings file.
//
// Preconditions:
//
// Parameters:
//
// Postconditions:
//
// Returns: B_OK if there were no errors or an error code from
// BFile::SetTo() or BMessage::Unflatten() if there were errors
// ---------------------------------------------------------------
status_t
LiveSettings::LoadSettings()
{
status_t result;
fLock.Lock();
// Don't try to open the settings file if there are
// no settings that need to be loaded
if (fDefCount > 0) {
BFile settingsFile;
result = settingsFile.SetTo(fSettingsPath.Path(), B_READ_ONLY);
if (result == B_OK) {
BMessage msg;
result = msg.Unflatten(&settingsFile);
if (result == B_OK)
result = LoadSettings(&msg);
}
} else
result = B_OK;
fLock.Unlock();
return result;
}
// ---------------------------------------------------------------
// LoadSettings
//
// Loads the settings from a BMessage passed to the function.
//
// Preconditions:
//
// Parameters: pmsg pointer to BMessage that contains the
// settings
//
// Postconditions:
//
// Returns: B_BAD_VALUE if pmsg is NULL or invalid options
// have been found, B_OK if there were no
// errors or an error code from BMessage::FindBool() or
// BMessage::ReplaceBool() if there were other errors
// ---------------------------------------------------------------
status_t
LiveSettings::LoadSettings(BMessage *pmsg)
{
status_t result = B_OK;
if (pmsg) {
fLock.Lock();
const LiveSetting *defs = fDefaults;
for (int32 i = 0; i < fDefCount; i++)
defs[i].AddReplaceValue(&fSettingsMsg, pmsg);
fLock.Unlock();
}
return result;
}
// ---------------------------------------------------------------
// SaveSettings
//
// Saves the settings as a flattened BMessage to the default
// settings file
//
// Preconditions:
//
// Parameters:
//
// Postconditions:
//
// Returns: B_OK if no errors or an error code from BFile::SetTo()
// or BMessage::Flatten() if there were errors
// ---------------------------------------------------------------
status_t
LiveSettings::SaveSettings()
{
status_t result;
fLock.Lock();
// Only write out settings file if there are
// actual settings stored by this object
if (fDefCount > 0) {
BFile settingsFile;
result = settingsFile.SetTo(fSettingsPath.Path(),
B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE);
if (result == B_OK)
result = fSettingsMsg.Flatten(&settingsFile);
} else
result = B_OK;
fLock.Unlock();
return result;
}
// ---------------------------------------------------------------
// GetConfigurationMessage
//
// Saves the current settings to the BMessage passed to the
// function
//
// Preconditions:
//
// Parameters: pmsg pointer to BMessage where the settings
// will be stored
//
// Postconditions:
//
// Returns: B_OK if there were no errors or an error code from
// BMessage::RemoveName() or BMessage::AddBool() if there were
// errors
// ---------------------------------------------------------------
status_t
LiveSettings::GetConfigurationMessage(BMessage *pmsg)
{
status_t result = B_BAD_VALUE;
if (pmsg) {
int32 i;
for (i = 0; i < fDefCount; i++) {
result = pmsg->RemoveName(fDefaults[i].GetName());
if (result != B_OK && result != B_NAME_NOT_FOUND)
break;
}
if (i == fDefCount) {
fLock.Lock();
result = B_OK;
BString tempStr;
const LiveSetting *defs = fDefaults;
for (i = 0; i < fDefCount && result >= B_OK; i++)
defs[i].AddReplaceValue(pmsg, &fSettingsMsg);
fLock.Unlock();
}
}
return result;
}
// ---------------------------------------------------------------
// FindLiveSetting
//
// Returns a pointer to the LiveSetting with the given name
//
//
// Preconditions:
//
// Parameters: name name of the LiveSetting to find
//
//
// Postconditions:
//
// Returns: NULL if the LiveSetting cannot be found, or a pointer
// to the desired LiveSetting if it is found
// ---------------------------------------------------------------
const LiveSetting *
LiveSettings::FindLiveSetting(const char *name)
{
for (int32 i = 0; i < fDefCount; i++) {
if (!strcmp(fDefaults[i].GetName(), name))
return fDefaults + i;
}
return NULL;
}
bool
LiveSettings::SetGetBool(const char *name, bool *pVal /*= NULL*/)
{
bool bPrevVal = false;
GetValue<bool>(name, bPrevVal);
if (pVal != NULL)
SetValue<bool>(name, *pVal);
return bPrevVal;
}
int32
LiveSettings::SetGetInt32(const char *name, int32 *pVal /*= NULL*/)
{
int32 iPrevVal = 0;
GetValue<int32>(name, iPrevVal);
if (pVal != NULL)
SetValue<int32>(name, *pVal);
return iPrevVal;
}
void
LiveSettings::SetString(const char *name, const BString &str)
{
SetValue<BString>(name, str);
}
void
LiveSettings::GetString(const char *name, BString &str)
{
GetValue<BString>(name, str);
}
template <class T>
bool
LiveSettings::SetValue(const char *name, const T &val)
{
bool bResult = false, bChanged = false;
fLock.Lock();
const LiveSetting *def = FindLiveSetting(name);
if (def) {
bResult = def->AddReplaceValue(&fSettingsMsg, val);
bChanged = true;
}
fLock.Unlock();
if (bChanged == true)
NotifySettingChanged(def->GetId());
return bResult;
}
template <class T>
bool
LiveSettings::GetValue(const char *name, T &val)
{
fLock.Lock();
bool bResult = false;
const LiveSetting *def = FindLiveSetting(name);
if (def)
bResult = def->GetValue(&fSettingsMsg, val);
fLock.Unlock();
return bResult;
}

View File

@ -0,0 +1,108 @@
/*****************************************************************************/
// LiveSettings
// Written by Michael Wilber
//
// LiveSettings.h
//
// This class manages (saves/loads/locks/unlocks) a collection of BMessage
// based settings. This class allows you to share settings between different
// classes in different threads and receive notifications when the settings
// change. This class makes it easy to share settings between a Translator
// and its config panel or a Screen Saver and its config panel.
//
//
// Copyright (C) Haiku
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
/*****************************************************************************/
#ifndef LIVE_SETTINGS_H
#define LIVE_SETTINGS_H
#include <Locker.h>
#include <Path.h>
#include <Message.h>
#include <String.h>
#include <vector>
#include "LiveSettingsObserver.h"
#include "LiveSetting.h"
class LiveSettings {
public:
LiveSettings(const char *settingsFile, LiveSetting *defaults,
int32 defCount);
LiveSettings *Acquire();
// increments the reference count, returns this
LiveSettings *Release();
// decrements the reference count, deletes this
// when count reaches zero, returns this when
// ref count is greater than zero, NULL when
// ref count is zero
bool AddObserver(LiveSettingsObserver *observer);
// returns true if observer was added sucessfully,
// false if observer already in the list or error
bool RemoveObserver(LiveSettingsObserver *observer);
// returns true if observer was removed successfully,
// false if observer not found or error
status_t LoadSettings();
status_t LoadSettings(BMessage *pmsg);
status_t SaveSettings();
status_t GetConfigurationMessage(BMessage *pmsg);
bool SetGetBool(const char *name, bool *pVal = NULL);
int32 SetGetInt32(const char *name, int32 *pVal = NULL);
void SetString(const char *name, const BString &str);
void GetString(const char *name, BString &str);
private:
const LiveSetting *FindLiveSetting(const char *name);
~LiveSettings();
// private so that Release() must be used
// to delete the object
void NotifySettingChanged(uint32 setting);
template <class T>
bool GetValue(const char *name, T &val);
template <class T>
bool SetValue(const char *name, const T &val);
BLocker fLock;
int32 fRefCount;
BPath fSettingsPath;
// where the settings file will be loaded from /
// saved to
BMessage fSettingsMsg;
// the actual settings
const LiveSetting *fDefaults;
int32 fDefCount;
typedef std::vector<LiveSettingsObserver *> ObserverList;
ObserverList fObservers;
};
#endif // #ifndef LIVE_SETTTINGS_H

View File

@ -0,0 +1,44 @@
/*****************************************************************************/
// LiveSettingsObserver
// Written by Michael Wilber
//
// LiveSettingsObserver.h
//
// This class provides an interface for classes that wish to get notification
// messages from changes to a LiveSettings object.
//
//
// Copyright (C) Haiku
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
/*****************************************************************************/
#ifndef LIVE_SETTINGS_OBSERVER_H
#define LIVE_SETTINGS_OBSERVER_H
class LiveSettingsObserver {
public:
LiveSettingsObserver() { }
virtual ~LiveSettingsObserver() { }
virtual void SettingChanged(uint32 setting) = 0;
};
#endif // #ifndef LIVE_SETTINGS_OBSERVER_H

View File

@ -0,0 +1,321 @@
/*****************************************************************************/
// SlideShowConfigView
// Written by Michael Wilber
//
// SlideShowConfigView.cpp
//
// This BView based object displays the SlideShowSaver settings options
//
//
// Copyright (C) Haiku
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
/*****************************************************************************/
#include <stdio.h>
#include <string.h>
#include <FilePanel.h>
#include "SlideShowConfigView.h"
BMessage *
delay_msg(int32 option)
{
BMessage *pMsg = new BMessage(CHANGE_DELAY);
pMsg->AddInt32("delay", option);
return pMsg;
}
// ---------------------------------------------------------------
// Constructor
//
// Sets up the view settings
//
// Preconditions:
//
// Parameters:
//
// Postconditions:
//
// Returns:
// ---------------------------------------------------------------
SlideShowConfigView::SlideShowConfigView(const BRect &frame, const char *name,
uint32 resize, uint32 flags, LiveSettings *settings)
: BView(frame, name, resize, flags)
{
fSettings = settings;
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
BMessage *pMsg;
int32 val;
// Show Caption checkbox
pMsg = new BMessage(CHANGE_CAPTION);
fShowCaption = new BCheckBox(BRect(10, 45, 180, 62),
"Show Caption", "Show Caption", pMsg);
val = (fSettings->SetGetBool(SAVER_SETTING_CAPTION)) ? 1 : 0;
fShowCaption->SetValue(val);
fShowCaption->SetViewColor(ViewColor());
AddChild(fShowCaption);
// Change Border checkbox
pMsg = new BMessage(CHANGE_BORDER);
fShowBorder = new BCheckBox(BRect(10, 70, 180, 87),
"Show Border", "Show Border", pMsg);
val = (fSettings->SetGetBool(SAVER_SETTING_BORDER)) ? 1 : 0;
fShowBorder->SetValue(val);
fShowBorder->SetViewColor(ViewColor());
AddChild(fShowBorder);
// Delay Menu
// setup PNG interlace options menu
int32 currentDelay = fSettings->SetGetInt32(SAVER_SETTING_DELAY) / 1000;
fDelayMenu = new BPopUpMenu("Delay Menu");
struct DelayItem {
const char *name;
int32 delay;
};
DelayItem items[] = {
{"No Delay", 0},
{"1 second", 1},
{"2 seconds", 2},
{"3 seconds", 3},
{"4 seconds", 4},
{"5 seconds", 5},
{"6 seconds", 6},
{"7 seconds", 7},
{"8 seconds", 8},
{"9 seconds", 9},
{"10 seconds", 10},
{"15 seconds", 15},
{"20 seconds", 20},
{"30 seconds", 30},
{"1 minute", 1 * 60},
{"2 minutes", 2 * 60},
{"5 minutes", 5 * 60},
{"10 minutes", 10 * 60},
{"15 minutes", 15 * 60}
};
for (uint32 i = 0; i < sizeof(items) / sizeof(DelayItem); i++) {
BMenuItem *menuItem =
new BMenuItem(items[i].name, delay_msg(items[i].delay));
fDelayMenu->AddItem(menuItem);
if (items[i].delay == currentDelay)
menuItem->SetMarked(true);
}
fDelayMenuField = new BMenuField(BRect(10, 100, 180, 120),
"Delay Menu Field", "Delay:", fDelayMenu);
fDelayMenuField->SetViewColor(ViewColor());
fDelayMenuField->SetDivider(40);
AddChild(fDelayMenuField);
// Choose Image Folder button
pMsg = new BMessage(CHOOSE_DIRECTORY);
fChooseFolder = new BButton(BRect(50, 160, 180, 180),
"Choose Folder", "Choose Image Folder...", pMsg);
AddChild(fChooseFolder);
// Setup choose folder file panel
pMsg = new BMessage(CHANGE_DIRECTORY);
fFilePanel = new BFilePanel(B_OPEN_PANEL, NULL, (const entry_ref *) NULL,
B_DIRECTORY_NODE, false, pMsg, NULL, true, true);
fFilePanel->SetButtonLabel(B_DEFAULT_BUTTON, "Select");
}
// ---------------------------------------------------------------
// Destructor
//
// Releases the translator settings
//
// Preconditions:
//
// Parameters:
//
// Postconditions:
//
// Returns:
// ---------------------------------------------------------------
SlideShowConfigView::~SlideShowConfigView()
{
fSettings->Release();
delete fFilePanel;
fFilePanel = NULL;
}
// ---------------------------------------------------------------
// AllAttached
//
//
//
// Preconditions:
//
// Parameters:
//
// Postconditions:
//
// Returns:
// ---------------------------------------------------------------
void
SlideShowConfigView::AllAttached()
{
BMessenger msgr(this);
fShowCaption->SetTarget(msgr);
fShowBorder->SetTarget(msgr);
fChooseFolder->SetTarget(msgr);
fFilePanel->SetTarget(msgr);
// Set target for menu items
for (int32 i = 0; i < fDelayMenu->CountItems(); i++) {
BMenuItem *item = fDelayMenu->ItemAt(i);
if (item)
item->SetTarget(msgr);
}
}
// ---------------------------------------------------------------
// MessageReceived
//
// Handles state changes of the RLE setting checkbox
//
// Preconditions:
//
// Parameters: message the actual BMessage that was received
//
// Postconditions:
//
// Returns:
// ---------------------------------------------------------------
void
SlideShowConfigView::MessageReceived(BMessage *message)
{
bool bNewVal;
switch (message->what) {
case CHANGE_CAPTION:
if (fShowCaption->Value())
bNewVal = true;
else
bNewVal = false;
fSettings->SetGetBool(SAVER_SETTING_CAPTION, &bNewVal);
fSettings->SaveSettings();
break;
case CHANGE_BORDER:
if (fShowBorder->Value())
bNewVal = true;
else
bNewVal = false;
fSettings->SetGetBool(SAVER_SETTING_BORDER, &bNewVal);
fSettings->SaveSettings();
break;
case CHOOSE_DIRECTORY:
{
BString strDirectory;
fSettings->GetString(SAVER_SETTING_DIRECTORY, strDirectory);
BEntry entry(strDirectory.String());
if (entry.InitCheck() != B_OK)
return;
entry_ref ref;
if (entry.GetRef(&ref) != B_OK)
return;
fFilePanel->SetPanelDirectory(&ref);
fFilePanel->Show();
break;
}
case CHANGE_DIRECTORY:
{
entry_ref ref;
if (message->FindRef("refs", &ref) != B_OK)
return;
BEntry entry(&ref, true);
if (entry.InitCheck() != B_OK)
return;
BPath path(&entry);
if (path.InitCheck() != B_OK)
return;
BString strDirectory = path.Path();
fSettings->SetString(SAVER_SETTING_DIRECTORY, strDirectory);
fSettings->SaveSettings();
Invalidate();
break;
}
case CHANGE_DELAY:
{
int32 newVal;
if (message->FindInt32("delay", &newVal) == B_OK) {
newVal *= 1000;
fSettings->SetGetInt32(SAVER_SETTING_DELAY, &newVal);
fSettings->SaveSettings();
}
break;
}
default:
BView::MessageReceived(message);
break;
}
}
// ---------------------------------------------------------------
// Draw
//
// Draws information about the SlideShowConfigTranslator to this view.
//
// Preconditions:
//
// Parameters: area, not used
//
// Postconditions:
//
// Returns:
// ---------------------------------------------------------------
void
SlideShowConfigView::Draw(BRect area)
{
SetFont(be_bold_font);
font_height fh;
GetFontHeight(&fh);
float xbold, ybold;
xbold = fh.descent + 1;
ybold = fh.ascent + fh.descent * 2 + fh.leading;
char title[] = "SlideShow Screen Saver";
DrawString(title, BPoint(xbold, ybold));
SetFont(be_plain_font);
font_height plainh;
GetFontHeight(&plainh);
float yplain;
yplain = plainh.ascent + plainh.descent * 2 + plainh.leading;
char writtenby[] = "Written by Michael Wilber";
DrawString(writtenby, BPoint(xbold, yplain * 1 + ybold));
// Draw current folder
BString strFolder;
fSettings->GetString(SAVER_SETTING_DIRECTORY, strFolder);
strFolder.Prepend("Image Folder: ");
DrawString(strFolder.String(), BPoint(10, yplain * 9 + ybold));
}

View File

@ -0,0 +1,83 @@
/*****************************************************************************/
// SlideShowConfigView
// Written by Michael Wilber
//
// SlideShowConfigView.h
//
// This BView based object displays the SlideShowSaver settings options
//
//
// Copyright (C) Haiku
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
/*****************************************************************************/
#ifndef SLIDE_SHOW_CONFIG_VIEW_H
#define SLIDE_SHOW_CONFIG_VIEW_H
#include <View.h>
#include <CheckBox.h>
#include <PopUpMenu.h>
#include <MenuField.h>
#include <MenuItem.h>
#include <Button.h>
#include <FilePanel.h>
#include "LiveSettings.h"
// SlideShowSaver Settings
enum {
CHANGE_CAPTION,
CHANGE_BORDER,
CHOOSE_DIRECTORY, CHANGE_DIRECTORY,
CHANGE_DELAY
};
#define SAVER_SETTING_CAPTION "slidesaver /caption"
#define SAVER_SETTING_BORDER "slidesaver /border"
#define SAVER_SETTING_DIRECTORY "slidesaver /directory"
#define SAVER_SETTING_DELAY "slidesaver /delay"
class SlideShowConfigView : public BView {
public:
SlideShowConfigView(const BRect &frame, const char *name, uint32 resize,
uint32 flags, LiveSettings *settings);
// sets up the view
~SlideShowConfigView();
// releases the settings
virtual void AllAttached();
virtual void MessageReceived(BMessage *message);
virtual void Draw(BRect area);
// draws information about the slide show screen saver
private:
BCheckBox *fShowCaption;
BCheckBox *fShowBorder;
BPopUpMenu *fDelayMenu;
BMenuField *fDelayMenuField;
BButton *fChooseFolder;
BFilePanel *fFilePanel;
LiveSettings *fSettings;
// the actual settings for the screen saver,
// shared with the screen saver
};
#endif // #ifndef SLIDE_SHOW_CONFIG_VIEW_H

View File

@ -0,0 +1,510 @@
/*****************************************************************************/
// SlideShowSaver
// Written by Michael Wilber
// Slide show code derived from ShowImage code, written by Michael Pfeiffer
//
// SlideShowSaver.cpp
//
//
// Copyright (C) Haiku
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
/*****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <BitmapStream.h>
#include <TranslatorRoster.h>
#include <Directory.h>
#include <File.h>
#include <Path.h>
#include <List.h>
#include <StringView.h>
#include "SlideShowSaver.h"
#include "SlideShowConfigView.h"
// Called by system to get the screen saver
extern "C" _EXPORT BScreenSaver *
instantiate_screen_saver(BMessage *message, image_id id)
{
return new SlideShowSaver(message, id);
}
// returns B_ERROR if problems reading ref
// B_OK if ref is not a directory
// B_OK + 1 if ref is a directory
status_t
ent_is_dir(const entry_ref *ref)
{
BEntry ent(ref);
if (ent.InitCheck() != B_OK)
return B_ERROR;
struct stat st;
if (ent.GetStat(&st) != B_OK)
return B_ERROR;
return S_ISDIR(st.st_mode) ? (B_OK + 1) : B_OK;
}
int CompareEntries(const void* a, const void* b)
{
entry_ref *r1, *r2;
r1 = *(entry_ref**)a;
r2 = *(entry_ref**)b;
return strcasecmp(r1->name, r2->name);
}
// Default settings for the Translator
LiveSetting gDefaultSettings[] = {
LiveSetting(CHANGE_CAPTION, SAVER_SETTING_CAPTION, true),
// Show image caption by default
LiveSetting(CHANGE_BORDER, SAVER_SETTING_BORDER, true),
// Show image border by default
LiveSetting(CHANGE_DIRECTORY, SAVER_SETTING_DIRECTORY, "/boot/home"),
// Set default image directory to home
LiveSetting(CHANGE_DELAY, SAVER_SETTING_DELAY, (int32) 3000)
// Default delay: 3 seconds
};
SlideShowSaver::SlideShowSaver(BMessage *archive, image_id image)
: BScreenSaver(archive, image), fLock("SlideShow Lock")
{
fNewDirectory = true;
fBitmap = NULL;
fShowBorder = true;
fShowCaption = true;
fSettings = new LiveSettings("SlideShowSaver_Settings",
gDefaultSettings, sizeof(gDefaultSettings) / sizeof(LiveSetting));
fSettings->LoadSettings();
// load settings from the settings file
fSettings->AddObserver(this);
}
SlideShowSaver::~SlideShowSaver()
{
delete fBitmap;
fBitmap = NULL;
fSettings->RemoveObserver(this);
fSettings->Release();
}
// Called by fSettings to notify that someone has changed
// a setting. For example, if the user changes a setting
// on the config panel, this will be called to notify this
// object.
void
SlideShowSaver::SettingChanged(uint32 setting)
{
switch (setting) {
case CHANGE_CAPTION:
UpdateShowCaption();
break;
case CHANGE_BORDER:
UpdateShowBorder();
break;
case CHANGE_DIRECTORY:
UpdateDirectory();
break;
case CHANGE_DELAY:
UpdateTickSize();
break;
default:
break;
}
}
status_t
SlideShowSaver::UpdateTickSize()
{
// Tick size is in microseconds, but is stored in settings as
// milliseconds
bigtime_t ticks = static_cast<bigtime_t>
(fSettings->SetGetInt32(SAVER_SETTING_DELAY)) * 1000;
SetTickSize(ticks);
return B_OK;
}
status_t
SlideShowSaver::UpdateShowCaption()
{
fShowCaption = fSettings->SetGetBool(SAVER_SETTING_CAPTION);
return B_OK;
}
status_t
SlideShowSaver::UpdateShowBorder()
{
fShowBorder = fSettings->SetGetBool(SAVER_SETTING_BORDER);
return B_OK;
}
status_t
SlideShowSaver::UpdateDirectory()
{
status_t result = B_OK;
fLock.Lock();
BString strDirectory;
fSettings->GetString(SAVER_SETTING_DIRECTORY, strDirectory);
BDirectory dir(strDirectory.String());
if (dir.InitCheck() != B_OK || dir.GetNextRef(&fCurrentRef) != B_OK)
result = B_ERROR;
// Use ShowNextImage to find which translatable image is
// alphabetically first in the given directory, and load it
if (result == B_OK && ShowNextImage(true, true) == false)
result = B_ERROR;
fNewDirectory = true;
fLock.Unlock();
return result;
}
void
SlideShowSaver::StartConfig(BView *view)
{
view->AddChild(new SlideShowConfigView(
BRect(10, 10, 250, 300), "SlideShowSaver Config",
B_FOLLOW_ALL, B_WILL_DRAW, fSettings->Acquire()));
}
status_t
SlideShowSaver::StartSaver(BView *view, bool preview)
{
UpdateShowCaption();
UpdateShowBorder();
if (UpdateDirectory() != B_OK)
return B_ERROR;
// Read ticksize setting and set it as the delay
UpdateTickSize();
return B_OK;
}
void
SlideShowSaver::Draw(BView *view, int32 frame)
{
fLock.Lock();
view->SetLowColor(0, 0, 0);
view->SetHighColor(192, 192, 192);
view->SetViewColor(192, 192, 192);
bool bResult = false;
if (fNewDirectory == true) {
// Already have a bitmap on the first frame
bResult = true;
} else {
bResult = ShowNextImage(true, false);
// try rewinding to beginning
if (bResult == false)
bResult = ShowNextImage(true, true);
}
fNewDirectory = false;
if (bResult == true && fBitmap != NULL) {
BRect destRect(0, 0, fBitmap->Bounds().Width(), fBitmap->Bounds().Height()),
vwBounds = view->Bounds();
if (destRect.Width() < vwBounds.Width()) {
destRect.OffsetBy((vwBounds.Width() - destRect.Width()) / 2, 0);
}
if (destRect.Height() < vwBounds.Height()) {
destRect.OffsetBy(0, (vwBounds.Height() - destRect.Height()) / 2);
}
BRect border = destRect, bounds = view->Bounds();
// top
view->FillRect(BRect(0, 0, bounds.right, border.top-1), B_SOLID_LOW);
// left
view->FillRect(BRect(0, border.top, border.left-1, border.bottom), B_SOLID_LOW);
// right
view->FillRect(BRect(border.right+1, border.top, bounds.right, border.bottom), B_SOLID_LOW);
// bottom
view->FillRect(BRect(0, border.bottom+1, bounds.right, bounds.bottom), B_SOLID_LOW);
if (fShowBorder == true) {
BRect strokeRect = destRect;
strokeRect.InsetBy(-1, -1);
view->StrokeRect(strokeRect);
}
view->DrawBitmap(fBitmap, fBitmap->Bounds(), destRect);
if (fShowCaption == true)
DrawCaption(view);
}
fLock.Unlock();
}
status_t
SlideShowSaver::SetImage(const entry_ref *pref)
{
entry_ref ref;
if (!pref)
ref = fCurrentRef;
else
ref = *pref;
BTranslatorRoster *proster = BTranslatorRoster::Default();
if (!proster)
return B_ERROR;
if (ent_is_dir(pref) != B_OK)
// if ref is erroneous or a directory, return error
return B_ERROR;
BFile file(&ref, B_READ_ONLY);
translator_info info;
memset(&info, 0, sizeof(translator_info));
BMessage ioExtension;
//if (ref != fCurrentRef)
// if new image, reset to first document
// fDocumentIndex = 1;
if (ioExtension.AddInt32("/documentIndex", 1 /*fDocumentIndex*/) != B_OK)
return B_ERROR;
if (proster->Identify(&file, &ioExtension, &info, 0, NULL,
B_TRANSLATOR_BITMAP) != B_OK)
return B_ERROR;
// Translate image data and create a new ShowImage window
BBitmapStream outstream;
if (proster->Translate(&file, &info, &ioExtension, &outstream,
B_TRANSLATOR_BITMAP) != B_OK)
return B_ERROR;
BBitmap *newBitmap = NULL;
if (outstream.DetachBitmap(&newBitmap) != B_OK)
return B_ERROR;
// Now that I've successfully loaded the new bitmap,
// I can be sure it is safe to delete the old one,
// and clear everything
delete fBitmap;
fBitmap = newBitmap;
newBitmap = NULL;
fCurrentRef = ref;
// Get path to use in caption
fCaption = "<< Unable to read the path >>";
BEntry entry(&fCurrentRef);
if (entry.InitCheck() == B_OK) {
BPath path(&entry);
if (path.InitCheck() == B_OK) {
fCaption = path.Path();
}
}
return B_OK;
}
// Function originally from Haiku ShowImage
bool
SlideShowSaver::ShowNextImage(bool next, bool rewind)
{
bool found;
entry_ref curRef, imgRef;
curRef = fCurrentRef;
found = FindNextImage(&curRef, &imgRef, next, rewind);
if (found) {
// Keep trying to load images until:
// 1. The image loads successfully
// 2. The last file in the directory is found (for find next or find first)
// 3. The first file in the directory is found (for find prev)
// 4. The call to FindNextImage fails for any other reason
while (SetImage(&imgRef) != B_OK) {
curRef = imgRef;
found = FindNextImage(&curRef, &imgRef, next, false);
if (!found)
return false;
}
return true;
}
return false;
}
// Function taken from Haiku ShowImage,
// function originally written by Michael Pfeiffer
bool
SlideShowSaver::IsImage(const entry_ref *pref)
{
if (!pref)
return false;
if (ent_is_dir(pref) != B_OK)
// if ref is erroneous or a directory, return false
return false;
BFile file(pref, B_READ_ONLY);
if (file.InitCheck() != B_OK)
return false;
BTranslatorRoster *proster = BTranslatorRoster::Default();
if (!proster)
return false;
BMessage ioExtension;
if (ioExtension.AddInt32("/documentIndex", 1) != B_OK)
return false;
translator_info info;
memset(&info, 0, sizeof(translator_info));
if (proster->Identify(&file, &ioExtension, &info, 0, NULL,
B_TRANSLATOR_BITMAP) != B_OK)
return false;
return true;
}
// Function taken from Haiku ShowImage,
// function originally written by Michael Pfeiffer
bool
SlideShowSaver::FindNextImage(entry_ref *in_current, entry_ref *out_image, bool next, bool rewind)
{
// ASSERT(next || !rewind);
BEntry curImage(in_current);
entry_ref entry, *ref;
BDirectory parent;
BList entries;
bool found = false;
int32 cur;
if (curImage.GetParent(&parent) != B_OK)
return false;
while (parent.GetNextRef(&entry) == B_OK) {
if (entry != *in_current) {
entries.AddItem(new entry_ref(entry));
} else {
// insert current ref, so we can find it easily after sorting
entries.AddItem(in_current);
}
}
entries.SortItems(CompareEntries);
cur = entries.IndexOf(in_current);
// ASSERT(cur >= 0);
// remove it so FreeEntries() does not delete it
entries.RemoveItem(in_current);
if (next) {
// find the next image in the list
if (rewind) cur = 0; // start with first
for (; (ref = (entry_ref*)entries.ItemAt(cur)) != NULL; cur ++) {
if (IsImage(ref)) {
found = true;
*out_image = (const entry_ref)*ref;
break;
}
}
} else {
// find the previous image in the list
cur --;
for (; cur >= 0; cur --) {
ref = (entry_ref*)entries.ItemAt(cur);
if (IsImage(ref)) {
found = true;
*out_image = (const entry_ref)*ref;
break;
}
}
}
FreeEntries(&entries);
return found;
}
// Function taken from Haiku ShowImage,
// function originally written by Michael Pfeiffer
void
SlideShowSaver::FreeEntries(BList *entries)
{
const int32 n = entries->CountItems();
for (int32 i = 0; i < n; i ++) {
entry_ref *ref = (entry_ref *)entries->ItemAt(i);
delete ref;
}
entries->MakeEmpty();
}
void
SlideShowSaver::LayoutCaption(BView *view, BFont &font, BPoint &pos, BRect &rect)
{
font_height fontHeight;
float width, height;
BRect bounds(view->Bounds());
font = be_plain_font;
width = font.StringWidth(fCaption.String()) + 1; // 1 for text shadow
font.GetHeight(&fontHeight);
height = fontHeight.ascent + fontHeight.descent;
// center text horizontally
pos.x = (bounds.left + bounds.right - width)/2;
// flush bottom
pos.y = bounds.bottom - fontHeight.descent - 5;
// background rectangle
rect.Set(0, 0, (width-1)+2, (height-1)+2+1); // 2 for border and 1 for text shadow
rect.OffsetTo(pos);
rect.OffsetBy(-1, -1-fontHeight.ascent); // -1 for border
}
void
SlideShowSaver::DrawCaption(BView *view)
{
BFont font;
BPoint pos;
BRect rect;
LayoutCaption(view, font, pos, rect);
view->PushState();
// draw background
view->SetDrawingMode(B_OP_ALPHA);
view->SetHighColor(0, 0, 255, 128);
view->FillRect(rect);
// draw text
view->SetDrawingMode(B_OP_OVER);
view->SetFont(&font);
view->SetLowColor(B_TRANSPARENT_COLOR);
// text shadow
pos += BPoint(1, 1);
view->SetHighColor(0, 0, 0);
view->SetPenSize(1);
view->DrawString(fCaption.String(), pos);
// text
pos -= BPoint(1, 1);
view->SetHighColor(255, 255, 0);
view->DrawString(fCaption.String(), pos);
view->PopState();
}

View File

@ -0,0 +1,98 @@
/*****************************************************************************/
// SlideShowSaver
// Written by Michael Wilber
// Slide show code derived from ShowImage code, written by Michael Pfeiffer
//
// SlideShowSaver.h
//
//
// Copyright (C) Haiku
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
/*****************************************************************************/
#ifndef SLIDE_SHOW_SAVER_H
#define SLIDE_SHOW_SAVER_H
#include <Locker.h>
#include <ScreenSaver.h>
#include <Bitmap.h>
#include <String.h>
#include <Entry.h>
#include "LiveSettings.h"
class SlideShowSaver :
public BScreenSaver,
public LiveSettingsObserver {
public:
SlideShowSaver(BMessage *archive, image_id image);
virtual ~SlideShowSaver(void);
virtual void SettingChanged(uint32 setting);
virtual void StartConfig(BView *view);
virtual status_t StartSaver(BView *view, bool preview);
virtual void Draw(BView *view, int32 frame);
protected:
// reload ticksize setting and apply it
status_t UpdateTickSize();
status_t UpdateShowCaption();
status_t UpdateShowBorder();
// reload directory setting and apply it
status_t UpdateDirectory();
// Function taken from Haiku ShowImage,
// function originally written by Michael Pfeiffer
status_t SetImage(const entry_ref *pref);
// Function originally from Haiku ShowImage
bool ShowNextImage(bool next, bool rewind);
// Function taken from Haiku ShowImage,
// function originally written by Michael Pfeiffer
bool IsImage(const entry_ref *pref);
// Function taken from Haiku ShowImage,
// function originally written by Michael Pfeiffer
bool FindNextImage(entry_ref *in_current, entry_ref *out_image, bool next, bool rewind);
// Function taken from Haiku ShowImage,
// function originally written by Michael Pfeiffer
void SlideShowSaver::FreeEntries(BList *entries);
void LayoutCaption(BView *view, BFont &font, BPoint &pos, BRect &rect);
void DrawCaption(BView *view);
// void UpdateCaption(BView *view);
private:
BLocker fLock;
bool fNewDirectory;
LiveSettings *fSettings;
BBitmap *fBitmap;
BString fCaption;
entry_ref fCurrentRef;
bool fShowCaption;
bool fShowBorder;
};
#endif // #ifndef SLIDE_SHOW_SAVER_H