======================
 NewEditϵṹ
======================

:: limodou
:ϵ: limodou@gmail.com
:汾: $Id: architecture.txt 42 2005-09-28 05:19:21Z limodou $
:ҳ: http://wiki.woodpecker.org.cn/moin/NewEdit
:BLOG: http://www.donews.net/limodou
:Ȩ: GPL

.. contents:: Ŀ¼
.. sectnum::


----

дĿ
~~~~~~~~
NewEdit ʹ˴ Mixins ˱ĵĴƪ Mixins ͬʱ
ͽṹԼһЩؼ˽⡣

Ŀ
--------


~~~~~~~~

Ŀļǿһͨõı༭ߣҪṹ㹦ܵάչϲ˷ֲʽ
MixinsܣڹҪʵֻ༭ߵȫܣͬʱҪ Python ԵصʵӦֹ֧ܡ

 1. ӦΪֶ֧ĵ༭˲еĶTabҳṹ
 2. Ϊӽ棬ҪΪײмĵ͵ײһЩӴڵİڷţҲ
    ʹöTabҳṹԷֱرպʹ򿪡ĵڸָĵı༭ʾ
 3. صͽԪҪMixins磺ࡢ˵˵
    

˵
--------


~~~~

һʹ飬µṹ֮ĳͻάһҪԭ򡣺
ڸտʼʱܽṹܺã䣬ܵķḻӣܻɽṹҲòӦ
ķչڱ༭˵ΪԡôNewEditιһĽṹ
еһ̽ͬʱᷢչΪһרҵȶر༭ˣNewEditƺľǣιһ
ļܹʹ¹ܵӸΪά

NewEditʹõPython+wxPythonˣNewEditԳֵPythonĶ̬ĺôͬ
ʱʹwxPythonʵֿƽ̨С

NewEdit˼ǳPythonԵĶ̬ԣϵʵּ
ȫMixinPlugin뿪Ϊͨ׵˵Ƿֲʽ̼Ϊ
(ֲʽǲͬģֲ̰MixinPluginһֻPlugin˲
Ĺչо޵)ʱΪ˼򵥣һзֲΪMixin嵽ϸʱϸMixinPlugin

磬տʼһΣֻĹܡˣһЩʵ˻ܵࡣЩȶͬ
ʱµʱʱҪЩչչΪ֣

 1. µķԵʵ 
 2. Ӷ·Եĵ

޷ͨµķʵֵĿܻҪµࡣʱԶеõڶչӶʵԭ
֮ϵ

֪չʽôȥʵأڵ1չҵķǣԭڵļǴһ
µļļʵµķԡȻͨһֻưµķĿںϣͬʱ
ʱʵֵġһĹſĽУͣؽչµչֱԭ
ļне޸ģһļпͬʱԶչ׵֪չЩ
άǳ㡣ЩչͨһֻƣʱԶĿںϣҪĹ
չҽΪMixinչڵ2չҵķǣԭӦĵýӿڣͬʱMixinչ
ӶԵýӿڵľʵ֣ӶͨýӿڽĹԭϵչҽΪPluginչ
ҲԽչ

MixinչĿҪǶĿйչµ෽޸෽µԵȡPlugin
չҪĿҪѰҺʵĵλãӦĵýӿڡͬʱʵ־Pluginʵִ롣

ﻹڵһҪǵǣPluginչҪݾǷҪʵ֡ȣʵPluginΪķ
ԵʹòԶɣҪһõ㡣չķĳ¼ƵĵùôԲʵPlugin
ڣҪʵӦPluginӿڡ

һӣһչʵ֡Щϸڻû漰ὲ::

    class MainFrame(wx.Frame):
        def __init__(self, parent, title='Test'):
            wx.Frame.__init__(self, parent, -1, title=title)
		
һ壬ܾǵĳΡһť԰ť¼Ӧǿֱ
MainFrame޸ġܼ򵥵ȻԣܸӣһθĶֹҪĶһطͲһ
׵ˡʹMixinķ

