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

📄 thedialog.cpp

📁 Linux/windows 环境下跨平台开发程序
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//TheDialog.cpp, Copyright (c) 2001, 2002, 2003, 2004, 2005 R.Lackner
//Operating system independent code for dialog boxes
//
//    This file is part of RLPlot.
//
//    RLPlot 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; either version 2 of the License, or
//    (at your option) any later version.
//
//    RLPlot 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.
//
//    You should have received a copy of the GNU General Public License
//    along with RLPlot; if not, write to the Free Software
//    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
#include "rlplot.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "TheDialog.h"

extern tag_Units Units[];
extern char TmpTxt[];
extern Default defs;
extern GraphObj *CurrGO;
extern EditText *CurrText;		//current EditText object
extern RECT rTxtCur;			//text cursor position and direction
extern UndoObj Undo;

char *WWWbrowser = 0L;
char *LoadFile = 0L;

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// internal declarations 
static int xbase = 2;
static int ybase = 2;
int dlgtxtheight = 10;
static unsigned long DlgBGcolor = 0x00e0e0e0L;
static unsigned long DlgBGhigh = 0x00e8e8e8L;
TextDEF DlgText = {0x00000000L, 0x00ffffffL, 4.0, 0.0f, 0.0f, 0, 
	TXA_HLEFT | TXA_VTOP, TXM_TRANSPARENT, TXS_NORMAL, FONT_HELVETICA, 0L}; 

//prototypes: WinSpec.cpp
void *CreateDlgWnd(char *title, int x, int y, int width, int height, tag_DlgObj *d, DWORD flags);

