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

📄 upseudosupport.cpp

📁 WinCVS 源码,流行的CVS客户端源码程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "stdafx.h"

#include "UPseudoSupport.h"
#include "uconsole.h"
#include "udraw.h"
#include "umenu.h"

#include <stdio.h>
#include <stdlib.h>

#include <UGAColorRamp.h>
#include <LTableMonoGeometry.h>
#include <LTableMultiGeometry.h>
#include <LTableSingleSelector.h>
#include <LOutlineKeySelector.h>
#include <LOutlineTable.h>
#include <LTextTableView.h>
#include <LCellSizeToFit.h>
#include <LTableArrayStorage.h>
#include <LTextArray.h>
#include <LTableSingleRowSelector.h>
#include <LEditText.h>
#include <LPopupButton.h>
#include <LScrollBar.h>
#include <LPageController.h>
#include <LTabsControl.h>
#include <LSlider.h>
#include <LLittleArrows.h>
#include <LCheckBoxGroupBox.h>

#ifndef NEW
#	define NEW new
#endif

#ifdef __GNUC__
#   include <typeinfo>
#else
#   if __option(RTTI)
#	include <typeinfo>
#   else
#	error "RTTI option disabled -- must be enabled for LPaneTree to function"
#   endif
#endif

bool gTurnOffBroadcast = false;

class UPPMenu : public UMenu
{
public:
	UPPMenu();
	virtual ~UPPMenu();
	
	static int sPPMenuWidID;
};

class LPseudoDrawAttachment : public LAttachment
{
public:
	LPseudoDrawAttachment(int widid, int cmdid);
	virtual ~LPseudoDrawAttachment();

protected:
	virtual void	ExecuteSelf(
							MessageT		inMessage,
							void*			ioParam);
	
	int m_widid, m_cmdid;
};

static bool macpp_getcmdid(LPane *view, int & cmdid)
{
	PaneIDT atype = view->GetPaneID();
	const char *atypestr = (char *)&atype;
	if(atypestr[0] != 'p' && atypestr[1] != 's')
		return false;
	
	if(atypestr[2] < '0' || atypestr[2] > '9')
		return false;
	if(atypestr[3] < '0' || atypestr[3] > '9')
		return false;
	cmdid = (int)(atypestr[2] - '0') * 10 + (int)(atypestr[3] - '0') + EV_COMMAND_START;
	return true;
}

static bool macpp_getcmdid(PaneIDT atype, int & cmdid)
{
	const char *atypestr = (char *)&atype;
	if(atypestr[0] != 'p' && atypestr[1] != 's')
		return false;
	
	if(atypestr[2] < '0' || atypestr[2] > '9')
		return false;
	if(atypestr[3] < '0' || atypestr[3] > '9')
		return false;
	cmdid = (int)(atypestr[2] - '0') * 10 + (int)(atypestr[3] - '0') + EV_COMMAND_START;
	return true;
}

LPseudoWinAttachment *macpp_getattachwindow(UWidget *wid)
{
	LPane *win = (LPane *)wid->GetWidget(kUMainWidget);
	LWindow *wind = dynamic_cast<LWindow *>((LPane *)win);
	
	if(wind != 0L)
	{
		return macpp_getattachwindow(wind);
	}
	return 0L;
}

LPseudoWinAttachment *macpp_getattachwindow(LWindow *wind)
{
	if(wind != 0L)
	{
		const TArray<LAttachment*>*	theAttachments = wind->GetAttachmentsList();

		if (theAttachments != nil)
		{
			TArrayIterator<LAttachment*> iterate(*theAttachments);
			
			LAttachment*	theAttach;
			while (iterate.Next(theAttach))
			{
				LPseudoWinAttachment*	theWinAttach = dynamic_cast<LPseudoWinAttachment*>(theAttach);
				if (theWinAttach != nil)
				{
					return theWinAttach;
				}
			}
		}
	}
	return 0L;
}

void macpp_fecthview(int widid, LPane *pane)
{
	int cmdid;
	if(macpp_getcmdid(pane, cmdid))
	{
		UEventSendMessage(widid, EV_INIT_WIDGET, cmdid, pane);

		// look for any attachement we know of
		const TArray<LAttachment*>*	theAttachments = pane->GetAttachmentsList();
		if (theAttachments != nil)
		{
			TArrayIterator<LAttachment*> iterate(*theAttachments);

			LAttachment*	theAttach;
			while (iterate.Next(theAttach))
			{
				UPseudoPageHider *hider = dynamic_cast<UPseudoPageHider*>(theAttach);
				if(hider != 0L)
					hider->SetWidID(widid);
			}
		}

		// for any control, set the broadcast message to be the Pane ID
		LControl *control = dynamic_cast<LControl*>(pane);
		if(control != 0L && control->GetValueMessage() == 0)
		{
			control->SetValueMessage(pane->GetPaneID());
		}
		
		// idem
		LCheckBoxGroupBox *groupbox = dynamic_cast<LCheckBoxGroupBox*>(pane);
		if(groupbox != 0L && groupbox->GetValueMessage() == 0)
		{
			groupbox->SetValueMessage(pane->GetPaneID());
		}
		
		// set the widget id for some custom controls
		UPseudoPlaceHolder *holder = dynamic_cast<UPseudoPlaceHolder*>(pane);
		if(holder != 0L)
		{
			holder->SetWidID(widid);
			return; // don't fetch inside, it'll be owned by another pseudo widget
		}

		// this attachment let us fire a EV_CUSTOM_DRAW event when painting
		if(typeid(*pane) == typeid(LView))
		{
			LPseudoDrawAttachment *attach = NEW LPseudoDrawAttachment(widid, cmdid);
			pane->AddAttachment(attach);
		}
	}

	// menus with an unspecified menu id need to be created if we want to use
	// later on the EV_COMBO_APPEND message on it.
	LPopupButton *controler = dynamic_cast<LPopupButton*>(pane);
	if(controler != 0L)
	{
		if(controler->GetMenuID() == MENU_Unspecified && controler->GetMacMenuH() == 0L)
			controler->SetMacMenuH(::NewMenu(::UniqueID('MENU'), "\p"), true);
	}

	// recurse
	LView *view = dynamic_cast<LView*>(pane);
	if(view == 0L)
		return;

	TArrayIterator<LPane*> iterator(view->GetSubPanes());
	LPane	*theSub;
	while (iterator.Next(theSub))
	{
		macpp_fecthview(widid, theSub);
	}
}

void macpp_linkbroadcasters(LPane *pane, LListener *listener)
{
	LBroadcaster *broadcaster = dynamic_cast<LBroadcaster *>(pane);
	if(broadcaster != 0L && !broadcaster->HasListener(listener))
		broadcaster->AddListener(listener);
	
	LView *view = dynamic_cast<LView*>(pane);
	if(view == 0L)
		return;
	
	TArrayIterator<LPane*> iterator(view->GetSubPanes());
	LPane	*theSub;
	while (iterator.Next(theSub))
	{
		macpp_linkbroadcasters(theSub, listener);
	}
}

void macpp_preparetable(LOutlineTable *table)
{
	if(table->GetTableGeometry() != 0L)
		return;
	
	// try to guess a good height for the geometry
	int height = 20;
	TextTraitsH traitsH = UTextTraits::LoadTextTraits(table->GetTextTraits());
	if(traitsH != 0L)
		height = ((**traitsH).size * 6) / 4;

	LTableMultiGeometry *geom = NEW LTableMultiGeometry(table, 50, height);
	if(geom != 0L)
		table->SetTableGeometry(geom);
	table->SetTableSelector(NEW LTableSingleRowSelector( table ));
	table->AddAttachment(NEW LOutlineKeySelector(table, msg_AnyMessage));
	table->AddAttachment(NEW LKeyScrollAttachment(table));
}

void macpp_preparetable(void *win, LTextTableView *table)
{
	if(table->GetTableGeometry() != 0L)
		return;
	
	SDimension16	tableSize;
	table->SetCellSizer(NEW LCellSizeToFit());
	table->GetFrameSize(tableSize);
	table->SetTableGeometry(NEW LTableMonoGeometry(table, 
		tableSize.width/1 /* col width = width/num Cols */, 
		12  /* row height */));
	table->SetTableSelector(NEW LTableSingleRowSelector( table ));
	table->SetTableStorage(NEW LTableArrayStorage(table, (UInt32)0));
	table->SetDoubleClickMessage(UTextTableView_DoubleClick);
	table->SetSingleClickMessage(UTextTableView_SingleClick);
	table->SetCustomHilite(true); // cause there is a hilite bug if we don't
}

static LWindow *macpp_findwindow(LPane *pane)
{
	LPane *topView = 0L;
	while(pane != 0L)
	{
		topView = pane;
		pane = pane->GetSuperView();
	}
	return dynamic_cast<LWindow *>(topView);
}

LPseudoDrawAttachment::LPseudoDrawAttachment(int widid, int cmdid) : LAttachment(msg_DrawOrPrint),
	m_widid(widid), m_cmdid(cmdid)
{
}

LPseudoDrawAttachment::~LPseudoDrawAttachment()
{
}

void LPseudoDrawAttachment::ExecuteSelf(MessageT inMessage, void *ioParam)
{
	SetExecuteHost(true);
	LView *view = dynamic_cast<LView*>(GetOwnerHost());
	UEventSendMessage(m_widid, EV_CUSTOM_DRAW, m_cmdid, view);
}

LMainPseudoAttachment::LMainPseudoAttachment() : LAttachment(msg_AnyMessage)
{
	StartIdling();
}

LMainPseudoAttachment::~LMainPseudoAttachment()
{
}

void LMainPseudoAttachment::SpendTime(const EventRecord&	inMacEvent)
{
	::UEventGiveTime();
}

void LMainPseudoAttachment::ExecuteSelf(MessageT inMessage, void *ioParam)
{
	SetExecuteHost(true);
	
	if(UPPMenu::sPPMenuWidID == -1)
	{
		NEW UPPMenu();
	}
	
	if((inMessage > 0 && inMessage < 800) || inMessage >= EV_COMMAND_START)
	{
		int handledFlag;
		int res = UEventSendMessageExt(UPPMenu::sPPMenuWidID, EV_CMD,
			inMessage, 0L, &handledFlag);
		if(res == 0 && handledFlag)
		{
			SetExecuteHost(false);
			return;
		}
		else
			SetExecuteHost(true);
	}

	switch (inMessage)
	{
		case msg_CommandStatus:
		{
			SCommandStatus *status = static_cast<SCommandStatus*> (ioParam);
			CommandT cmdid = status->command;
			UPseudoCmdStatusWrapper wrapper;
			wrapper.outEnabled = status->enabled;
			wrapper.outUsesMark = status->usesMark;
			wrapper.outMark = status->mark;
			wrapper.outName = status->name;
			
			// first forward the command to the focused widget : if it doesn't want it
			// we give it to the next pseudo widget.
			int widFocus = UWidget::GetFocus();
			if(widFocus != -1)
			{
				UCmdUI pUI(cmdid);
				pUI.m_wrapper = &wrapper;
				UEventSendMessage(widFocus, EV_UPDTCMD, pUI.m_nID, &pUI);
				if(!pUI.CanContinue())
				{
					SetExecuteHost(false);
					break;
				}
			}

			STD map<int, UCmdTarget *>::const_iterator i;
			const STD map<int, UCmdTarget *> & targets = UEventGetTargets();
			for(i = targets.begin(); i != targets.end(); ++i)
			{
				int widid = (*i).first;
				if(widid == widFocus)
					continue;
				
				UCmdUI pUI(cmdid);
				pUI.m_wrapper = &wrapper;
				UEventSendMessage(widid, EV_UPDTCMD, pUI.m_nID, &pUI);
				if(!pUI.CanContinue())
					break;
			}
			
			if(i != targets.end())
				SetExecuteHost(false);
			break;
		}

		case msg_Event:
		{
			EventRecord *ev = static_cast<EventRecord*> (ioParam);

#if 0
			if(ev->what == activateEvt)
			{
				bool activate = (ev->modifiers & activeFlag) != 0;
				LWindow	*theWindow = LWindow::FetchWindowObject((WindowPtr)ev->message);
				if(theWindow != 0L)
				{
					UEventNotifyMessage(EV_UPDATEFOCUS, !activate, theWindow);
						// so the pseudo widget update its current widget.
						// it's important for the menu handling.
				}
			}
#endif
			if(ev->what == activateEvt ||
				ev->what == mouseDown ||
				ev->what == mouseUp ||
				ev->what == keyDown ||
				ev->what == keyUp ||
				ev->what == autoKey)
			{
				UWidget::DoValidUI(false);
				LCommander::SetUpdateCommandStatus(true);
			}
			break;
		}
	}
}

LPseudoWinAttachment::LPseudoWinAttachment(int widid) : LAttachment(msg_GrowZone), m_widid(widid)
{
	::SetRect(&m_lastRect, 0, 0, 0, 0);

	CheckWindowSize();
}

LPseudoWinAttachment::~LPseudoWinAttachment()
{
	UEventSendMessage(m_widid, EV_DESTROY, 0, 0L);
}

int LPseudoWinAttachment::GetPageValue(int cmdid) const
{
	std::map<int, int>::const_iterator i = m_PageValues.find(cmdid);
	if(i != m_PageValues.end())
		return (*i).second;
	return 1;
}

void LPseudoWinAttachment::SetPageValue(int cmdid, int value)
{
	std::map<int, int>::value_type val(cmdid, value);
	m_PageValues.erase(cmdid);
	m_PageValues.insert(val);
}

void LPseudoWinAttachment::ExecuteSelf(MessageT inMessage, void *ioParam)
{
	SetExecuteHost(true);
	
	// not used yet
}

void LPseudoWinAttachment::CheckWindowSize(void)
{
	LWindow *wind = dynamic_cast<LWindow*>(GetOwnerHost());
	if(wind != 0L)
	{
		Rect r;
		wind->GetGlobalBounds(r);
		if(!::EqualRect(&r, &m_lastRect))
		{
			m_lastRect = r;
			URect ur(r);
			UEventSendMessage(m_widid, EV_RESIZE, kUMainWidget, &ur);
		}
	}
}

int LPseudoWinAttachment::SearchWidID(LPane *pane)
{
	int res = m_widid;

	// first ask the cache
	std::map<LPane *, int>::iterator i = m_CacheWidgets.find(pane);
	if(i != m_CacheWidgets.end())
		return (*i).second;
	
	// then look if it belongs to a tab
	UCmdTarget *target = UEventQueryWidget(m_widid);
	UWidget *wid = UDYNAMIC_CAST(UWidget, target);
	if(wid == 0L)
		return res;
	
	std::map<int, UWidget *>::iterator t;
	for(t = wid->m_tabs.begin(); t != wid->m_tabs.end(); ++t)
	{
		UWidget *tab = (*t).second;
		std::map<int, void *>::iterator s;
		for(s = tab->m_widgets.begin(); s != tab->m_widgets.end(); ++s)
		{
			if((*s).second == (void *)pane)
			{
				res = tab->GetWidID();
				break; // it's a tab widget
			}
		}
	}

	// so we guess it's in the main widget !
	std::map<LPane *, int>::value_type val(pane, res);
	m_CacheWidgets.insert(val);
	
	return res;
}

void LPseudoWinAttachment::InvalidCache(UWidget *tab_wid)
{
	std::map<int, void *>::iterator s;
	for(s = tab_wid->m_widgets.begin(); s != tab_wid->m_widgets.end(); ++s)
	{
		std::map<LPane *, int>::iterator i = m_CacheWidgets.find((LPane *)(*s).second);
		if(i != m_CacheWidgets.end())
			m_CacheWidgets.erase(i);
	}
}


void LPseudoWinAttachment::ListenToMessage(
							MessageT		inMessage,
							void*			ioParam)
{
	int cmdid;
	LPane *pane;
	
	if(gTurnOffBroadcast)
		return;

⌨️ 快捷键说明

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