1. ʹһʵֲַ̣ôҪʹΪMixin࣬ҶΪSlot()ôһĿ
   ࣬MixinչMainFrame::

    import Mixin
    import wx
    
    class MainFrame(wx.Frame, Mixin):
        __mixinname__ = 'mainframe'
        
        def __init__(self, parent, title='Test'):
            self.initmixin()
            wx.Frame.__init__(self, parent, -1, title=title)

ܼ򵥣ʹMainFrameһMixinĻ࣬һ__mixinname__: mainframe__init__е
self.initmixin()ǾͰһMainFameһࡣ

2. һļʵ־չ::

    import Mixin
    import wx
    
    def init(win):
        win.ID_CLICK = wx.NewId()
        win.btnClick = wx.Button(win, win.ID_CLICK, 'Click Me')
        wx.EVT_BUTTON(win.btnClick, win.ID_CLICK, win.OnClick)
        
    def OnClick(win, event):
        print 'Click Me'
        win.Close()
	
ԿļʵһһťõťʱOnClick¼һ
OnClick¼ǲʹMixinչô::

    import wx
    
    class MainFrame(wx.Frame):
        
        def __init__(self, parent, title='Test'):
            wx.Frame.__init__(self, parent, -1, title=title)
            self.ID_CLICK = wx.NewId()
            self.btnClick = wx.Button(self, self.ID_CLICK, 'Click Me')
            wx.EVT_BUTTON(self.btnClick, self.ID_CLICK, self.OnClick)
    
        def OnClick(self, event):
            print 'Click Me'
            self.Close()

ԿOnClickʵMainFrameĳԱinitӦλ__init__У__init__еһδʹMixinӦдأ
::

    import Mixin
    import wx
    
    def init(win):
        win.ID_CLICK = wx.NewId()
        win.btnClick = wx.Button(win, win.ID_CLICK, 'Click Me')
        wx.EVT_BUTTON(win.btnClick, win.ID_CLICK, win.OnClick)
    Mixin.setPlugin('mainframe', 'init', init)
        
    def OnClick(win, event):
        print 'Click Me'
        win.Close()
    Mixin.setMixin('mainframe', 'OnClick', OnClick)

setPluginPlugin÷init('mainframe')ĳõɲʵеásetMixinMixin
÷OnClick뵽УΪһԱ

ͬʱǻҪ޸MainFrameһõ::

    import Mixin
    import wx
    
    class MainFrame(wx.Frame, Mixin):
        __mixinname__ = 'mainframe'
        
        def __init__(self, parent, title='Test'):
            self.initmixin()
            wx.Frame.__init__(self, parent, -1, title=title)
            self.callplugin('init', self)

Mixinļ׼ˡβܽأܼ򵥣нMixinļΪһģ鵼뼴ɡ
ĹȵʱͨȽPluginMixinѼȻٵȵʵʱͨself.initmixin()ʵ
ֲִֻһΡ

MixinPluginǣMixinʵ·ԣPluginʵֵõľ崦򵥵⣺MixinǶδ֪չ
PluginǶ֪չ


~~~~~

һǿʵMixin࣬ҲĿࡣһΪMixinҪһ__mixinname__ԣ
ԾMixinPluginΨһʶͬʱڲĹ캯__init__Ҫself.initmixin()(Mixinһ)
ʵʱͻʹô˷˲صMixinPluginںϣӶյࡣ˹Ƕ౾
ʵͨڲƿԱִֻ֤һΡһֻʱڴһʵʱŻġһЩʵ
ҪлPythonĶ̬ԡ

Mixin
~~~~~~~~~

MixinΪԱķͳΪԵԡÿһMixinҪʵɺ󣬵Mixin
ģsetMixinMixinһںϡںϺơĶʵΪ::

    setMixin(slot_class_name, binding_name, instance)
    
slot_class_name
    ΪƣӦĲ__mixinname__ֵ