//The dialog object which just has the input focus
Dialog *DialogFocus = 0L;
Dialog *DialogDefault = 0L;
Dialog *DialogTabStop = 0L;

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Base classes to dialog items
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
DlgRoot::DlgRoot(DlgInfo *tmpl)
{
	int i;
	RECT rc;

	dlg = 0L;			flags = 0L;		tabstops = 0L;
	DlgText.iSize = dlgtxtheight;		DlgText.ColBg = DlgBGcolor;
	type = NONE;		Id = -2;		cContinue = 0;
	bActive = false;	Result = -1;	c_go = CurrGO;
	CurrDisp = 0L;		oldFocus = DialogFocus;		DialogFocus = 0L;
	oldDefault = DialogDefault;			oldTabStop = DialogTabStop;
	if(tmpl) {
		//count number of items first, then allocate memory
		for(cDlgs=1;!(tmpl[cDlgs-1].flags & LASTOBJ); cDlgs++);
		dlg = (DlgTmpl **)calloc(cDlgs+1, sizeof(DlgTmpl*));
		tabstops =(Dialog**)calloc(cDlgs, sizeof(Dialog*));
		if(dlg) for (i = 0; i < cDlgs; i++) {
			dlg[i] = (DlgTmpl *)malloc(sizeof(DlgTmpl));
			if(dlg[i]) {
				dlg[i]->id = tmpl[i].id;
				dlg[i]->next = tmpl[i].next;
				dlg[i]->first = tmpl[i].first;
				dlg[i]->flags = tmpl[i].flags;
				rc.left = tmpl[i].x * xbase;
				rc.right = rc.left + tmpl[i].w * xbase;
				rc.top = tmpl[i].y * ybase;
				rc.bottom = rc.top + tmpl[i].h * ybase;
				//an item appearing in the following list should have a corresponding
				//  entry in the list of ~DlgRoot()
				switch(tmpl[i].type) {
				case PUSHBUTTON:
					dlg[i]->dialog = new PushButton(this, &tmpl[i],rc,(char*)tmpl[i].ptype);
					break;
				case TEXTBOX:
					dlg[i]->dialog = new TextBox(this, &tmpl[i],rc,(char*)tmpl[i].ptype);
					break;
				case ARROWBUTT:
					dlg[i]->dialog = new ArrowButton(this, &tmpl[i],rc,(int*)tmpl[i].ptype);
					break;
				case COLBUTTON:
					dlg[i]->dialog = new ColorButton(this, &tmpl[i],rc, (unsigned long)tmpl[i].ptype);
					break;
				case FILLBUTTON:
					dlg[i]->dialog = new FillButton(this, &tmpl[i],rc, (FillDEF *)tmpl[i].ptype);
					break;
				case SHADE3D:
					dlg[i]->dialog = new Shade3D(this, &tmpl[i],rc, (FillDEF *)tmpl[i].ptype);
					break;
				case LINEBUTT:
					dlg[i]->dialog = new LineButton(this, &tmpl[i],rc, (LineDEF *)tmpl[i].ptype);
					break;
				case SYMBUTT:
					dlg[i]->dialog = new SymButton(this, &tmpl[i],rc, (Symbol **)tmpl[i].ptype);
					break;
				case FILLRADIO:
					dlg[i]->dialog = new FillRadioButt(this, &tmpl[i],rc, *((unsigned int*)tmpl[i].ptype));
					break;
				case SYMRADIO:
					dlg[i]->dialog = new SymRadioButt(this, &tmpl[i],rc, (int*)tmpl[i].ptype);
					break;
				case CHECKBOX:
					dlg[i]->dialog = new CheckBox(this, &tmpl[i],rc,(char*)tmpl[i].ptype);
					break;
				case CHECKPIN:
					dlg[i]->dialog = new CheckPin(this, &tmpl[i],rc);
					break;
				case TRASH:
					dlg[i]->dialog = new Trash(this, &tmpl[i],rc);
					break;
				case CONFIG:
					dlg[i]->dialog = new Config(this, &tmpl[i],rc);
					break;
				case RADIO0:	case RADIO1:	case RADIO2:
					dlg[i]->dialog = new RadioButton(this, &tmpl[i],rc,(char*)tmpl[i].ptype);
					break;
				case LTEXT:		case RTEXT:		case CTEXT:
					dlg[i]->dialog = new Text(this, &tmpl[i],rc,(char*)tmpl[i].ptype);
					break;
				case EDTEXT:
					dlg[i]->dialog = new InputText(this, &tmpl[i],rc,(char*)tmpl[i].ptype);
					break;
				case RANGEINPUT:
					dlg[i]->dialog = new RangeInput(this, &tmpl[i],rc,(char*)tmpl[i].ptype);
					break;
				case EDVAL1:
					dlg[i]->dialog = new InputValue(this, &tmpl[i],rc,(double*)tmpl[i].ptype);
					break;
				case INCDECVAL1:
					dlg[i]->dialog = new IncDecValue(this, &tmpl[i],rc,(double*)tmpl[i].ptype);
					break;
				case TXTHSP:
					dlg[i]->dialog = new TxtHSP(this, &tmpl[i],rc, (int*)tmpl[i].ptype);
					break;
				case VSCROLL:
					dlg[i]->dialog = new ScrollBar(this, &tmpl[i],rc, true);
					break;
				case HSCROLL:
					dlg[i]->dialog = new ScrollBar(this, &tmpl[i],rc, false);
					break;
				case ICON:
					dlg[i]->dialog = new Icon(this, &tmpl[i],rc, (int*)tmpl[i].ptype);
					break;
				case GROUP:
					dlg[i]->dialog = new Group(this, &tmpl[i], rc);
					break;
				case GROUPBOX:
					dlg[i]->dialog = new GroupBox(this, &tmpl[i],rc, (char*)tmpl[i].ptype);
					break;
				case SHEET:
					dlg[i]->dialog = new TabSheet(this, &tmpl[i],rc, (TabSHEET *)tmpl[i].ptype);
					break;
				case ODBUTTON:
					dlg[i]->dialog = new ODbutton(this, &tmpl[i],rc, tmpl[i].ptype);
					break;
				case LISTBOX1:
					dlg[i]->dialog = new Listbox(this, &tmpl[i],rc, (char**)tmpl[i].ptype);
					break;
				case TREEVIEW:
					dlg[i]->dialog = new Treeview(this, &tmpl[i],rc, (GraphObj*)tmpl[i].ptype);
					break;
				case LINEPAT:
					dlg[i]->dialog = new LinePat(this, &tmpl[i],rc, (LineDEF *)tmpl[i].ptype);
					break;
				default:
					dlg[i]->dialog = NULL;
					}
				}
			else break;
			}
		}
}

