wxListCtrl и джедайские приемы

June 19th, 2009 Begemot

Знаете как создать wxListCtrl с одной колонкой, ширина которой равна ширине контрола? не уже – что бы выделение было красивым и удобным для пользователя, не шире что бы не появлялась линейка прокрутки вообщем сделать так как должно быть в нормально продукте. Я думал просто, я был удивлен, нормального пути нет или я его не нашел.

Поскольку контрол в сайзере ширина его точно не известна, я смог сделать только так :

m_TransitionList = new wxListCtrl(....
m_TransitionList->Connect(wxEVT_SIZE, wxSizeEventHandler(MovieMaker::OnTransitionListSize)); // for correct resizing width of column

Ну и сам обработчик : 

void MovieMaker::OnTransitionListSize(wxSizeEvent& event) 
{	
	if (wxListCtrl * list = ((MovieMaker*)GetParent()->GetParent())->m_TransitionList) 
		list->SetColumnWidth(0, list->GetSize().GetWidth() - wxSystemSettings::GetMetric(wxSYS_VSCROLL_X) - 6); 
}

Учтите что обработчик принадлежит класу создающему wxListCtrl, а не класу контрола, поэтому this у него не “правильный”,  берем родителя (в моем случае дедушку), кастим к нужному класу  и устанавливаем ширину. Почему то пришлось вычитать еще 6 пикселов (?!), число 6 подобранно эксперементально.

Вот теперь у нас нормальный лист контрол который не стыдно отдать юзверю, а вы как решаете эту проблему?

Update: Новая более правильная версия, спасибо Алексею за облагораживание кода:

void MovieMaker::OnTransitionListSize(wxSizeEvent& event) 
{	
    if (wxListCtrl * list = dynamic_cast<wxListCtrl*>(event.GetEventObject()))
	list->SetColumnWidth(0, list->GetSize().GetWidth() - wxSystemSettings::GetMetric(wxSYS_VSCROLL_X) - 6); 
}

Если пост полезен для вас вы можете подписаться на RSS или мы можем доставлять вам новые посты прямо в ваш почтовый ящик.


Как выборочно отключить шоткаты в меню

September 26th, 2008 Begemot

При создании меню в wxWidgets, в названии пункта меню можно указать шоткат, который будет использоватся для выбора этого пункта. Автоматическую обработку шоткатов wxWidgets берет на себя, что с одной стороны, конечно, удобно и приятно. Но с другой – иногда, подобная услужливость, явна лишняя.

Уже во второй программе я сталкиваюсь с тем что мне необходимо, отключить автоматическую обработку для некоторых пунктов меню. Прямого способа нет. Я спрашивал в wx-листе, но там или меня не поняли или тоже не знали ответа.

Решение нашлось на форуме, собственно ответ тут. Добавляем обработчики для открытия\закрытия меню.

 

EVT_MENU_OPEN(MainFrame::OnOpenMenu)
EVT_MENU_CLOSE(MainFrame::OnCloseMenu)

void MainFrame::OnOpenMenu(wxMenuEvent & event)
{
       GetMenuBar()->FindItem(ID_COPYITEMTOCLIPBOARD)->SetItemLabel(_("&Copy to Clipboard\tCtrl+C"));
	event.Skip();
}

void MainFrame::OnCloseMenu(wxMenuEvent & event)
{
	GetMenuBar()->FindItem(ID_COPYITEMTOCLIPBOARD)->SetItemLabel(_("&Copy to Clipboard"));
	GetMenuBar()->FindItem(ID_COPYITEMTOCLIPBOARD)->SetBitmaps(wxBitmap(copy_clipboard_xpm), wxNullBitmap);  
	event.Skip();
}

Выглядит грязным хаком, но работает. Особое удивление у меня вызывает необходимость устанавливать каждый раз иконку для меню, причем именно в обработчике закрытия, а не открытия (!), но это волшебство я уже объяснить не могу.


Если пост полезен для вас вы можете подписаться на RSS или мы можем доставлять вам новые посты прямо в ваш почтовый ящик.