[sword-svn] r225 - trunk/src/SlideBible

kalemas at crosswire.org kalemas at crosswire.org
Mon Mar 8 14:22:29 MST 2010


Author: kalemas
Date: 2010-03-08 14:22:28 -0700 (Mon, 08 Mar 2010)
New Revision: 225

Added:
   trunk/src/SlideBible/sbFeatures.cpp
   trunk/src/SlideBible/sbFeatures.h
Modified:
   trunk/src/SlideBible/SlideBible.vcproj
   trunk/src/SlideBible/main.cpp
   trunk/src/SlideBible/sbBase.h
   trunk/src/SlideBible/sbControl.cpp
   trunk/src/SlideBible/sbControl.h
   trunk/src/SlideBible/sbCore.cpp
   trunk/src/SlideBible/sbCore.h
   trunk/src/SlideBible/sbItem.cpp
   trunk/src/SlideBible/sbItem.h
   trunk/src/SlideBible/sbList.cpp
   trunk/src/SlideBible/sbList.h
   trunk/src/SlideBible/sbTheme.cpp
   trunk/src/SlideBible/sbTheme.h
   trunk/src/SlideBible/todo.txt
Log:
+	huge rewrite
+		platform independent api layer
+		test base types
+			memory tracker
+			threading
+			sbColor - constructor from string
+		make it work
+			wm6.5 not started
+			release configuration not started
+	win32 platform
+	memory leak test
+	verse history
+		time function
+	timer to save configs
+	make list scrolling more smooth

Modified: trunk/src/SlideBible/SlideBible.vcproj
===================================================================
--- trunk/src/SlideBible/SlideBible.vcproj	2010-01-07 20:57:03 UTC (rev 224)
+++ trunk/src/SlideBible/SlideBible.vcproj	2010-03-08 21:22:28 UTC (rev 225)
@@ -1,10 +1,12 @@
-<?xml version="1.0" encoding="windows-1251"?>
+<?xml version="1.0" encoding="Windows-1252"?>
 <VisualStudioProject
 	ProjectType="Visual C++"
 	Version="9,00"
 	Name="SlideBible"
 	ProjectGUID="{F0CEF277-24C5-45BC-A0D0-56BE5A64AB94}"
+	RootNamespace="SlideBible"
 	Keyword="Win32Proj"
+	AssemblyReferenceSearchPaths="&quot;..\..\..\..\..\Program Files\Windows Mobile 6 SDK&quot;"
 	TargetFrameworkVersion="196613"
 	>
 	<Platforms>
@@ -48,15 +50,16 @@
 				ExecutionBucket="7"
 				AdditionalOptions="/D &quot;NO_VSNPRINTF&quot;"
 				Optimization="0"
-				AdditionalIncludeDirectories="..\Dll1\winceSword\include\;..\..\..\..\sword\trunk\include\;..\..\..\..\sword\trunk\include\internal\regex\"
+				AdditionalIncludeDirectories=".\platform\wince\;..\..\..\..\sword\trunk\include\;..\..\..\..\sword\trunk\include\internal\regex\"
 				PreprocessorDefinitions="DEBUG;ARM;_ARM_;UNDER_CE=$(CEVER);_WIN32_WCE=$(CEVER);$(CePlatform);UNICODE;SIMPLE"
 				IgnoreStandardIncludePath="false"
+				GeneratePreprocessedFile="0"
 				StringPooling="true"
 				MinimalRebuild="false"
 				RuntimeLibrary="1"
 				RuntimeTypeInfo="true"
 				UsePrecompiledHeader="0"
-				BrowseInformation="0"
+				BrowseInformation="1"
 				WarningLevel="3"
 				DebugInformationFormat="1"
 			/>
@@ -74,14 +77,14 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalOptions="/subsystem:windowsce,5.01"
 				AdditionalDependencies="aygshell.lib"
 				OutputFile="$(OutDir)/SlideBible.exe"
 				LinkIncremental="2"
 				DelayLoadDLLs="$(NOINHERIT)"
 				GenerateDebugInformation="true"
 				ProgramDatabaseFile="$(OutDir)/SlideBible.pdb"
-				SubSystem="0"
+				GenerateMapFile="true"
+				SubSystem="8"
 				StackReserveSize="65536"
 				StackCommitSize="4096"
 				EntryPointSymbol="WinMainCRTStartup"
@@ -118,6 +121,8 @@
 		</Configuration>
 		<Configuration
 			Name="Debug|Pocket PC 2003 (ARMV4)"
+			OutputDirectory="Pocket PC 2003 (ARMV4)\$(ConfigurationName)"
+			IntermediateDirectory="Pocket PC 2003 (ARMV4)\$(ConfigurationName)"
 			ConfigurationType="1"
 			CharacterSet="1"
 			>
@@ -135,34 +140,55 @@
 			/>
 			<Tool
 				Name="VCMIDLTool"
-				PreprocessorDefinitions="_WIN32_WCE=$(CEVER);UNDER_CE;$(PLATFORMDEFINES);WINCE;DEBUG;$(ARCHFAM);$(_ARCHFAM_);STANDARDSHELL_UI_MODEL;_DEBUG;DEBUG"
+				TargetEnvironment="1"
 			/>
 			<Tool
 				Name="VCCLCompilerTool"
 				ExecutionBucket="7"
+				AdditionalOptions="/D &quot;NO_VSNPRINTF&quot;"
 				Optimization="0"
-				PreprocessorDefinitions="_WIN32_WCE=$(CEVER);UNDER_CE;$(PLATFORMDEFINES);WINCE;DEBUG;$(ARCHFAM);$(_ARCHFAM_);STANDARDSHELL_UI_MODEL;_DEBUG;DEBUG"
-				MinimalRebuild="true"
+				AdditionalIncludeDirectories=".\platform\wince\;..\..\..\..\sword\trunk\include\;..\..\..\..\sword\trunk\include\internal\regex\"
+				PreprocessorDefinitions="DEBUG;ARM;_ARM_;UNDER_CE=$(CEVER);_WIN32_WCE=$(CEVER);$(CePlatform);UNICODE;SIMPLE"
+				IgnoreStandardIncludePath="false"
+				GeneratePreprocessedFile="0"
+				StringPooling="true"
+				MinimalRebuild="false"
+				RuntimeLibrary="1"
+				RuntimeTypeInfo="true"
+				UsePrecompiledHeader="0"
+				BrowseInformation="0"
 				WarningLevel="3"
-				DebugInformationFormat="3"
+				DebugInformationFormat="1"
 			/>
 			<Tool
 				Name="VCManagedResourceCompilerTool"
 			/>
 			<Tool
 				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="_WIN32_WCE=$(CEVER);UNDER_CE;$(PLATFORMDEFINES);WINCE;DEBUG;$(ARCHFAM);$(_ARCHFAM_);STANDARDSHELL_UI_MODEL;_DEBUG;DEBUG"
+				PreprocessorDefinitions="_DEBUG;_WIN32_WCE=$(CEVER);UNDER_CE;$(PLATFORMDEFINES)"
+				Culture="1033"
+				AdditionalIncludeDirectories="$(IntDir)"
 			/>
 			<Tool
 				Name="VCPreLinkEventTool"
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalOptions="/subsystem:windowsce,$(CEVER) /machine:$(ARCHFAM)"
+				AdditionalOptions="/subsystem:windowsce,5.01"
+				AdditionalDependencies="aygshell.lib"
+				OutputFile="$(OutDir)/SlideBible.exe"
 				LinkIncremental="2"
+				DelayLoadDLLs="$(NOINHERIT)"
 				GenerateDebugInformation="true"
+				ProgramDatabaseFile="$(OutDir)/SlideBible.pdb"
+				GenerateMapFile="true"
+				SubSystem="8"
 				StackReserveSize="65536"
 				StackCommitSize="4096"
+				EntryPointSymbol="WinMainCRTStartup"
+				RandomizedBaseAddress="1"
+				DataExecutionPrevention="0"
+				TargetMachine="0"
 			/>
 			<Tool
 				Name="VCALinkTool"
@@ -181,6 +207,7 @@
 			/>
 			<Tool
 				Name="VCPostBuildEventTool"
+				CommandLine=""
 			/>
 			<DeploymentTool
 				ForceDirty="-1"
@@ -216,17 +243,20 @@
 			<Tool
 				Name="VCCLCompilerTool"
 				Optimization="0"
-				AdditionalIncludeDirectories="..\Dll1\winceSword\include\;..\..\..\..\sword\trunk\include\"
-				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
+				AdditionalIncludeDirectories=".\platform\win32\;..\..\..\..\sword\trunk\include\;..\..\..\..\sword\trunk\include\internal\regex\"
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_CRTDBG_MAP_ALLOC;REGEX_MALLOC;DEBUG"
 				IgnoreStandardIncludePath="false"
 				StringPooling="true"
 				MinimalRebuild="false"
 				RuntimeLibrary="1"
 				RuntimeTypeInfo="true"
 				UsePrecompiledHeader="0"
+				AssemblerOutput="0"
+				AssemblerListingLocation="$(IntDir)\Listing"
 				BrowseInformation="0"
 				WarningLevel="3"
 				DebugInformationFormat="1"
+				ForcedIncludeFiles=""
 			/>
 			<Tool
 				Name="VCManagedResourceCompilerTool"
@@ -242,17 +272,17 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalOptions="/subsystem:windowsce,5.01"
-				AdditionalDependencies="aygshell.lib"
+				RegisterOutput="true"
+				AdditionalDependencies="msimg32.Lib"
 				OutputFile="$(OutDir)/SlideBible.exe"
 				LinkIncremental="2"
 				DelayLoadDLLs="$(NOINHERIT)"
 				GenerateDebugInformation="true"
 				ProgramDatabaseFile="$(OutDir)/SlideBible.pdb"
-				SubSystem="0"
+				SubSystem="2"
 				StackReserveSize="65536"
 				StackCommitSize="4096"
-				EntryPointSymbol="WinMainCRTStartup"
+				EntryPointSymbol=""
 				RandomizedBaseAddress="1"
 				DataExecutionPrevention="0"
 			/>
@@ -307,8 +337,9 @@
 				AdditionalOptions="/D &quot;NO_VSNPRINTF&quot;"
 				Optimization="2"
 				FavorSizeOrSpeed="2"
-				AdditionalIncludeDirectories="..\Dll1\winceSword\include\;..\..\..\..\sword\trunk\include\;..\..\..\..\sword\trunk\include\internal\regex\"
+				AdditionalIncludeDirectories=".\platform\wince\;..\..\..\..\sword\trunk\include\;..\..\..\..\sword\trunk\include\internal\regex\"
 				PreprocessorDefinitions="NDEBUG;_WIN32_WCE=$(CEVER);UNDER_CE;$(PLATFORMDEFINES);WINCE;_WINDOWS;$(ARCHFAM);$(_ARCHFAM_);_UNICODE;UNICODE"
+				StringPooling="true"
 				RuntimeLibrary="0"
 				UsePrecompiledHeader="0"
 				WarningLevel="3"
@@ -372,6 +403,8 @@
 		</Configuration>
 		<Configuration
 			Name="Release|Pocket PC 2003 (ARMV4)"
+			OutputDirectory="Pocket PC 2003 (ARMV4)\$(ConfigurationName)"
+			IntermediateDirectory="Pocket PC 2003 (ARMV4)\$(ConfigurationName)"
 			ConfigurationType="1"
 			CharacterSet="1"
 			>
@@ -389,15 +422,18 @@
 			/>
 			<Tool
 				Name="VCMIDLTool"
-				PreprocessorDefinitions="_WIN32_WCE=$(CEVER);UNDER_CE;$(PLATFORMDEFINES);WINCE;DEBUG;$(ARCHFAM);$(_ARCHFAM_);STANDARDSHELL_UI_MODELNDEBUG"
+				TargetEnvironment="1"
 			/>
 			<Tool
 				Name="VCCLCompilerTool"
 				ExecutionBucket="7"
+				AdditionalOptions="/D &quot;NO_VSNPRINTF&quot;"
 				Optimization="2"
 				FavorSizeOrSpeed="2"
-				PreprocessorDefinitions="_WIN32_WCE=$(CEVER);UNDER_CE;$(PLATFORMDEFINES);WINCE;DEBUG;$(ARCHFAM);$(_ARCHFAM_);STANDARDSHELL_UI_MODELNDEBUG"
-				MinimalRebuild="false"
+				AdditionalIncludeDirectories="..\Dll1\winceSword\include\;..\..\..\..\sword\trunk\include\;..\..\..\..\sword\trunk\include\internal\regex\"
+				PreprocessorDefinitions="NDEBUG;_WIN32_WCE=$(CEVER);UNDER_CE;$(PLATFORMDEFINES);WINCE;_WINDOWS;$(ARCHFAM);$(_ARCHFAM_);_UNICODE;UNICODE"
+				RuntimeLibrary="0"
+				UsePrecompiledHeader="0"
 				WarningLevel="3"
 				DebugInformationFormat="3"
 			/>
@@ -406,20 +442,30 @@
 			/>
 			<Tool
 				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="_WIN32_WCE=$(CEVER);UNDER_CE;$(PLATFORMDEFINES);WINCE;DEBUG;$(ARCHFAM);$(_ARCHFAM_);STANDARDSHELL_UI_MODELNDEBUG"
+				PreprocessorDefinitions="NDEBUG;_WIN32_WCE=$(CEVER);UNDER_CE;$(PLATFORMDEFINES)"
+				Culture="1033"
+				AdditionalIncludeDirectories="$(IntDir)"
 			/>
 			<Tool
 				Name="VCPreLinkEventTool"
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalOptions="/subsystem:windowsce,$(CEVER) /machine:$(ARCHFAM)"
+				AdditionalOptions=" /subsystem:windowsce,5.01"
+				AdditionalDependencies="aygshell.lib"
+				OutputFile="$(OutDir)/SlideBible.exe"
 				LinkIncremental="1"
+				DelayLoadDLLs="$(NOINHERIT)"
 				GenerateDebugInformation="true"
+				ProgramDatabaseFile="$(OutDir)/SlideBible.pdb"
+				SubSystem="0"
 				StackReserveSize="65536"
 				StackCommitSize="4096"
 				OptimizeReferences="2"
 				EnableCOMDATFolding="2"
+				RandomizedBaseAddress="1"
+				DataExecutionPrevention="0"
+				TargetMachine="0"
 			/>
 			<Tool
 				Name="VCALinkTool"
@@ -546,15 +592,15 @@
 				>
 			</File>
 			<File
-				RelativePath=".\sbCollection.h"
+				RelativePath=".\sbControl.h"
 				>
 			</File>
 			<File
-				RelativePath=".\sbControl.h"
+				RelativePath=".\sbCore.h"
 				>
 			</File>
 			<File
-				RelativePath=".\sbCore.h"
+				RelativePath=".\sbFeatures.h"
 				>
 			</File>
 			<File
@@ -1879,15 +1925,15 @@
 				>
 			</File>
 			<File
-				RelativePath=".\sbCollection.cpp"
+				RelativePath=".\sbControl.cpp"
 				>
 			</File>
 			<File
-				RelativePath=".\sbControl.cpp"
+				RelativePath=".\sbCore.cpp"
 				>
 			</File>
 			<File
-				RelativePath=".\sbCore.cpp"
+				RelativePath=".\sbFeatures.cpp"
 				>
 			</File>
 			<File
@@ -1904,59 +1950,23 @@
 			</File>
 		</Filter>
 		<Filter
-			Name="wince"
+			Name="utility"
 			>
 			<Filter
-				Name="source"
+				Name="header"
 				>
 				<File
-					RelativePath="..\Dll1\winceSword\src\dirent.cpp"
+					RelativePath=".\platform\xmlParser.h"
 					>
 				</File>
-				<File
-					RelativePath="..\Dll1\winceSword\src\fcntl.cpp"
-					>
-				</File>
-				<File
-					RelativePath="..\Dll1\winceSword\src\unistd.cpp"
-					>
-				</File>
 			</Filter>
 			<Filter
-				Name="header"
+				Name="source"
 				>
 				<File
-					RelativePath="..\Dll1\winceSword\include\dirent.h"
+					RelativePath=".\platform\xmlParser.cpp"
 					>
 				</File>
-				<File
-					RelativePath="..\Dll1\winceSword\include\errno.h"
-					>
-				</File>
-				<File
-					RelativePath="..\Dll1\winceSword\include\fcntl.h"
-					>
-				</File>
-				<File
-					RelativePath="..\Dll1\winceSword\include\unistd.h"
-					>
-				</File>
-				<Filter
-					Name="sys"
-					>
-					<File
-						RelativePath="..\Dll1\winceSword\include\sys\errno.h"
-						>
-					</File>
-					<File
-						RelativePath="..\Dll1\winceSword\include\sys\stat.h"
-						>
-					</File>
-					<File
-						RelativePath="..\Dll1\winceSword\include\sys\types.h"
-						>
-					</File>
-				</Filter>
 			</Filter>
 		</Filter>
 		<File

Modified: trunk/src/SlideBible/main.cpp
===================================================================
--- trunk/src/SlideBible/main.cpp	2010-01-07 20:57:03 UTC (rev 224)
+++ trunk/src/SlideBible/main.cpp	2010-03-08 21:22:28 UTC (rev 225)
@@ -1,5 +1,5 @@
 /*************************************************************************
- * main.cpp - only platform-dependent file, program entry
+ * main.cpp - program entry for win32 and wince platforms
  *
  * author: Konstantin Maslyuk "Kalemas" mailto:kalemas at mail.ru
  *
@@ -13,20 +13,53 @@
  * General Public License for more details.
  ************************************************************************/
 
-
-
 #include "sbCore.h"
 
 #include <windows.h>
 
+#include <dirent.cpp>
+
 #ifdef _WIN32_WCE
 #include <aygshell.h>
+
+#include <fcntl.cpp>
+#include <time_ce.cpp>
+#include <unistd.cpp>
 #endif
 
+
+
+// Globals
 HWND Window = NULL;
 
-void sbFillRect (sbRenderContext rc, const sbRect * rect, sbColor color)
+// Functions
+void sbMessage ( const char * format , ... )
 {
+	va_list args;
+
+	static FILE * file = NULL;
+	
+	file = fopen( "log.txt", file == NULL ? "w" : "a" );
+
+	if (file == NULL) return;
+
+	va_start(args, format);
+	vfprintf(file, format, args);
+	
+#ifdef _WIN32_WCE
+	vprintf(format, args);
+#else
+	char buffer [1024];
+	vsnprintf(buffer, 1024, format, args);
+	OutputDebugStringA(buffer);
+#endif
+	va_end(args);
+
+	fclose(file);
+}
+
+void sbFillRect ( sbSurface rc, const sbRect * rect, sbColor color )
+{
 	HBRUSH brush = CreateSolidBrush(RGB(color.red,color.green,color.blue));
 	RECT   rect2 = {rect->left,rect->top,rect->right,rect->bottom};
 	FillRect ((HDC)rc, &rect2, brush);
@@ -64,28 +97,32 @@
 	return ts;
 }
 
-void sbDrawGradient ( sbRenderContext rc, const sbRect * rect, sbColor startColor, sbColor endColor, bool vertical )
+void sbDrawGradient ( sbSurface rc, const sbRect * rect, sbColor startColor, sbColor endColor, bool vertical )
 {
-	TRIVERTEX        vert[2];	GRADIENT_RECT    gRect;
+	TRIVERTEX        vert[2];
+	GRADIENT_RECT    gRect;
+
 	vert [0] .x      = rect->left;
 	vert [0] .y      = rect->top;
 	vert [0] .Red    = startColor.red   << 8;
 	vert [0] .Green  = startColor.green << 8;
 	vert [0] .Blue   = startColor.blue  << 8;
 	vert [0] .Alpha  = 0x0000;
+
 	vert [1] .x      = rect->right;
 	vert [1] .y      = rect->bottom;
 	vert [1] .Red    = endColor.red   << 8;
 	vert [1] .Green  = endColor.green << 8;
 	vert [1] .Blue   = endColor.blue  << 8;
 	vert [1] .Alpha  = 0x0000;
+
 	gRect.UpperLeft  = 0;		gRect.LowerRight = 1;
+
 	GradientFill((HDC)rc, vert, 2, &gRect, 1, vertical ? GRADIENT_FILL_RECT_V : GRADIENT_FILL_RECT_H);
 }
 
-void sbDrawBitmap ( sbRenderContext rc, const sbRect * rect, sbBitmap bitmap, bool stretch )
+void sbDrawBitmap ( sbSurface rc, const sbRect * rect, sbBitmap bitmap, bool stretch )
 {
-
 	HDC     thdc = CreateCompatibleDC(NULL);
 	HBITMAP obm  = (HBITMAP)SelectObject(thdc, (HBITMAP)bitmap);
 	BITMAP  bm;
@@ -103,16 +140,6 @@
 	SelectObject(thdc, obm);
 	DeleteDC(thdc);
 }
-sbBitmap sbRenderContextBitmap ( sbRenderContext rc , int width, int height )
-{
-	sbAssert(Window==NULL);
-	HDC wdc = GetDC(Window);
-	HBITMAP bitmap = CreateCompatibleBitmap (wdc, width, height);
-	SelectObject((HDC)rc,bitmap);
-	SetBkMode((HDC)rc, TRANSPARENT);
-	ReleaseDC(Window,wdc);
-	return (sbBitmap)bitmap;
-}
 
 const char * sbGetLocale ()
 {
@@ -273,22 +300,16 @@
 	}
 	else if (timeout-time > 16)
 	{
-		sbMessage ("Thread termination takes %i msec.\n", timeout-time);
+		sbMessage ("Thread stoped in %i msec.\n", timeout-time);
 	}
 
+	CloseHandle(threadData->handle);
+
 	threadData->abort = false;
 
 	delete threadData;
 }
 
-#ifdef _WIN32_WCE
-#include "time_ce\time_ce.cpp"
-
-time_t time ( time_t * now ) { return time_ce ( now ); }
-//#define asctime asctime_ce
-//#define localtime localtime_ce
-#endif
-
 sbBitmap sbLoadBitmap ( const TCHAR * filename )
 {
 #ifdef _WIN32_WCE
@@ -298,19 +319,41 @@
 #endif
 }
 
+sbSurface sbSurfaceCreate ( int width, int height )
+{
+	sbAssert ( Window == NULL );
+
+	HDC wc = GetDC ( Window );
+
+	HDC dc = CreateCompatibleDC ( wc );
+	HBITMAP bitmap = CreateCompatibleBitmap ( wc, width, height );
+	
+	SelectObject ( dc, bitmap );
+	SetBkMode ( dc, TRANSPARENT );
+
+	ReleaseDC ( Window, wc );
+	
+	return (sbSurface)dc;
+}
+
+void sbSurfaceDestroy ( sbSurface surface )
+{
+	DeleteObject ( (HBITMAP)GetCurrentObject( (HDC)surface, OBJ_BITMAP ) );
+	DeleteDC ( (HDC)surface );
+}
+
+
 void            sbGetScreenRect        ( sbRect & rect )          { sbAssert (Window==NULL); RECT wr; GetClientRect(Window,&wr); rect.left = wr.left; rect.top = wr.top; rect.right = wr.right; rect.bottom = wr.bottom; }
-sbRenderContext sbCreateRenderContext  ()                         { return (sbRenderContext)CreateCompatibleDC(NULL); }
-void            sbDestroyRenderContext ( sbRenderContext rc )     { DeleteDC((HDC)rc); }
 int             sbGetLastError         ()                         { return GetLastError(); }
 void            sbDeleteFont           ( sbFont font )            { DeleteObject ((HFONT)font); }
 void            sbDeleteBitmap         ( sbBitmap bitmap )        { DeleteObject ((HBITMAP)bitmap); }
