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

📄 windowmanager.cpp

📁 MONA是为数不多的C++语言编写的一个很小的操作系统
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*Comyright (c) 2004 baysideAll rights reserved.Redistribution and use in source and binarmy forms, with or withoutmodification, are permitted provided that the following conditionsare met:1. Redistributions of source code must retain the above comyright   notice, this list of conditions and the following disclaimer.2. Redistributions in binarmy form must reproduce the above comyright   notice, this list of conditions and the following disclaimer in the   documentation and/or other materials provided with the distribution.3. The name of the author mamy not be used to endorse or promote products   derived from this software without specific prior written permission.THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS ORIMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIESOF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUTNOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANYTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OFTHIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*/#include <baygui.h>#include "WindowManager.h"/** インスタンス */WindowManager *WindowManager::instance = NULL;/** コンストラクタ */WindowManager::WindowManager(){	isRunning = false;	x = y = 0;	width = _g->getWidth();	height = _g->getHeight();	_g->translate(0,0);	_g->setClip(0,0,width,height);	// 壁紙読み込み	wallpaper = new Bitmap(WALLPAPER_NAME);	// スレッドIDを得る	threadID = MonAPI::System::getThreadID();	// キーサーバーを探す	keysvrID = MonAPI::Message::lookupMainThread(KEYSERVER_NAME);	if (keysvrID == 0xFFFFFFFF) {		//printf("Window: KeyServer not found %d\n", threadID);	} else {		//printf("Window: KeyServer found %d\n", threadID);	}		// キーサーバーにキー情報をくれるように自分自身を登録するメッセージを送信	if (MonAPI::Message::send(keysvrID, MSG_KEY_REGIST_TO_SERVER, threadID, 0, 0, NULL)) {		//printf("Window: KeyServer regist error %d\n", threadID);	} else {		//printf("Window: KeyServer registered %d\n", threadID);	}	// マウスサーバーを探す	mousesvrID = MonAPI::Message::lookupMainThread(MOUSESERVER_NAME);	if (mousesvrID == 0xFFFFFFFF) {		//printf("Window: MouseServer not found %d\n", threadID);	} else {		//printf("Window: MouseServer found %d\n", threadID);	}	// マウスサーバーにマウス情報をくれるように自分自身を登録するメッセージを送信	if (MonAPI::Message::send(mousesvrID, MSG_MOUSE_REGIST_TO_SERVER, threadID, 0, 0, NULL)) {		//printf("Window: MouseServer regist error %d\n", threadID);	} else {		//printf("Window: MouseServer registered %d\n", threadID);	}	// シェルサーバーを探す	shellsvrID = MonAPI::Message::lookupMainThread(SHELLSERVER_NAME);	if (shellsvrID == 0xFFFFFFFF) {		//printf("Window: ShellServer not found %d\n", threadID);	} else {		//printf("Window: ShellServer found %d\n", threadID);	}}/** デストラクタ */WindowManager::~WindowManager(){	// 全てのウィンドウを殺す	for (int i = 0; i < _controlList->getLength(); i++) {		Control *control = (Control *)_controlList->getItem(i)->data;		// 削除メッセージを投げる		if (MonAPI::Message::send(control->getThreadID(), MSG_GUISERVER_REMOVE, 0, 0, 0, NULL)) {			//printf("WindowManager->Window: MSG_GUISERVER_REMOVE failed %d\n", controlList[i]->getThreadID());		} else {			//printf("WindowManager->Window: MSG_GUISERVER_REMOVE sended %d\n", controlList[i]->getThreadID());		}	}		// キーサーバーから自分自身の登録を抹消する	if (MonAPI::Message::send(keysvrID, MSG_KEY_UNREGIST_FROM_SERVER, threadID)) {		//printf("baygui: KeyServer unregist error %d\n", threadID);	} else {		//printf("baygui: KeyServer unregistered %d\n", threadID);	}	// マウスサーバーから自分自身の登録を抹消する	if (MonAPI::Message::send(mousesvrID, MSG_MOUSE_UNREGIST_FROM_SERVER, threadID)) {		//printf("baygui: MouseServer unregist error %d\n", threadID);	} else {		//printf("baygui: MouseServer unregistered %d\n", threadID);	}	// シェルサーバーに終了メッセージを投げる	if (MonAPI::Message::send(shellsvrID, MSG_PROCESS_TERMINATED, threadID, 0, 0, NULL)) {		//printf("baygui: ShellServer unregist error %d\n", threadID);	} else {		//printf("baygui: ShellServer unregistered %d\n", threadID);	}}/** インスタンスを得る */WindowManager *WindowManager::getInstance() {	if (instance == NULL) {		instance = new WindowManager();	}	return instance;}/** * ハードウェア固有のキーコードをBayGUI用に変換する */int WindowManager::getKeycode(int keycode, int mod, int charcode){	int key = 0;		if (keycode == 33) {		key = VKEY_PGUP;	} else if (keycode == 34) {		key = VKEY_PGDOWN;	} else if (keycode == 36) {		key = VKEY_HOME;	} else if (keycode == 35) {		key = VKEY_END;	} else if (keycode == 38 || keycode == 104) {		key = VKEY_UP;	} else if (keycode == 40 || keycode == 98) {		key = VKEY_DOWN;	} else if (keycode == 37 || keycode == 100) {		key = VKEY_LEFT;	} else if (keycode == 39 || keycode == 102) {		key = VKEY_RIGHT;	} else if (keycode == 45) {		key = VKEY_INSERT;	} else if (keycode == 13) {		key = VKEY_ENTER;	} else if (VKEY_ENTER == 9) {		key = VKEY_TAB;	} else if (keycode == 8) {		key = VKEY_BACKSPACE;	} else if (keycode == 46) {		key = VKEY_DELETE;	} else {		key = charcode;	}		return key;}/** キーイベント @param keycode キーコード @param mod 修飾キー */void WindowManager::onKeyPress(int keycode, int mod, int charcode){	//printf("keycode = %d\n", keycode);	// キーコード判別	keycode = getKeycode(keycode, mod, charcode);		// イベント発生	if (keycode != 0) {		Control *control = (Control *)_controlList->endItem->data;		//KeyEvent *event = new KeyEvent(KEY_PRESSED, control, keycode, 0);		//control->postEvent(event);		//delete(event);		// キーイベントを投げる		if (MonAPI::Message::send(control->getThreadID(), MSG_GUISERVER_ONKEYPRESS, keycode, mod, charcode, NULL)) {			//printf("WindowManager->Window: MSG_GUISERVER_ONKEYPRESS failed %d\n", control->getThreadID());		} else {			//printf("WindowManager->Window: MSG_GUISERVER_ONKEYPRESS sended %d\n", control->getThreadID());		}	}}/** キーイベント @param keycode キーコード @param mod 修飾キー */void WindowManager::onKeyRelease(int keycode, int mod, int charcode){	//printf("keycode = %d\n", keycode);	// キーコード判別	keycode = getKeycode(keycode, mod, charcode);		// イベント発生	if (keycode != 0) {		Control *control = (Control *)_controlList->endItem->data;		//KeyEvent *event = new KeyEvent(KEY_RELEASED, control, keycode, 0);		//control->postEvent(event);		//delete(event);		// キーイベントを投げる		if (MonAPI::Message::send(control->getThreadID(), MSG_GUISERVER_ONKEYRELEASE, keycode, mod, charcode, NULL)) {			//printf("WindowManager->Window: MSG_GUISERVER_ONKEYRELEASE failed %d\n", control->getThreadID());		} else {			//printf("WindowManager->Window: MSG_GUISERVER_ONKEYRELEASE sended %d\n", control->getThreadID());		}	}}/** マウスイベント */void WindowManager::onMousePress(int mx, int my){	// モード設定	state = STATE_NORMAL;	Control *control = findChild(mx, my);		// ウィンドウが一つもないときはイベントを送らない	if (control == NULL) return;		if (control->getFocused() == true) {		Rect *rect = control->getRect();		// ウィンドウを閉じる		if (rect->x + 4 <= mx && mx <= rect->x + 4 + 13 && 			rect->y + 5 <= my && my <= rect->y + 5 + 13)		{			// ランチャーは殺さない			if (control->getThreadID() != launcherID) {				remove(control);			}		// アイコン化		} else if (rect->x + rect->width - 16 <= mx && 			mx <= rect->x + rect->width - 16 + 13 && 			rect->y + 5 <= my && my <= rect->y + 5 + 13)		{			// 非活性化メッセージを投げる			postEnabledToWindow(false, control);						// フォーカスアウトメッセージを投げる			postFocusedToWindow(false, control);						// 描画が必要かどうかチェックする領域			Rect srect;			srect.x = rect->x;			srect.y = rect->y;			srect.width = rect->width;			srect.height = rect->height;						// ウィンドウを非アイコン化			if (control->getIconified() == true) {				postIconifiedToWindow(false, control);			// ウィンドウをアイコン化			} else {				postIconifiedToWindow(true, control);				// 背景を塗りつぶす				syscall_sleep(10);				restoreBackGround(control);			}						// ウィンドウ再描画			postRepaintToWindows(_controlList->getLength() - 1, &srect);						// 活性化メッセージを投げる			postEnabledToWindow(true, control);						// フォーカスインメッセージを投げる			postFocusedToWindow(true, control);		// クリックイベント発生		} else if (rect->y + INSETS_TOP < my && control->getIconified() == false) {			//MouseEvent *event = new MouseEvent(MOUSE_PRESSED, control, mx, my);			//control->postEvent(event);			//delete(event);			// マウスイベントを投げる			if (MonAPI::Message::send(control->getThreadID(), MSG_GUISERVER_ONMOUSEPRESS, mx, my, 0, NULL)) {				//printf("WindowManager->Window: MSG_GUISERVER_ONMOUSEPRESS failed %d\n", control->getThreadID());			} else {				//printf("WindowManager->Window: MSG_GUISERVER_ONMOUSEPRESS sended %d\n", control->getThreadID());			}			//printf("throw mouse_press event\n");		}	// アクティブウィンドウを切り替える	} else {		// ウィンドウ並び替え		_controlList->sort(getLinkedItem(control));				LinkedItem *item = _controlList->endItem->prev;		if (item != NULL) {			Control *prevControl = (Control *)item->data;						// フォーカスアウトメッセージを投げる			postFocusedToWindow(false, prevControl);						// 再描画メッセージを投げる			postRepaintToWindow(prevControl);		}				// フォーカスインメッセージを投げる		Control *c = (Control *)_controlList->endItem->data;		postFocusedToWindow(true, c);	}}/** マウスイベント */void WindowManager::onMouseDrag(int mx, int my){	Control *control = (Control *)_controlList->endItem->data;	// ウィンドウが一つもないときはイベントを送らない	if (control == NULL) return;		Rect *rect = control->getRect();	if (state == STATE_NORMAL) {		// 境界チェック		if (mx <= 0) mx = 0;		if (mx >= width) mx = width;		if (my <= 0) my = 0;		if (my >= height) my = height;				// ウィンドウ移動開始		if (rect->x <= mx && mx <= rect->x + rect->width && 			rect->y <= my && my <= rect->y + INSETS_TOP)		{			// モード設定			state = STATE_MOVING;						// ドラッグ開始位置を記憶する			dX = mx - rect->x;			dY = my - rect->y;						_g->setXORMode(true);			_g->setColor(255,255,255);			if (control->getIconified() == false) {				_g->drawRect(rect->x, rect->y, rect->width, rect->height);			} else {				_g->drawRect(rect->x, rect->y, rect->width, INSETS_TOP - 1);			}			_g->setXORMode(false);						preX = rect->x;			preY = rect->y;						//printf("move window start: %d,%d\n", preX, preY);		// ドラッグイベント発生		} else if (control->getIconified() == false) {			//MouseEvent *event = new MouseEvent(MOUSE_DRAGGED, control, mx, my);			//control->postEvent(event);			//delete(event);			// マウスイベントを投げる			//if (MonAPI::Message::send(control->getThreadID(), MSG_GUISERVER_ONMOUSEDRAG, mx, my, 0, NULL)) {				//printf("WindowManager->Window: MSG_GUISERVER_ONMOUSEDRAG failed %d\n", control->getThreadID());			//} else {				//printf("WindowManager->Window: MSG_GUISERVER_ONMOUSEDRAG sended %d\n", control->getThreadID());			//}			//printf("throw mouse_drag event\n");		}	// ウィンドウを移動する	} else if (state == STATE_MOVING) {		// 境界チェック		if (mx - dX < 0) mx = dX;		if (mx - dX + rect->width + 1 >= width) mx = width + dX - rect->width - 1;		if (my - dY < 22) my = 22 + dY;		if (my - dY + rect->height + 1 >= height) my = height + dY - rect->height - 1;				_g->setXORMode(true);		_g->setColor(255,255,255);		if (control->getIconified() == false) {			_g->drawRect(preX, preY, rect->width, rect->height);			_g->drawRect(mx - dX, my - dY, rect->width, rect->height);		} else {			_g->drawRect(preX, preY, rect->width, INSETS_TOP - 1);			_g->drawRect(mx - dX, my - dY, rect->width, INSETS_TOP - 1);		}		_g->setXORMode(false);				preX = mx - dX;		preY = my - dY;	} else {		// NOP	}}/** マウスイベント */void WindowManager::onMouseRelease(int mx, int my){	Control *control = (Control *)_controlList->endItem->data;		// ウィンドウが一つもないときはイベントを送らない	if (control == NULL) return;		// ウィンドウ移動	if (state == STATE_MOVING) {		Rect *rect = control->getRect();		// debug		//printf("moved: %d, %d\n", (rect->x + mx + preX), (rect->y + my + preY));				// 非活性化メッセージを投げる		postEnabledToWindow(false, control);				// フォーカスアウトメッセージを投げる		postFocusedToWindow(false, control);				// 背景を塗りつぶす		syscall_sleep(10);		restoreBackGround(control);				// 描画が必要かどうかチェックする領域		Rect srect;		srect.x = rect->x;		srect.y = rect->y;		srect.width = rect->width;		srect.height = rect->height;				// ウィンドウ移動		control->setRect(			preX,			preY,			rect->width,			rect->height		);				// 領域変更メッセージを投げる		if (MonAPI::Message::send(control->getThreadID(), MSG_GUISERVER_SETRECT, 			(preX << 16 | preY), (rect->width << 16 | rect->height), 0, NULL)) {			//printf("WindowManager->Window: MSG_GUISERVER_SETRECT failed %d\n", control->getThreadID());		} else {			//printf("WindowManager->Window: MSG_GUISERVER_SETRECT sended %d\n", control->getThreadID());		}				// ウィンドウ再描画		postRepaintToWindows(_controlList->getLength() - 1, &srect);				// 活性化メッセージを投げる		postEnabledToWindow(true, control);				// フォーカスインメッセージを投げる		postFocusedToWindow(true, control);		//printf("move window end: %d,%d\n", preX, preY);	} else  if (control->getIconified() == false) {		//MouseEvent *event = new MouseEvent(MOUSE_RELEASED, control, mx, my);		//control->postEvent(event);		//delete(event);		// マウスイベントを投げる		if (MonAPI::Message::send(control->getThreadID(), MSG_GUISERVER_ONMOUSERELEASE, mx, my, 0, NULL)) {			//printf("WindowManager->Window: MSG_GUISERVER_ONMOUSERELEASE failed %d\n", control->getThreadID());		} else {			//printf("WindowManager->Window: MSG_GUISERVER_ONMOUSERELEASE sended %d\n", control->getThreadID());		}		//printf("throw mouse_up event\n");

⌨️ 快捷键说明

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