Skip to content

Commit

Permalink
Add basic Doc/View framework
Browse files Browse the repository at this point in the history
  • Loading branch information
dontpanic92 committed May 14, 2017
1 parent 28cc5d3 commit d73adb0
Show file tree
Hide file tree
Showing 24 changed files with 209,935 additions and 158,696 deletions.
Binary file added build/docview
Binary file not shown.
6 changes: 5 additions & 1 deletion build/postprocess.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import sys, os, re

regex = re.compile("^const (.+?) int = (.+?)$", re.MULTILINE)
regex_ctor = re.compile("^func New(.+?)\((.+?)\).+? {$", re.MULTILINE)
regex_ctor = re.compile("^func New(.+?)\((.+?)\)(.+?) {$", re.MULTILINE)

def calc_new_value(var_value):
values = var_value.split('+')
Expand Down Expand Up @@ -42,9 +42,13 @@ def add_tracked_type(code):
for match_object in regex_ctor.finditer(code):
type_name = match_object.group(1)
ctor_param = match_object.group(2)

if "__SWIG_" in type_name or type_name in exceptions:
continue

if type_name.startswith("Director"):
continue

ctor_args = ""
if ctor_param == "a ...interface{}":
ctor_args = "a..."
Expand Down
74 changes: 74 additions & 0 deletions examples/src/docview/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package main

import "github.com/dontpanic92/wxGo/wx"

// See view.go for inheritance usage

type TextEditDocument struct {
wx.Document
}

type overwrittenMethodsForTextEditDocument struct {
doc wx.Document
}

func (self *overwrittenMethodsForTextEditDocument) OnCreate(path string, flags int) bool {

if !wx.DirectorDocumentOnCreate(self.doc, path, flags) {
return false
}

wx.Bind(self.GetTextCtrl(), wx.EVT_TEXT, self.OnTextChange, self.GetTextCtrl().GetId())

return true
}

func (self *overwrittenMethodsForTextEditDocument) IsModified() bool {
textCtrl := self.GetTextCtrl()
return wx.DirectorDocumentIsModified(self.doc) || (textCtrl.Swigcptr() != 0 && textCtrl.IsModified())
}

func (self *overwrittenMethodsForTextEditDocument) Modify(mod bool) {
wx.DirectorDocumentModify(self.doc, mod)
textCtrl := self.GetTextCtrl()
if textCtrl.Swigcptr() != 0 && !mod {
textCtrl.DiscardEdits()
}
}

func (self *overwrittenMethodsForTextEditDocument) DoSaveDocument(path string) bool {
return self.GetTextCtrl().SaveFile(path);
}

func (self *overwrittenMethodsForTextEditDocument) DoOpenDocument(path string) bool {
if !self.GetTextCtrl().LoadFile(path) {
return false
}

wx.DirectorDocumentModify(self.doc, false);

return true;
}

func (self *overwrittenMethodsForTextEditDocument) OnTextChange(e wx.Event) {
self.Modify(true)
e.Skip()
}

func (self *overwrittenMethodsForTextEditDocument) GetTextCtrl() wx.TextCtrl {
// Get our go object back
view := viewTrack[self.doc.GetFirstView().Swigcptr()]
if (view == nil) {
return wx.ToTextCtrl(wx.NullWindow)
}

return view.GetCtrl()
}

func NewTextEditDocument() wx.Document {
om := &overwrittenMethodsForTextEditDocument{}
dd := wx.NewDirectorDocument(om)
om.doc = dd

return dd
}
25 changes: 25 additions & 0 deletions examples/src/docview/doctemplate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package main

import "github.com/dontpanic92/wxGo/wx"

// See view.go for inheritance usage

type MyTextDocTemplate struct {
dt wx.DocTemplate
}

func (self *MyTextDocTemplate) DoCreateDocument() wx.Document {
return NewTextEditDocument()
}

func (self *MyTextDocTemplate) DoCreateView() wx.View {
return NewMyTextView()
}

func NewMyTextDocTemplate(docMan wx.DocManager, descr string, filter string, dir string, ext string,
docTypeName string, viewTypeName string) wx.DocTemplate {
tdt := &MyTextDocTemplate{}
dt := wx.NewDirectorDocTemplate(tdt, docMan, descr, filter, dir, ext, docTypeName, viewTypeName)
tdt.dt = dt
return dt
}
43 changes: 43 additions & 0 deletions examples/src/docview/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package main

import "github.com/dontpanic92/wxGo/wx"

type MainFrame struct {
wx.Frame
docMan wx.DocManager
}

func NewMainFrame() *MainFrame {
self := &MainFrame{}
self.docMan = wx.NewDocManager()
NewMyTextDocTemplate(self.docMan, "Text", "*.txt;*.text", "", "txt;text",
"Text Doc", "Text View")

self.Frame = wx.NewDocMDIParentFrame(self.docMan, wx.ToFrame(wx.NullWindow), wx.ID_ANY,
"wxGo DocView Sample");

menuFile := wx.NewMenu()
menuFile.Append(wx.ID_NEW)
menuFile.Append(wx.ID_OPEN)
menuFile.AppendSeparator()
menuFile.Append(wx.ID_EXIT)

menuBar := wx.NewMenuBar()
menuBar.Append(menuFile, "File")

self.Frame.SetMenuBar(menuBar)
self.Layout()

self.docMan.CreateNewDocument()

return self
}


func main() {
wx1 := wx.NewApp()
frame := NewMainFrame()
frame.Show()
wx1.MainLoop()
return
}
171 changes: 171 additions & 0 deletions examples/src/docview/view.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
package main

import "github.com/dontpanic92/wxGo/wx"

/* This file demostrates how to subclass a C++ class in Go.
* It may be not intuitive because of the different design and machanism
* between C++ and go, but the folowing code works, thanks to SWIG.
* Here we take the wxView class as an example to see how it works.
*
* We will deal with 3 things here:
* 1. a director object
* 2. overwrittenMethodsForView object that holds all overwritten
* virtual methods
* 3. out myTextView struct that acts as a sub class of wxView
*
* 1. The overwrittenMethodsForView structure
* Let's see the overwrittenMethodsForView first. Actually it is NOT a wxView
* (Please note that it does NOT embed a wx.View and it shouldn't), but just
* holds all overwritten virtual methods, e.g. wxView::OnCreate, etc.
* 2. The director object
* We use wx.NewDirectorView to create a director object of wxView. A director
* is an object that is responsible for "routing". It contains TWO parts:
* the C++ part, which is a sub class of the base class (here the base class
* is wxView), and it implements ALL virtual functions that the base class has,
* including pure virtual functions. The other part is the Go part, which contains
* a `overwrittenMethodsForView` struct.
* When a virtual function called, the director object will check whether the
* `overwrittenMethodsForView` object has an implementation of this virtual
* function. If Yes, then our go function will be called. If NO, the super
* function will be called when this function is NOT a pure virtual function,
* otherwise a panic will be raised - There is no implementation of a pure
* virtual function which is surely an error.
* 3. myTextView
* This is the object that will be used in Go code. It is a wxView, as it embeds
* a wx.View. And it also solves another problem: Finalizers will not be called
* if there is a circular reference. The director and overwrittenMethodsForView
* refer each other, so we cannot apply finalizers on them. But myTextView is
* OK.
*
* Overview:
*
* myTextView==============================
* circular ref
* wx.View (the director object)------ <---------------> overwrittenMethodsForView-----------------
* responsible for routing virtual calls virtual void OnCreate
* ----------------------------------- virtual void OnDraw
* (Other virtual function implemtations)
* (User-defined part of myTextView) ------------------------------------------
* ========================================
**/

// Our interface using in Go code
// It can be a superset of base class
type MyTextView interface {
wx.View
GetCtrl() wx.TextCtrl
}

// Our structure that implement the interface
type myTextView struct {
wx.View
}

// We can get our MyTextView back using this hash.
// Mapping C++ pointer to Go object
// See overwrittenMethodsForTextEditDocument.GetTextCtrl function
var viewTrack map[uintptr]MyTextView = make(map[uintptr]MyTextView)

// This struct will hold all overwritten virtual methods.
type overwrittenMethodsForView struct {
view wx.View
textCtrl wx.TextCtrl
}

func (self *overwrittenMethodsForView) OnCreate(doc wx.Document, flags int) bool {
// Use wx.DirectorXYZABC to call super function XYZ::ABC
// Do NOT call view.OnCreate in this function - that will cause recursion
// because this function is extactly the view.OnCreate!
if !wx.DirectorViewOnCreate(self.view, doc, flags) {
return false
}

document := doc.SwigGetDocument()

subFrame := wx.NewDocMDIChildFrame(document, self.view, wx.ToDocMDIParentFrame(wx.AppGetInstance().GetTopWindow()), wx.ID_ANY, "Child Frame", wx.DefaultPosition, wx.NewSizeT(300, 300))

menuFile := wx.NewMenu()
menuFile.Append(wx.ID_NEW)
menuFile.Append(wx.ID_OPEN)
menuFile.AppendSeparator()
menuFile.Append(wx.ID_EXIT)

menuEdit := wx.NewMenu()
menuEdit.Append(wx.ID_COPY)
menuEdit.Append(wx.ID_PASTE)
menuEdit.Append(wx.ID_SELECTALL)

menuBar := wx.NewMenuBar()
menuBar.Append(menuFile, "File")
menuBar.Append(menuEdit, "Edit")

subFrame.SetMenuBar(menuBar)

self.textCtrl = wx.NewTextCtrl(subFrame, wx.ID_ANY, "", wx.DefaultPosition, wx.DefaultSize, wx.TE_MULTILINE)

subFrame.Show()
return true
}

func (self *overwrittenMethodsForView) OnDraw(dc wx.DC) {
// Do nothing.
// The text ctrl will deal with all of the drawing things.
}

func (self *overwrittenMethodsForView) OnClose(deleteWindow bool) bool {
if !wx.DirectorViewOnClose(self.view, deleteWindow) {
return false
}

self.view.Activate(false)
if (deleteWindow) {
self.view.GetFrame().Destroy()
self.view.SetFrame(wx.ToFrame(wx.NullWindow))
}

delete(viewTrack, self.view.Swigcptr())
return true
}

func (self *overwrittenMethodsForView) OnCopy(e wx.Event) {
self.textCtrl.Copy();
}

func (self *overwrittenMethodsForView) OnPaste(e wx.Event) {
self.textCtrl.Paste();
}

func (self *overwrittenMethodsForView) OnSelectAll(e wx.Event) {
self.textCtrl.SelectAll();
}

func (self myTextView) GetCtrl() wx.TextCtrl {
return self.DirectorInterface().(*overwrittenMethodsForView).textCtrl
}

func NewMyTextView() MyTextView {
om := &overwrittenMethodsForView{}
dv := wx.NewDirectorView(om)
om.view = dv
// This makes circular reference but it's ok

wx.Bind(dv, wx.EVT_MENU, om.OnCopy, wx.ID_COPY)
wx.Bind(dv, wx.EVT_MENU, om.OnPaste, wx.ID_PASTE)
wx.Bind(dv, wx.EVT_MENU, om.OnSelectAll, wx.ID_SELECTALL)

mtv := &myTextView{View: dv}

// Store our go object in the map
viewTrack[mtv.Swigcptr()] = mtv
return mtv
}

// In this case, wxWidgets will be resonsible for
// release the view object. If the C++ code won't delete
// the obejct and you want Go to recycle the memory
// automatically, use the following function:
/* func NewMyTextViewT() MyTextView {
myTextView := NewMyTextView()
myTextView.SwigTrackObject()
return myTextView
} */
Loading

0 comments on commit d73adb0

Please sign in to comment.