-sbFont          sbSelectFont           ( sbRenderContext rc, sbFont font ) { return (sbFont)SelectObject((HDC)rc,(HFONT)font); }
-sbColor         sbSelectColor          ( sbRenderContext rc, sbColor color ) { COLORREF old = SetTextColor((HDC)rc,RGB(color.red,color.green,color.blue)); return sbColor(GetRValue(old),GetGValue(old),GetBValue(old)); }
-void            sbDrawText             ( sbRenderContext rc, int x, int y, const TCHAR * text, int count ) { ExtTextOut((HDC)rc, x, y, ETO_OPAQUE, NULL, text, count, 0); }
-void            sbSleep                ( int milliseconds )        { Sleep (milliseconds); }
+sbFont          sbSelectFont           ( sbSurface rc, sbFont font ) { return (sbFont)SelectObject((HDC)rc,(HFONT)font); }
+sbColor         sbSelectColor          ( sbSurface rc, sbColor color ) { COLORREF old = SetTextColor((HDC)rc,RGB(color.red,color.green,color.blue)); return sbColor(GetRValue(old),GetGValue(old),GetBValue(old)); }
+void            sbDrawText             ( sbSurface rc, int x, int y, const TCHAR * text, int count ) { ExtTextOut((HDC)rc, x, y, ETO_OPAQUE, NULL, text, count, 0); }
+void            sbSleep                ( int milliseconds )       { Sleep (milliseconds); }
 void            sbSetTimer             ( const int timer, int refreshRate ) { sbAssert(Window==NULL); SetTimer(Window, timer, refreshRate, (TIMERPROC) NULL); }
-void            sbKillTimer            ( const int timer ) { sbAssert(Window==NULL); KillTimer(Window, timer); }
-void            sbBitBlt               ( sbRenderContext toRc, int left, int top, int width, int height, sbRenderContext fromRc, int x, int y) { BitBlt((HDC)toRc, left, top, width, height, (HDC)fromRc, x, y, SRCCOPY); }
+void            sbKillTimer            ( const int timer )        { sbAssert(Window==NULL); KillTimer(Window, timer); }
+void            sbBitBlt               ( sbSurface toRc, int left, int top, int width, int height, sbSurface fromRc, int x, int y) { BitBlt((HDC)toRc, left, top, width, height, (HDC)fromRc, x, y, SRCCOPY); }
 long            sbGetTickCount         ()                         { return GetTickCount(); }
 void            sbExit                 ( int code )               { PostQuitMessage(code); }
 
@@ -327,24 +370,24 @@
 	case WM_KILLFOCUS: // loose focus
 		sbSetSip ( false );
 		Core->switchList ( sbList::TYPE_NONE );
-		break;
+		return 1;
 
 	case WM_SETFOCUS: // receive focus
-		Core->switchList ( sbList::TYPE_CURRENT );
-		break;
+		if ( Core != NULL ) Core->switchList ( sbList::TYPE_CURRENT );
+		return 1;
 
 	case WM_ACTIVATE:
 #ifdef _WIN32_WCE
 		SHFullScreen ( hwnd, SHFS_HIDESIPBUTTON | SHFS_HIDETASKBAR | SHFS_HIDESTARTICON );
 #endif
-		break;
+		return 1;
 
 	case WM_PAINT:
 		{
 			PAINTSTRUCT ps;
 			HDC hdc = BeginPaint(hwnd, &ps);
 
-			Core->onPaint((sbRenderContext)hdc);
+			Core->onPaint((sbSurface)hdc);
 
 			/*HDC rc = CreateCompatibleDC(NULL);
 			HDC rc2 = GetDC(Window);
@@ -377,106 +420,100 @@
 
 			EndPaint(hwnd, &ps);
 			DeleteDC(hdc);
-			return 1;
 		}
-
+		return 1;
 	
-	case WM_LBUTTONUP:
-		Core->onMouse ( LOWORD(lParam), HIWORD(lParam), MSG_MOUSE_L_UP );
-		break;
-
-	case WM_MOUSEMOVE:
-		Core->onMouse ( LOWORD(lParam), HIWORD(lParam), MSG_MOUSE_MOVE );
-		break;
-
-	case WM_LBUTTONDOWN:
-		Core->onMouse ( LOWORD(lParam), HIWORD(lParam), MSG_MOUSE_L_DOWN );
-		break;
-
-	case WM_KEYDOWN:
-		Core->onKey ( wParam, true );
-		break;
-
-	case WM_KEYUP:
-		Core->onKey ( wParam, false );
-		break;
-
-	case WM_CHAR:
-		Core->onChar ( (TCHAR)wParam );
-		break;
-
-	case WM_TIMER:
-		Core->onTimer ( wParam );
-		break;
-
-	case WM_CREATE:
-		break;
+	case WM_LBUTTONUP:              Core->onMouse ( LOWORD(lParam), HIWORD(lParam), MSG_MOUSE_L_UP );       return 1;
+	case WM_MOUSEMOVE:              Core->onMouse ( LOWORD(lParam), HIWORD(lParam), MSG_MOUSE_MOVE );       return 1;
+	case WM_LBUTTONDOWN:            Core->onMouse ( LOWORD(lParam), HIWORD(lParam), MSG_MOUSE_L_DOWN );     return 1;
+	case WM_KEYDOWN:                Core->onKey   ( wParam, true );                                         return 1;
+	case WM_KEYUP:                  Core->onKey   ( wParam, false );                                        return 1;
+	case WM_CHAR:                   Core->onChar  ( (TCHAR) wParam );                                       return 1;
+	case WM_TIMER:                  Core->onTimer ( wParam );                                               return 1;
 	}
 
 	return DefWindowProc(hwnd, message, wParam, lParam);
 }
 
-int WINAPI WinMain ( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow )
+int WINAPI _tWinMain ( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow )
 {
-	HWND hwnd = FindWindow ( L"SlideBible Application", L"SlideBible" );
+	const TCHAR * appClass = L"SlideBible Application";
+	const TCHAR * appTitle = L"SlideBible";
+	
+	int returnValue = 0;
 
+	HWND hwnd = FindWindow ( appClass, appTitle );
+
 	if (hwnd)
 	{
 		SetForegroundWindow(hwnd);
-		return -1;
+		returnValue = -1;
 	}
+	else
+	{
+		HCURSOR oldCursor = SetCursor ( LoadCursor ( NULL, IDC_WAIT ) );
 
-	HCURSOR oldCursor = SetCursor ( LoadCursor ( NULL, IDC_WAIT ) );
+		HACCEL accelTable = LoadAccelerators ( hInstance, NULL );
 
-	HACCEL accelTable = LoadAccelerators ( hInstance, NULL );
+		WNDCLASS wc;
 
-	WNDCLASS wc;
+		wc.style          = 0;
+		wc.lpfnWndProc    = wndProc;
+		wc.cbClsExtra     = 0;
+		wc.cbWndExtra     = 0;
+		wc.hInstance      = 0;
+		wc.hIcon          = 0;
+		wc.hCursor        = 0;
+		wc.hbrBackground  = (HBRUSH)GetStockObject(BLACK_BRUSH);
+		wc.lpszMenuName   = 0;
+		wc.lpszClassName  = appClass;
 
-	wc.style         = 0;
-	wc.lpfnWndProc   = wndProc;
-	wc.cbClsExtra    = 0;
-	wc.cbWndExtra    = 0;
-	wc.hInstance     = 0;
-	wc.hIcon         = 0;
-	wc.hCursor       = 0;
-	wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
-	wc.lpszMenuName  = 0;
-	wc.lpszClassName = L"SlideBible Application";
+		SetCursor ( oldCursor );
 
-	SetCursor ( oldCursor );
+		if ( RegisterClass ( & wc ) )
+		{
+#ifdef _WIN32_WCE
+			Window = CreateWindow( appClass, appTitle, WS_VISIBLE,
+				0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN),
+				NULL, NULL, hInstance, NULL );
+#else
+			Window = CreateWindow( appClass, appTitle, WS_VISIBLE,
+				CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
+				NULL, NULL, hInstance, NULL );
+#endif
 
-	if ( RegisterClass ( & wc ) )
-	{
-		Window = CreateWindow(L"SlideBible Application", L"SlideBible", WS_VISIBLE,
-			0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN),
-			NULL, NULL, hInstance, NULL);
+			if ( Window == NULL )
+			{
+				sbMessage ( "Can not create window becouse of %i error.\n", GetLastError() );
 
-		if ( Window == NULL )
-		{
-			sbMessage ( "Can not create window becouse of %i error.\n", GetLastError() );
-			PostQuitMessage ( 1 );
-			return 0;
-		}
-		else
-		{
-			sbCore core;
+				PostQuitMessage ( 1 );
+			}
+			else
+			{
+				sbCore core;
 
-			MSG message;
+				ShowWindow(Window, nCmdShow);
+				UpdateWindow(Window);
 
-			while ( GetMessage ( & message, NULL, 0, 0 ) )
-			{
-				if ( ! accelTable || ! TranslateAccelerator ( message.hwnd, accelTable, & message ) ) 
+				MSG message;
+
+				while ( GetMessage ( & message, NULL, 0, 0 ) )
 				{
-					TranslateMessage ( & message );
-					DispatchMessage ( & message );
+					if ( ! accelTable || ! TranslateAccelerator ( message.hwnd, accelTable, & message ) ) 
+					{
+						TranslateMessage ( & message );
+						DispatchMessage ( & message );
+					}
 				}
-			}
 
-			DestroyWindow(Window);
+				DestroyWindow(Window);
 
-			return message.wParam;
+				returnValue = message.wParam;
+			}
 		}
 	}
 
-	return 0;
+	//dumpLeakReport();
+
+	return returnValue;
 }

Modified: trunk/src/SlideBible/sbBase.h
===================================================================
--- trunk/src/SlideBible/sbBase.h	2010-01-07 20:57:03 UTC (rev 224)
+++ trunk/src/SlideBible/sbBase.h	2010-03-08 21:22:28 UTC (rev 225)
@@ -13,26 +13,23 @@
 * General Public License for more details.
 ************************************************************************/
 
+
 #ifndef SBBASE_H
 #define SBBASE_H
 
-//#include <windows.h>
-//#include <tchar.h>
-
-//#include <string.h>
-
-//#include <stdio.h>
+#include <stdio.h>
 #include <stdlib.h>
-//#include <iostream>
-//
-//#include "mmgr\mmgr.h"
 
-//#include <map>
-//#include <vector>
-#include <algorithm>
+#include <tchar.h>
 
-void sbMessage ( const char *format , ... );
+#ifndef _WIN32_WCE
+#include <math.h>
+#include <stdarg.h>
+#include <varargs.h>
+#endif
 
+void sbMessage ( const char * format , ... );
+
 #define sbAssert(condition) ((condition)?(sbMessage("sbAssert : " #condition ". at %s : %d\n", __FILE__, __LINE__), __debugbreak()) : 0)
 
 #ifndef max
@@ -44,44 +41,6 @@
 #endif
 
 /*
- *  sbObject - memory tracker utility.
- *  require copy operator
- */
-/*class sbObject
-{
-public:
-	sbObject ( const char * _name_ = "Generic" )
-	{
-		name = _name_;
-		tracker[name].push_back(this);
-
-		sbMessage("Create : %s at %#x\n",name,this);
-	}
-
-	~sbObject ()
-	{
-		sbMessage("Delete : %s at %#x\n",name,this);
-
-		std::vector<sbObject*>::iterator item = std::find(tracker[name].begin(),tracker[name].end(),this);
-
-		if (item != tracker[name].end())
-		{
-			tracker[name].erase(item);
-			//if (tracker[name].size() == 0) tracker.erase(name);
-		}
-		else
-		{
-			sbMessage ( "Deletion of unrecognized \"%s\" at %#x\n",name,this);
-		}
-	}
-
-	static std::map<const char*,std::vector<sbObject*>> tracker;
-
-private:
-	const char * name;
-};*/
-
-/*
  * sbRect - screen rect
  */
 struct sbRect
@@ -97,34 +56,6 @@
 };
 
 /*
- * sbLayout - screen-dimentions-independent rect
- */
-class sbLayout
-{
-public:
-	enum
-	{
-		SYSTEM_SCREEN = 0,
-		SYSTEM_LIST,
-		SYSTEM_TOOLBAR,
-		SYSTEM_EDGE_LEFT,
-		SYSTEM_EDGE_RIGHT,
-		SYSTEM_MATRIX
-	};
-	
-	sbLayout ( unsigned char _system_ , unsigned short _order_ = 1 , unsigned short _amount_ = 1 ) : order ( _order_ ) , amount ( _amount_ ) , system ( _system_ ) { update (); }
-	
-	void update ();
-	
-	sbRect rect;
-	
-private:
-	unsigned short order;
-	unsigned short amount;
-	unsigned char  system;
-};
-
-/*
  * sbColor - color
  */
 struct sbColor
@@ -150,33 +81,32 @@
 };
 
 typedef void * sbThread;
-typedef void * sbRenderContext;
+typedef void * sbSurface;
 typedef void * sbBitmap;
 typedef void * sbFont;
 
 sbThread        sbThreadCreate         ( void (*executor) (bool *) );
 void            sbThreadDestroy        ( sbThread threadData );
-void            sbFillRect             ( sbRenderContext rc, const sbRect * rect, sbColor color );
-void            sbDrawGradient         ( sbRenderContext rc, const sbRect * rect, sbColor startColor, sbColor endColor, bool vertical );
-void            sbDrawBitmap           ( sbRenderContext rc, const sbRect * rect, sbBitmap bitmap, bool stretch = false );
+void            sbFillRect             ( sbSurface rc, const sbRect * rect, sbColor color );
+void            sbDrawGradient         ( sbSurface rc, const sbRect * rect, sbColor startColor, sbColor endColor, bool vertical );
+void            sbDrawBitmap           ( sbSurface rc, const sbRect * rect, sbBitmap bitmap, bool stretch = false );
 void            sbGetScreenRect        ( sbRect & rect );
 sbBitmap        sbLoadBitmap           ( const TCHAR * filename );
-sbRenderContext sbCreateRenderContext  ();
-void            sbDestroyRenderContext ( sbRenderContext rc );
-int             sbGetLastError         (); /* sbGetError */
+sbSurface       sbSurfaceCreate        ( int width, int height );
+void            sbSurfaceDestroy       ( sbSurface surface );
+int             sbGetLastError         (); /* sbGetError */ // cut
 sbFont          sbMakeFont             ( int size, const TCHAR *face, bool bold, bool italic );
 sbPoint         sbGetTextExtent        ( sbFont font, const TCHAR * text, int count );
 void            sbDeleteFont           ( sbFont font );
 void            sbDeleteBitmap         ( sbBitmap bitmap );
-sbFont          sbSelectFont           ( sbRenderContext rc, sbFont font );
-sbColor         sbSelectColor          ( sbRenderContext rc, sbColor color );
-void            sbDrawText             ( sbRenderContext rc, int x, int y, const TCHAR * text, int count );
+sbFont          sbSelectFont           ( sbSurface rc, sbFont font );
+sbColor         sbSelectColor          ( sbSurface rc, sbColor color );
+void            sbDrawText             ( sbSurface rc, int x, int y, const TCHAR * text, int count );
 void            sbSleep                ( int milliseconds );
-sbBitmap        sbRenderContextBitmap  ( sbRenderContext rc , int width, int height );
 const char *    sbGetLocale            ();
 void            sbSetTimer             ( const int timer, int refreshRate );
 void            sbKillTimer            ( const int timer );
-void            sbBitBlt               ( sbRenderContext toRc, int left, int top, int width, int height, sbRenderContext fromRc, int x, int y);
+void            sbBitBlt               ( sbSurface toRc, int left, int top, int width, int height, sbSurface fromRc, int x, int y);
 void            sbUpdateScreen         ();
 void            sbSetSip               ( bool on );
 long            sbGetTickCount         ();

Modified: trunk/src/SlideBible/sbControl.cpp
===================================================================
--- trunk/src/SlideBible/sbControl.cpp	2010-01-07 20:57:03 UTC (rev 224)
+++ trunk/src/SlideBible/sbControl.cpp	2010-03-08 21:22:28 UTC (rev 225)
@@ -16,36 +16,48 @@
 #include "sbCore.h"
 #include "sbControl.h"
 