binding_name
    ΪںϺ

instance
    ΪMixinĶ

::

    def OnClick(win, event):
        print 'Click Me'
        win.Close()
    Mixin.setMixin('mainframe', 'OnClick', OnClick)

Ϊ'mainframe'

󶨺Ϊ'OnClick'ʵںϺڲ෽ΪOnClickҲԸûиĶMixinں
ͬģڣ

1. ෽

   ںϵķ滻ǰںϵķ

2. 

   ԵĲͬвͬĴ

   1. бtuple

      µӵѾڵ֮
    
   2. ֵ

      µѾڵݽغϲѾĳµֵ滻ɵֵ
    
   3. 

      ֵ滻ֵ
    
MixinʵΪģеOnClick
    
Plugin
~~~~~~~~~~

ʵPlugin֮ǰӦӦмõ㣬ӣself.callplugin()self.execplugin()ĵáȻMixinļж
ӦPlugincallpluginexecpluginMixinģķߺcallpluginֵexecpluginᴦ
ֵPluginΪһõԶӦPlugin

callpluginexecplugin
^^^^^^^^^^^^^^^^^^^^^^^

Ϊ::

    callplugin('plugin_call_name', *args, **kwargs)
    execplugin('plugin_call_name', *args, **kwargs)

Կÿһõ㶼һַ֣ȻӦĲ

ǿһ㣬pluginԶݲࡢplugin_call_nameз࣬ͬʱִsetPluginʱָȼˣ
pluginջ֯Ϊһɭ֣ÿöԾһ࣬ÿɸõ㣬ÿõӦһȼббеÿһ
Ԫؾһplugin--

callpluginѵõӦķбезȼ˳Զִһ飬ͬʱ\*args, \**\kwargsΪ::

    self.callplugin('init', self)

plugin_call_nameΪ'init'Ϊʵ: self

execpluginҲᰴȼд

1. ȡһͬʱӦĲ
2. жϷֵΪ٣һΪ棬ͬʱؽ

ˣʱķֵͷǳҪˡĳûӰ죬ô㲻÷κֵ(ʱPython᷵None)򷵻ؼֵ
ĳִк󣬲ĴҪһֵкٽдˡȼͷֵҪϸؿ


PluginĶ
^^^^^^^^^^^^^^^^

ȶһĲӦĵõĲһ¡ȻϺ󣬵setPlugin˺ĸģĸõ󶨡
setPluginĺΪ::

    setPlugin(slot_class_name, binding_name, instance, priority, nice)

slot_class_name
    ơΪӦĲ__mixinname__ֵ
    
binding_name
    󶨺
    
instance
    PluginĶʵ
    
priority
    ںбе˳ֵΪͬͬӦPlugin֯Ϊһбֵ˳򡣵һ
    ŵļһHIGH, MIDDLE, LOWͬļִsetPlugin˳ġȱʡΪMIDDLE
    
nice
    ȼpriority࣬ǻᱻΪĳȷȼHIGH=100, MIDDL=500, LOW=900niceֱ趨
    ȼ˲ȱʡΪ-1ʾδ壬ֵ >= 0һPluginȼʹôniceֵȷϣʹpriorityȷ
    ˣ˲priorityǻģֻһЧ
    
Ϊ˶һPluginִ˳һʹȼ趨һַ趨õ㣬Pluginɵͬĵõϡڵ
ִ˳ģҲPluginڴķΧϵִ˳

MixinĴ
~~~~~~~~~~~~~~~

ǰҪMixinPluginĿβſʵֲӦĲ֮ںϻأЩαأ

1. MixinPluginģ

   Щģ飬صԡǶ룬ڵģлᴴӦʵͬʱִЩsetMixin
   setPluginôЩὫԡռMixinģȫ__mixinset__ȥеMixinPluginģ
   鱻ЩMixinPluginռ__mixinset__ȥռͬʱӦĲƽз࣬ͬһƵĲ
   ŵһȻģMixinPluginĲֱͬдĴǰѾˡMixinģȫϣ
   ӦĲںϴǺҪġ

