⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sugarmemolearn.c

📁 最好用的背单词软件, palm 平台, 如果能移植到别的平台
💻 C
📖 第 1 页 / 共 3 页
字号:
#include <PalmOS.h>
#include "SugarMemo.h"
#include "SugarMemoRsc.h"
#include "SugarMemoLearn.h"
#include "SugarMemoDB.h"
#include "SugarMemoTools.h"

#define ShowNext 				1
#define ShowShowAnswer 			2
#define ShowRightWrong 			12
#define ShowBingoPassFail 		112

#define	DynamicPushButtonStart	6666
#define	DynamicPushButtonGroup	1234

#define RightWrongGroup 	1
#define BingoPassFailGroup 	2

typedef union{
	struct{
		unsigned reserved	:9;
		unsigned fail 	:1;	//64
		unsigned pass	:1;	//32
		unsigned bingo	:1;	//16
		unsigned wrong	:1;	//8
		unsigned right 	:1;	//4
		unsigned show 	:1;	//2
		unsigned next 	:1;	//1
	} bits;
	UInt16 allBits;
}	ControlFlags;

typedef enum{
	nextControl = 0,
	showControl,
	rightControl,
	wrongControl,
	bingoControl,
	passControl,
	failControl,
	controlCounts,
	noSelectedControl = 0xFFFF
} Control;

UInt16		CurrentAnswerTop;
UInt16 		CurrentTop = 0;
UInt16 		CurrentHeight;
UInt16 		maxQuestionPaneHeight = 80;
Boolean		ShowAnswerPane = false;

Control 	PushSelection;

ControlType*	fieldTab[WordFieldsCount];
WordFields		CurrentAnswerField = WordFieldAnswer;
WordFields 		DefaultAnswerField = WordFieldAnswer;

RectangleType 	QuestionPane;
RectangleType 	AnswerPane;
RectangleType	ToolBar = {{0, 145}, {160, 15}};

Boolean Lefty = false;
WordFieldFlags 	fieldFlag;
ControlFlags 	controlFlag;

extern EditLabel fieldLabel[WordFieldsCount];

static void 	RemoveBlankHead(char** p);
static void 	DrawFieldHeight(char* p, UInt16* height, TextAlignment align, Boolean draw);
static UInt16 	DrawPaneHeight(Boolean draw);
static void 	ScrollCanvas(Boolean up);
static void 	DrawBanner();
static void		DrawCanvas();
static void		DrawQuestionPane();
static void		DrawAnswerPane();
static void 	LoadAnswerTab();
static void		ClearAnswerTab();

static void 	UpdateScrollers();
static void 	LoadControls();
static UInt16 	GetQuestionPageFields();
static UInt16 	GetAnswerPageFields();

static void 	DoControlShowButton();
static void 	DoControlNext();
static UInt8 	Difficulty(float efactor);
static RectangleType GetCanvasBounds();
static Boolean 	LoadWord();
static void 	Finish();
static void 	SwitchButtonOff(UInt16 controlID);
static void 	SwitchButtonOn(UInt16 controlID);
static Boolean 	LearnFormDoCommand(UInt16 command);

static void 	DrawCanvas(){
	DrawQuestionPane();

	WinEraseRectangle(&AnswerPane, 0);
	
	WinPushDrawState();
	WinSetForeColor(UIColorGetTableEntryIndex(UIObjectSelectedFill));
	WinDrawGrayLine(0, AnswerPane.topLeft.y - 3 , 160, AnswerPane.topLeft.y - 3);
	WinPopDrawState();
	
	FrmUpdateScrollers(FrmGetActiveForm(), GetObjectIndex(LearnScrollUpRepeating),
		GetObjectIndex(LearnScrollDownRepeating), false, false);
	

	if (ShowAnswerPane)	{
		CurrentAnswerField = DefaultAnswerField;
		LoadAnswerTab();
		
		FrmDrawForm(FrmGetActiveForm());
		DrawAnswerPane();
	}
}

