在这个问题上,我一直在尝试捕获AUI窗格配置,以便在关闭任何窗格时可以恢复它。wxPHP的文档和wxWidgets的上游文档有些限制,所以我在很大程度上是在摸索。
我已经意识到SavePaneInfo
将帮助我捕获窗格的状态 - 它输出一个透视字符串,表示窗格在给定时刻的位置和选项。因此,我需要做的就是捕获窗格何时更改并更新我的内部表示形式。
为了感兴趣,透视如下所示:
name=auiPane3;caption=Caption 3;state=2099196;dir=3;layer=0;row=0;pos=1;prop=100000;bestw=90;besth=25;minw
=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1
但是,捕获移动/停靠事件并非易事。我可以看到与AUI相关的六个事件:
wxEVT_AUI_FIND_MANAGER
wxEVT_AUI_PANE_BUTTON
wxEVT_AUI_PANE_CLOSE
wxEVT_AUI_PANE_MAXIMISE
wxEVT_AUI_PANE_RESTORE
wxEVT_AUI_PANE_RENDER
我已经能够捕获还原和关闭事件,而find_manager似乎没有任何作用。我在这个窗口上尝试了wxEVT_ANY
,它似乎也没有捕获任何东西。我也在单个窗格上尝试过,但无济于事(据我所知,什么都没有叫):
$managedWindow->getWindowByIndex(0)->Connect(wxEVT_ANY, array($this, "onAny"));
上游库 wxWidgets 的文档提到了此事件:
EVT_AUI_PANE_ACTIVATED
但是,这似乎没有在wxPHP中实现 - 这是我想要的吗?这听起来不太对,但是如果我可以在没有常量的情况下访问它,我肯定会尝试一下。
我想我可以将wxAuiManager::SetArtProvider
与标准艺术提供程序对象一起使用,修改为捕获窗格状态,但这感觉就像一把大锤来敲碎螺母。我还可以捕获关闭事件并更改返回的透视字符串,以便不设置"关闭"位,但这也不是特别优雅。
我想做的事情感觉真的很微不足道,并且会与wxWidgets的其他部分保持一致,但事实并非如此。有什么建议可以尝试吗?
我有一个解决方案。我想从wxAuiManagerEvent
中检测哪个窗格正在关闭,以便我只记录窗格关闭时的透视字符串。但是,这似乎是不可能的:
- 来自
$event->GetEventObject()
的引用是NULL
- 这可能是一个wxPHP错误; $event->GetPane()
返回的窗格没有用于读取窗格名称的属性或方法。
因此,我采用了在关闭一个窗格时保存所有透视字符串的方法。
我发现透视字符串包含一个位来表示窗格的关闭状态,因此在存储这些字符串时,我确保未设置此位。重新组装透视字符串并不是最优雅的事情,但它有效,并且比取消停靠和重新停靠要好得多(请参阅原始帖子中的链接问题)。
下面是一些代码,用于循环浏览我的窗格,获取透视字符串,取消设置关闭标志并将透视保存在窗口列表中:
public function onPaneClose(wxAuiManagerEvent $event)
{
for($i = 0; $i <= 7; $i++)
{
$pi = $this->getPaneInfoByIndex($i);
$persp = $this->getManagedWindow()->getAuiManager()->SavePaneInfo($pi);
// Split perspective string into pieces, get the second one (state)
$items = explode(';', $persp);
$state = $items[2];
// Decode the bitfield within
$stateItems = explode('=', $state);
$stateBitfield = (int) $stateItems[1];
// Set up bitmask to ignore closed state
$bitMask = (-1 ^ 2);
// Reset the perspective string minus the closed state bit
$replacementBitfield = $stateBitfield & $bitMask;
$items[2] = "state=" . $replacementBitfield;
$newPersp = implode(';', $items);
// Finally save the perspective
$this->windowSaves[$i] = $newPersp;
}
}
我找到了另一种解决方案,我认为我更喜欢。事实证明,可以从wxAuiPaneInfo
对象中获取窗格名称 - 透视包含它!这允许我简化算法 - 我只是将名称转换为序号,然后单独保存窗格透视。
由于窗格关闭事件总是在关闭之前触发(即当它们仍然可否决时),它们不会设置关闭位,所以很高兴我不必修改它。这是我的新事件处理程序:
public function onPaneClose(wxAuiManagerEvent $event)
{
// In the absence of being able to read the pane name from a paneinfo
// method, we can parse it out from the perpective string
$info = $event->GetPane();
$persp = $this->getManagedWindow()->getAuiManager()->SavePaneInfo($info);
// Fish out the number, which represents the pane ordinal
$matches = [];
preg_match('#name=auiPane('d+)#', $persp, $matches);
if ($matches)
{
$index = $matches[1];
$this->windowSaves[$index] = $persp;
}
}
我刚刚在透视字符串上使用了一个正则表达式,该正则表达式与我的命名格式 auiPane<index>
匹配。