2. ĳʵ

   ĳҪʵʱǴMixinҰҪһʱMixininitmixin()ȼǷѾ
   ںϵĲѾֱӷءûУִںϲӦı־λʾִɡںϲִֻһΡ
   ִںϲʱinitmixinԶ__mixinset____mixinname__һµMixinPluginݲͬвͬĴ
   磺Mixinʹsetattr()ֱΪԱPluginͳһŵ__plugins__С

   ںϹĳʵʱɡͬʱཫΪһࡣ

3. ڲлһЩطִcallplugin()execpluginģӶɶ¹ܵĵá

˵
~~~~~~~~

1. ΪʲôʹַΪֱʹ౾أ

   ΪPythonУ౾ҲһҪʹñҪȽ䵼롣Ͳ׽ϵͳƵñȽϣ޸Ĳ㡣

NewEditеľʵ
-------------------

Ŀ¼ṹ
~~~~~~~~

䱾Ŀ¼Ϊ::

    src\
     |
     |---- NewEdit.py             ó
     |
     |---- doc\                   ĵĿ¼
     |
     |---- mixins\                MixinPluginĿ¼Ŀ¼Ϊݣͬʱص
     |
     |---- modules\               ģĿ¼
     |
     |---- plugins\               ǺĲĿ¼Blog, ĵӵ
     |
     |---- tools\                 һЩ߽űi18nķĵ
     |
     |---- resources\             ԻxmlԴļĿ¼
     |
     |---- images\                ͼƬĿ¼
    
NewEditйصݾmixinsĿ¼pluginsĿ¼(Ǳ)modules/Mixinģ飬NewEdit.pyNewEdit.pyΪűڴ
вһЩ趨MixinPluginӦʵ

Mixin˵
~~~~~~~~~~~~~

ǴNewEdit.pyȡһƬΣMixinĳʼӦá

::

    from modules import Mixin

    class NewEditApp(wx.App, Mixin.Mixin):
    
        __mixinname__ = 'app'
    
        def OnInit(self):
            self.initmixin()	#initialize mixin
    
            self.appname = __appname__
            self.i18n = i18n
            self.workpath = workpath
            self.defaultencoding = encoding
            self.ddeflag = ddeflag
            self.skipsessionfile = skipsessionfile
            
            return self.execplugin('init', self, files)

    import mixins

    app = NewEditApp(0)
    
    app.MainLoop()

NewEditAppӦò࣬__mixinname__Ϊ'app'OnInitжһõ㣬self.execplugin('init', self, files)һ
зֵĵõ㣬棬Уؼ٣˳õУһһҪ򿪵ļ
б

import mixins ǵmixinsĿ¼еMixinmixinsĿ¼֯Ϊʽһ__init__.pyݾǵеMixin
Щѡڣеĵѱעֻͣʣһimport Import.pyѡΪ˼ٵļĸͨһűԶдע͵
importеģļԶһImport.pyļֻһImportģͿˡ޸עеimportУִнű
Import.pyͿˡ

ǿԿûһдǴNewEditڡ˵ģôܾȫself.execplugin()ˡ

ȿһϰ汾__init__.py::

    import mPreference
    import mMainFrame
    import mMainSubFrame
    import mEditorCtrl
    import mEditor
    
    # 1.0 other
    import mComEdit
    import mToolbar
    import mIcon
    ...

NewEdit 1.0ʱ__init__.pyе(ʵб仯ģ)