static void 	DrawQuestionPane(){

	WinHandle activeWinH, offscreenWinH;
	RectangleType bounds, questionPane;
	Err error;
	
	UInt16 height;
	
	SugarAppInfoType* app;
	
	app = GetAppInfoPtr(CurrentDB);
	fieldFlag = app -> 	questionPageFields;
	MemPtrUnlock(app);
	
	height = DrawPaneHeight(false);
	if (height > maxQuestionPaneHeight) height = maxQuestionPaneHeight;
	
	//save current active window handle
	activeWinH = WinGetActiveWindow();
	
	//create offscreen window and set as draw window
	questionPane = GetCanvasBounds();
	questionPane.extent.y = height;
	offscreenWinH = WinCreateOffscreenWindow(questionPane.extent.x, questionPane.extent.y, genericFormat, &error);
	
	if (error) ErrAlert(error);
	WinSetDrawWindow(offscreenWinH);
	
	//draw the window
	DrawPaneHeight(true);

	//change the draw window
	WinSetDrawWindow(activeWinH);
	
	//blit
	bounds.topLeft.x = 0;
	bounds.topLeft.y = 0;
	bounds.extent.x = questionPane.extent.x;
	bounds.extent.y = questionPane.extent.y;
	WinCopyRectangle(offscreenWinH, activeWinH, &bounds, questionPane.topLeft.x, questionPane.topLeft.y, winPaint);
	
	//delete offscreen window
	WinDeleteWindow(offscreenWinH, false);
	
	AnswerPane.topLeft.x = questionPane.topLeft.x;
	AnswerPane.topLeft.y = questionPane.topLeft.y + questionPane.extent.y;
	AnswerPane.extent.x = questionPane.extent.x;
	AnswerPane.extent.y = GetCanvasBounds().extent.y - questionPane.extent.y;
}

static void 	DrawAnswerPane(){
	
	WinHandle activeWinH, offscreenWinH;
	RectangleType bounds;
	Err error;
	FontID currFont;
	
	SugarAppInfoType* app;
	MemHandle recordH;
	WordRecordType record;
	UInt16 top = 0;

	UInt16 upIndex, downIndex;
	Boolean Scrollup = false;
	Boolean Scrolldown = false;


	//	Get App Info Pointer	
	app = GetAppInfoPtr(CurrentDB);
	GetWordRecord(CurrentDB, CurrentRecord, &record, &recordH);

	currFont = FntSetFont(app -> learnFieldFont[CurrentAnswerField]);
	DrawFieldHeight(record.field[CurrentAnswerField], &top, app->learnFieldAlignment[CurrentAnswerField], false);
	
	if (top <= AnswerPane.extent.y) {
		CurrentAnswerTop = (AnswerPane.extent.y - top) / 2;
	}
	
	//save current active window handle
	activeWinH = WinGetActiveWindow();
	
	//create offscreen window and set as draw window
	offscreenWinH = WinCreateOffscreenWindow(AnswerPane.extent.x, AnswerPane.extent.y, genericFormat, &error);
	
	if (error) ErrAlert(error);
	WinSetDrawWindow(offscreenWinH);
	
	//draw the window
	top = CurrentAnswerTop;
	DrawFieldHeight(record.field[CurrentAnswerField], &top, app->learnFieldAlignment[CurrentAnswerField], true);
	
	//	release pointer
	MemHandleUnlock(recordH);
	MemPtrUnlock(app);
	FntSetFont(currFont);

	//change the draw window
	WinSetDrawWindow(activeWinH);
	
	//blit
	bounds.topLeft.x = 0;
	bounds.topLeft.y = 0;
	bounds.extent.x = AnswerPane.extent.x;
	bounds.extent.y = AnswerPane.extent.y;
	WinCopyRectangle(offscreenWinH, activeWinH, &bounds, AnswerPane.topLeft.x, AnswerPane.topLeft.y, winPaint);
	
	//delete offscreen window
	WinDeleteWindow(offscreenWinH, false);
	
	if (CurrentAnswerTop > 160)
		Scrollup = true;

	if (top > AnswerPane.extent.y)
		Scrolldown = true;
	
	upIndex = GetObjectIndex(LearnScrollUpRepeating);
	downIndex = GetObjectIndex(LearnScrollDownRepeating);
	
	FrmUpdateScrollers(FrmGetActiveForm(), upIndex, downIndex, Scrollup, Scrolldown);
}