DlgRoot::~DlgRoot()
{
	int i;

	if(dlg){
		for (i = 0; dlg[i] && i < cDlgs; i++) {
			//we need to delete each object using a cast on its proper type
			//to call the proper destructor
			if(dlg[i]->dialog){
				switch(dlg[i]->dialog->type) {
				case PUSHBUTTON:	delete((PushButton*)dlg[i]->dialog);		break;
				case TEXTBOX:		delete((TextBox*)dlg[i]->dialog);			break;
				case ARROWBUTT:		delete((ArrowButton*)dlg[i]->dialog);		break;
				case COLBUTTON:		delete((ColorButton*)dlg[i]->dialog);		break;
				case FILLBUTTON:	delete((FillButton*)dlg[i]->dialog);		break;
				case SHADE3D:		delete((Shade3D*)dlg[i]->dialog);			break;
				case LINEBUTT:		delete((LineButton*)dlg[i]->dialog);		break;
				case SYMBUTT:		delete((SymButton*)dlg[i]->dialog);			break;
				case FILLRADIO:		delete((FillRadioButt*)dlg[i]->dialog);		break;
				case SYMRADIO:		delete((SymRadioButt*)dlg[i]->dialog);		break;
				case CHECKBOX:		delete((CheckBox*)dlg[i]->dialog);			break;
				case CHECKPIN:		delete((CheckPin*)dlg[i]->dialog);			break;
				case TRASH:			delete((Trash*)dlg[i]->dialog);				break;
				case CONFIG:		delete((Config*)dlg[i]->dialog);			break;
				case RADIO0:	case RADIO1:
				case RADIO2:		delete((RadioButton*)dlg[i]->dialog);		break;
				case LTEXT:	case RTEXT:	
				case CTEXT:	delete((Text*)dlg[i]->dialog);						break;
				case EDTEXT:		delete((InputText*)dlg[i]->dialog);			break;
				case RANGEINPUT:	delete((RangeInput*)dlg[i]->dialog);			break;
				case EDVAL1:		delete((InputValue*)dlg[i]->dialog);		break;
				case INCDECVAL1:	delete((IncDecValue*)dlg[i]->dialog);		break;
				case TXTHSP:		delete((TxtHSP*)dlg[i]->dialog);			break;
				case HSCROLL:
				case VSCROLL:		delete((ScrollBar*)dlg[i]->dialog);			break;
				case ICON:			delete((Icon*)dlg[i]->dialog);				break;
				case GROUP:			delete((Group*)dlg[i]->dialog);				break;
				case GROUPBOX:		delete((GroupBox*)dlg[i]->dialog);			break;
				case SHEET:			delete((TabSheet*)dlg[i]->dialog);			break;
				case ODBUTTON:		delete((ODbutton*)dlg[i]->dialog);			break;
				case LISTBOX1:		delete((Listbox*)dlg[i]->dialog);			break;
				case TREEVIEW:		delete((Treeview*)dlg[i]->dialog);			break;
				case LINEPAT:		delete((LinePat*)dlg[i]->dialog);			break;
				default:
				//DEBUG: we should issue a message that an unknown item is
				//   deleted: this might result in a memory leak;
					InfoBox("unknown dialog object found\nin \"DlgRoot::~DlgRoot()\"");
					delete(dlg[i]->dialog);
					break;
					}
				}
			free(dlg[i]);
			}
		free(dlg);
		}
	if(tabstops) free(tabstops);
	DialogFocus = oldFocus;			DialogDefault = oldDefault;
	DialogTabStop = oldTabStop;		CurrGO = c_go;
}

bool
DlgRoot::Command(int cmd, void *tmpl, anyOutput *o)
{
	Dialog *d;
	int i, j;
	RECT rc;

	switch (cmd) {
	case CMD_UNDO:
		if(CurrDisp) {
			Undo.Restore(false, CurrDisp);
			DoPlot(CurrDisp);
			}
		return true;
	case CMD_REDRAW:
		if(CurrDisp) {
			CurrDisp->Erase(DlgBGcolor);		DoPlot(CurrDisp);
			CurrDisp->GetSize(&rc);				CurrDisp->UpdateRect(&rc, false);
			}
		return true;
	case CMD_MOUSE_EVENT:
		mev = (MouseEvent *) tmpl;
		switch(mev->Action) {
		case MOUSE_LBDOWN:
			bActive = true;
		case MOUSE_MOVE:
			if(!(mev->StateFlags & 1))return false;
			//track mouse and display controls accordingly
			if(bActive)ForEach(CMD_MOUSE_EVENT, 0, o);
			return true;
		case MOUSE_LBDOUBLECLICK:
			ForEach(CMD_MOUSE_EVENT, 0, o);
			bActive = false;				//skip next event (LB up);
			return true;
		case MOUSE_LBUP:
			if(bActive)ForEach(CMD_LBUP, 0, o);
			return true;
			}
		return true;
	case CMD_ENDDIALOG:
		d = (Dialog *)tmpl;
		if(d) {
			Result = d->Id;		// end dialog by object
			cContinue = 0;
			}
		else if(cContinue >0) {
			cContinue--;
			return true;		// no end upon killing the focus
			}
		else {
			Result = 0;			// end dialog with closebox or loose focus
			}
		return true;
	case CMD_CONTINUE:
		cContinue++;
		return true;
	case CMD_TABDLG:
		if(tabstops) for (i = 0; i < cDlgs; i++) 
			if(!tabstops[i] || tabstops[i] == (Dialog*)tmpl) {
				tabstops[i] = (Dialog*)tmpl;
				return true;
				}
		return false;
	case CMD_NOTABDLG:
		if(tabstops) for (i = j = 0; i < cDlgs; i++) {
			if(tabstops[i] == (Dialog*)tmpl) tabstops[i] = 0L;
			if(tabstops[i]) tabstops[j++] = tabstops[i];
			}
		return true;
	case CMD_TAB:
		HideTextCursor();
		if(tabstops && DialogTabStop) {
			for(i = 0; tabstops[i] && tabstops[i] != DialogTabStop && i < cDlgs; i++);
			if(tabstops[i]) i++;
			if(!tabstops[i]) i = 0;
			switch(tabstops[i]->type) {
			case PUSHBUTTON:
				d = DialogDefault;
				DialogTabStop = DialogDefault = tabstops[i];
				d->DoPlot(o);
				DialogDefault->DoPlot(o);
				break;
			case EDTEXT:			case EDVAL1:	case RANGEINPUT:
			case INCDECVAL1:
				DialogTabStop = DialogFocus = tabstops[i];
				if((InputText*)DialogFocus->bActive)
					((InputText*)DialogFocus)->Activate(DialogFocus->Id, true);
				else Command(cmd, tmpl, o);
				break;
				}
			}
		return true;
	case CMD_SHTAB:
		HideTextCursor();
		if(tabstops && DialogTabStop) {
			for(j = 0; tabstops[j]; j++);
			for(i = j-1; tabstops[i] != DialogTabStop && i; i--);
			i = i >0 ? i-1 : j-1;
			switch(tabstops[i]->type) {
			case PUSHBUTTON:
				d = DialogDefault;
				DialogTabStop = DialogDefault = tabstops[i];
				d->DoPlot(o);
				DialogDefault->DoPlot(o);
				break;
			case EDTEXT:			case EDVAL1:			case INCDECVAL1:
			case RANGEINPUT:
				DialogTabStop = DialogFocus = tabstops[i];
				((InputText*)DialogFocus)->Activate(DialogFocus->Id, true);
				break;
				}
			}
		return true;
	case CMD_CURRUP:	case CMD_CURRDOWN:
		if(DialogFocus && DialogFocus->type == TEXTBOX)
			return DialogFocus->Command(cmd, tmpl, o);
        else return CurUpDown(cmd);
	case CMD_CURRLEFT:	case CMD_CURRIGHT:	case CMD_DELETE:
	case CMD_POS_FIRST:	case CMD_POS_LAST:	case CMD_SHIFTLEFT:
	case CMD_SHIFTRIGHT:	case CMD_COPY:	case CMD_PASTE:
		Undo.SetDisp(CurrDisp);
		bActive = true;
		if(DialogFocus)return DialogFocus->Command(cmd, tmpl, CurrDisp);
        else return false;
	case CMD_ADDCHAR:
		if(!tmpl) return false;
		bActive = true;
		if(*((int*)tmpl) == 27) {						//Esc
			HideCopyMark();
			for (i = 0; dlg[i] && i < cDlgs; i++) 
				if(dlg[i]->dialog) dlg[i]->dialog->Command(cmd, tmpl, o);
			return Command(CMD_REDRAW, 0L, 0L);
			}
		if(DialogDefault && *((int*)tmpl) == 0x0d){		//return pressed
			HideTextCursor();
			return DialogDefault->Command(cmd, tmpl, o);
			}
		if(DialogFocus)return DialogFocus->Command(cmd, tmpl, o);
        else return false;
	case CMD_UNLOCK:
		CurrDisp = 0L;
		for(i = 0; i < cDlgs; i++)
			if(dlg[i] && dlg[i]->dialog) dlg[i]->dialog->Command(CMD_UNLOCK, 0L, 0L);
		break;
		}
	return false;
}

void
DlgRoot::DoPlot(anyOutput *o)
{
	int i;

	HideCopyMark();
	if(tabstops) for(i = 0; i < cDlgs; tabstops[i++] = 0);
	if(o)CurrDisp = o;
	if(CurrDisp) {
		CurrDisp->SetTextSpec(&DlgText);
		ForEach(CMD_DOPLOT, 0, CurrDisp);
		}
}

bool
DlgRoot::CurUpDown(int cmd)
{
	int i, ya, yb, dy;
	Dialog *above=0L, *below=0L;

	ya = -1000;		yb = 10000;
	if(DialogFocus && tabstops && DialogTabStop == DialogFocus) {
		for(i = 0; tabstops[i] && i < cDlgs; i++) {
			if(tabstops[i] != DialogTabStop) {
				switch(tabstops[i]->type) {
				case EDVAL1:	case INCDECVAL1:	case EDTEXT:	case RANGEINPUT:
					if(rTxtCur.left > tabstops[i]->cr.left && 
						rTxtCur.right < tabstops[i]->cr.right) {
						if((dy = (tabstops[i]->cr.top - rTxtCur.top))< 0) {
							if(dy > ya) {
								ya = dy;	above = tabstops[i];
								}
							}
						else {
							if(dy < yb) {
								yb = dy;	below = tabstops[i];
								}
							}
						}
					break;
					}
				}
			}
		switch(cmd) {
		case CMD_CURRUP:
			if(above) {
				above->Select(rTxtCur.left, (above->cr.top + above->cr.bottom)>>1, CurrDisp); 
				}
			break;
		case CMD_CURRDOWN:
			if(below) {
				below->Select(rTxtCur.left, (below->cr.top + below->cr.bottom)>>1, CurrDisp); 
				}
			break;
			}
		}
	return false;
}

bool
DlgRoot::GetColor(int id, DWORD *color)
{
	int i;

	i = FindIndex(id);
	if(i && dlg[i]) return dlg[i]->dialog->GetColor(id, color);
	return false;
}

void
DlgRoot::SetColor(int id, DWORD color)
{
	int i;

	i = FindIndex(id);
	if(i && dlg[i]) {
		dlg[i]->dialog->SetColor(id, color);
		if(CurrDisp && !(dlg[i]->dialog->flags & HIDDEN)) dlg[i]->dialog->DoPlot(CurrDisp);
		}
}

bool
DlgRoot::GetValue(int id, double *val)
{
	int i;

	i = FindIndex(id);
	if(i && dlg[i]) return dlg[i]->dialog->GetValue(id, val);
	return false;
}

bool
DlgRoot::GetInt(int id, int *val)
{
	int i;

	i = FindIndex(id);
	if(i && dlg[i]) return dlg[i]->dialog->GetInt(id, val);
	return false;
}

bool
DlgRoot::SetCheck(int id, anyOutput *o, bool state)
{
	int i;

⌨️ 快捷键说明

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