Щimport㿴NewEditÿһimportһֹܡȥĳimportһЩܣһ㲻ӰĹ
ܡˣʹMixinѶ̬˾ҪЩܣҪЩܡǳ㡣ΪʲôǿԵأΪܴ붼ǲأȫأ
ǾͿ԰صĹʵּеһ𣬲ͨMixinķµĹܣͬʱ𵽷ָܴáǿ׵֪һܵ
ʵ֣Ҫ漰Щ࣬ҪЩطµķԡõ㡣ͬʱЩܵļ룬־ܵؼٶеܵӰ졣Mixin
һҪ֮ͷ5importNewEditġǿһmMainFrameеݰ::

    from modules import Mixin
    import wx
    
    def init(app, filenames):
        from MainFrame import MainFrame
        
        app.frame = MainFrame(app, filenames)
        if app.frame:
            app.frame.workpath = app.workpath
            app.frame.Show(True)
            app.SetTopWindow(app.frame)
            
            app.frame.afterinit()
            app.frame.editctrl.openPage()
            
            return True, True
        else:
            return True, False
    Mixin.setPlugin('app', 'init', init)

ǰ棬NewEditAppжһinitĵõ㡣ômMainFrame.pyõ㴴һPluginУ
ǵMainFrameӶNewEditͬʱMainFrameл˵õ㣬õУʹNotebookʵ
NewEditĶĵ༭ĻNewEditһˡ

NewEditҪMixinPluginĻԼɷо˽NewEditеĸֲ࣬Щõ㣬ЩιģҲ
ϤֹչáλãӶʵѵMixin

˽ֲ
~~~~~~~~~~~~

ÿNewEditNewEditĿ¼һdebug.txtļһЩϢMixinPluginϢз࣬
һʾ::

    [ INFO] -- 	name=messagewindow
    [ INFO] -- 	   |----mixin
    [ INFO] -- 	          |OnIdle	mixins.Import.OnIdle
    [ INFO] -- 	          |OnKeyDown	mixins.Import.OnKeyDown
    [ INFO] -- 	          |OnKeyUp	mixins.Import.OnKeyUp
    [ INFO] -- 	          |RunCheck	mixins.Import.RunCheck
    [ INFO] -- 	   |----plugin
    [ INFO] -- 	          |init
    [ INFO] -- 		          500 mixins.Import.init
    [ INFO] -- 	name=pythonfiletype
    [ INFO] -- 	   |----mixin
    [ INFO] -- 	          |menulist
    [ INFO] -- 	          |toolbaritems
    [ INFO] -- 	          |toollist
    [ INFO] -- 	   |----plugin
    [ INFO] -- 	          |on_enter
    [ INFO] -- 		          500 mixins.Import.on_enter
    [ INFO] -- 		          500 mixins.Import.on_enter
    [ INFO] -- 	          |on_leave
    [ INFO] -- 		          500 mixins.Import.on_leave
    [ INFO] -- 		          500 mixins.Import.on_leave

nameʾƣmixinΪ˲MixinбÿMixinںƺʵϢpluginΪ˲PluginϢ
õзָ࣬õӦPluginȼͨdebug.txt˽ĳ඼ʵЩMixinPlugin
˽ⶼﶨģֽʲô

ڽṹʾ
~~~~~~~~~~~~

һʾͼʾĴڿܡ

.. image:: classes.png

ͼֻһʾ򵥽һÿ:

mainframe
  壬˵״̬Ӵ嶼

panel
  һ4SashWindowĸ壬4SashWindow𵽷ָĻãΪ(top)(bottom)(left)(right)

top, bottom, left, right
  SashWindowڣСǿԸıġരΪá

bottombook, leftbook, rightbook
  Notebook͵Ĵ壬һĴ壬snippetwindow(Ƭδ)projectwindow(Ŀ)shellwindow(Shell)
  messagewindow(Ϣ)ftpwindow(ftp)blogwindow(blog)ǷģԶҳʽ档

editctrl
  Ǳ༭ڵĸڣһNotebookڣµı༭ڣ༭ڵĹرյȡ

documents
  Ǳ༭ڣжͣTextEditor(һı༭)HtmlViewer(Html)BlogEditor(Blog༭)


`[]`_

.. _`[]`: technical.htm