Boolean LearnFormHandleEvent(EventType * event){

	FormType* frmP = FrmGetActiveForm();
	UInt16 gadgetIndex;
	RectangleType bounds;
	Boolean handled = false;
	
	switch (event->eType){
		
		case frmOpenEvent:
			
			if (LoadWord()){
				LoadControls();
				DrawBanner();
				FrmDrawForm(frmP);			
				DrawCanvas();
			}
			handled = true;
			break;
			
		case frmUpdateEvent:
			LoadControls();
			FrmDrawForm(frmP);
			DrawCanvas();
			handled = true;
			break;			
			
		case menuEvent:
            return LearnFormDoCommand(event->data.menu.itemID);			
			
		case penDownEvent:
			gadgetIndex = FrmGetObjectIndex(frmP, LearnCanvasGadget);
			FrmGetObjectBounds(frmP,gadgetIndex, &bounds);
			if (RctPtInRectangle(event->screenX, event->screenY, &bounds)){
				SndPlaySystemSound(sndClick);
				FrmGotoForm(EditForm);
				handled = true;
				break;
			}
						
		case ctlSelectEvent:
			if (event->data.ctlSelect.controlID - DynamicPushButtonStart < WordFieldsCount){
				CurrentAnswerField = event->data.ctlSelect.controlID - DynamicPushButtonStart;
				CurrentAnswerTop = 0;
				DrawAnswerPane();
				handled = true;
				break;
			}
			switch (event->data.ctlSelect.controlID){
								
				case LearnShowButton:
					DoControlShowButton();
					handled = true;
					break;
					
				case LearnNextButton:
					DoControlNext();
					handled = true;
					break;
					
				case LearnRightPushButton:
					PushSelection = rightControl;
					DoControlNext();
					break;
					
				case LearnWrongPushButton:
					PushSelection = wrongControl;
					DoControlNext();
					break;
					
				case LearnBingoPushButton:
					PushSelection = bingoControl;
					DoControlNext();
					break;
					
				case LearnPassPushButton:
					PushSelection = passControl;
					DoControlNext();
					break;
					
				case LearnFailPushButton:
					PushSelection = failControl;
					DoControlNext();
					break;
					
				
				default:
					break;
			
			}
			break;
		
		case ctlRepeatEvent:
			switch(event->data.ctlRepeat.controlID){
				case LearnScrollUpRepeating:
					ScrollCanvas(true);
					break;
				case LearnScrollDownRepeating:
					ScrollCanvas(false);
					break;
			
			}
			break;
			
		case keyDownEvent:

			if (EvtKeydownIsVirtual(event))
			{
				switch (event->data.keyDown.chr)
				{
					case vchrPageUp:
						ScrollCanvas (true);
						handled = true;
						break;
		
					case vchrPageDown:
						ScrollCanvas (false);
						handled = true;
						break;
				}
			}
			break;
			
		default:
			break;
	}
	
	return handled;
}

Boolean LearnFormDoCommand(UInt16 command){
	
	FormType* frmP = FrmGetActiveForm();
	Boolean handled = false;
	
	switch(command){
//		case OptionQuit:
//			MenuEraseStatus(0);
			
//			if (CurrentDB != NULL) DmCloseDatabase(CurrentDB);
//			HeaderRecordIndex = HeaderIndexCounts; 
//			FrmGotoForm(MainForm);
//			handled = true;
//			break;
		
		default:
			break;
	}
	return handled;
}

UInt16 DrawPaneHeight(Boolean draw){
	FontID currFont;
	UInt16 top = 0;
	WordRecordType record;
	MemHandle recordH;
	WordFields i;
	char* p;
	SugarAppInfoType * appInfo;
	
	appInfo = GetAppInfoPtr(CurrentDB);
	currFont = FntGetFont();
	GetWordRecord(CurrentDB, CurrentRecord, &record, &recordH);
	for (i = WordFieldQuestion; i < WordFieldsCount; i++){
		if (GetBitMacro(fieldFlag.allBits, i) != 0 && record.field[i]!= NULL){
			top += 3;
			p = record.field[i];
			FntSetFont(appInfo -> learnFieldFont[i]);
			DrawFieldHeight(p, &top, appInfo -> learnFieldAlignment[i], draw);
		}
	}
	MemHandleUnlock(recordH);
	
	MemPtrUnlock(appInfo);
	FntSetFont(currFont);
	
	top += 6;
	return top;
}

void DrawFieldHeight(char* p, UInt16* top, TextAlignment align, Boolean draw){

	Int16 strWidth;
	Int16 strLength;
	Int16 xpos;
	char* p2;
	
	while (true){
		RemoveBlankHead(&p);
		if ((*p) == 0) break;
		strWidth = 160;
		strLength = StrLen(p);
		//FntCharsInWidth(p, &strWidth, &strLength, &fit);
		strLength = FntWordWrap(p, 160);
		strWidth = FntCharsWidth(p, strLength);
		
		p2 = p + strLength - 1;
		if ((*p2) == 9 || (*p2) == 10 || (*p2) == 13 || (*p2) == 32)
			strLength--;
		
		if (draw){
			switch (align){
				case LeftAlignment:
					xpos = 0;
					break;
				case CenterAlignment:
					xpos = (160 - strWidth)/2;
					break;
				case RightAlignment:
					xpos = 160 - strWidth;
					break;
			}
			WinDrawChars(p, strLength, xpos, *top); 
		}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -