📄 upseudosupport.cpp
字号:
#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 + -