📄 sugarmemolearn.c
字号:
#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 + -