📄 cmyscreensaverplugin.cpp
字号:
#include "CMyScreenSaverPlugin.h"
#include <e32math.h>
#include <e32std.h>
#include <avkon.rsg>
#include <gdi.h> // fonts
#include <AknKeyLock.h> // for keylock query (workaround without API)
#include <settinginfo.h> // for profile query (workaround without API)
// CONSTANTS
_LIT(KSeparator, ":");
_LIT(KZero, "0");
const TInt KScreenSizeX = 176;
const TInt KScreenSizeY = 208;
const TInt KRandomizedRangeX = 100;
const TInt KRandomizedRangeY = 100;
const TInt KCoordOffsetX = 23;
const TInt KCoordOffsetY = 20;
const TInt KActiveDisplayAreaOffsetUp = 16;
const TInt KActiveDisplayAreaOffsetDown = 58;
// ----------------------------------------------------------------------------
// CreatePluginModule
//
// Creation of plugin module from host application
// ----------------------------------------------------------------------------
EXPORT_C MScreensaverPlugin* CreatePluginModule()
{
return new CMyScreenSaverPlugin;
}
// ----------------------------------------------------------------------------
// CMyScreenSaverPlugin::InitializeL
//
// Used to initialize the plugin module after creation.
// Name() function may be called without the plugin being initialized,
// to enable name query from modules that are not plugin hosts.
// ----------------------------------------------------------------------------
TInt CMyScreenSaverPlugin::InitializeL(MScreensaverPluginHost *aHost)
{
iHost = aHost;
// Since the plugin provides indicators for calls, messages and keylock,
// we must call host's OverrideStandardIndicators. If UseStandardIndicators
// is called, then every time when a call or message has arrived the
// default screensaver is shown instead of the plugin.
iHost->OverrideStandardIndicators();
// Refresh time for calling the Draw-function of the plugin.
iHost->SetRefreshTimerValue( 10000000 ); // 10 seconds
// Setting the random seed for randomizing drawing position
TTime time;
time.HomeTime();
TDateTime dateTime = time.DateTime();
TInt seed = dateTime.MicroSecond();
iRandSeed = seed;
return KErrNone;
}
// ----------------------------------------------------------------------------
// CMyScreenSaverPlugin::Draw
//
// When a plugin module is active this method is called every time
// when refresh timer expires in screensaver application.
// ----------------------------------------------------------------------------
TInt CMyScreenSaverPlugin::Draw(CWindowGc& aGc)
{
TInt i = 0;
TInt status = KErrNone;
// Randomize the position of graphics to be drawn
TPoint pos;
RandomizeDrawingPosition(KRandomizedRangeX, KRandomizedRangeY, pos);
// Adjust randomized coordinate's offsets
pos.iX += KCoordOffsetX;
pos.iY += KCoordOffsetY;
// Clear the drawing area.
// The cleared area is set to be horizontally the whole size of the screen,
// otherwise there may be old mess. Vertically it's the size of screensaver.
TRect clearArea = TRect(TPoint(0,pos.iY-KActiveDisplayAreaOffsetUp-1),
TPoint(KScreenSizeX,pos.iY+KActiveDisplayAreaOffsetDown+1));
// Initialize graphic settings
InitializeGraphics(aGc, clearArea);
// Setting the screen partial mode that will decrease power consumption.
// Outside the drawing area the pixels are physically turned off
TScreensaverPartialMode partialMode;
// Apparently these partialMode-settings have no effect, they can be
// whatever but in partial mode at least in 7610 there are always 3 bit
// (8) colours in use
partialMode.iBpp = 0;
partialMode.iType = EPartialModeTypeMostPowerSaving;
status = iHost->SetActiveDisplayArea(pos.iY-KActiveDisplayAreaOffsetUp,
pos.iY+KActiveDisplayAreaOffsetDown,
partialMode);
// Get the indicator values, first new messages
iStatusCallsOrMsgs = EFalse;
TIndicatorPayload result;
status = iHost->GetIndicatorPayload(EScreensaverIndicatorIndexNewMessages, result);
if (status == KErrNone)
{
// Check if there is excessive amount of messages, show max 4
if (result.iInteger > 4)
{
result.iInteger = 4;
}
// Loop for drawing message icons
for (i = 0; i < result.iInteger; i++)
{
// Draw envelope
iStatusCallsOrMsgs = ETrue;
aGc.SetBrushColor(KRgbWhite);
aGc.DrawRect(TRect(TPoint(pos.iX+40,pos.iY+(15*i)), TSize(14,10)));
aGc.DrawLine(TPoint(pos.iX+40,pos.iY+(15*i)),TPoint(pos.iX+47,pos.iY+5+(15*i)));
aGc.DrawLineTo(TPoint(pos.iX+54,pos.iY+(15*i)));
}
}
// Get call indicator status
status = iHost->GetIndicatorPayload(EScreensaverIndicatorIndexNewMissedCalls, result);
if (status == KErrNone)
{
// Check if there is excessive amount of calls, show max 4
if (result.iInteger > 4)
{
result.iInteger = 4;
}
// Loop for drawing missed calls
for (i = 0; i < result.iInteger; i++)
{
// Draw call icon
iStatusCallsOrMsgs = ETrue;
aGc.SetPenSize(TSize(2,2));
aGc.DrawLine(TPoint(pos.iX-8,pos.iY+5+(15*i)), TPoint(pos.iX-8,pos.iY+(15*i)));
aGc.DrawLineTo(TPoint(pos.iX-21,pos.iY+(15*i)));
aGc.DrawLineTo(TPoint(pos.iX-21,pos.iY+5+(15*i)));
aGc.SetPenSize(TSize(1,1));
}
}
// Draw green square, if no calls or messages have arrived. Otherwise red.
if (iStatusCallsOrMsgs)
{
aGc.SetPenColor(KRgbRed);
aGc.SetBrushColor(KRgbRed);
}
else
{
aGc.SetPenColor(KRgbGreen);
aGc.SetBrushColor(KRgbGreen);
}
aGc.DrawRect(TRect(TPoint(pos.iX,pos.iY), TSize(34,40)));
// Draw clock display
TTime time;
time.HomeTime();
TDateTime dateTime = time.DateTime();
aGc.SetPenColor(KRgbBlack);
TBuf<10> clockTime;
// Append leading zero to time if needed
if (dateTime.Hour() < 10)
{
clockTime.Append(KZero);
}
clockTime.AppendNum(dateTime.Hour());
clockTime.Append(KSeparator);
if (dateTime.Minute() < 10)
{
clockTime.Append(KZero);
}
clockTime.AppendNum(dateTime.Minute());
aGc.DrawText(clockTime,TPoint(pos.iX,pos.iY+KActiveDisplayAreaOffsetDown));
// Check active profile
iFontUsed = iEikonEnv->AnnotationFont();
aGc.UseFont(iFontUsed);
// Here is a workaroud for profile showing. First is queried is the used
// profile 'General'. This check is needed because the GetIndicatorPayLoad-
// API call returns erroneously old used profile before 'General'. That's
// why we need to use CSettingInfo-class first.
// HACK start -----------------------------------------------------------------
TInt errorState = KErrNone;
TInt profile;
// This part of code may not leave
TRAP(errorState,
CSettingInfo* info = CSettingInfo::NewL(NULL);
CleanupStack::PushL(info);
User::LeaveIfError(info->Get(SettingInfo::EActiveProfile, profile));
//profile == 0 (general) 1 (silent) 2 (meeting) 3 (outdoor) 4 (pager)
CleanupStack::PopAndDestroy(info);
);
// Query profile name if it's other than 'General'
if (profile != 0 && errorState == KErrNone)
{
// HACK end -------------------------------------------------------------------
// This is the main API call, it'd be enough if API worked correctly
status = iHost->GetIndicatorPayload(EScreensaverIndicatorIndexProfileName,
result);
if (status == KErrNone)
{
// Draw used profile
aGc.SetPenColor(KRgbBlack);
aGc.DrawText(result.iText,TPoint(pos.iX,pos.iY-5));
}
}
// Draw key symbol if phone is locked
/*
status = iHost->GetIndicatorPayload(EScreensaverIndicatorIndexKeyGuardState,
result);
// If result is other than '0', keylock is activated
if (status == KErrNone && result.iInteger != 0)
{
// Draw key symbol
}
*/
// NOTE! The API call
// GetIndicatorPayload(EScreensaverIndicatorIndexKeyGuardState,...)
// doesn't work, so used Avkon function as a workaround.
RAknKeyLock keyLock;
if (keyLock.Connect() == KErrNone)
{
TBool locked = keyLock.IsKeyLockEnabled();
if (locked)
{
// Draw key symbol
aGc.SetPenColor(KRgbWhite);
aGc.SetPenSize(TSize(2,2));
aGc.DrawEllipse(TRect(TPoint(pos.iX+20,pos.iY+15),
TPoint(pos.iX+26,pos.iY+23)));
aGc.DrawLine(TPoint(pos.iX+20,pos.iY+19),
TPoint(pos.iX+7,pos.iY+19));
aGc.DrawLine(TPoint(pos.iX+9,pos.iY+19),
TPoint(pos.iX+9,pos.iY+22));
}
keyLock.Close();
}
return KErrNone;
}
// ----------------------------------------------------------------------------
// CMyScreenSaverPlugin::Name
//
// Returns the name of plugin module. Returned name is displayed in
// the list of installed plugin modules in personalization application.
// ----------------------------------------------------------------------------
const TDesC16& CMyScreenSaverPlugin::Name() const
{
return KMyScreenSaverPluginName;
}
// ----------------------------------------------------------------------------
// CMyScreenSaverPlugin::HandleScreensaverEventL
//
// Handler function for screensaver events.
// ----------------------------------------------------------------------------
TInt CMyScreenSaverPlugin::HandleScreensaverEventL( TScreensaverEvent /*aEvent*/,
TAny* /*aData*/)
{
return KErrNone;
}
// ----------------------------------------------------------------------------
// CMyScreenSaverPlugin::InitializeGraphics
//
// Initializes the graphic display
// ----------------------------------------------------------------------------
void CMyScreenSaverPlugin::InitializeGraphics(CWindowGc& aGc, TRect aClearArea)
{
aGc.Clear(aClearArea);
aGc.SetPenColor( KRgbBlack );
aGc.SetBrushStyle( CGraphicsContext::ESolidBrush );
aGc.SetPenStyle( CGraphicsContext::ESolidPen );
iFontUsed = iEikonEnv->TitleFont();
aGc.UseFont(iFontUsed);
}
// ----------------------------------------------------------------------------
// CMyScreenSaverPlugin::RandomizeDrawingPosition
//
// Randomizes the point to draw within given X & Y -range
// ----------------------------------------------------------------------------
void CMyScreenSaverPlugin::RandomizeDrawingPosition(TInt aRandomizedRangeX,
TInt aRandomizedRangeY,
TPoint& aPos)
{
// The coordinates are randomized
TReal xReal = Math::FRand(iRandSeed);
TReal yReal = Math::FRand(iRandSeed);
TInt x = (TInt(xReal*aRandomizedRangeX));
TInt y = (TInt(yReal*aRandomizedRangeY));
aPos = TPoint(x,y);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -