wxCairo

cairo라는 오픈소스 백터 그래픽 라이브러리가 있다.

http://www.cairographics.org/

wxCairo는 cairo를 wxWidgets의 프레임에 붙여서 사용할수 있는 예제를 제공하는 프로젝트이다.
라이브러리가 아니라 예제를 제공한다.
즉 간단히 말하자면 dc 를 얻어와 맵핑시켜준후 사용할 수 있는 예제를 제공한다.

다운로드는 svn에서.

# Non-members may check out a read-only working copy anonymously over HTTP.
svn checkout http://wxcairo.googlecode.com/svn/trunk/ wxcairo-read-only

아래는 제공하는 예제를 mingw에서 컴파일해본 화면이다.

cairo를 이용한 고품질의 그래프 위젯을 생각해볼만도 하다.
python용으로 개발된 Cairo Plot 이라는 프로젝트가 있는데.. 상당히 괜찮아보인다.

스샷은 여기서.

wxWidgets버전으로 포팅해볼까나..

wxArt2D

홈페이지: http://www.wxart2d.org/

wxWidgets전용 2D 그래픽 라이브러리이다.

WxArt2d is a library for 2D graphical programming. WxArt2D is build on top of the wxWidgets Library. It is build around a document View Framework, and has several graphical drawing context classes. You can display (multiple and different levels) views of a document filled with a hierachy of graphical objects. Tools allow you to zoom, drag, edit etc. the objects on the view.

download

다운로드: CVS 2009-11-05

wxRibbon

MFC로 만든 MS Office 2007버전은 Ribbon 위젯을 탑재하고 있는데, 다행스럽게도 이 위젯이 wxRibbon이라는 이름으로 wxWidgets버전으로 구현이 되었으며, wxWidgets 2.9.1 버전에 포함된다한다.

최신의 trunk 버전을 checkout 하면 시험해볼 수 있다.

collapse_3

최신 trunk 62507 버전을 빌드를 해놨는데, 아래서 받아서 사용해보면 된다.
http://blog.tcltk.co.kr/?p=999

wxTreeCtrl의 노드 상태 저장및 복구하기

wxWidgets의 wxTreeCtrl 위젯을 사용할때 노드의 상태를 복구 하고 싶을때 아래의 방법으로 한다.

#include <wx/wx.h> 
#include <wx/treectrl.h> 
#include <wx/xml/xml.h> 

class MyFrame : public wxFrame 
{ 
        wxTreeCtrl * m_TreeCtrl; 
        void CreateControls(); 
public: 
        bool Create(wxWindow * parent) 
        { 
                bool res = wxFrame::Create(parent, wxID_ANY, wxT("Tree Test")); 
                if(res) 
                { 
                        CreateControls(); 
                } 
                return res; 
        } 

        MyFrame() 
        { 
                Create(NULL); 
        }               

        void LoadTreeNodeState(wxTreeItemId id, wxXmlNode * node); 
        void SaveTreeNodeState(wxTreeItemId id, wxXmlNode * node); 

        DECLARE_EVENT_TABLE() 
        void OnOpen(wxCommandEvent & event); 
        void OnSave(wxCommandEvent & event); 
        void OnExit(wxCommandEvent & event); 
}; 

BEGIN_EVENT_TABLE(MyFrame, wxFrame) 
EVT_MENU(wxID_OPEN, MyFrame::OnOpen) 
EVT_MENU(wxID_SAVE, MyFrame::OnSave) 
EVT_MENU(wxID_EXIT, MyFrame::OnExit) 
END_EVENT_TABLE() 

void MyFrame::CreateControls() 
{ 
        wxMenuBar * menuBar = new wxMenuBar; 
        SetMenuBar(menuBar); 

        wxMenu * fileMenu = new wxMenu; 
        fileMenu->Append(wxID_OPEN, _("Open\tCtrl+O")); 
        fileMenu->Append(wxID_SAVE, _("Save\tCtrl+S")); 
        fileMenu->AppendSeparator(); 
        fileMenu->Append(wxID_EXIT, _("Exit\tAlt+F4")); 

        menuBar->Append(fileMenu, _("File")); 

        wxBoxSizer * sizer = new wxBoxSizer(wxVERTICAL); 
        m_TreeCtrl = new wxTreeCtrl(this, wxID_ANY, wxDefaultPosition, wxSize(400, 300), 
                wxTR_SINGLE|wxTR_HAS_BUTTONS|wxTR_LINES_AT_ROOT); 

        sizer->Add(m_TreeCtrl, 1, wxALL|wxEXPAND, 5); 

        CreateStatusBar(); 

        wxTreeItemId root_item = m_TreeCtrl->AddRoot(_("Root")); 
        wxTreeItemId id;        
        id = m_TreeCtrl->AppendItem(root_item, _("Group1")); 
        m_TreeCtrl->AppendItem(id, _("Child 1")); 
        m_TreeCtrl->AppendItem(id, _("Child 2")); 
        m_TreeCtrl->AppendItem(id, _("Child 3")); 
        id = m_TreeCtrl->AppendItem(root_item, _("Group2")); 
        m_TreeCtrl->AppendItem(id, _("Child 4")); 
        m_TreeCtrl->AppendItem(id, _("Child 5")); 
        m_TreeCtrl->AppendItem(id, _("Child 6")); 
        id = m_TreeCtrl->AppendItem(root_item, _("Group3")); 
        m_TreeCtrl->AppendItem(id, _("Child 7")); 
        m_TreeCtrl->AppendItem(id, _("Child 8")); 
        m_TreeCtrl->AppendItem(id, _("Child 9"));        
        sizer->Fit(this); 
} 

void MyFrame::LoadTreeNodeState(wxTreeItemId id, wxXmlNode * node) 
{        
        if(!node) return; 
        bool expanded = !(wxAtoi(node->GetPropVal(wxT("Expanded"), wxT("0"))) == 0); 
        if(expanded) 
        { 
                m_TreeCtrl->Expand(id); 
        } else m_TreeCtrl->Collapse(id); 
        wxTreeItemIdValue cookie; 
        wxTreeItemId child = m_TreeCtrl->GetFirstChild(id, cookie); 
        wxXmlNode * child_node = node->GetChildren(); 
        while(child.IsOk() && child_node) 
        { 
                LoadTreeNodeState(child, child_node); 
                if(child == m_TreeCtrl->GetLastChild(id)) break; 
                child = m_TreeCtrl->GetNextChild(id, cookie); 
                child_node = child_node->GetNext(); 
        } 
} 

void MyFrame::SaveTreeNodeState(wxTreeItemId id, wxXmlNode * node) 
{ 
        if(!node) return; 
        if(!id.IsOk()) return; 
        node->AddProperty(wxT("Expanded"), wxString::Format(wxT("%u"), !!m_TreeCtrl->IsExpanded(id))); 
        wxTreeItemIdValue cookie; 
        wxTreeItemId child = m_TreeCtrl->GetFirstChild(id, cookie); 
        wxXmlNode * child_node; 
        while(child.IsOk()) 
        { 
                child_node = new wxXmlNode(wxXML_ELEMENT_NODE, wxT("Item")); 
                node->AddChild(child_node); 
                SaveTreeNodeState(child, child_node); 
                if(child == m_TreeCtrl->GetLastChild(id)) break; 
                child = m_TreeCtrl->GetNextChild(id, cookie); 
                child_node = child_node->GetNext(); 
        } 
} 

void MyFrame::OnOpen(wxCommandEvent & event) 
{ 
        wxFileDialog dlg(this, wxFileSelectorPromptStr, wxEmptyString, wxEmptyString, 
                _("XML Files (*.xml)|*.xml"), wxFD_OPEN); 
        if(dlg.ShowModal() == wxID_OK) 
        { 
                wxXmlDocument document(dlg.GetPath()); 
                if(document.IsOk()) 
                { 
                        wxXmlNode * node = document.GetRoot(); 
                        LoadTreeNodeState(m_TreeCtrl->GetRootItem(), node); 
                } 
        } 
} 

void MyFrame::OnSave(wxCommandEvent & event) 
{ 
        wxFileDialog dlg(this, wxFileSelectorPromptStr, wxEmptyString, wxEmptyString, 
                _("XML Files (*.xml)|*.xml"), wxFD_SAVE); 
        if(dlg.ShowModal() == wxID_OK) 
        { 
                wxXmlDocument document; 
                wxTreeItemId root_item = m_TreeCtrl->GetRootItem(); 
                if(root_item.IsOk()) 
                { 
                        wxXmlNode * root_node = new wxXmlNode(wxXML_ELEMENT_NODE, wxT("Item")); 
                        document.SetRoot(root_node); 
                        SaveTreeNodeState(root_item, root_node); 
                        document.Save(dlg.GetPath()); 
                } 
        } 
} 

void MyFrame::OnExit(wxCommandEvent & event) 
{ 
        Close(); 
} 

class MyApp : public wxApp 
{ 
        virtual bool OnInit() 
        { 
                MyFrame * frame = new MyFrame; 
                SetTopWindow(frame); 
                frame->Centre(); 
                frame->Show(); 
                return true; 
        } 
}; 

IMPLEMENT_APP(MyApp); 

wxWidgets + SDL 의 조합

마침 회사에서 일하면서 GUI와 SDL의 조합도 필요했거니와, GUI는 wxWidgets가 자신있던터라 SDL 프레임을 끼워넣을수 있을까 생각을 해봤다.
모… 이렇게 사용할 유저가 있을지 모르겠다만…

monitor

위의 이미지는 간단히 직접 구현해본 예제이다.
코드는 여기서 받으면 된다.

아래는 참고한 코드들이다.