gnome-logs開發記錄4--noob重構代碼就是這個feel

bug鏈接:https://bugzilla.gnome.org/show_bug.cgi?id=726228


只記得貢獻了第一次代碼後,在bugzilla中找來找去,不知怎麼就選上了這個任務。或許是表面上看着很簡單吧。至少現在看來我是大錯特錯了。

當時自己確定要修復這個bug時,就給David發了一封郵件,告知他我的意願。David在回信中談到了他自己對這個bug的認識,如下:

My suggestion would be to create a new GlEventView widget, which would be a stack which switches between the category list/event list view and the details view. It might be a bit complex to disentangle the code, especially the signal propagation during view mode changes, but the majority of the patch should be moving code from one file to another.

當然,對於我這麼一個newbie來說,這些解釋肯定是對我的幫助不太大的。通過之後和David的交流,我算是向前買了一小步。當然這一段時間,自己也算是摸不着北地摸索了很久,筆記本又增加了若干頁墨跡的重量。

之前程序中構件等級是這樣的:

window

->category list

->stack

    ->event list view

    ->detail view

目標是這樣:

window

->stack

    ->events view (GlEventView)

        ->category list

        ->event list view

    ->detail view

又是幾頁的墨跡,我來到了這一步:自己畫了一個簡圖,有了三步走計劃

簡圖

三步走計劃:

  The first: make event list view a GtkBox

  The second: create a GtkBox named event_view to contain category list and event list view

  The third: create a GtkStack named GlEventView which contains event_view and detail view


So,我目標很明確。照着這三步,一個個實現就一定ok了。當時是這麼想的,不過後來發現我錯了。

雖然目標明確,但我還是不知從哪裏下手,比如在哪裏改動UI等。就這麼在這幾天學習了一些關於signal、GValue、GAction等知識,雖然是一知半解,沒有完全明白。


再往後,弄明白了一共需要兩個GtkStack來處理頁面轉換。一個是GlEventView,另一個是GlEventViewList(當時這麼理解,其實GlEventViewList應該是GtkBox)。

當然這期間,自己一直在做的一件事情就是用g_print() 輸出一些輔助信息來幫助自己理解整個程序是怎麼運行的。比如說,打開程序和我點擊某一個event view list row後什麼函數會被調用和其間的順序。


再往後,就到了一個轉折點。

我終於明白了新建一個GlEventView是要新建一個類,需要新建.c、.h和一個.ui文件。一個月就這麼過去了,已經10月14日了。

在這裏記錄下這個郵件:

Hi David
    I think I get the idea about fixing the bug. For such a long time, I was heading a wrong direction.
    I should create a type named GlEventView which is a stack, and move the some parts of the existing stack GlEventViewList to GlEventView. Then I should do the things we discussed days ago, like making GlCategoryList and GlEventViewList in the same widget, etc. Am I right? I think finally I get the right idea about it.


之後遇到的一個很棘手的問題是關於類的調用問題,比如說我想在gl-eventview.c中調用GlEventViewList這個類的指針。

在這裏詳細解釋下這個問題。

在C++中,如果在一個類A的實現中需要調用另一個類B的話,一般我們只要生成一個B類的對象或者指針就可以。但是在Gnome開發中就不可以這樣了。因爲一個類就對應着一個widget,重新生成是無法解決問題的。其實這裏涉及到一個知識,那就是在Gnome開發中,一個widget對應的類只能操作其的子類。而這個父子關係是通過.ui文件來實現的。

我提交的patch中gl-eventview.ui文件內容如下:

<interface domain="gnome-logs">
    <template class="GlEventView" parent="GtkStack">
        <property name="visible">True</property>
        <child>
            <object class="GlEventViewList" id="events">
                <property name="visible">True</property>
            </object>
        </child>
    </template>
</interface>

這個.ui 文件是描述GlEventView的佈局,<child>標籤就說明了GlEventViewList是GlEventView的子類。然後如果我想在gl-eventview.c中想要用到GlEventViewList的話,我還需要做些工作。那就是在GlEventViewPrivate中添加一個條目GtkWidget *events;。在gl_event_view_class_init中使用下面兩個語句來將GlEventViewList和events綁定:

gtk_widget_class_set_template_from_resource (widget_class,
                                                 "/org/gnome/Logs/gl-eventview.ui");
    gtk_widget_class_bind_template_child_private (widget_class, GlEventView,
                                                  events);

在這裏有一點需要注意.ui文件中GlEventViewList的id要和GlEventViewPrivate中widget的名字一樣。如此一來,我們就將GlEventViewList和GtkWidget *events綁定。想要用到GlEventViewList的指針時,需要以下的代碼:

    GlEventViewPrivate *priv;
    GlEventViewList *events;

    priv = gl_event_view_get_instance_private (view);
    events = GL_EVENT_VIEW_LIST (priv->events);

這麼以來events就是GlEventViewList的指針了。


到此,進度還不到三分之一。

今天就先寫到這裏吧。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章