-sbRect layout (int index, int num, int scheme)
+#pragma warning(disable : 4018)
+
+sbRect layout (int scheme, int num, int start, int end = 0)
 {
-	const int themeSize = Core->getTheme()->size;
+	const int themeSize = Core->getTheme()->scale;
 	const sbRect * screenRect = &Core->getSurface(sbCore::SURFACE::TYPE_WHOLE)->rect;
 
 	sbRect rect;
 
 	if (scheme == 1) // bottom bar
 	{
-		rect.left   = screenRect->right*(index-1)/num;
-		rect.top    = screenRect->bottom-(themeSize*20/100);
-		rect.right  = screenRect->right*index/num;
-		rect.bottom = screenRect->bottom;
+		if (end > 0)
+		{
+			rect.left   = screenRect->right*start/num;
+			rect.top    = screenRect->bottom-(themeSize*20/100);
+			rect.right  = screenRect->right*end/num;
+			rect.bottom = screenRect->bottom;
+		}
+		else
+		{
+			rect.left   = screenRect->right*(start-1)/num;
+			rect.top    = screenRect->bottom-(themeSize*20/100);
+			rect.right  = screenRect->right*start/num;
+			rect.bottom = screenRect->bottom;
+		}
 	}
 	else if (scheme == 2) // can switch
 	{
-		rect.left   = screenRect->right*(index-1)/num;
+		rect.left   = screenRect->right*(start-1)/num;
 		rect.top    = screenRect->bottom-(themeSize*40/100);
-		rect.right  = screenRect->right*index/num;
+		rect.right  = screenRect->right*start/num;
 		rect.bottom = screenRect->bottom-(themeSize*20/100);
 	}
 	else if (scheme == 0) // screen matrix
 	{
 		int rows, columns, pv, ph, sep=themeSize/((num+2)*4), indent=max(themeSize*8/100,sep*4/3);
 
-		columns = (int)sqrt(num+2);
+		columns = (int)sqrt((float)num+2);
 		rows = (int)ceil(num/(float)columns);
 
-		pv = index%columns == 0 ? columns : index%columns;
-		ph = ((index-pv)/columns)+1;
+		pv = start%columns == 0 ? columns : start%columns;
+		ph = ((start-pv)/columns)+1;
 
 		rect.left   = indent+((screenRect->right-(indent*2)+sep)*(pv-1)/columns);
 		rect.top    = (themeSize*10/100)+indent+((screenRect->bottom-(themeSize*30/100)-(indent*2)+sep)*(ph-1)/rows);
@@ -71,33 +83,39 @@
 : type ( _type_ )
 , text ( L"" )
 {
-	const int themeSize = Core->getTheme()->size;
-	const sbRect* screenRect = &Core->getSurface( sbCore::SURFACE::TYPE_WHOLE )->rect;
+	const int themeSize = Core->getTheme()->scale;
+	const sbRect * screenRect = & Core->getSurface( sbCore::SURFACE::TYPE_WHOLE )->rect;
 
 	switch (type)
 	{
-	case TYPE_CLOSE:                 rect = layout(4,4,1);   setText(L"(X)");   break;
-	case TYPE_BUTTON_CLOSE:          rect = layout(4,4,1);   setText(L"X");     break;
-	case TYPE_OPEN_BOOK_SELECTION:   rect = layout(1,4,1);   setText(L"B");     break;
-	case TYPE_OPEN_MODULE_SELECTION: rect = layout(2,4,1);   setText(L"M");     break;
-	case TYPE_OPEN_NAVIGATION:       rect = layout(1,4,1);   setText(L"N");     break;
-	case TYPE_MODE_ADD_STAR:         rect = layout(2,4,1);   setText(L"*");     break;
-	case TYPE_OPEN_SEARCH:           rect = layout(3,4,1);   setText(L"S");     break;
-	case TYPE_OPEN_TEXT:             rect = layout(2,4,1);   setText(L"H");     break;
-	case TYPE_OPEN_HOME:             rect = layout(4,4,1);   setText(L"H");     break;
-	case TYPE_WIDE_CLOSE:            rect = layout(1,1,1);   setText(L"Close"); break;
-	case TYPE_CAN_SWITCH_LEFT:       rect = layout(1,12,2);  setText(L"<");     break;
-	case TYPE_CAN_SWITCH_RIGHT:      rect = layout(12,12,2); setText(L">");     break;
-	case TYPE_BUTTON_OPEN_FILE:      rect = layout(1,4,1);   setText(L"");      break;
-	case TYPE_OPEN_HISTORY:          rect = layout(1,4,1);   setText(L"H");    break;
-	case TYPE_OPEN_BOOKMARKS:        rect = layout(2,4,1);   setText(L"B");    break;
-	case TYPE_OPEN_READINGS:         rect = layout(3,4,1);   setText(L"R");    break;
+	// navigation
+	case TYPE_OPEN_BOOK_SELECTION:   rect = layout(1,16, 0, 6);  setText(L"Book");    break;
+	case TYPE_OPEN_MODULE_SELECTION: rect = layout(1,16, 6,13);  setText(L"Module");  break;
+	case TYPE_CLOSE:                 rect = layout(1,16,13,16);  setText(L"X");       break;
+	// list
+	case TYPE_OPEN_NAVIGATION_LIST:  rect = layout(1,16, 0, 7);  setText(L"Goto");    break;
+	case TYPE_LIST_SPACE:            rect = layout(1,16, 7,13);  setText(L" ");       break;
+	case TYPE_OPEN_HOME:             rect = layout(1,16,13,16);  setText(L"X");       break;
+	// home
+	case TYPE_OPEN_NAVIGATION:       rect = layout(1,16,0,5);    setText(L"Goto");    break;
+	case TYPE_OPEN_HISTORY:          rect = layout(1,16,5,12);   setText(L"History"); break;
+	case TYPE_EXIT:                  rect = layout(1,16,12,16);  setText(L"Exit");    break;
+	// other
+	case TYPE_MODE_ADD_STAR:         rect = layout(1,4,2);       setText(L"*");       break;
+	case TYPE_OPEN_SEARCH:           rect = layout(1,4,3);       setText(L"S");       break;
+	case TYPE_OPEN_TEXT:             rect = layout(1,4,2);       setText(L"H");       break;
+	case TYPE_WIDE_CLOSE:            rect = layout(1,1,1);       setText(L"Close");   break;
+	case TYPE_CAN_SWITCH_LEFT:       rect = layout(2,12,1);      setText(L"<");       break;
+	case TYPE_CAN_SWITCH_RIGHT:      rect = layout(2,12,12);     setText(L">");       break;
+	case TYPE_BUTTON_OPEN_FILE:      rect = layout(1,4,1);       setText(L"");        break;
+	case TYPE_OPEN_BOOKMARKS:        rect = layout(1,4,2);       setText(L"B");       break;
+	case TYPE_OPEN_READINGS:         rect = layout(1,4,3);       setText(L"R");       break;
 	case TYPE_MENU_EXIT:
 		{
 			rect = *screenRect;
 		
-			childrens.push_back(new sbControl (sbControl::TYPE_MENU_EXIT_YES, layout(1,2,0), L"Yes"));
-			childrens.push_back(new sbControl (sbControl::TYPE_MENU_EXIT_NO,  layout(2,2,0), L"No"));
+			childrens.push_back(new sbControl (sbControl::TYPE_MENU_EXIT_YES, layout(0,2,1), L"Yes"));
+			childrens.push_back(new sbControl (sbControl::TYPE_MENU_EXIT_NO,  layout(0,2,2), L"No"));
 
 			setText(L"Exit?");
 		}
@@ -109,10 +127,10 @@
 
 			// get verse state
 
-			childrens.push_back(new sbControl (sbControl::TYPE_MENU_VERSE_ADD_DYNAMIC_BOOKMARK, layout(1,4,0), L"DB"));
-			childrens.push_back(new sbControl (sbControl::TYPE_MENU_VERSE_ADD_STATIC_BOOKMARK,  layout(2,4,0), L"SB"));
-			childrens.push_back(new sbControl (sbControl::TYPE_MENU_VERSE_REMOVE_BOOKMARK,      layout(3,4,0), L"-B"));
-			childrens.push_back(new sbControl (sbControl::TYPE_MENU_VERSE_START_EDITING,        layout(4,4,0), L"Edit"));
+			childrens.push_back(new sbControl (sbControl::TYPE_MENU_VERSE_ADD_DYNAMIC_BOOKMARK, layout(0,4,1), L"DB"));
+			childrens.push_back(new sbControl (sbControl::TYPE_MENU_VERSE_ADD_STATIC_BOOKMARK,  layout(0,4,2), L"SB"));
+			childrens.push_back(new sbControl (sbControl::TYPE_MENU_VERSE_REMOVE_BOOKMARK,      layout(0,4,3), L"-B"));
+			childrens.push_back(new sbControl (sbControl::TYPE_MENU_VERSE_START_EDITING,        layout(0,4,4), L"Edit"));
 			childrens.push_back(new sbControl (sbControl::TYPE_MENU_CANCEL,                     layout(1,1,1), L"Cancel"));
 
 			setText(L"Verse");
@@ -137,7 +155,7 @@
 				TCHAR* text = new TCHAR [5];
 				text = _itot ( i*step , text , 10 );
 				
-				childrens.push_back( new sbControl ((TYPE)(TYPE_SET_VERSE+(i*step)), layout(i,count+1,0), text));
+				childrens.push_back( new sbControl ((TYPE)(TYPE_SET_VERSE+(i*step)), layout(0,count+1,i), text));
 			}
 
 			childrens.push_back( new sbControl (sbControl::TYPE_MENU_CANCEL, layout(1,1,1), L"Cancel"));
@@ -171,15 +189,16 @@
 	for (int i = 0; i < childrens.size(); i++) delete childrens[i];
 }
 
-void sbControl::onPaint ( sbRenderContext hdc ) const
+void sbControl::onPaint ( sbSurface hdc ) const
 {
 	sbFont font = sbSelectFont(hdc, Core->getTheme()->styles[style].font);
-	sbColor color = sbSelectColor(hdc, Core->getTheme()->ItemTextColor);
+	sbColor color = sbSelectColor(hdc, Core->getTheme()->ControlsColor);
 	
 	switch (type)
 	{
 	case TYPE_CAN_SWITCH_LEFT:
 	case TYPE_CAN_SWITCH_RIGHT:
+		sbSelectColor ( hdc, Core->getTheme()->ItemSubTextColor  );
 		sbDrawText ( hdc, textPos.x, textPos.y, text, _tcslen(text));
 		break;
 	default:
@@ -211,50 +230,29 @@
 {
 	switch (type)
 	{
-	case TYPE_OPEN_HOME:
-		Core->switchList(sbList::TYPE_HOME);
-		break;
-	case TYPE_OPEN_TEXT:
-		Core->switchList(sbList::TYPE_MODULE_VIEW);
-		break;
-	case TYPE_OPEN_SEARCH:
-		Core->switchList(sbList::TYPE_SEARCH);
-		break;
-	case TYPE_OPEN_BOOK_SELECTION:
-		Core->switchList(sbList::TYPE_SELECT_BOOK);
-		break;
-	case TYPE_OPEN_MODULE_SELECTION:
-		Core->switchList(sbList::TYPE_SELECT_MODULE);
-		break;
-	case TYPE_OPEN_HISTORY:
-		Core->switchList(sbList::TYPE_HISTORY);
-		break;
-	case TYPE_OPEN_BOOKMARKS:
-		Core->switchList(sbList::TYPE_BOOKMARKS);
-		break;
-	case TYPE_OPEN_READINGS:
-		Core->switchList(sbList::TYPE_READINGS);
-		break;
-	case TYPE_MENU_EXIT_YES:
-		sbExit(1);
-		break;
+	case TYPE_OPEN_HOME:                  Core->switchList(sbList::TYPE_HOME);             break;
+	case TYPE_OPEN_TEXT:                  Core->switchList(sbList::TYPE_MODULE_VIEW);      break;
 	case TYPE_OPEN_NAVIGATION:
-		Core->switchList(sbList::TYPE_NAVIGATION);
-		break;
-	case TYPE_WIDE_CLOSE:
-	case TYPE_CLOSE:
-		Core->switchList(sbList::PIN_PARENT);
-		break;
+	case TYPE_OPEN_NAVIGATION_LIST:
+	case TYPE_OPEN_BOOK_SELECTION:        Core->switchList(sbList::TYPE_SELECT_BOOK);      break;
+	case TYPE_OPEN_MODULE_SELECTION:      Core->switchList(sbList::TYPE_SELECT_MODULE);    break;
+	case TYPE_OPEN_HISTORY:               Core->switchList(sbList::TYPE_HISTORY);          break;
+	case TYPE_OPEN_BOOKMARKS:             Core->switchList(sbList::TYPE_BOOKMARKS);        break;
+	case TYPE_OPEN_READINGS:              Core->switchList(sbList::TYPE_READINGS);         break;
+	case TYPE_MENU_EXIT_YES:              sbExit(1);                                       break;
+	case TYPE_WIDE_CLOSE:                 Core->switchList(sbList::TYPE_HOME);             break;
+	case TYPE_CLOSE:                      Core->switchList(sbList::TYPE_MODULE_VIEW);      break;
+	case TYPE_LIST_SPACE:
 	case TYPE_CAN_SWITCH_LEFT:
-	case TYPE_CAN_SWITCH_RIGHT:
-		break;
+	case TYPE_CAN_SWITCH_RIGHT:                                                            break;
+
 	default:
 		{
 			if (isMenu())
 			{
 				for (int i=0; i < childrens.size(); i++)
 				{
-					if (childrens[i]->hit(Core->getInput()->lastx, Core->getInput()->lasty))
+					if (childrens[i]->hit(Core->getInput()->last.x, Core->getInput()->last.y))
 					{
 						childrens[i]->onPressed();
 					}

Modified: trunk/src/SlideBible/sbControl.h
===================================================================
--- trunk/src/SlideBible/sbControl.h	2010-01-07 20:57:03 UTC (rev 224)
+++ trunk/src/SlideBible/sbControl.h	2010-03-08 21:22:28 UTC (rev 225)
@@ -22,7 +22,7 @@
 #include <vector>
 
 // Screen Layout Generator
-sbRect layout ( int index , int num , int scheme );
+//sbRect layout ( int index , int num , int scheme );
 
 class sbControl
 {
@@ -30,11 +30,13 @@
 	enum TYPE
 	{
 		TYPE_NONE = 0,
-		TYPE_BUTTON_CLOSE,
+		TYPE_EXIT,
 		TYPE_WIDE_CLOSE,
 		TYPE_CLOSE,
 		TYPE_BUTTON_OPEN_FILE,
 		TYPE_OPEN_NAVIGATION,
+		TYPE_OPEN_NAVIGATION_LIST,
+		TYPE_LIST_SPACE,
 		TYPE_OPEN_MODULE_SELECTION,
 		TYPE_OPEN_BOOK_SELECTION,
 		TYPE_OPEN_SEARCH,
@@ -73,10 +75,8 @@
 
 public:
 
-	//void                         operator =        ( const sbControl & control ) {;}
-
 	void                         onPressed         ();
-	void                         onPaint           ( sbRenderContext rc ) const;
+	void                         onPaint           ( sbSurface rc ) const;
 
 	inline bool                  hit               ( int x , int y ) const {return (rect.inRect(x,y));}
 

Modified: trunk/src/SlideBible/sbCore.cpp
===================================================================
--- trunk/src/SlideBible/sbCore.cpp	2010-01-07 20:57:03 UTC (rev 224)
+++ trunk/src/SlideBible/sbCore.cpp	2010-03-08 21:22:28 UTC (rev 225)
@@ -20,62 +20,36 @@
 
 #include "sbCore.h"
 
-#pragma warning(disable : 4018)
+#pragma warning(disable : 4018) // signed/unsigned mismatch
 
+// Globals
 sbCore * Core;
-
 sbList * sbCore::backgroundList;
 
-//std::map<const char*,std::vector<sbObject*>> sbObject::tracker;
-
-void sbMessage ( const char * format , ... )
-{
-	va_list args;
-
-	static FILE * file = NULL;
-	
-	file = fopen( "log.txt", file == NULL ? "w" : "a" );
-
-	if (file == NULL) return;
-
-	va_start(args, format);
-	vfprintf(file, format, args);
-	vprintf(format, args);
-	va_end(args);
-
-	fclose(file);
-}
-
 sbCore::sbCore ()
-: defaultModule ( NULL )
 {
 	sbMessage ("Launch SlideBible Core.\n");
 	
-	sbAssert ( Core != NULL );
+	sbAssert ( Core != NULL ); // only one instance of sbCore allowed
 
 	Core = this;
 
 	// init data
-	currentList         = NULL;
-	listModule          = NULL;
-	listModuleSelection = NULL;
-	listBookSelection   = NULL;
-	listNavigation      = NULL;
-	listSearch          = NULL;
-	listHome            = NULL;
-	
+	currentList         = sbList::TYPE_HOME;
 	redrawTimerOn       = false;
 	requestedRedraw     = false;
 
 	listShift           = 0;
 
-	showListBanner      = false;
+	showBanner      = false;
 
 	backgroundThread    = NULL;
 	
-	mpOptions           = NULL;
-	mpSwordMgr          = NULL;
+	options             = NULL;
+	swordMgr            = NULL;
 
+	currentModule       = NULL;
+
 	// init surfaces
 	sbGetScreenRect (rClient);
 
@@ -84,112 +58,97 @@
 	theme.init(); // this must be after init SURFACE::TYPE_WHOLE, but before SURFACE::TYPE_LIST
 
 	surfaces[SURFACE::TYPE_LIST].rect = rClient;
-	surfaces[SURFACE::TYPE_LIST].rect.bottom -= theme.size/5;
+	surfaces[SURFACE::TYPE_LIST].rect.bottom -= theme.scale/5;
 
 	surfaces[SURFACE::TYPE_BUFFER].rect = surfaces[SURFACE::TYPE_LIST].rect;
 
 	for (int i=0; i<SURFACE::COUNT; i++)
 	{
-		surfaces[i].hdc = sbCreateRenderContext();
-		surfaces[i].bitmap = sbRenderContextBitmap (surfaces[i].hdc, surfaces[i].rect.width(), surfaces[i].rect.height());
+		surfaces[i].hdc = sbSurfaceCreate(surfaces[i].rect.width(), surfaces[i].rect.height());
 		surfaces[i].needRedraw = true;
 	}
 	
 	sbUpdateScreen();
 
-	//sword::SWLog::getSystemLog()->setLogLevel(5);
+	sword::SWLog::getSystemLog()->setLogLevel(5);
 
 	// load options
-	mpOptions = new sword::SWConfig(".\\options.conf"); sbAssert ( mpOptions == NULL ); mpOptions->Load();
+	options = new sword::SWConfig(".\\options.conf");   sbAssert ( options == NULL );   options->Load();
 	
-	cineticDamping = (float)atof((*mpOptions)["Ui"].getWithDefault("CineticDamping", "0.95"));
-	cineticFactor  = (float)atof((*mpOptions)["Ui"].getWithDefault("CineticFactor", "0.5"));
-	refreshRate    = 1000/atoi((*mpOptions)["Ui"].getWithDefault("RefreshRate", "30"));
-	scrollStep     = atoi((*mpOptions)["Ui"].getWithDefault("scrollStep", "1"));
-	versesMax      = atoi((*mpOptions)["Ui"].getWithDefault("versesMax", "500"));
-	versesOptimal  = atoi((*mpOptions)["Ui"].getWithDefault("versesOptimal", "50"));
+	cineticDamping = (float)atof((*options)["Ui"].getWithDefault("CineticDamping", "0.95"));
+	cineticFactor  = (float)atof((*options)["Ui"].getWithDefault("CineticFactor", "0.5"));
+	refreshRate    = 1000/atoi((*options)["Ui"].getWithDefault("RefreshRate", "30"));
+	scrollStep     = atoi((*options)["Ui"].getWithDefault("scrollStep", "1"));
+	versesMax      = atoi((*options)["Ui"].getWithDefault("versesMax", "500"));
+	versesOptimal  = atoi((*options)["Ui"].getWithDefault("versesOptimal", "50"));
 
 	// user locale
-	sword::LocaleMgr::getSystemLocaleMgr()->setDefaultLocaleName((*mpOptions)["General"].getWithDefault("Locale", sbGetLocale()));
+	sword::LocaleMgr::getSystemLocaleMgr()->setDefaultLocaleName((*options)["General"].getWithDefault("Locale", sbGetLocale()));
 
 	// init sword
-	mpSwordMgr = new sword::SWMgr(new sword::MarkupFilterMgr(sword::FMT_OSIS, sword::ENC_UTF16));
+	swordMgr = new sword::SWMgr(new sword::MarkupFilterMgr(sword::FMT_OSIS, sword::ENC_UTF16));
 	
-	sbAssert(mpSwordMgr == NULL);
+	sbAssert(swordMgr == NULL);
 
-	currentModule = mpSwordMgr->getModule((*mpOptions)["General"].getWithDefault("DefaultModule", "KJV"));
+	sbMessage ("Sword init finished.\n");
 
-	if (currentModule == NULL && mpSwordMgr->Modules.size() != 0)
-		currentModule = mpSwordMgr->Modules.begin()->second;
+	defaultModule = swordMgr->getModule((*options)["General"].getWithDefault("DefaultModule", "KJV"));
 
-	((sword::SWModule*)defaultModule) = currentModule;
+	if (defaultModule == NULL && swordMgr->Modules.size() != 0) defaultModule = swordMgr->Modules.begin()->second;
 
-	// restore collections
-	collections["bookmarks"].load(".\\verselists.conf","bookmarks");
-	collections["readings"].load(".\\verselists.conf","readings");
-	collections["history"].load(".\\verselists.conf","history");
+	//currentModule = defaultModule;
+
+	// restore features
+	features.load();
+
+	sbSetTimer( TIMER_SAVE_CONFIG, 5*60*1000 );
 	
 	// create ui
 	switchList ( sbList::TYPE_HOME );
+
+	sbMessage ("Finish Launch SlideBible Core.\n");
 }
 
 sbCore::~sbCore()
 {
 	threadDestroy();
 	
-	if (listModule != NULL && listModule->hasModule())
-		(*mpOptions)["Bookmarks"]["LastPlace"] = listModule->getKey()->getText();
+	// save configs
+	onTimer ( TIMER_SAVE_CONFIG );
 
-	// save collections
-	for (std::map<const char*,sbCollection>::iterator it=collections.begin(); it != collections.end(); it++)
+	// remove views
+	for (std::map<sbList::TYPE,sbList*>::iterator it=lists.begin(); it != lists.end(); it++)
 	{
-		it->second.save(".\\verselists.conf",it->first);
+		while (it->second->getPrev() != NULL) delete it->second->getPrev();
+		while (it->second->getNext() != NULL) delete it->second->getNext();
+		delete it->second;
 	}
 
-	sbList * lists[] = {listModule, listModuleSelection, listBookSelection, listSearch, listHome};
-
-	for (int i=0; i<sizeof(lists)/sizeof(sbList*); i++)
-	{
-		if (lists[i] != NULL)
-		{
-			while (lists[i]->getPrev() != NULL) delete lists[i]->getPrev();
-			while (lists[i]->getNext() != NULL) delete lists[i]->getNext();
-			delete lists[i];
-		}
-	}
-
-	if (mpOptions != NULL) mpOptions->Save();
-
 	// clear sword
-	if (mpSwordMgr != NULL) delete mpSwordMgr;
-	if (mpOptions != NULL) delete mpOptions;
+	if (swordMgr != NULL) delete swordMgr;
+	if (options  != NULL) delete options;
 
 	for (int i=0; i<SURFACE::COUNT; i++)
 	{
-		sbDeleteBitmap(surfaces[i].bitmap);
-		sbDestroyRenderContext(surfaces[i].hdc);
+		sbSurfaceDestroy(surfaces[i].hdc);
 	}
 
-	//for (std::map<const char*,std::vector<sbObject*>>::iterator it = sbObject::tracker.begin(); it != sbObject::tracker.end(); it++)
-	//	if (it->second.size() != 0)
-	//		sbMessage ("Delete misalignment of %s (%i)\n", it->first, it->second.size());
-
 	sbMessage ("Shutdown SlideBible Core.\n");
 }
 
-void sbCore::onPaint ( sbRenderContext hdc )
+void sbCore::onPaint ( sbSurface hdc )
 {
-	if (currentList != NULL)
+	if (lists[currentList] != NULL)
 	{
 		if (listShift == 0)
 		{
-			currentList->render(surfaces[SURFACE::TYPE_WHOLE].hdc,showListBanner);
+			lists[currentList]->render(surfaces[SURFACE::TYPE_WHOLE].hdc,showBanner);
 		}
 		else
 		{
 			if (surfaces[SURFACE::TYPE_LIST].needRedraw)
 			{
-				currentList->render(surfaces[SURFACE::TYPE_LIST].hdc,true);
+				lists[currentList]->render(surfaces[SURFACE::TYPE_LIST].hdc,true);
 				surfaces[SURFACE::TYPE_LIST].needRedraw = false;
 			}
 
@@ -197,8 +156,8 @@
 			{
 				if (surfaces[SURFACE::TYPE_BUFFER].needRedraw)
 				{
-					if (currentList->getNext() != NULL)
-						currentList->getNext()->render(surfaces[SURFACE::TYPE_BUFFER].hdc,true);
+					if (lists[currentList]->getNext() != NULL)
+						lists[currentList]->getNext()->render(surfaces[SURFACE::TYPE_BUFFER].hdc,true);
 					else
 						Core->getTheme()->drawElement(surfaces[SURFACE::TYPE_BUFFER].hdc, &surfaces[SURFACE::TYPE_BUFFER].rect, sbTheme::ELEMENT::BACKGROUND);
 
@@ -212,8 +171,8 @@
 			{
 				if (surfaces[SURFACE::TYPE_BUFFER].needRedraw)
 				{
-					if (currentList->getPrev() != NULL)
-						currentList->getPrev()->render(surfaces[SURFACE::TYPE_BUFFER].hdc,true);
+					if (lists[currentList]->getPrev() != NULL)
+						lists[currentList]->getPrev()->render(surfaces[SURFACE::TYPE_BUFFER].hdc,true);
 					else
 						Core->getTheme()->drawElement(surfaces[SURFACE::TYPE_BUFFER].hdc, &surfaces[SURFACE::TYPE_BUFFER].rect, sbTheme::ELEMENT::BACKGROUND);
 
@@ -225,10 +184,10 @@
 			}
 		}
 
-		for (std::vector<sbControl*>::const_iterator it=currentList->getControls()->begin(); it != currentList->getControls()->end(); it++)
+		for (std::vector<sbControl*>::const_iterator it=lists[currentList]->getControls()->begin(); it != lists[currentList]->getControls()->end(); it++)
 			(*it)->onPaint(surfaces[SURFACE::TYPE_WHOLE].hdc);
 
-		if (currentList->needScroll != 0)
+		if (lists[currentList]->needScroll != 0)
 		{
 			if (!bScrollTimer)
 			{
@@ -236,14 +195,14 @@
 				sbSetTimer(TIMER_SCROLL, refreshRate);
 			}
 			
-			if (currentList->needScroll < 0)
+			if (lists[currentList]->needScroll < 0)
 			{
 				cineticPower--;
 
 				if (cineticPower < 0.11f && cineticPower > -0.11f) //fix timer stopping
 					cineticPower = -0.11f;
 
-				cineticPower = max(cineticPower, currentList->needScroll*0.11f);
+				cineticPower = max(cineticPower, lists[currentList]->needScroll*0.11f);
 			}
 			else
 			{
@@ -252,7 +211,7 @@
 				if (cineticPower < 0.11f && cineticPower > -0.11f) //fix timer stopping
 					cineticPower = 0.11f;
 
-				cineticPower = min(cineticPower, currentList->needScroll*0.11f);
+				cineticPower = min(cineticPower, lists[currentList]->needScroll*0.11f);
 			}
 		}
 	}
@@ -263,119 +222,114 @@
 
 	if (input.tapCounter > 0)
 	{
-		sbRect rect (input.startx-(input.tapCounter*4), input.starty-(input.tapCounter*4), input.startx+(input.tapCounter*4), input.starty+(input.tapCounter*4));
+		sbRect rect (input.start.x-(input.tapCounter*4), input.start.y-(input.tapCounter*4), input.start.x+(input.tapCounter*4), input.start.y+(input.tapCounter*4));
 		Core->getTheme()->drawElement(surfaces[SURFACE::TYPE_WHOLE].hdc, &rect, sbTheme::ELEMENT::TAPPED, input.tapCounter);
 	}
 
 	const SURFACE * whole = & surfaces[SURFACE::TYPE_WHOLE];
 
-	//sbFillRect(surfaces[SURFACE::TYPE_WHOLE].hdc,&rClient,sbColor(0,255,0));
-	//sbFillRect(hdc,&rClient,sbColor(0,255,0));
-
 	sbBitBlt(hdc, whole->rect.left, whole->rect.top, whole->rect.width(), whole->rect.height(), whole->hdc, 0, 0);
 }
 
 void sbCore::onMouse ( int x, int y, const int state )
 {
+	static int scrolldatay [2];
+	static int scrolldataticks [2];
+
 	if ( state == MSG_MOUSE_L_DOWN )
 	{
-		sbAssert(input.mousePressed == true);
-
 		if (listShift != 0) return;
 
-		input.lastx = input.startx = x;
-		input.lasty = input.starty = y;
+		input.last.x = input.start.x = x;
+		input.last.y = input.start.y = y;
 
 		input.leaveZone = false;
 		input.mousePressed = true;
 
-		if (currentList != NULL)
-			currentList->onPressed(x,y);
+		if (lists[currentList] != NULL)
+			lists[currentList]->onPressed(x,y);
 		
 		input.tapCounter = 0;
 		sbSetTimer(TIMER_TAP, 1000/10);
+		
+		//sbMessage ("start click ================= \n");
+
+		scrolldatay[0]     = y;
+		scrolldataticks[0] = sbGetTickCount();
 	}
 	else if ( state == MSG_MOUSE_MOVE )
 	{
 		if (!input.mousePressed) return;
 
-		const int max = theme.size/20;
+		const int max = theme.scale/20;
 
-		int dx = x - input.lastx;
-		int dy = y - input.lasty;
+		int dx = x - input.last.x;
+		int dy = y - input.last.y;
 
-		//if (input.block) {dx = 0; dy = 0;}
-
-		if (abs(input.startx-x) > max || abs(input.starty-y) > max)
+		if (abs(input.start.x-x) > max || abs(input.start.y-y) > max)
 		{
 			input.leaveZone = true;
 			sbKillTimer(TIMER_TAP);
 			input.tapCounter = 0;
 		}
 
-		// update cinetic power
-		if (sbGetTickCount()-cineticTicks > 500)
+		scrolldataticks[1] = sbGetTickCount();
+		scrolldatay[1]     = y;
+
+		if (scrolldataticks[1] - scrolldataticks[0] > 200)
 		{
-			if (fabsf(cineticPower) > (float)abs(dy))
-				cineticPower = (float)dy;
+			scrolldatay[0]     = scrolldatay[1] + ((scrolldatay[0]-scrolldatay[1]) * (200.0f/(scrolldataticks[1]-scrolldataticks[0])));
+			scrolldataticks[0] = scrolldataticks[1] - 200;
 		}
-		else
-		{
-			if (fabsf(cineticPower) < (float)abs(dy))
-				cineticPower = (float)dy;
-		}
 
-		cineticTicks = sbGetTickCount();
-
-		if ((dy > 0 && cineticPower < 0) || (dy < 0 && cineticPower > 0))
-			cineticPower = 0.0f;
-
-		if (currentList != NULL)
+		if (lists[currentList] != NULL)
 		{
 			if (!input.block)
 			{
-				if (abs(input.startx-x) > (rClient.right/6)+(abs(input.starty-y)/2))
-					listShift = input.startx-x;
+				if (abs(input.start.x-x) > (rClient.right/6)+(abs(input.start.y-y)/2))
+					listShift = input.start.x-x;
 				else
 					listShift = 0;
 			
-				if (listShift < 0 && currentList->getPrev() == NULL) listShift = 0;
-				if (listShift > 0 && currentList->getNext() == NULL) listShift = 0;
+				if (listShift < 0 && lists[currentList]->getPrev() == NULL) listShift = 0;
+				if (listShift > 0 && lists[currentList]->getNext() == NULL) listShift = 0;
 			}
 
 			if (dy != 0 && listShift == 0)
-				currentList->scroll((float)dy);
+				lists[currentList]->scroll((float)dy);
 
 			redraw();
 		}
 		
-		input.lasty = y;
-		input.lastx = x;
+		input.last.y = y;
+		input.last.x = x;
 	}
 	else if ( state == MSG_MOUSE_L_UP )
 	{
 		if (!input.mousePressed) return;
 
-		// update cinetic power
-		float factor;
-		float t = (float)sbGetTickCount()-cineticTicks;
-		if (t > 500)
+		scrolldataticks[1] = sbGetTickCount();
+		scrolldatay[1]     = y;
+
+		if (scrolldataticks[1] - scrolldataticks[0] > 200)
 		{
-			t = 1-((t-500)/1500);
-			if (t<0) t = 0;
-			cineticPower *= t;
+			scrolldatay[0]     = scrolldatay[1] + ((scrolldatay[0]-scrolldatay[1]) * (200.0f/(scrolldataticks[1]-scrolldataticks[0])));
+			scrolldataticks[0] = scrolldataticks[1] - 200;
 		}
 
-		factor = (abs(input.starty-y)/(rClient.bottom*cineticFactor));
+		float speed = (scrolldatay[1]-scrolldatay[0])/(float)max((scrolldataticks[1]-scrolldataticks[0]),120);
+		
+		cineticPower = (speed*50.0f) + (cineticPower*min(fabs(speed)*200.0f/Core->getTheme()->scale,1.0f));
+		
+		//sbMessage ("Ticks %i\t Y %i\t cineticPower %f\n", scrolldataticks[0], scrolldatay[0], cineticPower);
+		//sbMessage ("Ticks %i\t Y %i\t Duration %i\t Speed %f\n", scrolldataticks[1], scrolldatay[1],scrolldataticks[1]-scrolldataticks[0],speed);
 
-		cineticPower *= factor;
-
-		if (currentList != NULL)
+		if (lists[currentList] != NULL)
 		{
-			currentList->onReleased(x,y);
+			lists[currentList]->onReleased(x,y);
 
 			if (!input.leaveZone)
-				input.tapCounter >= 8 ? currentList->onTapped(x,y) : currentList->onClicked(x,y);
+				input.tapCounter >= 8 ? lists[currentList]->onTapped(x,y) : lists[currentList]->onClicked(x,y);
 		}
 
 		if (listShift != 0)
@@ -387,13 +341,13 @@
 		if (fabsf(cineticPower) > 0.0f)
 		{
 			bScrollTimer = true;
-			sbSetTimer(TIMER_SCROLL, refreshRate);
+			sbSetTimer ( TIMER_SCROLL , refreshRate );
 		}
 
 		input.mousePressed = false;
-		input.tapCounter = 0;
+		input.tapCounter   = 0;
 
-		sbKillTimer(TIMER_TAP);
+		sbKillTimer ( TIMER_TAP );
 		
 		redraw();
 	}
@@ -401,15 +355,26 @@
 
 void sbCore::onTimer (const int timer)
 {
-	if (currentList != NULL) currentList->onTimer(timer);
+	if (currentList != sbList::TYPE_NONE && lists[currentList] != NULL)
+		lists[currentList]->onTimer(timer);
 
 	switch (timer)
 	{
+	case TIMER_SAVE_CONFIG:
+		{
+			sbMessage ("Save configs.\n");
+
+			features.save();
+
+			if (options != NULL) options->Save();
+		}
+		break;
+
 	case TIMER_REDRAW:
 		{
 			if ( requestedRedraw )
 			{
-				if ( currentList != NULL ) currentList->onTimer( TIMER_BEFORE_REDRAW );
+				if ( lists[currentList] != NULL ) lists[currentList]->onTimer( TIMER_BEFORE_REDRAW );
 
 				requestedRedraw = false;
 		
@@ -424,9 +389,9 @@
 			{
 				cineticPower *= cineticDamping;
 
-				if (!input.mousePressed && currentList != NULL)
+				if (!input.mousePressed && lists[currentList] != NULL)
 				{
-					if (currentList->scroll(cineticPower) || currentList->needFill)
+					if (lists[currentList]->scroll(cineticPower) || lists[currentList]->needFill)
 						redraw();
 				}
 			}
@@ -483,8 +448,8 @@
 
 	case TIMER_BANNER:
 		{
-			showListBanner = false;
-			sbKillTimer(TIMER_BANNER);
+			showBanner = false;
+			sbKillTimer ( TIMER_BANNER );
 			redraw();
 		}
 		break;
@@ -511,225 +476,124 @@
 	}
 }
 
-void sbCore::switchList (sbList::TYPE to)
+void sbCore::switchList ( sbList::TYPE type )
 {
-	sbList* oldList = currentList;
+	sbList * oldList = lists[currentList];
 
-	sbMessage("switch list %i\n", to);
+	sbMessage("Switch view to : %i\n", type);
 
-	switch (to)
+	switch (type)
 	{
 	case sbList::PIN_NEXT:
-		if (currentList->getNext() != NULL)
+		if (lists[currentList]->getNext() != NULL)
 		{
-			currentList = currentList->getNext();
-
-			if (currentList->type == sbList::TYPE_SELECT_BOOK || currentList->type == sbList::TYPE_SELECT_MODULE)
-			{
-				listNavigation = currentList;
-			}
-			if (currentList->type == sbList::TYPE_MODULE_VIEW)
-			{
-				listModule = currentList;
-			}
+			lists[currentList] = lists[currentList]->getNext();
 		}
-		else if (currentList->type == sbList::TYPE_MODULE_VIEW)
-		{
-			if (currentList->getNext() == NULL)
-				currentList->attach (new sbList(sbList::TYPE_MODULE_VIEW), sbList::PIN_NEXT);
-		
-			listModule = currentList = currentList->getNext();
-		}
+		type = currentList;
 		break;
 
 	case sbList::PIN_PREV:
-		if (currentList->getPrev() != NULL)
+		if (lists[currentList]->getPrev() != NULL)
 		{
-			currentList = currentList->getPrev();
-
-			if (currentList->type == sbList::TYPE_SELECT_BOOK || currentList->type == sbList::TYPE_SELECT_MODULE)
-			{
-				listNavigation = currentList;
-			}
-			if (currentList->type == sbList::TYPE_MODULE_VIEW)
-			{
-				listModule = currentList;
-			}
+			lists[currentList] = lists[currentList]->getPrev();
 		}
-		else if (currentList->type == sbList::TYPE_MODULE_VIEW)
-		{
-			if (currentList->getPrev() == NULL)
-				currentList->attach (new sbList(sbList::TYPE_MODULE_VIEW), sbList::PIN_PREV);
-		
-			currentList = currentList->getPrev();
-		}
+		type = currentList;
 		break;
 
-	case sbList::PIN_PARENT:
-		{
-			sbAssert(currentList->getParent() == NULL);
+	case sbList::TYPE_CURRENT:
+		switchList(currentList);
+		return;
 
-			currentList = currentList->getParent();
-		}
-		break;
+	case sbList::TYPE_NONE:
+		return;
 
-	case sbList::TYPE_SELECT_BOOK:
-		sbAssert(listNavigation == NULL);
-		currentList = listNavigation = listBookSelection;
-		break;
+	default:
+		if (lists[type] == NULL) lists[type] = new sbList (type);
 
-	case sbList::TYPE_SELECT_MODULE:
-		sbAssert(listNavigation == NULL);
-		currentList = listNavigation = listModuleSelection;
-		break;
-		
-	case sbList::TYPE_SEARCH:
-		sbAssert(listNavigation == NULL);
-		currentList = listNavigation = listSearch;
-		break;
+		sbAssert (lists[type] == NULL);
 
-	case sbList::TYPE_NAVIGATION:
-		if (listNavigation == NULL)
+		if (type == sbList::TYPE_MODULE_VIEW && currentModule == NULL)
 		{
-			listBookSelection   = new sbList(sbList::TYPE_SELECT_BOOK);
-			listModuleSelection = new sbList(sbList::TYPE_SELECT_MODULE);
-			listSearch          = new sbList (sbList::TYPE_SEARCH);
-			listNavigation      = listBookSelection;
+			switchList( sbList::TYPE_HOME );
+			return;
 		}
-		currentList = listNavigation;
-		break;
 
-	case sbList::TYPE_HOME:
-		if (listHome == NULL)
+		// fix hollow module view
+		/*if (type == sbList::TYPE_MODULE_VIEW && lists[type]->module == NULL)
 		{
-			listHome = new sbList (sbList::TYPE_HOME);
-			listHome->attach (new sbList(sbList::TYPE_OPTIONS), sbList::PIN_NEXT);
-
-			if (listModule == NULL)
+			if (lists[type]->getNext() != NULL && lists[type]->getNext()->module == currentModule && lists[type]->getNext()->place.Index() == currentVerse.Index())
 			{
-				listModule = new sbList(sbList::TYPE_MODULE_VIEW);
-				listModule->attach(new sbList(sbList::TYPE_MODULE_VIEW), sbList::PIN_NEXT);
-				listModule->attach(new sbList(sbList::TYPE_MODULE_VIEW), sbList::PIN_PREV);
+				lists[type] = lists[type]->getNext();
 			}
-			else
+			else if (lists[type]->getPrev() != NULL && lists[type]->getPrev()->module == currentModule && lists[type]->getPrev()->place.Index() == currentVerse.Index())
 			{
-				sbAssert(true);
+				lists[type] = lists[type]->getPrev();
 			}
-		}
-
-		listHome->attach(listModule, sbList::PIN_PARENT);
-		
-		currentList = listHome;
-		break;
-
-	case sbList::TYPE_MODULE_VIEW:
-		sbAssert(listModule == NULL);
-		
-		currentList = listModule;
-		break;
-
-	case sbList::TYPE_CURRENT:
-		break;
-
-	case sbList::TYPE_NONE:
-		threadDestroy();
-		return;
-
-	default:
-		sbAssert(true);
+			else if (lists[type]->getPrev() != NULL || lists[type]->getNext() != NULL)
+			{
+				sbAssert ( true );
+			}
+		}*/
 	}
-	
-	if (oldList != currentList)
-	{
-		if (currentList == listNavigation)
-			currentList->attach(listModule, sbList::PIN_PARENT);
 
-		cineticPower = 0.0f;
+	currentList = type;
 
-		threadDestroy();
+	threadDestroy();
 
-		if (currentList->type == sbList::TYPE_MODULE_VIEW && currentList->hasModule())
-			threadCreate(currentList);
-	}
+	lists[currentList]->onActivate();
 
-	showListBanner = oldList != NULL && currentList != NULL && oldList->type == sbList::TYPE_MODULE_VIEW && currentList->type == sbList::TYPE_MODULE_VIEW;
+	showBanner = oldList != NULL && lists[currentList] != NULL && oldList->type == sbList::TYPE_MODULE_VIEW && lists[currentList]->type == sbList::TYPE_MODULE_VIEW;
 
-	if ( showListBanner )
-	{
-		sbSetTimer( TIMER_BANNER , 5000 );
-	}
-	else
-	{
-		sbKillTimer( TIMER_BANNER );
-	}
-	
-	currentList->onActivate();
+	if (showBanner) sbSetTimer ( TIMER_BANNER , 5000 ); else sbKillTimer ( TIMER_BANNER );
 
 	redraw();
 }
 
 
-void sbCore::threadMain (bool * abort)
+void sbCore::threadMain ( bool * abort )
 {
-	sbAssert(backgroundList==NULL);
-	backgroundList->updateVerses(abort);
+	sbAssert ( backgroundList == NULL );
+
+	backgroundList->process ( abort );
 }
 
 void sbCore::threadCreate (sbList *list)
 {
+	sbMessage ("threadCreate\n");
+
 	backgroundList   = list;
-	backgroundThread = sbThreadCreate( &this->threadMain );
+	backgroundThread = sbThreadCreate ( & this->threadMain );
 }
 
-void sbCore::threadDestroy()
+void sbCore::threadDestroy ()
 {
-	if ( backgroundThread != NULL ) sbThreadDestroy(backgroundThread);
+	sbMessage ("threadDestroy\n");
+
+	if ( backgroundThread != NULL )
+	{
+		sbThreadDestroy( backgroundThread );
 	
-	backgroundThread = NULL;
-	backgroundList   = NULL;
+		backgroundThread = NULL;
+		backgroundList   = NULL;
+	}
 }
 
-void sbCore::controlPressed (sbControl::TYPE type)
+void sbCore::controlPressed ( sbControl::TYPE type ) // REMOVE
 {
-	switch (type)
+	switch ( type )
 	{
 	default:
-		if (!currentList->onControl(type))
-			sbAssert(true);
+		if (!lists[currentList]->onControl(type)) sbAssert(true);
 	}
 }
 
 void sbCore::onChar ( TCHAR character )
 {
-	if ( currentList != NULL ) currentList->onChar(character);
+	if ( lists[currentList] != NULL ) lists[currentList]->onChar( character );
 }
 
 void sbCore::onKey ( int key , bool down )
 {
-	if ( currentList != NULL && down ) currentList->onKey ( key );
+	if ( lists[currentList] != NULL && down ) lists[currentList]->onKey ( key );
 }
 
-sbCollection * sbCore::getCollection ( const char * name )
-{
-	if ( name == "bookmarks" || !strcmp(name,"bookmarks") )
-	{
-		return & collections["bookmarks"];
-	}
-	else if ( name == "readings" || !strcmp(name,"readings") )
-	{
-		return & collections["readings"];
-	}
-	else if ( name == "history" || !strcmp(name,"history") )
-	{
-		return & collections["history"];
-	}
-	else
-	{
-		// check verse lists
-		// check tag lists
-
-		sbAssert ( "Attempt to get wrong verse collection" );
-	}
-
-	return NULL;
-}

Modified: trunk/src/SlideBible/sbCore.h
===================================================================
--- trunk/src/SlideBible/sbCore.h	2010-01-07 20:57:03 UTC (rev 224)
+++ trunk/src/SlideBible/sbCore.h	2010-03-08 21:22:28 UTC (rev 225)
@@ -21,8 +21,7 @@
 #include "sbTheme.h"
 #include "sbControl.h"
 #include "sbList.h"
-#include "sbCollection.h"
-#include "sbBase.h"
+#include "sbFeatures.h"
 
 class sbCore
 {
@@ -39,8 +38,8 @@
 			COUNT
 		};
 		
-		sbRenderContext          hdc;
-		sbBitmap                 bitmap;
+		sbSurface          hdc;
+		//sbBitmap                 bitmap;
 		sbRect                   rect;
 		
 		bool                     needRedraw;
@@ -49,14 +48,11 @@
 	
 	struct INPUT
 	{
-		INPUT () : block ( false ) , startx ( 0 ) , starty ( 0 ) , tapCounter ( 0 ) { ; }
+		INPUT () { memset (this,0,sizeof(INPUT)); }
 
 		bool                     mousePressed;
 		
-		int                      startx;
-		int                      starty;
-		int                      lastx;
-		int                      lasty;
+		sbPoint                  start, last;
 
 		bool                     leaveZone;
 		int                      tapCounter;
@@ -72,13 +68,14 @@
 		TIMER_REDRAW,
 		TIMER_BEFORE_REDRAW, // send before redraw view
 		TIMER_SLIDE,
+		TIMER_SAVE_CONFIG,
 	};
 
 	sbCore();
    ~sbCore();
 	
 	void                         onMouse          ( int x, int y, const int state );
-	void                         onPaint          ( sbRenderContext rc );
+	void                         onPaint          ( sbSurface rc );
 	void                         onTimer          ( const int timer );
 	void                         onChar           ( TCHAR c );
 	void                         onKey            ( int key , bool down );
@@ -86,15 +83,14 @@
 	void                         redraw           ( );
 
 	const sbTheme *              getTheme         ( )                    {return &theme;}
-	sword::SWMgr *               getSword         ( )                    {return mpSwordMgr;}
-	sword::SWConfig *            getOptions       ( )                    {return mpOptions;}
+	sword::SWMgr *               getSword         ( )                    {return swordMgr;}
+	sword::SWConfig *            getOptions       ( )                    {return options;}
 	const SURFACE *              getSurface       ( SURFACE::TYPE type ) {return &surfaces[type];}
 	const INPUT *                getInput         ( )                    {return &input;}
-	sbCollection *               getCollection    ( const char * name );
 	
 	void                         switchList       ( sbList::TYPE to );
 
-	void                         threadCreate     ( sbList *list );
+	void                         threadCreate     ( sbList * list );
 	void                         threadDestroy    ( );
 	
 	void                         controlPressed   ( sbControl::TYPE type );
@@ -105,19 +101,15 @@
 	static void                  threadMain (bool * abort);
 	static sbList               *backgroundList;
 
-	sbList                      *currentList;
+	sbList::TYPE                 currentList;
+	sbList::TYPE                 overlayList;
 
-	sbList                      *listModule;
-	sbList                      *listNavigation;
-	sbList                      *listModuleSelection;
-	sbList                      *listBookSelection;
-	sbList                      *listSearch;
-	sbList                      *listHome;
+	std::map < sbList::TYPE , sbList * >   lists;
 
 	int                          listShift;
 
 	float                        cineticPower;
-	int                          cineticTicks;
+	//int                          cineticTicks;
 
 	INPUT                        input;
 
@@ -130,26 +122,36 @@
 
 	sbRect                       rClient;
 	
-	SURFACE                      surfaces[SURFACE::COUNT];
+	SURFACE                      surfaces[SURFACE::COUNT]; // CUT
 
-	sword::SWMgr                *mpSwordMgr;
-	sword::SWConfig             *mpOptions;
+	sword::SWMgr                *swordMgr;
+	sword::SWConfig             *options;
 
-	std::map <const char*, sbCollection> collections;
-
 	float                        cineticDamping;
 	float                        cineticFactor;
 	int                          refreshRate;
 
-	bool                         showListBanner;
+	bool                         showBanner;
 
 public:
+
+	sbFeatures                   features;
+
+
 	unsigned int                 scrollStep;
 	unsigned int                 versesMax;
 	unsigned int                 versesOptimal;
 
-	sword::SWModule * const      defaultModule;
-	sword::SWModule             *currentModule;
+	// Core shared data
+	sword::SWModule             *defaultModule;     // base module for all new module views
+	sword::SWModule             *currentModule;     // module of active list, null if module view was not activated
+
+	sword::VerseKey              currentVerse;      // last place
+
+	bool                         goVerse;           // necessity of transition, with currentVerse and currentModule
+	int                          goReading;         // need attach reading on activate, default -1
+
+	//int                          readingRemoved;    // should be broadcast message for all lists, default -1
 };
 
 extern sbCore * Core;

Added: trunk/src/SlideBible/sbFeatures.cpp
===================================================================
--- trunk/src/SlideBible/sbFeatures.cpp	                        (rev 0)
+++ trunk/src/SlideBible/sbFeatures.cpp	2010-03-08 21:22:28 UTC (rev 225)
@@ -0,0 +1,246 @@
+/*************************************************************************
+* sbFeatures.cpp - engine for per-verse data
+*
+* author: Konstantin Maslyuk "Kalemas" mailto:kalemas at mail.ru
+*
+* This program is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License as published by the
+* Free Software Foundation version 2.
+*
+* This program is distributed in the hope that it will be useful, but
+* WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* General Public License for more details.
+************************************************************************/
+
+#include "sbCore.h"
+#include "sbFeatures.h"
+
+#include "platform\xmlParser.h"
+
+#pragma warning(disable : 4018)
+
+const int sbFeatures::revision = 1;
+
+sbFeatures::sbFeatures()
+{
+	;
+}
+
+sbFeatures::~sbFeatures()
+{
+	for (int i=0; i<strings.size(); i++) free((char*)strings[i]);
+}
+
+const char * sbFeatures::holdString (const char * string)
+{
+	if (string == NULL || strlen(string) == 0) return NULL;
+
+	for (int i=0; i < strings.size(); i++)
+	{
+		if (!strcmp(string,strings[i])) return strings[i];
+	}
+
+	strings.push_back(_strdup(string));
+
+	return strings.back();
+}
+
+void sbFeatures::load ()
+{
+	if (Core->defaultModule == NULL) return;
+
+	bool   firstRun = false;
+	FILE * file     = fopen (".\\features.xml","rb");
+
+	if (file != NULL)
+	{
+		fclose(file);
+
+		int loadRevision = 0;
+		XMLNode xml = XMLNode::openFileHelper(".\\features.xml");
+		
+		if (!xml.getChildNode("Features").isEmpty())
+		{
+			const char * text = xml.getChildNode("Features").getAttribute("revision");
+			loadRevision = atoi(text);
+		}
+
+		if (loadRevision == revision)
+		{
+			XMLNode xr = xml.getChildNode("Features").getChildNode("Readings");
+
+			if (!xr.isEmpty())
+			{
+				readings.reserve(xr.nChildNode("reading")+8);
+
+				for (int i = 0; i < xr.nChildNode("reading"); i++)
+				{
+					XMLNode n = xr.getChildNode("reading",i);
+					Reading r;
+
+					//const char * cp = n.getAttribute("created");
+					//long lp         = atol(n.getAttribute("created"));
+					//time_t tp       = atol(n.getAttribute("created"));
+
+					r.created = atol(n.getAttribute("created"));
+					r.visited = atol(n.getAttribute("visited"));
+					r.module  = holdString(n.getAttribute("module"));
+					r.place   = atol(n.getAttribute("place"));
+
+					readings.push_back(r);
+				}
+			}
+
+			XMLNode xh = xml.getChildNode("Features").getChildNode("History");
+
+			if (!xh.isEmpty())
+			{
+				history.reserve(xh.nChildNode("history")+64);
+
+				for (int i = 0; i < xh.nChildNode("history"); i++)
+				{
+					XMLNode n = xh.getChildNode("history",i);
+					History h;
+
+					h.module     = holdString(n.getAttribute("module"));
+					h.placeStart = atol(n.getAttribute("placeStart"));
+					h.placeEnd   = atol(n.getAttribute("placeEnd"));
+					h.visitStart = atol(n.getAttribute("visitStart"));
+					h.visitEnd   = atol(n.getAttribute("visitEnd"));
+
+					history.push_back(h);
+				}
+			}
+		}
+		else
+		{
+			firstRun = true;
+		}
+	}
+	else
+	{
+		firstRun = true;
+	}
+
+	if ( firstRun )
+	{
+		sword::VerseKey workKey = Core->defaultModule->getKey();
+
+		readings.resize(2);
+
+		time(&readings[0].created);
+		time(&readings[0].visited);
+		readings[0].module = Core->defaultModule->Name();
+		workKey = "Gen 1:1";
+		readings[0].place = workKey.Index();
+		
+		time(&readings[1].created);
+		time(&readings[1].visited);
+		readings[1].module = Core->defaultModule->Name();
+		workKey = "Matt 1:1";
+		readings[1].place = workKey.Index();
+	}
+
+	// delete history for unknown modules
+	/*for (int i=history.size()-1; i>=0; i--)
+	{
+		if (Core->getSword()->getModule(history[i].module) == NULL) history.erase(history.begin()+i);
+	}*/
+}
+
+void sbFeatures::save()
+{
+	if (Core->defaultModule == NULL) return;
+
+	XMLNode xml = XMLNode::createXMLTopNode("xml",true);
+
+	char buf [32];
+
+	xml.addAttribute("version","1.0");
+
+	XMLNode xf = xml.addChild("Features");
+
+	_itoa(revision,buf,10);
+	xf.addAttribute("revision",buf);
+
+	if (readings.size() > 0)
+	{
+		XMLNode xr = xf.addChild("Readings");
+
+		for (int i=0; i < readings.size(); i++)
+		{
+			XMLNode n = xr.addChild("reading");
+
+			_ltoa(readings[i].created,buf,10);                n.addAttribute("created",buf);
+			_ltoa(readings[i].visited,buf,10);                n.addAttribute("visited",buf);
+			_ltoa(readings[i].place,buf,10);                  n.addAttribute("place",buf);
+			n.addAttribute("module",readings[i].module);
+		}
+
+		XMLNode xh = xf.addChild("History");
+
+		for (int i=0; i < history.size(); i++)
+		{
+			XMLNode n = xh.addChild("history");
+
+			_ltoa(history[i].placeStart,buf,10);              n.addAttribute("placeStart",buf);
+			_ltoa(history[i].placeEnd,buf,10);                n.addAttribute("placeEnd",buf);
+			_ltoa(history[i].visitStart,buf,10);              n.addAttribute("visitStart",buf);
+			_ltoa(history[i].visitEnd,buf,10);                n.addAttribute("visitEnd",buf);
+			n.addAttribute("module",history[i].module);
+		}
+	}
+
+	xml.writeToFile(".\\features.xml");
+}
+
+// return history id
+// todo, check for previous history item
+int sbFeatures::addHistory ( const char * module, long place )
+{
+	//sbMessage ("sbFeatures::addHistory module %s place %i\n",module,place);
+
+	History h;
+	time(&h.visitStart);
+	h.visitEnd   = h.visitStart;
+	h.module     = module;
+	h.placeStart = h.placeEnd = place;
+
+	history.push_back(h);
+
+	return history.size()-1;
+}
+
+void sbFeatures::updateHistory ( int id, long place )
+{
+	//sbMessage ("sbFeatures::updateHistory id %i place %i\n",id,place);
+
+	if (place < history[id].placeStart)
+	{
+		history[id].placeStart = place;
+	}
+	else if (place > history[id].placeEnd)
+	{
+		history[id].placeEnd = place;
+	}
+
+	time(&history[id].visitEnd);
+}
+
+void sbFeatures::updateReading( int id, const char * module, long place )
+{
+	//sbMessage ("sbFeatures::updateReading id %i module %s place %i\n",id,module,place);
+
+	if (module != readings[id].module)
+	{
+		readings[id].place = place;
+		time(&readings[id].visited);
+		readings[id].module = module;
+	}
+	else if (place > readings[id].place)
+	{
+		readings[id].place = place;
+		time(&readings[id].visited);
+	}
+}
\ No newline at end of file

Added: trunk/src/SlideBible/sbFeatures.h
===================================================================
--- trunk/src/SlideBible/sbFeatures.h	                        (rev 0)
+++ trunk/src/SlideBible/sbFeatures.h	2010-03-08 21:22:28 UTC (rev 225)
@@ -0,0 +1,73 @@
+/*************************************************************************
+* sbFeatures.h - engine for per-verse data
+*
+* author: Konstantin Maslyuk "Kalemas" mailto:kalemas at mail.ru
+*
+* This program is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License as published by the
+* Free Software Foundation version 2.
+*
+* This program is distributed in the hope that it will be useful, but
+* WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* General Public License for more details.
+************************************************************************/
+
+#ifndef SBFEATURES_H
+#define SBFEATURES_H
+
+#include <vector>
+#include <time.h>
+
+class sbFeatures
+{
+public:
+	sbFeatures ();
+	~sbFeatures();
+
+	typedef struct Reading
+	{
+		const char               * module;
+		long                       place;
+		time_t                     created;
+		time_t                     visited;
+	};
+
+	typedef struct Bookmark
+	{
+		//const TCHAR              * name;
+		const char               * module;
+		long                       place;
+//		time_t                     created;
+//		time_t                     visited;
+	};
+
+	typedef struct History
+	{
+		const char               * module;
+		long                       placeStart;
+		long                       placeEnd;
+		time_t                     visitStart;
+		time_t                     visitEnd;
+	};
+
+	int                       addHistory     ( const char * module, long place );
+	void                      updateHistory  ( int id, long place );
+	void                      updateReading  ( int id, const char * module, long place );
+
+	void                      save ();
+	void                      load ();
+
+	const char *              holdString     ( const char * string );
+
+	static const int          revision;
+
+	std::vector<Reading>      readings;
+	std::vector<History>      history;
+
+private:
+	std::vector<const char*>  strings;
+
+};
+
+#endif

Modified: trunk/src/SlideBible/sbItem.cpp
===================================================================
--- trunk/src/SlideBible/sbItem.cpp	2010-01-07 20:57:03 UTC (rev 224)
+++ trunk/src/SlideBible/sbItem.cpp	2010-03-08 21:22:28 UTC (rev 225)
@@ -160,7 +160,7 @@
 	}
 }
 
-void sbItem::setText ( const TCHAR* _text_ )
+void sbItem::setText ( const TCHAR * _text_ )
 {
 	sbPoint sz;
 	int  lineWidth = 0, length = _tcslen( _text_ );
@@ -249,7 +249,7 @@
 			
 			if (sz.y > lines.back().height)
 			{
-				sbAssert ((sz.y >= 30) && (type == TYPE_VERSE));
+				sbAssert ((sz.y >= Core->getTheme()->scale/8) && (type == TYPE_VERSE));
 				lines.back().height = (unsigned short) sz.y;
 			}
 			

Modified: trunk/src/SlideBible/sbItem.h
===================================================================
--- trunk/src/SlideBible/sbItem.h	2010-01-07 20:57:03 UTC (rev 224)
+++ trunk/src/SlideBible/sbItem.h	2010-03-08 21:22:28 UTC (rev 225)
@@ -21,6 +21,37 @@
 
 #include "sbBase.h"
 
+/*
+	sbItem should have type,                    content, and parameter
+		verse                                 verse_id (indicates its position in Bible)
+		goVerse                               verse_id
+		title                                 no
+		expanding_button                      what_to_expand
+		text                                  no
+		module_select                         module_id
+		book_select                           verse_id
+		text_field
+		goView                                view_type
+		chapterTitle, bookTitle            verse_id
+
+	Examples of items:
+
+	Mattew 14:11
+	   yestarday
+
+	-- Readings ----------------|  V  |--
+
+	1 In the begining God created heaven
+	  and earth.  
+	               2 After all He created
+	  man and woman  
+	                 3 And then they have
+	  sin...
+
+
+	  next,prev,child
+*/
+
 class sbItem
 {
 public:
@@ -51,10 +82,13 @@
 		TYPE_BUTTON_BOOKMARK_DELETE,
 		TYPE_BUTTON_BOOKMARK_POSITION,
 		TYPE_BUTTON_ADD_BOOKMARK,
-		TYPE_BUTTON_ADD_FAVORITE
+		TYPE_BUTTON_ADD_FAVORITE,
+		TYPE_GOTO_MODULES,
+		TYPE_GO_HISTORY,
+		TYPE_GO_READING
 	};
 	
-	sbItem( sbItem::TYPE type, const TCHAR *text, int width, long index = -1, int number = -1 );
+	sbItem( sbItem::TYPE type, const TCHAR * text, int width, long index = -1, int number = -1 );
 	~sbItem();
 
 	const TYPE                    type;

Modified: trunk/src/SlideBible/sbList.cpp
===================================================================
--- trunk/src/SlideBible/sbList.cpp	2010-01-07 20:57:03 UTC (rev 224)
+++ trunk/src/SlideBible/sbList.cpp	2010-03-08 21:22:28 UTC (rev 225)
@@ -1,5 +1,5 @@
 /*************************************************************************
- * sbList.cpp - items scrolling container
+ * sbList.cpp - current screen state controller
  *
  * author: Konstantin Maslyuk "Kalemas" mailto:kalemas at mail.ru
  *
@@ -13,24 +13,28 @@
  * General Public License for more details.
  ************************************************************************/
 
+#include <time.h>
+
+#include <swversion.h>
+
 #include "sbCore.h"
 #include "sbList.h"
-#include <swversion.h>
 
 #pragma warning ( disable : 4018 )
+#pragma warning ( disable : 4996 )
 
-sbList::sbList ( sbList::TYPE _type_ )
-: type ( _type_ )
+sbList::sbList ( sbList::TYPE _type_ ) : type ( _type_ )
 {
 	itemCurrent = itemHover = itemEdit = itemSelected = NULL;
 
-	displaceHeight     = 0;
-	displacePart       = 0.0f;
+	displace     = 0.0f;
 	
 	module             = NULL;
 
-	next = prev = parent = child = NULL;
+	next = prev = NULL;
 
+	attachedReading = attachedHistory = -1;
+
 	rect = &Core->getSurface(sbCore::SURFACE::TYPE_LIST)->rect;
 
 	verseFirst    = verseLast      = NULL;
@@ -40,71 +44,41 @@
 
 	switch(type)
 	{
-	case TYPE_SEARCH:
 	case TYPE_SELECT_BOOK:
 	case TYPE_SELECT_MODULE:
 		{
 			addControl(sbControl::TYPE_OPEN_MODULE_SELECTION);
 			addControl(sbControl::TYPE_OPEN_BOOK_SELECTION);
-			addControl(sbControl::TYPE_OPEN_SEARCH);
 			addControl(sbControl::TYPE_CLOSE);
-		
-			// fill with items in sbList::setKey
 		}
 		break;
 
 	case TYPE_MODULE_VIEW:
 		{
-			addControl(sbControl::TYPE_OPEN_NAVIGATION);
-			addControl(sbControl::TYPE_MODE_ADD_STAR);
-			addControl(sbControl::TYPE_OPEN_SEARCH);
+			addControl(sbControl::TYPE_OPEN_NAVIGATION_LIST);
+			addControl(sbControl::TYPE_LIST_SPACE);
 			addControl(sbControl::TYPE_OPEN_HOME);
 
-			if (module != NULL)
-			{
-				addControl(sbControl::TYPE_CAN_SWITCH_LEFT);
-				addControl(sbControl::TYPE_CAN_SWITCH_RIGHT);
-
-				setKey(module->getKey());
-			}
-
 			listEndConstructed = listStartConstructed = false;
 		}
 		break;
 
-	case TYPE_OPTIONS:
-		{
-			TCHAR vesionText[64];
-			_sntprintf(vesionText,64,L"Current SWORD version :\n%S",sword::SWVersion::currentVersion.getText());
-			itemCurrent = new sbItem (sbItem::TYPE_TEXT, vesionText, rect->width()), sbItem::NEXT;
-			itemCurrent->center = true;
-
-			rect = &Core->getSurface(sbCore::SURFACE::TYPE_WHOLE)->rect;
-		}
-		break;
-
 	case TYPE_READINGS:
 	case TYPE_HISTORY:
 	case TYPE_BOOKMARKS:
 		{
 			addControl(sbControl::TYPE_WIDE_CLOSE);
-
-			// fill with items in sbList::onActivate
 		}
 		break;
 
 	case TYPE_HOME:
 		{
+			addControl(sbControl::TYPE_OPEN_NAVIGATION);
 			addControl(sbControl::TYPE_OPEN_HISTORY);
-			addControl(sbControl::TYPE_OPEN_BOOKMARKS);
-			addControl(sbControl::TYPE_OPEN_READINGS);
-			addControl(sbControl::TYPE_BUTTON_CLOSE);
-
-			// fill with items in sbList::onActivate
+			addControl(sbControl::TYPE_EXIT);
 		}
 		break;
 
-
 	default:
 		sbAssert ( true );
 	}
@@ -118,21 +92,11 @@
 	{
 		next->prev = prev;
 	}
-	else
-	{
-		//if (type != TYPE_MODULE_VIEW)
-		//	addControl(sbControl::TYPE_CAN_SWITCH_RIGHT, false);
-	}
 
 	if (prev != NULL)
 	{
 		prev->next = next;
 	}
-	else
-	{
-		//if (type != TYPE_MODULE_VIEW)
-		//	addControl(sbControl::TYPE_CAN_SWITCH_LEFT, false);
-	}
 
 	for (int i=0; i < controls.size(); i++) delete controls[i];
 }
@@ -171,216 +135,11 @@
 		
 		break;
 
-	case PIN_PARENT:
-		if ( type == TYPE_SELECT_BOOK || type == TYPE_SELECT_MODULE )
-		{
-			parent = list;
-			
-			module = list->module == NULL ? Core->currentModule : list->module;
-			
-			setKey ( module->getKey() );
-		}
-		else if ( type == TYPE_HOME || type == TYPE_SEARCH )
-		{
-			parent = list;
-		}
-		else
-			sbAssert ( true );
-
-		break;
-
 	default:
 		sbAssert(true);
 	}
 }
 
-/*   sbList::setKey
- *   set current position of list module
- */
-void sbList::setKey ( sword::VerseKey verse )
-{
-	sbMessage("sbList setKey: type:%i module:%s : %s %i:%i\n", type, (module == NULL ? "null" : module->Name()), verse.getBookName(), verse.getChapter(), verse.getVerse());
-
-	switch (type)
-	{
-	case TYPE_SELECT_MODULE:
-		{
-			int id = 0;
-
-			clear();
-
-			for (sword::ModMap::iterator it = Core->getSword()->Modules.begin(); it != Core->getSword()->Modules.end(); it++)
-			{
-				sword::SWModule *mod = (*it).second;
-
-				if (!strcmp(mod->Type(), "Biblical Texts"))
-				{
-					TCHAR *text = new TCHAR[strlen(mod->Description())+1];
-					for(int i=0; i<=strlen(mod->Description()); i++)
-						text[i] = mod->Description()[i];
-
-					sbItem *item = new sbItem (sbItem::TYPE_BUTTON_SELECTION_MODULE, text, rect->width(), (long)mod);
-					item->center = true;
-
-					delete [] text;
-
-					if (parent != NULL && parent->module == mod) item->highlighted = true;
-
-					if (itemCurrent == NULL)
-					{
-						itemCurrent = item;
-					}
-					else
-					{
-						itemCurrent->attach (item, sbItem::NEXT);
-						itemCurrent = itemCurrent->next;
-					}
-				}
-
-				id++;
-			}
-
-			id = 0;
-
-			for (sword::ModMap::iterator it = Core->getSword()->Modules.begin(); it != Core->getSword()->Modules.end(); it++)
-			{
-				sword::SWModule *mod = (*it).second;
-
-				if (!strcmp(mod->Type(), "Commentaries"))
-				{
-					TCHAR *text = new TCHAR[strlen(mod->Description())+1];
-					for(int i=0;i<=strlen(mod->Description()); i++)
-						text[i] = mod->Description()[i];
-
-					sbItem *item = new sbItem (sbItem::TYPE_BUTTON_SELECTION_MODULE, text, rect->width(), (long)mod);
-					item->center = true;
-
-					delete [] text;
-
-					if (parent != NULL && parent->module == mod) item->highlighted = true;
-
-					if (itemCurrent == NULL)
-					{
-						itemCurrent = item;
-					}
-					else
-					{
-						itemCurrent->attach (item, sbItem::NEXT);
-						itemCurrent = itemCurrent->next;
-					}
-				}
-
-				id++;
-			}
-
-			while (itemCurrent->prev != NULL)
-				itemCurrent = itemCurrent->prev;
-		}
-		break;
-
-	case TYPE_SELECT_BOOK:
-		{
-			sbItem * setItem = NULL;
-
-			sbAssert (module == NULL);
-			
-			sword::VerseKey workKey = module->getKey();
-
-			const char * moduleBook = workKey.getBookName();
-
-			clear();
-
-			workKey.setPosition(sword::TOP);
-
-			while ( true )
-			{
-				const char * book = workKey.getBookName();
-
-				TCHAR * text = new TCHAR [strlen(book)+1];
-				
-				mbstowcs(text,book,strlen(book)+1);
-
-				sbItem *item = new sbItem (sbItem::TYPE_BUTTON_SELECTION_BOOK, text, rect->width(), workKey.Index());
-				item->center = true;
-
-				delete [] text;
-
-				if (moduleBook == book)
-				{
-					setItem = item;
-				}
-				
-				if (itemCurrent == NULL)
-				{
-					itemCurrent = item;
-				}
-				else
-				{
-					itemCurrent->attach (item, sbItem::NEXT);
-					itemCurrent = itemCurrent->next;
-				}
-
-				// next book
-				int b = workKey.getBook();
-
-				workKey.setBook(workKey.getBook()+1);
-
-				if (b == workKey.getBook()) break;
-			}
-
-			if (setItem != NULL)
-			{
-				itemCurrent = setItem;
-			}
-			else
-			{
-				while (itemCurrent->prev != NULL)
-					itemCurrent = itemCurrent->prev;
-			}
-		}
-		break;
-
-	case TYPE_MODULE_VIEW:
-		{
-			if (module == NULL) module = Core->defaultModule;
-			
-			sbAssert(module == NULL);
-
-			//sbAssert(strcmp(verse.getVersificationSystem(),module->getConfigEntry("Versification")));
-
-			if (next == NULL) attach (new sbList(sbList::TYPE_MODULE_VIEW), sbList::PIN_NEXT);
-			if (prev == NULL) attach (new sbList(sbList::TYPE_MODULE_VIEW), sbList::PIN_PREV);
-
-			addControl(sbControl::TYPE_CAN_SWITCH_LEFT);
-			if (prev != NULL) prev->addControl(sbControl::TYPE_CAN_SWITCH_RIGHT);
-
-			addControl(sbControl::TYPE_CAN_SWITCH_RIGHT);
-			if (next != NULL) next->addControl(sbControl::TYPE_CAN_SWITCH_LEFT);
-
-			clear();
-		
-			key.setVersificationSystem( module->getConfigEntry("Versification") );
-
-			key.setText ( verse.getText() );
-
-			displaceHeight = rect->height()*2/5;
-
-			// adding blank verses starts automatically in sbList::onTimer(sbCore::TIMER_BEFORE_REDRAW)
-			// filling with text occurs in sbList::updateVerses
-
-			Core->redraw();
-
-			// update collections
-			sbCollection::item * mark = Core->getCollection("history")->add(&key);
-			time_t now; time(&now); mark->visited = now; mark->visits++;
-		}
-		break;
-
-	default:
-		sbAssert(true);
-	}
-}
-
 /*   sbList::clear
  *   empty list from items
  */
@@ -399,7 +158,7 @@
 		verseLast      = NULL;
 		versesForward  = 0;
 		versesBackward = 0;
-		displaceHeight = 0;
+		displace       = 0;
 
 		if (type == TYPE_MODULE_VIEW) listStartConstructed = listEndConstructed = false;
 	}
@@ -408,13 +167,13 @@
 /*   sbList::render
 *   draw list
 */
-void sbList::render ( sbRenderContext hdc , bool showPlace )
+void sbList::render ( sbSurface hdc , bool showPlace )
 {
 	sbItem *oldItem , *workItem = itemCurrent;
 	sbRect workRect;
-	int screenHeight = displaceHeight;
+	int screenHeight = displace;
 
-	Core->getTheme()->drawElement( hdc, rect, sbTheme::ELEMENT::BACKGROUND );
+	Core->getTheme()->drawElement ( hdc, rect, sbTheme::ELEMENT::BACKGROUND );
 
 	while ( true )
 	{
@@ -426,13 +185,13 @@
 
 		if (Core->getTheme()->ListSeparatorHeight > 0 && workItem->prev == NULL)
 		{
-			workRect = * rect;
+			workRect        = *rect;
 			workRect.bottom = screenHeight;
 			workRect.top    = workRect.bottom - Core->getTheme()->ListSeparatorHeight;
 			Core->getTheme()->drawElement(hdc, &workRect, sbTheme::ELEMENT::SEPARATOR);
 		}
 
-		workRect = * rect;
+		workRect       = *rect;
 		workRect.right = 0;
 
 		// horizontal parse
@@ -554,7 +313,7 @@
 	if ( showPlace && module != NULL )
 	{
 		sbPoint      ks;
-		const char * kt = key.getShortText();
+		const char * kt = place.getShortText();
 		int          kl = strlen ( kt );
 		TCHAR      * kw = new TCHAR [ kl + 1 ];
 		const char * mt = module->Description();
@@ -568,7 +327,7 @@
 		sbSelectFont (hdc, Core->getTheme()->styles[sbTheme::STYLE::CAPTION].font );
 		ks = sbGetTextExtent (Core->getTheme()->styles[sbTheme::STYLE::CAPTION].font, kw, kl);
 
-		sbRect tempRect ((rect->right-ks.x)/2, (Core->getTheme()->size/6)-(ks.y/2), (rect->right-ks.x)/2+ks.x, (Core->getTheme()->size/6)-(ks.y/2)+ks.y);
+		sbRect tempRect ((rect->right-ks.x)/2, (Core->getTheme()->scale/6)-(ks.y/2), (rect->right-ks.x)/2+ks.x, (Core->getTheme()->scale/6)-(ks.y/2)+ks.y);
 
 		sbSelectFont ( hdc, Core->getTheme()->styles[sbTheme::STYLE::DESCRIPTION].font );
 
@@ -599,12 +358,15 @@
 
 		sbSelectFont ( hdc, Core->getTheme()->styles[sbTheme::STYLE::DESCRIPTION].font );
 		sbDrawText ( hdc, workRect.left, workRect.top + Core->getTheme()->styles[sbTheme::STYLE::CAPTION].size , mw, mc );
+
+		delete [] kw;
+		delete [] mw;
 	}
 
-	if (displaceHeight >= 0)
+	if (displace >= 0)
 	{
-		needScroll = -displaceHeight;
-		needFill = displaceHeight != 0 || screenHeight < rect->height();
+		needScroll = -displace;
+		needFill = displace != 0 || screenHeight < rect->height();
 	}
 	else if (screenHeight < rect->height())
 	{
@@ -629,33 +391,29 @@
 {
 	if (itemCurrent == NULL) return false;
 
-	if (abs((int)(amount+displacePart)) < Core->scrollStep)
-	{
-		displacePart += amount;
-		return false;
-	}
+	int oldDisplace = displace;
 
-	amount += displacePart;
-	displacePart = amount - (int)amount;
-
 	// don't allow scroll further then list is
-	if (amount < 0 && itemCurrent->next == NULL && itemCurrent->height+Core->getTheme()->ListSeparatorHeight+displaceHeight+amount < 0)
+	if (amount < 0 && itemCurrent->next == NULL && itemCurrent->height+Core->getTheme()->ListSeparatorHeight+displace+amount < 0)
 	{
-		amount = -(itemCurrent->height+Core->getTheme()->ListSeparatorHeight+displaceHeight);
+		amount = -(itemCurrent->height+Core->getTheme()->ListSeparatorHeight+displace);
 		sbAssert (amount > 0);
 	}
 	if (amount > 0 && itemCurrent->prev == NULL)
 	{
-		amount = min(amount, rect->height()-displaceHeight);
+		amount = min(amount, rect->height()-displace);
 		sbAssert(amount < 0);
 	}
 
-	sbAssert (fabs(amount) > rect->height());
+	if ( fabs(amount) > rect->height()/3 )
+	{
+		amount = amount > 0 ? rect->height()/3 : -rect->height()/3;
+	}
+	
+	displace += amount;
 
-	if ((int)amount == 0) return false;
+	if ( (int)displace == (int)oldDisplace ) return false;
 
-	displaceHeight += (int)amount;
-
 	return true;
 }
 
@@ -667,7 +425,7 @@
 	if (itemCurrent == NULL) return NULL;
 
 	sbItem* i = itemCurrent;
-	int top = displaceHeight;
+	int top = displace;
 
 	while (i != NULL && top < rect->height())
 	{
@@ -703,13 +461,24 @@
 {
 	if (Core->getInput()->block) return;
 
+	// if over control
+	for(int i=controls.size()-1; i>=0; i--) if (controls[i]->hit(x,y)) return;
+
 	itemHover = getItem(x,y);
 
 	if (itemHover != NULL)
 	{
 		if (itemHover->type == sbItem::TYPE_VERSE)
-			key.Index(itemHover->index);
+		{
+			// update current verse
+			place.Index(itemHover->index);
 
+			Core->currentVerse.copyFrom ( place );
+
+			if (attachedReading >= 0) Core->features.updateReading(attachedReading,module->Name(),place.Index());
+			if (attachedHistory >= 0) Core->features.updateHistory(attachedHistory,place.Index());
+		}
+
 		Core->redraw();
 	}
 }
@@ -744,25 +513,37 @@
 
 	if (Core->getInput()->block) return;
 
-	sbItem *item = getItem(x,y);
+	sbItem * item = getItem(x,y);
 
 	if (item == NULL) return;
 
-	if (itemEdit != NULL && item != itemEdit)
-		setEditMode(false);
+	if (itemEdit != NULL && item != itemEdit) setEditMode (false);
 
 	switch (item->type)
 	{
-	case sbItem::TYPE_BUTTON_BOOKMARK:
+	case sbItem::TYPE_GOTO_MODULES:
 		{
-			sbAssert(parent == NULL);
-			sbAssert(parent->type != sbList::TYPE_MODULE_VIEW);
+			Core->switchList(sbList::TYPE_MODULE_VIEW);
+		}
+		break;
 
-			sword::VerseKey workKey ( Core->defaultModule->getKey() );
+	case sbItem::TYPE_GO_HISTORY:
+		{
+			Core->goVerse       = true;
+			Core->currentModule = Core->getSword()->getModule(Core->features.history[item->index].module);
+			Core->currentVerse.copyFrom (Core->currentModule->getKey());
+			Core->currentVerse.Index ( Core->features.history[item->index].placeEnd );
 
-			workKey.Index( item->index );
+			Core->switchList(sbList::TYPE_MODULE_VIEW);
+		}
+		break;
 
-			parent->setKey( workKey );
+	case sbItem::TYPE_BUTTON_BOOKMARK:
+		{
+			Core->goVerse       = true;
+			Core->currentModule = Core->defaultModule;
+			Core->currentVerse.copyFrom(Core->defaultModule->getKey());
+			Core->currentVerse.Index ( item->index );
 
 			Core->switchList(sbList::TYPE_MODULE_VIEW);
 		}
@@ -770,106 +551,79 @@
 
 	case sbItem::TYPE_BUTTON_SELECTION_BOOK:
 		{
-			if (parent == NULL)
+			if (item->next != NULL && item->next->type == sbItem::TYPE_BUTTON_SELECTION_CHAPTER)
 			{
-				sbAssert(parent != NULL);
+				// remove chapters
+				while (item->next != NULL && item->next->type == sbItem::TYPE_BUTTON_SELECTION_CHAPTER)
+					delete item->next;
 			}
 			else
 			{
-				if (item->next != NULL && item->next->type == sbItem::TYPE_BUTTON_SELECTION_CHAPTER)
+				// add chapters
+				sbItem *tmpItem = item;
+				sword::VerseKey workKey ( Core->currentModule->getKey() );
+				workKey.Index( item->index );
+
+				for (int i=0; i < workKey.getChapterMax(); i++)
 				{
-					// remove chapters
-					while (item->next != NULL && item->next->type == sbItem::TYPE_BUTTON_SELECTION_CHAPTER)
-						delete item->next;
-				}
-				else
-				{
-					// add chapters
-					sbItem *tmpItem = item;
-					sword::VerseKey workKey ( module->getKey() );
-					workKey.Index( item->index );
+					workKey.setChapter(i+1);
+					TCHAR text[8];
+					_itot(workKey.getChapter(), text, 10);
+					
+					sbItem *item = new sbItem (sbItem::TYPE_BUTTON_SELECTION_CHAPTER, text, rect->width()/3, workKey.Index());
 
-					for (int i=0; i < workKey.getChapterMax(); i++)
-					{
-						workKey.setChapter( i + 1 );
-						TCHAR text[8];
-						_itot(workKey.getChapter(), text, 10);
-						
-						sbItem *item = new sbItem (sbItem::TYPE_BUTTON_SELECTION_CHAPTER, text, rect->width()/3, workKey.Index());
+					item->center = true;
 
-						item->center = true;
-
-						if (tmpItem->type == sbItem::TYPE_BUTTON_SELECTION_CHAPTER &&
-							(tmpItem->right == NULL || tmpItem->right->right == NULL))
-						{
-							sbItem *last = tmpItem;
-							while(last->right != NULL) last = last->right;
-							last->attach(item, sbItem::RIGHT);
-						}
-						else
-						{
-							tmpItem->attach (item, sbItem::NEXT);
-							tmpItem = tmpItem->next;
-						}
+					if (tmpItem->type == sbItem::TYPE_BUTTON_SELECTION_CHAPTER &&
+						(tmpItem->right == NULL || tmpItem->right->right == NULL))
+					{
+						sbItem *last = tmpItem;
+						while(last->right != NULL) last = last->right;
+						last->attach(item, sbItem::RIGHT);
 					}
-
-					// add space
-					if  (tmpItem->type == sbItem::TYPE_BUTTON_SELECTION_CHAPTER)
+					else
 					{
-						if (tmpItem->right == NULL)
-							tmpItem->attach(new sbItem (sbItem::TYPE_SPACE, L"", rect->width()/3*2), sbItem::RIGHT);
-						else if (tmpItem->right->right == NULL)
-							tmpItem->right->attach(new sbItem (sbItem::TYPE_SPACE, L"", rect->width()/3), sbItem::RIGHT);
+						tmpItem->attach (item, sbItem::NEXT);
+						tmpItem = tmpItem->next;
 					}
 				}
+
+				// add space
+				if  (tmpItem->type == sbItem::TYPE_BUTTON_SELECTION_CHAPTER)
+				{
+					if (tmpItem->right == NULL)
+						tmpItem->attach(new sbItem (sbItem::TYPE_SPACE, L"", rect->width()/3*2), sbItem::RIGHT);
+					else if (tmpItem->right->right == NULL)
+						tmpItem->right->attach(new sbItem (sbItem::TYPE_SPACE, L"", rect->width()/3), sbItem::RIGHT);
+				}
 			}
 		}
 		break;
+
 	case sbItem::TYPE_BUTTON_SELECTION_CHAPTER:
 		{
-			sbAssert(module == NULL);
-
-			sword::VerseKey workKey ( module->getKey() );
-
-			workKey.Index ( item->index );
-
-			module->setKey ( workKey );  // necessary for menu correct work
-
-			addControl((sbControl::TYPE)(sbControl::TYPE_MENU_SET_VERSE+workKey.getVerseMax()));
+			Core->currentVerse.Index ( item->index );
+			
+			addControl((sbControl::TYPE)(sbControl::TYPE_MENU_SET_VERSE+Core->currentVerse.getVerseMax()));
 		}
 		break;
 
 	case sbItem::TYPE_BUTTON_SELECTION_MODULE:
 		{
-			sword::SWModule *newModule = (sword::SWModule*) item->index;
+			sword::SWModule * setModule = (sword::SWModule*) item->index;
 
-			sbAssert ( newModule == NULL );
-			
-			sbAssert ( parent == NULL );
-			
-			if (parent->module != newModule)
-			{
-				if (parent->module == NULL)
-					newModule->setKey ( "John 1:1" );
-				else
-					newModule->setKey ( parent->module->getKey() );
+			sbAssert ( setModule == NULL );
 
-				parent->module = newModule;
-				parent->setKey ( parent->module->getKey() );
+			// highlighting
+			sbItem * workItem = item;
+			while ( workItem->prev != NULL ) workItem = workItem->prev;
+			while ( workItem != NULL ) { workItem->highlighted = false; workItem = workItem->next; }
+			item->highlighted = true;
 
+			Core->goVerse       = true;
+			Core->currentModule = setModule;
 
-				// highlighting
-				sbItem * workItem = item;
-				while ( workItem->prev != NULL ) workItem = workItem->prev;
-				while ( workItem->next != NULL )
-				{
-					workItem->highlighted = false;
-					workItem = workItem->next;
-				}
-				item->highlighted = true;
-
-				Core->redraw();
-			}
+			Core->redraw();
 		}
 		break;
 	}
@@ -878,43 +632,36 @@
 /*   sbList::onTapped
  *   input
  */
-void sbList::onTapped (int x, int y)
+void sbList::onTapped ( int x, int y )
 {
 	if (Core->getInput()->block) return;
 
-	sbItem *item = getItem(x,y);
+	sbItem * item = getItem(x,y);
 
 	if (item == NULL) return;
 
 	if (item->type == sbItem::TYPE_VERSE)
 	{
-		key.Index(item->index);
 		addControl(sbControl::TYPE_MENU_VERSE);
 	}
 }
 
-/*   sbList::getKey
- *   get current module position
- */
-sword::VerseKey* sbList::getKey ()
-{
-	sbAssert(module == NULL);
-	return &key;
-}
-
-/*   sbList::updateVerses
+/*   sbList::process
  *   fill verses with text from module
  *   also delete unnecessary items
  */
-void sbList::updateVerses ( bool * abort )
+void sbList::process ( bool * abort )
 {
 	sbAssert ( module == NULL );
+	sbAssert ( type != sbList::TYPE_MODULE_VIEW );
+
+	sword::VerseKey workKey ( place );
 	
 	if (itemCurrent == NULL) return;
 
-	while ( ! *abort )
+	while ( ! * abort )
 	{
-		int      displace  = displaceHeight;
+		int      displace  = sbList::displace;
 		sbItem * item      = itemCurrent;
 		bool     atEnd     = false;
 		
@@ -960,41 +707,34 @@
 		sbItem * last  = item;
 		sbItem * first = item;
 
-		while ( ! *abort )
+		while ( ! * abort )
 		{
-			bool needBreak = false;
-
-			// process item text
 			if ( item->type == sbItem::TYPE_VERSE && item->text.size() == 0 )
 			{
-				sword::VerseKey workKey ( key );
+				workKey.Index ( item->index );
 
-				workKey.Index(item->index);
+				module->SetKey ( workKey );
 
-				module->SetKey(workKey);
-
-				// TODO some times this cause crush, should i make it in try statement ?
 				TCHAR * text = (TCHAR*) module->RenderText();
+
 				int length = _tcslen ( text );
 
-				if ( length > 0 )
-				{
-					TCHAR * add = new TCHAR [ length + 1 ];
-					for ( int i=0; i <= length; i++ ) add[i] = text[i];
+				if ( length == 0 ) break;
+				
+				TCHAR * add = new TCHAR [ length + 1 ];
 
-					int oldHeight = item->height;
+				for ( int i=0; i <= length; i++ ) add[i] = text[i];
 
-					item->setText ( add );
+				int oldHeight = item->height;
 
-					item->expanding = item->height;
-					item->height    = oldHeight;
+				item->setText ( add );
 
-					needBreak = true;
-				}
+				delete [] add;
+
+				item->expanding = item->height;
+				item->height    = oldHeight;
 			}
 
-			if (needBreak) break;
-
 			if (atEnd && last->next != NULL)
 			{
 				last      = last->next;
@@ -1007,11 +747,18 @@
 				item      = first;
 				displace -= item->height;
 			}
-			else break;
+			else
+			{
+				sbSleep(50);
+				break;
+			}
 
 			atEnd = ! atEnd;
 		}
 	}
+
+	sbAssert ( ! abort );
+	sbMessage ("sbList : thread stoped.\n");
 }
 
 /*
@@ -1024,7 +771,7 @@
 	{
 	case sbControl::TYPE_MENU_VERSE_ADD_DYNAMIC_BOOKMARK:
 	case sbControl::TYPE_MENU_VERSE_ADD_STATIC_BOOKMARK:
-		Core->getCollection("bookmarks")->add(&key);
+		//Core->getCollection("bookmarks")->add(&place); /*TODO retrieve current key from Core*/
 		removeControl ( sbControl::TYPE_MENU_CURRENT );
 		break;
 
@@ -1033,7 +780,7 @@
 			sbItem* item = itemCurrent;
 
 			while (item->next != NULL)
-				if (item->index == key.Index() && item->type == sbItem::TYPE_VERSE)
+				if (item->index == place.Index() && item->type == sbItem::TYPE_VERSE)
 					break;
 				else
 					item = item->next;
@@ -1049,7 +796,7 @@
 		removeControl ( sbControl::TYPE_MENU_CURRENT );
 		break;
 
-	case sbControl::TYPE_BUTTON_CLOSE:
+	case sbControl::TYPE_EXIT:
 		addControl ( sbControl::TYPE_MENU_EXIT );
 		break;
 
@@ -1057,16 +804,12 @@
 		if (type >= sbControl::TYPE_SET_VERSE && type < sbControl::TYPE_SET_VERSE_MAX)
 		{
 			sbAssert ( this->type != sbList::TYPE_SELECT_BOOK );
-			sbAssert ( module == NULL );
-
-			sword::VerseKey workKey ( module->getKey() );
 			
-			workKey.setVerse ( type-sbControl::TYPE_SET_VERSE );
-			parent->setKey ( workKey );
+			Core->currentVerse.setVerse ( type - sbControl::TYPE_SET_VERSE );
+			Core->goVerse = true;
 
-			Core->switchList ( sbList::PIN_PARENT );
-
 			removeControl ( sbControl::TYPE_MENU_CURRENT );
+			Core->switchList ( sbList::TYPE_MODULE_VIEW );
 		}
 		else
 			return false;
@@ -1123,7 +866,7 @@
 				for ( int dir=0; dir < 2; dir++ )
 				{
 					sbItem* item = itemCurrent;
-					int displace = displaceHeight;
+					int displace = sbList::displace;
 
 					while ( item != NULL )
 					{
@@ -1136,7 +879,7 @@
 							}
 							else
 							{
-								const int add = min((int)ceil((item->expanding-item->height)*0.3f)+(Core->getTheme()->size/100),item->expanding-item->height);
+								const int add = min((int)ceil((item->expanding-item->height)*0.3f)+(Core->getTheme()->scale/100),item->expanding-item->height);
 
 								item->height += add;
 
@@ -1178,7 +921,8 @@
 			// add blank verses
 			if ( type == sbList::TYPE_MODULE_VIEW && module != NULL )
 			{
-				sword::VerseKey workKey ( key );
+				sword::VerseKey workKey ( place );
+
 				int added = 0;
 
 				if (itemCurrent == NULL)
@@ -1303,7 +1047,7 @@
 			// itemCurrent may be not first on screen, so do correction
 			if ( itemCurrent != NULL )
 			{
-				while (displaceHeight > -Core->getTheme()->ListSeparatorHeight && itemCurrent->prev != NULL)
+				while (displace > -Core->getTheme()->ListSeparatorHeight && itemCurrent->prev != NULL)
 				{
 					if (itemCurrent->type == sbItem::TYPE_VERSE)
 					{
@@ -1312,14 +1056,14 @@
 					}
 
 					itemCurrent = itemCurrent->prev;
-					displaceHeight -= itemCurrent->height + Core->getTheme()->ListSeparatorHeight;
+					displace -= itemCurrent->height + Core->getTheme()->ListSeparatorHeight;
 				}
 
-				while (displaceHeight < 0 && abs(displaceHeight) > itemCurrent->height + Core->getTheme()->ListSeparatorHeight)
+				while (displace < 0 && fabs(displace) > itemCurrent->height + Core->getTheme()->ListSeparatorHeight)
 				{
 					if (itemCurrent->next == NULL) break;
 
-					displaceHeight += itemCurrent->height + Core->getTheme()->ListSeparatorHeight;
+					displace += itemCurrent->height + Core->getTheme()->ListSeparatorHeight;
 
 					if (itemCurrent->type == sbItem::TYPE_VERSE)
 					{ versesBackward++; versesForward--; }
@@ -1337,93 +1081,72 @@
  */
 void sbList::onActivate ( )
 {
-	sbSetSip (itemEdit != NULL);
+	sbSetSip ( itemEdit != NULL );
 
-	if (module != NULL)
-	{
-		Core->currentModule = module;
-	}
-
 	switch (type)
 	{
-	case TYPE_HISTORY:
-	case TYPE_BOOKMARKS:
-	case TYPE_READINGS:
+	case TYPE_HOME:
 		{
-			sbCollection * collection = Core->getCollection ( type == TYPE_BOOKMARKS ? "bookmarks" : type == TYPE_HISTORY ? "history" : "readings" );
+			float saveDisplacement = 0;
 
-			if ( collection != NULL )
+			if (itemCurrent != NULL)
 			{
-				sword::VerseKey workKey ( Core->defaultModule->getKey() );
-
-				clear();
-
-				for (int i=0; i < collection->size(); i++)
+				while (itemCurrent->prev != NULL)
 				{
-					const char * verse = collection->get(i).verse;
-
-					workKey.setText ( verse );
-
-					TCHAR * text = new TCHAR [strlen(verse)+1];
-					mbstowcs (text, verse , strlen(verse)+1);
-
-					sbItem * item = new sbItem (sbItem::TYPE_BUTTON_BOOKMARK, text, rect->width(), workKey.Index());
-
-					if ( itemCurrent == NULL )
-					{
-						itemCurrent = item;
-					}
-					else
-					{
-						itemCurrent->attach (item,sbItem::PIN::NEXT);
-						itemCurrent = itemCurrent->next;
-					}
-
+					itemCurrent = itemCurrent->prev;
+					displace -= itemCurrent->height + Core->getTheme()->ListSeparatorHeight;
 				}
-
-				while (itemCurrent->prev != NULL) itemCurrent = itemCurrent->prev;
+				saveDisplacement = displace;
 			}
 
-		}
-	case TYPE_HOME:
-		{
 			clear();
-			
+
+			displace = saveDisplacement;
+
 			itemCurrent = new sbItem (sbItem::TYPE_HEADER, L"Welcome to\nSlideBible!", rect->width());
 
-			if (Core->defaultModule != NULL)
+			if ( Core->defaultModule != NULL )
 			{
 				sword::VerseKey workKey ( Core->defaultModule->getKey() );
 
-				if ( parent != NULL && parent->hasModule() )
+				if ( Core->currentModule != NULL ) // here we should check last active module view
 				{
-					const char * place = workKey.getText();
+					const char * place = Core->currentVerse.getText();
 
-					const TCHAR * pre = L"Return to ";
-					
-					TCHAR * text = new TCHAR [_tcslen(pre)+strlen(place)+1];
+					const TCHAR * pre = L" \nReturn to ";
+
+					TCHAR * text = new TCHAR [_tcslen(pre)+strlen(place)+1+2];
 					memcpy ( text, pre, sizeof(TCHAR)*_tcslen(pre) );
 					mbstowcs ( text+_tcslen(pre), place , strlen( place ) + 1 );
 
-					itemCurrent->attach(new sbItem (sbItem::TYPE_BUTTON_BOOKMARK, text, rect->width(), workKey.Index()), sbItem::NEXT);
+					text[_tcslen(text)+2] = NULL;
+					text[_tcslen(text)+1] = L' ';
+					text[_tcslen(text)]   = L'\n';
+
+					itemCurrent->attach(new sbItem (sbItem::TYPE_GOTO_MODULES, text, rect->width()), sbItem::NEXT);
 					itemCurrent = itemCurrent->next;
 					itemCurrent->center = true;
 
 					delete [] text;
 				}
-				else if ((*Core->getOptions())["Bookmarks"]["LastPlace"] != "")
+				else if (Core->features.history.size() > 0)
 				{
-					itemCurrent->attach(new sbItem (sbItem::TYPE_DESCRIPTION, L"Your Last Place :", rect->width()), sbItem::NEXT);
-					itemCurrent = itemCurrent->next;
+					workKey.copyFrom(Core->getSword()->getModule(Core->features.history.back().module)->getKey());
+					workKey.Index(Core->features.history.back().placeEnd);
 
-					const char * bookmark = (*Core->getOptions())["Bookmarks"]["LastPlace"];
+					const char * place = workKey.getText();
 
-					workKey.setText ( bookmark );
+					const TCHAR * pre = L" \nContinue read from ";
 
-					TCHAR * text = new TCHAR [strlen( bookmark ) + 1];
-					mbstowcs ( text, bookmark , strlen( bookmark ) + 1 );
+					TCHAR * text = new TCHAR [_tcslen(pre)+strlen(place)+1+2];
+					memcpy ( text, pre, sizeof(TCHAR)*_tcslen(pre) );
+					mbstowcs ( text+_tcslen(pre), place , strlen( place ) + 1 );
 
-					itemCurrent->attach(new sbItem (sbItem::TYPE_BUTTON_BOOKMARK, text, rect->width(), workKey.Index()), sbItem::NEXT);
+					text[_tcslen(text)+2] = NULL;
+					text[_tcslen(text)+1] = L' ';
+					text[_tcslen(text)]   = L'\n';
+
+					itemCurrent->attach(new sbItem (sbItem::TYPE_GO_HISTORY, text, rect->width(), Core->features.history.size()-1), sbItem::NEXT);
 					itemCurrent = itemCurrent->next;
 					itemCurrent->center = true;
 
@@ -1432,7 +1155,7 @@
 				else
 				{
 					workKey.setText ( "John 1:1" );
-					itemCurrent->attach(new sbItem (sbItem::TYPE_BUTTON_BOOKMARK, L"Read Bible ...", rect->width(), workKey.Index()), sbItem::NEXT);
+					itemCurrent->attach(new sbItem (sbItem::TYPE_BUTTON_BOOKMARK, L" \nRead Bible ...\n ", rect->width(), workKey.Index()), sbItem::NEXT);
 					itemCurrent = itemCurrent->next;
 					itemCurrent->center = true;
 				}
@@ -1443,8 +1166,258 @@
 				itemCurrent = itemCurrent->next;
 			}
 
+			TCHAR text [128];
+
+			_sntprintf(text,128,L"About :\nVersion built on %S\n Using SWORD version %S",__DATE__,sword::SWVersion::currentVersion.getText());
+			itemCurrent->attach(new sbItem (sbItem::TYPE_DESCRIPTION, text, rect->width()), sbItem::NEXT);
+			itemCurrent = itemCurrent->next;
+			itemCurrent->center = true;
+
 			while ( itemCurrent->prev != NULL ) itemCurrent = itemCurrent->prev;
 		}
+		break;
+
+	case TYPE_MODULE_VIEW:
+		{
+			if (Core->goVerse)
+			{
+				Core->goVerse = false;
+
+				sbAssert ( Core->currentModule == NULL );
+
+				module = Core->currentModule;
+
+				clear();
+
+				place.copyFrom ( Core->currentVerse );
+
+				displace = rect->height()*2.0f/5.0f;
+
+				// adding blank verses starts automatically in sbList::onTimer(sbCore::TIMER_BEFORE_REDRAW)
+				// filling with text occurs in sbList::updateVerses
+
+				// update history
+				attachedHistory = Core->features.addHistory(module->Name(),place.Index());
+
+				Core->redraw();
+			}
+
+			if (module != NULL)
+			{
+				if (next == NULL) attach (new sbList(sbList::TYPE_MODULE_VIEW), sbList::PIN_NEXT);
+				if (prev == NULL) attach (new sbList(sbList::TYPE_MODULE_VIEW), sbList::PIN_PREV);
+
+				Core->threadCreate(this);
+
+
+				if (module != NULL)
+				{
+					Core->currentModule = module;
+					Core->currentVerse.copyFrom ( place );
+				}
+			}
+		}
+		break;
+
+	case TYPE_SELECT_BOOK:
+		{
+			sbItem * setItem = NULL;
+
+			sword::VerseKey workKey ( Core->currentVerse );
+
+			const char * moduleBook = workKey.getBookName();
+
+			clear();
+
+			workKey.setPosition(sword::TOP);
+
+			while ( true )
+			{
+				const char * book = workKey.getBookName();
+
+				TCHAR * text = new TCHAR [strlen(book)+1];
+
+				mbstowcs(text,book,strlen(book)+1);
+
+				sbItem *item = new sbItem (sbItem::TYPE_BUTTON_SELECTION_BOOK, text, rect->width(), workKey.Index());
+				item->center = true;
+
+				delete [] text;
+
+				if (moduleBook == book) setItem = item;
+
+				if (itemCurrent == NULL)
+				{
+					itemCurrent = item;
+				}
+				else
+				{
+					itemCurrent->attach (item, sbItem::NEXT);
+					itemCurrent = itemCurrent->next;
+				}
+
+				// next book
+				int b = workKey.getBook();
+
+				workKey.setBook(workKey.getBook()+1);
+
+				if (b == workKey.getBook()) break;
+			}
+
+			if (setItem != NULL)
+				itemCurrent = setItem;
+			else 
+				while (itemCurrent->prev != NULL) itemCurrent = itemCurrent->prev;
+		}
+		break;
+
+	case TYPE_SELECT_MODULE:
+		{
+			int id = 0;
+
+			clear();
+
+			for (sword::ModMap::iterator it = Core->getSword()->Modules.begin(); it != Core->getSword()->Modules.end(); it++)
+			{
+				sword::SWModule *mod = (*it).second;
+
+				if (!strcmp(mod->Type(), "Biblical Texts"))
+				{
+					TCHAR * text = new TCHAR[strlen(mod->Description())+1];
+					for(int i=0; i<=strlen(mod->Description()); i++)
+						text[i] = mod->Description()[i];
+
+					sbItem *item = new sbItem (sbItem::TYPE_BUTTON_SELECTION_MODULE, text, rect->width(), (long)mod);
+					item->center = true;
+
+					delete [] text;
+
+					if (Core->currentModule == mod) item->highlighted = true;
+
+					if (itemCurrent == NULL)
+					{
+						itemCurrent = item;
+					}
+					else
+					{
+						itemCurrent->attach (item, sbItem::NEXT);
+						itemCurrent = itemCurrent->next;
+					}
+				}
+
+				id++;
+			}
+
+			id = 0;
+
+			for (sword::ModMap::iterator it = Core->getSword()->Modules.begin(); it != Core->getSword()->Modules.end(); it++)
+			{
+				sword::SWModule *mod = (*it).second;
+
+				if (!strcmp(mod->Type(), "Commentaries"))
+				{
+					TCHAR * text = new TCHAR [strlen(mod->Description())+1];
+					for(int i=0;i<=strlen(mod->Description()); i++)
+						text[i] = mod->Description()[i];
+
+					sbItem *item = new sbItem (sbItem::TYPE_BUTTON_SELECTION_MODULE, text, rect->width(), (long)mod);
+					item->center = true;
+
+					delete [] text;
+
+					if (Core->currentModule == mod) item->highlighted = true;
+
+					if (itemCurrent == NULL)
+					{
+						itemCurrent = item;
+					}
+					else
+					{
+						itemCurrent->attach (item, sbItem::NEXT);
+						itemCurrent = itemCurrent->next;
+					}
+				}
+
+				id++;
+			}
+
+			while (itemCurrent->prev != NULL) itemCurrent = itemCurrent->prev;
+		}
+		break;
+
+	case TYPE_HISTORY:
+		{
+			clear();
+
+			for (int i=Core->features.history.size()-1; i >= 0 ; i--)
+			{
+				sword::VerseKey workKey ( Core->getSword()->getModule(Core->features.history[i].module)->getKey() );
+				workKey.Index (Core->features.history[i].placeEnd);
+
+				TCHAR * text = new TCHAR [strlen(workKey.getText())+1];
+				mbstowcs (text, workKey.getText() , strlen(workKey.getText())+1);
+
+				sbItem * item = new sbItem (sbItem::TYPE_GO_HISTORY, text, rect->width(), i);
+
+				if ( itemCurrent == NULL )
+				{
+					itemCurrent = item;
+				}
+				else
+				{
+					itemCurrent->attach(item,sbItem::PIN::NEXT);
+					itemCurrent = itemCurrent->next;
+				}
+
+				delete [] text;
+			}
+
+			if ( itemCurrent != NULL ) while ( itemCurrent->prev != NULL ) itemCurrent = itemCurrent->prev;
+		}
+		break;
+
+	case TYPE_BOOKMARKS:
+	case TYPE_READINGS:
+		{
+			/*sbCollection * collection = Core->getCollection ( type == TYPE_BOOKMARKS ? "bookmarks" : type == TYPE_HISTORY ? "history" : "readings" );
+
+			if ( collection != NULL )
+			{
+				sword::VerseKey workKey ( Core->defaultModule->getKey() );
+
+				clear();
+
+				for (int i=0; i < collection->size(); i++)
+				{
+					const char * verse = collection->get(i).verse;
+
+					workKey.setText ( verse );
+
+					TCHAR * text = new TCHAR [strlen(verse)+1];
+					mbstowcs (text, verse , strlen(verse)+1);
+
+					sbItem * item = new sbItem (sbItem::TYPE_BUTTON_BOOKMARK, text, rect->width(), workKey.Index());
+
+					delete [] text;
+
+					if ( itemCurrent == NULL )
+					{
+						itemCurrent = item;
+					}
+					else
+					{
+						itemCurrent->attach (item,sbItem::PIN::NEXT);
+						itemCurrent = itemCurrent->next;
+					}
+
+				}
+
+				while ( itemCurrent->prev != NULL ) itemCurrent = itemCurrent->prev;
+			}*/
+
+		}
+		break;
+
 	default:
 		;
 	}
@@ -1501,10 +1474,29 @@
 
 bool sbList::onKey ( int key )
 {
-	if ( itemSelected == NULL )
+	switch ( key )
 	{
-		itemSelected = itemCurrent;
+	case 0x25: // VK_LEFT
+		Core->switchList(PIN_PREV);
 		return true;
+
+	case 0x27: // VK_RIGHT
+		Core->switchList(PIN_NEXT);
+		return true;
+
+	case 0x28: // VK_DOWN
+		if ( itemSelected == NULL )
+			itemSelected = itemCurrent;
+		else if ( itemSelected->next != NULL )
+			itemSelected = itemSelected->next;
+		return true;
+
+	case 0x26: // VK_UP
+		if ( itemSelected == NULL )
+			itemSelected = itemCurrent;
+		else if ( itemSelected->prev != NULL )
+			itemSelected = itemSelected->prev;
+		return true;
 	}
 	return false;
 }

Modified: trunk/src/SlideBible/sbList.h
===================================================================
--- trunk/src/SlideBible/sbList.h	2010-01-07 20:57:03 UTC (rev 224)
+++ trunk/src/SlideBible/sbList.h	2010-03-08 21:22:28 UTC (rev 225)
@@ -17,14 +17,14 @@
 #define SBLIST_H
 
 #include <vector>
+
 #include <swmgr.h>
 #include <swmodule.h>
 #include <versekey.h>
 
+#include "sbBase.h"
 #include "sbItem.h"
 #include "sbControl.h"
-#include "sbBase.h"
-#include "sbCollection.h"
 
 class sbList
 {
@@ -35,7 +35,7 @@
 		TYPE_CURRENT,                 // virtual, to update current list
 		PIN_NEXT,                     // pin
 		PIN_PREV,                     // pin
-		PIN_PARENT,                   // pin
+		//PIN_PARENT,                   // pin
 		TYPE_MODULE_VIEW,
 		TYPE_SELECT_MODULE,
 		TYPE_SELECT_BOOK,
@@ -45,37 +45,37 @@
 		TYPE_BOOKMARKS,
 		TYPE_READINGS,
 		TYPE_HISTORY,
-		TYPE_OPTIONS,
-		TYPE_SEARCH,                  // virtual
+		//TYPE_OPTIONS,
+		//TYPE_SEARCH,                  // virtual
 		TYPE_SEARCH_OPTIONS,
 		TYPE_SEARCH_RESULTS,
-		TYPE_NAVIGATION,              // virtual
+		//TYPE_NAVIGATION,              // virtual
 		TYPES_COUNT
 	};
 	
-	sbList(sbList::TYPE type);
-	~sbList();
+	sbList ( sbList::TYPE type );
+	~sbList ();
  
 	// event handlers
-	void                      onPressed      ( int x, int y );
-	void                      onReleased     ( int x, int y );
-	void                      onClicked      ( int x, int y );
-	void                      onTapped       ( int x, int y );
+	void                      onPressed           ( int x, int y );
+	void                      onReleased          ( int x, int y );
+	void                      onClicked           ( int x, int y );
+	void                      onTapped            ( int x, int y );
 
-	bool                      onChar         ( TCHAR character );
-	bool                      onKey          ( int key );
+	bool                      onChar              ( TCHAR character );
+	bool                      onKey               ( int key );
 	
-	void                      onTimer        ( const int timer );
-	void                      onActivate     ( );
-	bool                      onControl      ( sbControl::TYPE type );
+	void                      onTimer             ( const int timer );
+	void                      onActivate          ( );
+	bool                      onControl           ( sbControl::TYPE type );
 
 	// methods
-	void                      attach         ( sbList * list, sbList::TYPE pin );
-	bool                      scroll         ( float amount );
-	void                      render         ( sbRenderContext rc , bool showPlace = false );
+	void                      attach              ( sbList * list, sbList::TYPE pin );
+	bool                      scroll              ( float amount );
+	void                      render              ( sbSurface rc , bool showPlace = false );
 
-	int                       displaceHeight;
-	float                     displacePart;
+	float                     displace;
+	//float                     displacePart;
 	int                       screenHeight;
 
 	int                       needScroll;
@@ -83,26 +83,22 @@
 	
 	const TYPE                type;
 
-	sbList*                   getNext       ( ) const {return next;}
-	sbList*                   getPrev       ( ) const {return prev;}
-	sbList*                   getParent     ( ) const {return parent;}
+	sbList*                   getNext             () const {return next;}
+	sbList*                   getPrev             () const {return prev;}
 
-	bool                      hasModule     ( ) const {return module != NULL;}
-	sword::VerseKey*          getKey        ( );
-	void                      updateVerses  ( bool *abort );
+	void                      process             ( bool *abort );
 
-	const std::vector<sbControl*> * getControls () const { return &controls; }
+	const std::vector<sbControl*> * getControls   () const { return &controls; }
 	
 private:
-	void                      setKey  ( sword::VerseKey verse ); // to cut
-	void                      clear   ( );
-	sbItem*                   getItem ( int x, int y ) const;
+	void                      clear               ();
+	sbItem*                   getItem             ( int x , int y ) const;
 
 	sbItem                   *itemCurrent;
 	sbItem                   *itemHover;
 	sbItem                   *itemSelected;
 
-	void                      setEditMode (sbItem* item);
+	void                      setEditMode         ( sbItem * item );
 	sbItem                   *itemEdit;
 	int                       itemEditCursor;
 
@@ -119,25 +115,20 @@
 	// List Related
 	sbList                   *next;
 	sbList                   *prev;
-	sbList                   *parent;
-	sbList                   *child;
 
-	void                      addControl (sbControl::TYPE type);
-	void                      removeControl (sbControl::TYPE type);
+	void                      addControl          ( sbControl::TYPE type );
+	void                      removeControl       ( sbControl::TYPE type );
 
 	std::vector<sbControl*>   controls;
 
 	const sbRect             *rect;
 
-	// Parameters
-
-	// Module View related
+public:
 	sword::SWModule          *module;
-	sword::VerseKey           key; // to cut
+	sword::VerseKey           place;
 
-	sbCollection::item       *attachedReading;
-
-	// Navigation related
+	int                       attachedReading;
+	int                       attachedHistory;
 };
 
 #endif

Modified: trunk/src/SlideBible/sbTheme.cpp
===================================================================
--- trunk/src/SlideBible/sbTheme.cpp	2010-01-07 20:57:03 UTC (rev 224)
+++ trunk/src/SlideBible/sbTheme.cpp	2010-03-08 21:22:28 UTC (rev 225)
@@ -15,204 +15,109 @@
 
 #include "sbTheme.h"
 #include "sbCore.h"
-#include <unistd.h>
 
+#include "platform\xmlParser.h"
+
 #pragma warning(disable : 4018)
 #pragma warning(disable : 4244)
 
 void sbTheme::init()
 {
-	sword::SWConfig  themeConf(".\\theme.conf");
-	themeConf.Load();
+	sword::SWConfig config (".\\theme.conf");
+	config.Load();
 
-	const sbRect* screenRect = &Core->getSurface(sbCore::SURFACE::TYPE_WHOLE)->rect;
-	size = min(screenRect->height(), screenRect->width());
+	const sbRect * screenRect = &Core->getSurface(sbCore::SURFACE::TYPE_WHOLE)->rect;
+	scale = min(screenRect->height(), screenRect->width());
 
 	// colors
-	ItemTextColor        = sbColor(themeConf["Color"].getWithDefault("ItemText", "14141400"));
-	ItemMenuTextColor    = sbColor(themeConf["Color"].getWithDefault("MenuText", "E0E0E000"));
-	ItemSubTextColor     = sbColor(themeConf["Color"].getWithDefault("ItemSubText", "AAAAAA00"));
+	ItemTextColor        = sbColor(config["Color"].getWithDefault("ItemText", "14141400"));
+	ControlsColor        = sbColor(config["Color"].getWithDefault("ControlsText", "14141400"));
+	ItemMenuTextColor    = sbColor(config["Color"].getWithDefault("MenuText", "E0E0E000"));
+	ItemSubTextColor     = sbColor(config["Color"].getWithDefault("ItemSubText", "AAAAAA00"));
 
-	itemTopMargin        = size/atof(themeConf["Size"].getWithDefault("itemTopMarginDiv",    "200.0"));
-	itemLeftMargin       = size/atof(themeConf["Size"].getWithDefault("itemLeftMarginDiv",   "10.0"));
-	itemBottomMargin     = size/atof(themeConf["Size"].getWithDefault("itemBottomMarginDiv", "100.0"));
-	itemRightMargin      = size/atof(themeConf["Size"].getWithDefault("itemRightMarginDiv",  "14.0"));
+	itemTopMargin        = scale/atof(config["Size"].getWithDefault("itemTopMarginDiv",    "200.0"));
+	itemLeftMargin       = scale/atof(config["Size"].getWithDefault("itemLeftMarginDiv",   "10.0"));
+	itemBottomMargin     = scale/atof(config["Size"].getWithDefault("itemBottomMarginDiv", "100.0"));
+	itemRightMargin      = scale/atof(config["Size"].getWithDefault("itemRightMarginDiv",  "14.0"));
 
-	fingerSize           = size/atof(themeConf["Size"].getWithDefault("fingerSizeDiv",       "6.0"));
+	fingerSize           = scale/atof(config["Size"].getWithDefault("fingerSizeDiv",       "6.0"));
 
+	ListSeparatorHeight  = scale*atof(config["Element.Separator"].getWithDefault("SizeDiv", "0.0"));
+	BannerBorderSize     = scale/atof(config["Element.Banner"].getWithDefault("BorderDiv", "25.0"));
+
 	// elements
 	for (int i=0; i<ELEMENT::COUNT; i++)
 	{
-		const char* name;
-		const char* type;
-		const char* color;
-		const char* color2;
-		const char* color3;
+		const char * data;
 
-		switch (i)
-		{
-		case ELEMENT::ITEM:
-			name   = "Element.Item";
-			type   = themeConf[name].getWithDefault("Type", "HOLLOW");
-			color  = themeConf[name].getWithDefault("Color", "FFFFFF00");
-			color2 = themeConf[name].getWithDefault("Color2", "");
-			break;
-		case ELEMENT::ITEM_SELECTED:
-			name   = "Element.ItemSelected";
-			type   = themeConf[name].getWithDefault("Type", "SOLID");
-			color  = themeConf[name].getWithDefault("Color", "AAFFFF00");
-			color2 = themeConf[name].getWithDefault("Color2", "");
-			break;
-		case ELEMENT::ITEM_HIGHLIGHTED:
-			name   = "Element.ItemHighlighted";
-			type   = themeConf[name].getWithDefault("Type", "VGRAD3");
-			color  = themeConf[name].getWithDefault("Color", "FFFFFFFF");
-			color2 = themeConf[name].getWithDefault("Color2", "FF55AA00");
-			color3 = themeConf[name].getWithDefault("Color3", "FFFFFFFF");
-			break;
-		case ELEMENT::ITEM_HOVER:
-			name   = "Element.ItemHover";
-			type   = themeConf[name].getWithDefault("Type", "VGRAD3");
-			color  = themeConf[name].getWithDefault("Color", "FFFFFFFF");
-			color2 = themeConf[name].getWithDefault("Color2", "FFFF0000");
-			color3 = themeConf[name].getWithDefault("Color3", "FFFFFFFF");
-			break;
-		case ELEMENT::SEPARATOR:
-			name   = "Element.Separator";
-			type   = themeConf[name].getWithDefault("Type", "SOLID");
-			color  = themeConf[name].getWithDefault("Color", "CDCDCD00");
-			color2 = themeConf[name].getWithDefault("Color2", "");
-			ListSeparatorHeight = size/atof(themeConf[name].getWithDefault("SizeDiv", "0.0"));
-			break;
-		case ELEMENT::BACKGROUND:
-			name   = "Element.Background";
-			type   = themeConf[name].getWithDefault("Type", "VGRAD");
-			color  = themeConf[name].getWithDefault("Color", "CBDADD00");
-			color2 = themeConf[name].getWithDefault("Color2", "FFFFFF00");
-			break;
-		case ELEMENT::CONTROL:
-			name   = "Element.Control";
-			type   = themeConf[name].getWithDefault("Type", "VGRAD");
-			color  = themeConf[name].getWithDefault("Color", "FFFFFF00");
-			color2 = themeConf[name].getWithDefault("Color2", "CBDADD00");
-			break;
-		case ELEMENT::CONTROL_PRESSED:
-			name   = "Element.ControlPressed";
-			type   = themeConf[name].getWithDefault("Type", "VGRAD");
-			color  = themeConf[name].getWithDefault("Color", "CBDADD00");
-			color2 = themeConf[name].getWithDefault("Color2", "FFFFFF00");
-			break;
-		case ELEMENT::TAPPED:
-			name   = "Element.Tap";
-			type   = themeConf[name].getWithDefault("Type", "SOLID");
-			color  = themeConf[name].getWithDefault("Color", "FF660000");
-			color2 = themeConf[name].getWithDefault("Color2", "");
-			break;
-		case ELEMENT::BANNER:
-			name   = "Element.Banner";
-			type   = themeConf[name].getWithDefault("Type", "VGRAD3");
-			color  = themeConf[name].getWithDefault("Color", "CBDADD00");
-			color2 = themeConf[name].getWithDefault("Color2", "B4CFD600");
-			color3 = themeConf[name].getWithDefault("Color3", "CBDADD00");
-			BannerBorderSize = size/atof(themeConf[name].getWithDefault("BorderDiv", "25.0"));
-			break;
-		default:
-			sbAssert(true);
-		}
+		if (i == ELEMENT::ITEM)
+			data   = config["Element"].getWithDefault("Item",            "<e><s c=\"FFFFFFFF\"/></e>");
+		else if (i == ELEMENT::ITEM_SELECTED)
+			data   = config["Element"].getWithDefault("ItemSelected",    "<e><s c=\"AAFFFF00\"/></e>");
+		else if (i == ELEMENT::ITEM_HIGHLIGHTED)
+			data   = config["Element"].getWithDefault("ItemHighlighted", "<e gradient=\"1\" vertical=\"1\"><s c=\"FFFFFFFF\"/><s c=\"FF55AA00\"/><s c=\"FFFFFFFF\"/></e>");
+		else if (i == ELEMENT::ITEM_HOVER)
+			data   = config["Element"].getWithDefault("ItemHover",       "<e gradient=\"1\" vertical=\"1\"><s c=\"FFFFFFFF\"/><s c=\"FFFF0000\"/><s c=\"FFFFFFFF\"/></e>");
+		else if (i == ELEMENT::SEPARATOR)
+			data   = config["Element"].getWithDefault("Separator",       "<e><s c=\"CDCDCD00\"/></e>");
+		else if (i == ELEMENT::BACKGROUND)
+			data   = config["Element"].getWithDefault("Background",      "<e gradient=\"1\" vertical=\"1\"><s c=\"CBDADD00\"/><s c=\"FFFFFF00\"/></e>");
+		else if (i == ELEMENT::CONTROL)
+			data   = config["Element"].getWithDefault("Control",         "<e gradient=\"1\" vertical=\"1\"><s c=\"FFFFFF00\"/><s c=\"CBDADD00\"/></e>");
+		else if (i == ELEMENT::CONTROL_PRESSED)
+			data   = config["Element"].getWithDefault("ControlPressed",  "<e gradient=\"1\" vertical=\"1\"><s c=\"CBDADD00\"/><s c=\"FFFFFF00\"/></e>");
+		else if (i == ELEMENT::TAPPED)
+			data   = config["Element"].getWithDefault("Tapped",          "<e><s c=\"FF660000\"/></e>");
+		else if (i == ELEMENT::BANNER)
+			data   = config["Element"].getWithDefault("Banner",          "<e gradient=\"1\" vertical=\"1\"><s c=\"CBDADD00\"/><s c=\"B4CFD600\"/><s c=\"CBDADD00\"/></e>");
+		else
+			sbAssert ( true );
 
-		//themeConf[name].getWithDefault("FrameNum", "0");
+		XMLNode xml = XMLNode::parseString(data);
 
-		if (!strcmp(type,"SOLID"))
+		if (xml.getAttribute("gradient") != NULL && !strcmp(xml.getAttribute("gradient"),"1")) elements[i].gradient = true; else elements[i].gradient = false;
+		if (xml.getAttribute("vertical") != NULL && !strcmp(xml.getAttribute("vertical"),"1")) elements[i].vertical = true; else elements[i].vertical = false;
+
+		for (int p = 0; p < xml.nChildNode("s"); p++)
 		{
-			elements[i].type      = ELEMENT::SOLID;
-			elements[i].color     = sbColor(color);
-		}
-		else if (!strcmp(type,"VGRAD"))
-		{
-			elements[i].type      = ELEMENT::VGRAD;
-			elements[i].color     = sbColor(color);
-			elements[i].color2    = sbColor(color2);
-		}
-		else if (!strcmp(type,"HGRAD"))
-		{
-			elements[i].type      = ELEMENT::HGRAD;
-			elements[i].color     = sbColor(color);
-			elements[i].color2    = sbColor(color2);
-		}
-		else if (!strcmp(type,"HGRAD3"))
-		{
-			elements[i].type      = ELEMENT::HGRAD3;
-			elements[i].color     = sbColor(color);
-			elements[i].color2    = sbColor(color2);
-			elements[i].color3    = sbColor(themeConf[name].getWithDefault("Color3", ""));
-			elements[i].pos1      = atoi(themeConf[name].getWithDefault("Separation1", "500"));
-		}
-		else if (!strcmp(type,"VGRAD3"))
-		{
-			elements[i].type      = ELEMENT::VGRAD3;
-			elements[i].color     = sbColor(color);
-			elements[i].color2    = sbColor(color2);
-			elements[i].color3    = sbColor(themeConf[name].getWithDefault("Color3", ""));
-			elements[i].pos1      = atoi(themeConf[name].getWithDefault("Separation1", "500"));
-		}
-		else if (!strcmp(type,"HOLLOW"))
-		{
-			elements[i].type      = ELEMENT::HOLLOW;
-		}
-		else if (!strcmp(type,"BMP"))
-		{
-			elements[i].type      = ELEMENT::BMP;
-			elements[i].color     = sbColor(themeConf[name].getWithDefault("Color", "FFFFFF00"));
+			XMLNode n = xml.getChildNode("s",p);
 
-			elements[i].stretch   = atoi(themeConf[name].getWithDefault("Stretch", "0"));
+			sbColor color ( n.getAttribute("c") == NULL ? "00000000" : n.getAttribute("c") );
 
-			const char* filename  = themeConf[name]["Bitmap"];
+			int pos = 1000*p/max(xml.nChildNode("s")-(elements[i].gradient ? 1 : 0),1);
 
-			if (*filename != NULL)
-			{
-				filename = adaptpath(filename);
-				TCHAR* t_filename = new TCHAR [strlen(filename)+1];
-				mbstowcs(t_filename, filename, strlen(filename)+1);
-				elements[i].bitmap = sbLoadBitmap(t_filename); //SHLoadImageFile(t_filename);
+			if (n.getAttribute("p") != NULL) pos = atoi(n.getAttribute("p"));
 
-				int error = sbGetLastError();
-				sbAssert(error != 0);
-
-				delete [] t_filename;
-			}
-			else
-				elements[i].bitmap = NULL;
+			elements[i].fill.push_back(std::pair<sbColor,short>(color,pos));
 		}
-		else
-			sbAssert(true);
 	}
 
 	// fonts
-	const char *fontName = themeConf["Font"].getWithDefault("Item", "Tahoma");
+	const char * fontName = config["Font"].getWithDefault("Item", "Tahoma");
 
 	TCHAR *fontNameT = new TCHAR [strlen(fontName)+1];
-	for (int i=0; i<=strlen(fontName); i++)
-		fontNameT[i] = fontName[i];
 
-	styles[STYLE::TEXT].size          = size/(atof(themeConf["Size"].getWithDefault("TextDiv", "12.0")));
+	for (int i = 0; i <= strlen ( fontName ); i++) fontNameT[i] = fontName[i];
+
+	styles[STYLE::TEXT].size          = scale/(atof(config["Size"].getWithDefault("TextDiv", "12.0")));
 	styles[STYLE::TEXT].font          = sbMakeFont(styles[STYLE::TEXT].size,         fontNameT, false, false);
 	
 	styles[STYLE::TEXT_ITALIC].size   = styles[STYLE::TEXT].size;
 	styles[STYLE::TEXT_ITALIC].font   = sbMakeFont(styles[STYLE::TEXT_ITALIC].size,  fontNameT, false, true);
 	
-	styles[STYLE::BUTTON].size        = size/(atof(themeConf["Size"].getWithDefault("ButtonTextDiv", "10.0")));
+	styles[STYLE::BUTTON].size        = scale/(atof(config["Size"].getWithDefault("ButtonTextDiv", "11.0")));
 	styles[STYLE::BUTTON].font        = sbMakeFont(styles[STYLE::BUTTON].size,       fontNameT, false, false);
 	
-	styles[STYLE::BUTTON_SMALL].size  = size/(atof(themeConf["Size"].getWithDefault("ButtonSmallTextDiv", "15.0")));
+	styles[STYLE::BUTTON_SMALL].size  = scale/(atof(config["Size"].getWithDefault("ButtonSmallTextDiv", "15.0")));
 	styles[STYLE::BUTTON_SMALL].font  = sbMakeFont(styles[STYLE::BUTTON_SMALL].size, fontNameT, false, false);
 	
-	styles[STYLE::STANZA].size        = size/(atof(themeConf["Size"].getWithDefault("SubTextDiv",     "16.0")));
+	styles[STYLE::STANZA].size        = scale/(atof(config["Size"].getWithDefault("SubTextDiv",     "16.0")));
 	styles[STYLE::STANZA].font        = sbMakeFont(styles[STYLE::STANZA].size,       fontNameT, true, false);
 	
-	styles[STYLE::DESCRIPTION].size   = size/(atof(themeConf["Size"].getWithDefault("DescriptionDiv", "14.0")));
+	styles[STYLE::DESCRIPTION].size   = scale/(atof(config["Size"].getWithDefault("DescriptionDiv", "14.0")));
 	styles[STYLE::DESCRIPTION].font   = sbMakeFont(styles[STYLE::DESCRIPTION].size,  fontNameT, false, false);
 	
-	styles[STYLE::CAPTION].size       = size/(atof(themeConf["Size"].getWithDefault("HeaderDiv",      "8.0")));
+	styles[STYLE::CAPTION].size       = scale/(atof(config["Size"].getWithDefault("HeaderDiv",      "9.0")));
 	styles[STYLE::CAPTION].font       = sbMakeFont(styles[STYLE::CAPTION].size,      fontNameT, true, false);
 
 	// clear
@@ -222,154 +127,72 @@
 sbTheme::~sbTheme()
 {
 	for (int i=0; i<STYLE::COUNT; i++) sbDeleteFont (styles[i].font);
-
-	for (int i=0; i<ELEMENT::COUNT; i++)
-		if (elements[i].type == ELEMENT::BMP && elements[i].bitmap != NULL)
-			sbDeleteBitmap (elements[i].bitmap);
 }
 
-/*
- *  sbTheme::drawElement
- *  outside methods should only place element types on the screen
- *  in future real paint will be in something like flushScreen()
- */
-void sbTheme::drawElement (sbRenderContext rc, const sbRect * rect, sbTheme::ELEMENT::TYPE type, const int animFrame) const
+void sbTheme::drawElement (sbSurface rc, const sbRect * rect, sbTheme::ELEMENT::TYPE type, const int animFrame) const
 {
-	bool vertical = true;
-	sbColor nc1,nc2,nc3;
-	
-	switch (elements[type].type)
+	for (int i = 0; i < elements[type].fill.size(); i++)
 	{
-	case sbTheme::ELEMENT::SOLID:
-		{
-			if (Core->getSurface(sbCore::SURFACE::TYPE_WHOLE)->fade)
-			{
-				nc1.red   = elements[type].color.red*2/3;
-				nc1.green = elements[type].color.green*2/3;
-				nc1.blue  = elements[type].color.blue*2/3;
-			}
-			else
-			{
-				nc1 = elements[type].color;
-			}
-			checkTransparentColor(nc1,rect->left,rect->top);
-			sbFillRect (rc,rect,nc1);
-		}
-		break;
+		sbColor start = elements[type].fill[i].first;
+		sbColor end   = elements[type].fill.size()-1 == i ? start : elements[type].fill[i+1].first;
+		sbRect  fill  = *rect;
 
-	case sbTheme::ELEMENT::HGRAD:
+		if (start.alpha >= 255 && (elements[type].gradient == false || end.alpha >= 255)) continue;
+
+		if (Core->getSurface(sbCore::SURFACE::TYPE_WHOLE)->fade)
 		{
-			vertical = false;
+			start.red   = start.red*2/3;
+			start.green = start.green*2/3;
+			start.blue  = start.blue*2/3;
+
+			end.red     = end.red*2/3;
+			end.green   = end.green*2/3;
+			end.blue    = end.blue*2/3;
 		}
-	case sbTheme::ELEMENT::VGRAD:
-		{
-			if (Core->getSurface(sbCore::SURFACE::TYPE_WHOLE)->fade)
-			{
-				nc1 = sbColor(elements[type].color.red*2/3,  elements[type].color.green*2/3,  elements[type].color.blue*2/3);
-				nc2 = sbColor(elements[type].color2.red*2/3, elements[type].color2.green*2/3, elements[type].color2.blue*2/3);
-			}
-			else
-			{
-				nc1 = elements[type].color;
-				nc2 = elements[type].color2;
-			}
-			checkTransparentColor(nc1,rect->left,rect->top);
-			checkTransparentColor(nc2,rect->right,rect->bottom);
-			sbDrawGradient(rc, rect, nc1, nc2, vertical);
-		}
-		break;
 
-	case sbTheme::ELEMENT::HGRAD3:
+		if (elements[type].vertical)
 		{
-			vertical = false;
+			fill.top    = fill.height()*elements[type].fill[i].second/1000+fill.top;
+			fill.bottom = (elements[type].fill.size()-1 == i ? fill.height() : fill.height()*elements[type].fill[i+1].second/1000)+fill.top;
 		}
-	case sbTheme::ELEMENT::VGRAD3:
+		else
 		{
-			if (Core->getSurface(sbCore::SURFACE::TYPE_WHOLE)->fade)
-			{
-				nc1 = sbColor(elements[type].color.red*2/3,  elements[type].color.green*2/3,  elements[type].color.blue*2/3);
-				nc2 = sbColor(elements[type].color2.red*2/3, elements[type].color2.green*2/3, elements[type].color2.blue*2/3);
-				nc3 = sbColor(elements[type].color3.red*2/3, elements[type].color3.green*2/3, elements[type].color3.blue*2/3);
-			}
-			else
-			{
-				nc1 = elements[type].color;
-				nc2 = elements[type].color2;
-				nc3 = elements[type].color3;
-			}
-
-			sbRect temp;
-
-			if (elements[type].pos1 != 0)
-			{
-				temp = * rect;
-
-				if (vertical)
-					temp.bottom = temp.height()*elements[type].pos1/1000+temp.top;
-				else
-					temp.right  = temp.width()*elements[type].pos1/1000+temp.left;
-
-				checkTransparentColor(nc1,temp.left,temp.top);
-				checkTransparentColor(nc2,temp.right,temp.bottom);
-
-				sbDrawGradient(rc, &temp, nc1, nc2, vertical);
-			}
-			if (elements[type].pos1 != 1000)
-			{
-				temp = * rect;
-
-				if (vertical)
-					temp.top  = temp.height()*elements[type].pos1/1000+temp.top;
-				else
-					temp.left = temp.width()*elements[type].pos1/1000+temp.left;
-				
-				checkTransparentColor(nc2,temp.left,temp.top);
-				checkTransparentColor(nc3,temp.right,temp.bottom);
-
-				sbDrawGradient(rc, &temp, nc2, nc3, vertical);
-			}
+			fill.right  = fill.width()*elements[type].fill[i].second/1000+fill.right;
+			fill.left   = (elements[type].fill.size()-1 == i ? fill.width() : fill.width()*elements[type].fill[i+1].second/1000)+fill.left;
 		}
-		break;
 
-	case sbTheme::ELEMENT::HOLLOW:
-		break;
+		checkTransparentColor ( start, fill.left,  fill.top );
+		checkTransparentColor ( end,   fill.right, fill.bottom );
 
-	case sbTheme::ELEMENT::BMP:
-		{
-			sbDrawBitmap (rc,rect,elements[type].bitmap,elements[type].stretch);
-		}
-		break;
-
-	default:
-		sbAssert(true);
+		if (elements[type].gradient)
+			sbDrawGradient ( rc, &fill, start, end, elements[type].vertical );
+		else
+			sbFillRect ( rc, &fill, start );
 	}
 }
 
 void sbTheme::checkTransparentColor ( sbColor & color , int x , int y ) const
 {
-	if ( color.alpha != 0 ) // transparent
+	if ( color.alpha != 0 )
 	{
-		if (elements[sbTheme::ELEMENT::BACKGROUND].type == sbTheme::ELEMENT::SOLID)
+		if (elements[sbTheme::ELEMENT::BACKGROUND].fill.size() == 2)
 		{
-			color = elements[sbTheme::ELEMENT::BACKGROUND].color;
-		}
-		else if (elements[sbTheme::ELEMENT::BACKGROUND].type == sbTheme::ELEMENT::VGRAD)
-		{
-			unsigned char r1 = elements[sbTheme::ELEMENT::BACKGROUND].color.red;
-			unsigned char g1 = elements[sbTheme::ELEMENT::BACKGROUND].color.green;
-			unsigned char b1 = elements[sbTheme::ELEMENT::BACKGROUND].color.blue;
-			unsigned char r2 = elements[sbTheme::ELEMENT::BACKGROUND].color2.red;
-			unsigned char g2 = elements[sbTheme::ELEMENT::BACKGROUND].color2.green;
-			unsigned char b2 = elements[sbTheme::ELEMENT::BACKGROUND].color2.blue;
 			const sbRect rect = Core->getSurface(sbCore::SURFACE::TYPE_WHOLE)->rect;
-			int value = min(1000,((y-rect.top)*1000)/rect.height());
-			color = sbColor (r1+((r2-r1)*value/1000),g1+((g2-g1)*value/1000),b1+((b2-b1)*value/1000));
+
+			unsigned char r1 = elements[sbTheme::ELEMENT::BACKGROUND].fill[0].first.red;
+			unsigned char g1 = elements[sbTheme::ELEMENT::BACKGROUND].fill[0].first.green;
+			unsigned char b1 = elements[sbTheme::ELEMENT::BACKGROUND].fill[0].first.blue;
+			unsigned char r2 = elements[sbTheme::ELEMENT::BACKGROUND].fill[1].first.red;
+			unsigned char g2 = elements[sbTheme::ELEMENT::BACKGROUND].fill[1].first.green;
+			unsigned char b2 = elements[sbTheme::ELEMENT::BACKGROUND].fill[1].first.blue;
+
+			int v = min(1000,((y-rect.top)*1000)/rect.height());
+
+			color = sbColor (r1+((r2-r1)*v/1000),g1+((g2-g1)*v/1000),b1+((b2-b1)*v/1000));
 		}
-		else if (elements[sbTheme::ELEMENT::BACKGROUND].type == sbTheme::ELEMENT::BMP)
+		else
 		{
-			color = elements[sbTheme::ELEMENT::BACKGROUND].color;
+			color = elements[sbTheme::ELEMENT::BACKGROUND].fill[0].first;
 		}
-		else
-			sbAssert(true);
 	}
 }

Modified: trunk/src/SlideBible/sbTheme.h
===================================================================
--- trunk/src/SlideBible/sbTheme.h	2010-01-07 20:57:03 UTC (rev 224)
+++ trunk/src/SlideBible/sbTheme.h	2010-03-08 21:22:28 UTC (rev 225)
@@ -16,6 +16,7 @@
 #ifndef SBTHEME_H
 #define SBTHEME_H
 
+#include <vector>
 #include "sbBase.h"
 
 class sbTheme
@@ -28,10 +29,13 @@
 	void                  init();
 
 private:
+
 	void                  checkTransparentColor (sbColor & color, int x, int y) const;
 
 public:
+
 	sbColor               ItemTextColor;
+	sbColor               ControlsColor;
 	sbColor               ItemSubTextColor;
 	sbColor               ItemMenuTextColor;
 
@@ -72,40 +76,34 @@
 			COUNT
 		};
 
-		enum DRAW_TYPE
-		{
-			HOLLOW = 0,
-			SOLID,
-			VGRAD, VGRAD3, VGRAD4,
-			HGRAD, HGRAD3, HGRAD4,
-			BMP,
-		};
+		std::vector<std::pair<sbColor,short>>   fill;      // short - gradients vertical/horizontal sparation in range 0-1000
 
-		char              type;
-		sbColor           color;
-		sbColor           color2;
-		sbColor           color3;
-		sbColor           color4;
-		short             pos1;                      // gradients vertical/horizontal sparation in range 0-1000
-		short             pos2;
-		sbBitmap          bitmap;
-		char              stretch:1, centered:1, transparency:1;
+		std::vector<std::vector<std::pair<sbColor,sbPoint>>> region;
+
+		sbBitmap                                bitmap;
+
+		bool                                    have;      // have bitmap
+		bool                                    vertical;
+		bool                                    gradient;
+		bool                                    stretch;
 	};
 
 	ELEMENT               elements [ELEMENT::COUNT];
 
-	void                  drawElement ( sbRenderContext rc, const sbRect * rect, sbTheme::ELEMENT::TYPE type, const int animFrame = 0 ) const;
+	void                  drawElement ( sbSurface surface, const sbRect * rect, sbTheme::ELEMENT::TYPE type, const int animFrame = 0 ) const;
 
 	int                   ListSeparatorHeight;
 	int                   BannerBorderSize;
 
-	int                   size; // screen minimal dimention, determine font and control sizes
+	int                   scale; // screen minimal dimension, determine font and control sizes
 	int                   fingerSize;
 
 	int                   itemTopMargin;
 	int                   itemBottomMargin;
 	int                   itemLeftMargin;
 	int                   itemRightMargin;
+
+	sbSurface             listBackground;
 };
 
 #endif

Modified: trunk/src/SlideBible/todo.txt
===================================================================
--- trunk/src/SlideBible/todo.txt	2010-01-07 20:57:03 UTC (rev 224)
+++ trunk/src/SlideBible/todo.txt	2010-03-08 21:22:28 UTC (rev 225)
@@ -10,25 +10,70 @@
 +		make it work
 +			wm6.5 not started
 +			release configuration not started
-	verse history
++	win32 platform
++	memory leak test
++	verse history
 +		time function
-	timer to save configs
-	remake lists sytem
-	remake current place indicator
-	win32 platform
-		
-	verse data
-		bookmarks, history, ratings, thematic verse lists, tags, colors
-			dialog: verse actions(favorite|send to list...|send to new list)
-			dialog: select verse(s)
-			dialog: menu verse
-	?	verse features:
-			readings count (forgotten places/chapters)
-			bookmarks static/dynamic
-				on screen marks
-			attendance history: date, module, key
-			verse lists (remember for...)
++	timer to save configs
++	make list scrolling more smooth
+	make verse expantion without jerks
+	history view with dates
+	keypad
+		active control
+
+
+
+	remake sytems
+		general reason why it is needed to remake, that lists should have
+			static decription 
+				home - welcome, readings, history, ... , about
+				added controls
+			and dynamical changing
+				readings count should changing
+				verses should be added dynamicaly
+				text addition in verse
+			sbList - screen controller
+				sbItem - square container
+					sbRenderCache
+		adding items should not be so constrained
+		remove surfaces, make:
+			items-draw-cache: mask surface
+		views interaction
+			make throught Core
+			anywhere i could get current reading place and set necceserity of transition
+t		while view active its background thread should work
+		should be interface to obtain state of module view (current place, current module)
+		if module attached to reading, when reading deleted, module ---removed too--- deatached from reading
+			core should access all lists reading attachments and convert
+		book_select and verse_select
+			cycled attachment
+			in lists map presists both
 			
+	verse features
+		bookmarks
+			data tree (for bookmarks folders)
+			date created (for sorting)
+			only one item per place in folder
+			ranges allowed
+			place - "KJV:Gen 1:1-12", path - "Holiness\God"
+		history
+			date visited
+			many items per place
+			ranges
+		ratings/favourite
+			no ranges, byte-array
+		readings
+			reading should be as restoreable view
+			get / set (on switch and destroy) place
+			remember module also
+			place, module, date started, date visited
+?		colors
+		reading count
+			created as byte-array for every versification
+?			increased when exceed 256-bound
+?			converted beetwheen v11ns on call
+			or maybe implement this throught history
+			
 	search
 		clucence
 		input text items
@@ -36,18 +81,27 @@
 			cursor
 ?			copy/paste
 
-
-	combining unicode accents, like accute (should be in platform-dependent part)
-?	double click for zoom out
+	warning war - clean build log from warnings
+?	need i naming for members, like m_Strings or mStrings?
+		ability to search
+		mStrings - member
+		pName - pointer
+		its reduce readableness
+	fopen in application dir for wince
+~	use posix functions
+	background thread some times stops
+	features: move deleted history to special array, and save it with xml
+	render recieve horizontal displacement
+	volume+/- scroll half of screen, long press linvolve cinetic scroll with increasing speed, zoom-/+ scroll as mouse scroll
+	side slide should be not on one list but on some
+	combining unicode accents, like accute, should be in platform-dependent part
 	smart item surface cacher, create square surface of longer screen side
-		render item in sbItem::render
 	text fade
 	2. Ïàðàëèïîìå\níîí\n4 in chapter title
 	start slide to empty list, but drop to not empty produces blank screen
 	daily devotionals
-	make list scrolling more smooth
-	make verse expantion without jerks
 	cross-references, footnotes
+		will be shown in verse context menu, or by multitouch expand
 	controls, pressed/released
 	link neighbor lists: items will be fitted by height, empty verses will be displayed hollow
 	keypad: on key pressed, keyMode activated, every button on displayed as common text, as touchscreen pressed, every button on screen become drawn as button
@@ -55,7 +109,6 @@
 	slide list and stroke down/up - link list
  	sometimes happens something wrong with height of empty verse and verse text line height
 	different screens and runtime orientation change
-		g-sensor support
 
 ?	update theme from psd file
 ?	data abort in gwes.exe on emulator
@@ -70,9 +123,11 @@
 	icons and graphics
 
 release
-	sliding, animated backgrounds
+?	sliding, animated backgrounds
 	Link, like Opera Link to synchronize bookmarks and all Per Verse Data among all user devices
 		need Sword change that every verse in Bibile at every v11n has unique id
-	read html / txt / rtf / doc formats
+?	read html / txt / rtf / doc formats
 	another platform : android , mac os x ,  openembedded , symbian , maemo , ...
+	g-sensor changes orientation, option
+	multitouch
 	
\ No newline at end of file




More information about the sword-cvs mailing list