¸®´ª½º ±âŸ ÀÚ·á

HomePage Backward Forward Post Reply List
Delete Modify
  Á¦¸ñ   gtk °­Á #11 1998/07/10 (17:34)
À̸§ ±èÈ¿¿ø
¹øÈ£ 95
Á¶È¸ 336
º»¹®
¡º¸®´ª½º Çдç-¹ø¿ª¹° (go LINUX)¡» 207¹ø
Á¦  ¸ñ:[¹ø¿ª] gtk Tutorial, Chap19ÀÔ´Ï´Ù.                          
¿Ã¸°ÀÌ:Áß¾ÓÀÚ´ë(ÀÌÈÆ    )    98/03/12 19:53    ÀÐÀ½:206 °ü·ÃÀÚ·á ¾øÀ½
-----------------------------------------------------------------------------

******************************
*** 19. ÀڽŸ¸ÀÇ widget ¸¸µé±â
******************************

***
*** 19-1. °³¿ä
***
 ºñ·Ï GTK ¹èÆ÷ÆÇ¿¡ Æ÷ÇԵǾî ÀÖ´Â ¼ö¸¹Àº widgetµéÀÌ ´ëºÎºÐÀÇ ±âº»ÀûÀÎ
¿ä±¸»çÇ×À» ÃæÁ·½ÃÄÑ ÁÖÁö¸¸, ¾ðÁ¨°¡ ½º½º·Î »õ·Î¿î widgetÀ» ¸¸µé¾î¾ß ÇÒ ¶§°¡
¿Ã °ÍÀÌ´Ù.  GTK°¡ widgetÀÇ »ó¼ÓÀ» ±¤¹üÀ§ÇÏ°Ô ÀÌ¿ëÇÏ°í ¶Ç ÀÌ ¸¸µé¾îÁ® ÀÖ´Â
widgetµéÀÌ ¿©·¯ºÐÀÇ ¿ä±¸¿¡ ±ÙÁ¢ÇÑ °ÍµéÀ̱⠶§¹®¿¡, À¯¿ëÇÏ°í »õ·Î¿î widgetÀ»
¸¸µå´Â °Íµµ ´ÜÁö ¸î ÁÙÀÇ ÄÚµå·Î½á °¡´ÉÇÒ ¼öµµ ÀÖ´Ù.  ±×·¯³ª »õ·Î¿î widgetÀ»
¸¸µå´Â ÀÛ¾÷À» ½ÃÀÛÇϱâ Àü¿¡, ¸ÕÀú ´©±º°¡ ±×°ÍÀ» ÀÌ¹Ì ¸¸µé¾î ³õÁö ¾Ê¾Ò´ÂÁö
üũÇÏÀÚ.  ÀÌ·¸°Ô Çؼ­ ³ë·ÂÀÇ Áߺ¹À» ¸·°í ¶Ç GTK widgetÀÇ °¹¼ö¸¦ ÃÖ¼ÒÇÑÀ¸·Î
À¯ÁöÇÒ ¼ö ÀÖ´Ù.  ÀÌ°ÍÀº ¼­·Î ´Ù¸¥ ¾îÇÃµé »çÀÌ¿¡¼­ ÄÚµå¿Í ÀÎÅÍÆäÀ̽º ¸ðµÎÀÇ
ÅëÀϼºÀ» À¯ÁöÇÏ´Â °ÍÀÌ´Ù.  ÀÌ·¸°Ô ÇÏ´Â ÇÑ°¡Áö ¹æ¹ýÀ¸·Î, ¸¸¾à ¿©·¯ºÐÀÌ
ÀڽŸ¸ÀÇ widgetÀ» ¿Ï¼ºÇÏ°Ô µÇ¸é, ±×°ÍÀ» ´Ù¸¥ »ç¶÷µé ¸ðµÎ ÀÌ¿ëÇÒ ¼ö ÀÖ°Ô
¼¼°è¿¡ ³Î¸® ¾Ë¸®ÀÚ.  ÀÌ·¸°Ô ÇÒ ¼ö ÀÖ´Â °¡Àå ÁÁÀº Àå¼Ò´Â ¾Æ¸¶ gtk-listÀÏ
°ÍÀÌ´Ù.

***
*** 19-2. WidgetÀÇ ±¸Á¶
***
 »õ·Î¿î widgetÀ» ¸¸µå´Â µ¥ À־, GTK objectµéÀÌ ¾î¶»°Ô µ¿ÀÛÇÏ´ÂÁö ÀÌÇØ
ÇÏ´Â °ÍÀÌ Áß¿äÇÒ °ÍÀÌ´Ù.  À̹ø ¼½¼ÇÀº ´ÜÁö ª¸·ÇÑ °³¿ä¸¸À» ¼Ò°³ÇÏ°íÀÚ ÇÑ´Ù.
ÀÚ¼¼ÇÑ °ÍÀº Âü°í ¹®¼­¸¦ º¸¶ó.

 GTK widgetµéÀº °´Ã¼ÁöÇâÀû ¹æ¹ýÀ» ÁöÇâÇÑ´Ù.  ±×·¯³ª, ±×µéÀº Ç¥ÁØ C·Î
¾²¿©Áø´Ù.  ÀÌ°ÍÀº ÇöÀç ¼öÁØÀÇ C++ ÄÄÆÄÀÏ·¯¸¦ ¾²´Â °Íº¸´Ù À̽ļº°ú ¾ÈÁ¤¼ºÀ»
Å©°Ô Çâ»ó½ÃŲ´Ù.  ÇÏÁö¸¸ ÀÌ°ÍÀº widget ÀÛ¼ºÀÚ°¡ ¸î¸î ¼¼ºÎÀûÀÎ °÷¿¡ ÁÖÀǸ¦
±â¿ï¿©¾ß¸¸ ÇÏ´Â °ÍÀ» ÀǹÌÇÑ´Ù.  ÇÑ Å¬·¡½ºÀÇ widgetµé(¿¹¸¦µéÀÚ¸é ¸ðµç Button
widgetµé)ÀÇ instanceµé ¸ðµÎ¿¡ °øÅëÀûÀÎ Á¤º¸´Â class structure¿¡ ÀúÀåµÇ¾î
ÀÖ´Ù.  ÀÌ classÀÇ ½Ã±×³ÎµéÀº ÇÔ¼ö¿¡ ´ëÇÑ Æ÷ÀÎÅÍ, Áï callback ÇÔ¼ö·Î ó¸®
µÇ°í, C++¿¡¼­ÀÇ virtual ÇÔ¼öó·³ ÇϳªÀÇ º¹»çº»¸¸ÀÌ Á¸ÀçÇØ ÁØ´Ù.  »ó¼ÓÀ»
Áö¿øÇϱâ À§Çؼ­, class structureÀÇ Ã¹¹ø° Çʵå´Â parent class structureÀÇ
copy°¡ µÇ¾î¾ß ÇÑ´Ù.  GtkButtonÀ̶ó´Â class structureÀÇ ¼±¾ðÀº ÀÌ·¸°Ô µÈ´Ù.  

      struct _GtkButtonClass
      {
        GtkContainerClass parent_class;

        void (* pressed)  (GtkButton *button);
        void (* released) (GtkButton *button);
        void (* clicked)  (GtkButton *button);
        void (* enter)    (GtkButton *button);
        void (* leave)    (GtkButton *button);
      };

 ¹öÆ°ÀÌ ÇϳªÀÇ ÄÁÅ×À̳ʷΠ´Ù·ç¾îÁø´Ù¸é(¿¹¸¦µé¾î, resizeµÇ¾úÀ» ¶§), ±×°ÍÀÇ
class structure´Â GtkContainerClass·Î ij½ºÆ®µÉ ¼ö ÀÖ°í, ¶Ç ½Ã±×³ÎµéÀ» ´Ù·ç±â
À§ÇØ °ü·ÃµÈ ÇʵåµéÀÌ ¾²ÀÌ°Ô µÈ´Ù.

 ÇϳªÀÇ instance basis¸¦ ±â¹ÝÀ¸·Î ÇÑ °¢°¢ÀÇ widgetµéÀ» À§ÇÑ ±¸Á¶Ã¼µµ ÀÖ´Ù.
ÀÌ ±¸Á¶Ã¼´Â ¾î¶² widgetÀÇ °¢°¢ÀÇ instance¸¦ À§ÇÑ ¼­·Î ´Ù¸¥ Á¤º¸¸¦ °¡Áö°í
ÀÖ´Ù.  ¿ì¸®´Â ÀÌ ±¸Á¶Ã¼¸¦ object structure¶ó°í ºÎ¸¦ °ÍÀÌ´Ù.  ¹öÆ° Ŭ·¡½º¸¦
¿¹·Î µç´Ù¸é ÀÌ·¸°Ô µÈ´Ù.

      struct _GtkButton
      {
        GtkContainer container;

        GtkWidget *child;

        guint in_button : 1;
        guint button_down : 1;
      };

 Class structure¿¡¼­¿Í ¸¶Âù°¡Áö·Î ù¹ø° Çʵå´Â parent classÀÇ object
structureÀÓÀ» ÁÖÀÇÇ϶ó.  ±×·¡¼­ ÀÌ ±¸Á¶Ã¼´Â ÇÊ¿äÇÒ °æ¿ì parent classÀÇ
object·Î ij½ºÆ®µÉ ¼öµµ ÀÖ´Â °ÍÀÌ´Ù.

***
*** 19-3. Composite(ÇÕ¼º,È¥¼º) widget ¸¸µé±â
***

***
*** 19-3.1. ¼Ò°³
***
 ¿ì¸®°¡ ¸¸µé°íÀÚ ÇÏ´Â ¾î¶² widgetÀº ´ÜÁö ´Ù¸¥ GTK widgetµéÀÇ ÁýÇÕüÀÏ »ÓÀÏ
¼öµµ ÀÖ´Ù.  ÀÌ·± widgetÀº ²À »õ·Î¿î °ÍÀ¸·Î ¸¸µé¾îÁ®¾ß ÇÒ °ÍÀº ¾Æ´ÏÁö¸¸,
Àç»ç¿ë¼ºÀ» À§ÇØ »ç¿ëÀÚ ÀÎÅÍÆäÀ̽ºÀûÀÎ ¿ä¼ÒµéÀ» ÆÐŰ¡ÇÏ´Â µ¥ ÀÖ¾î Æí¸®ÇÑ
¹æ½ÄÀ» Á¦°øÇÑ´Ù.  Ç¥ÁØ GTK ¹èÆ÷ÆÇ¿¡ ÀÖ´Â FileSelection°ú ColorSelection
widgetÀÌ ¿¹°¡ µÉ °ÍÀÌ´Ù.

 ¿ì¸®°¡ ¿©±â¼­ ¸¸µé·Á´Â ¿¹Á¦´Â Tictactoe widgetÀ¸·Î, Åä±Û¹öÆ°ÀÇ 3x3 ¹è¿­
¿¡¼­ ¾î´À ÇÑ Çà ¶Ç´Â ¿­ ¶Ç´Â ´ë°¢¼ººÐ ¸ðµÎ°¡ ´­·¯Áö°Ô µÇ¸é ½Ã±×³ÎÀ» ³»º¸³½
´Ù.

***
*** 19-3.2. Parent class¸¦ °í¸£±â
***
 ÀüÇüÀûÀ¸·Î composite widgetÀÇ parent class´Â ±× composite widgetÀÇ ¸ðµç
¸â¹öµéÀ» °¡Áö°í ÀÖ´Â ÄÁÅ×ÀÌ³Ê Å¬·¡½ºÀÌ´Ù.  ¿¹¸¦µé¾î, FileSelection widgetÀÇ
parent class´Â Dialog Ŭ·¡½ºÀÌ´Ù.  ¿ì¸® ¹öÆ°µéÀº table ¾È¿¡ ´Ã¾î¼­ ÀÖÀ» °Í
À̹ǷÎ, parent class·Î GtkTable Ŭ·¡½º°¡ µÇ´Â °ÍÀÌ ÀÚ¿¬½º·´´Ù.  ºÒÇàÈ÷µµ,
ÀÌ°ÍÀº µ¿ÀÛÇÏÁö ¾Ê´Â´Ù.  ÇÑ widgetÀ» ¸¸µå´Â °ÍÀº µÎ ÇÔ¼ö¿¡ ÀÇÇÑ °ÍÀ¸·Î
³ª´¶´Ù.  WIDGETNAME_new() ÇÔ¼ö¸¦ »ç¿ëÀÚ°¡ ºÎ¸£°í, ±×¸®°í WIDGETNAME_init()
ÇÔ¼ö´Â _new()ÇÔ¼öÀÇ ÀÎÀÚ·Î ÁÖ¾îÁø widgetµé¿¡ ´ëÇÑ ±âº»ÀûÀÎ ÃʱâÈ­ ÀÛ¾÷À»
ÇÑ´Ù.  Descendent widgetµéÀº ´ÜÁö ±×µéÀÇ parent widgetÀÇ _init()ÇÔ¼ö¸¸
ºÎ¸£°Ô µÈ´Ù.  ±×·¯³ª ÀÌ ÀÛ¾÷ ºÐÇÒÀº Å×ÀÌºí¿¡ ´ëÇؼ­´Â Àß µ¿ÀÛÇÏÁö ¾Ê´Â´Ù.
Å×À̺íÀÇ °æ¿ì¿¡´Â ¸¸µé¾îÁú ¶§ Çà°ú ¿­ÀÇ °¹¼ö¸¦ ¾Ë Çʿ伺ÀÌ Àֱ⠶§¹®ÀÌ´Ù.
±×·¸Áö ¾ÊÀ¸¸é ¿ì¸®´Â ÀÌ Tictactoe widget¿¡ ÀÖ´Â gtk_table_new()ÀÇ ´ëºÎºÐÀÇ
±â´ÉµéÀ» Áߺ¹Çؼ­ ÀÌ¿ëÇÏ°Ô µÉ °ÍÀÌ´Ù.  ±×·¯¹Ç·Î, ¿ì¸®´Â ´ë½Å ±×°ÍÀ» GtkVBox
·ÎºÎÅÍ À̲ø¾î³»¾î, ¿ì¸®ÀÇ Å×À̺íÀ» VBox ³»ºÎ·Î ºÙ¿©ÁÙ °ÍÀÌ´Ù.

***
*** 19-3.3. Çì´õ ÆÄÀÏ
***
 °¢°¢ÀÇ widget class´Â public ÇÔ¼ö¿Í ±¸Á¶Ã¼ ¹× °´Ã¼ÀÇ ¼±¾ðµéÀÌ ÀÖ´Â Çì´õ
ÆÄÀÏÀ» °¡Áö°í ÀÖ´Ù.  ¿©±â¼­ °£´ÜÈ÷ »ìÆ캸ÀÚ.  Áߺ¹ Á¤ÀǸ¦ ÇÇÇϱâ À§Çؼ­,
¿ì¸®´Â Çì´õÆÄÀÏ Àüü¸¦ ÀÌ·¸°Ô µÑ·¯½Ñ´Ù.

 #ifndef __TICTACTOE_H__
 #define __TICTACTOE_H__
 #endif /* __TICTACTOE_H__ */

 ±×¸®°í C++ ÇÁ·Î±×·¥À» °í·ÁÇؼ­ À̰͵µ Ãß°¡ÇÑ´Ù.

      #ifdef __cplusplus
      extern "C" {
      #endif /* __cplusplus */
      #ifdef __cplusplus
      }
      #endif /* __cplusplus */

 ÇÔ¼ö¿Í ±¸Á¶Ã¼µé¿¡ ´ëÇØ, ¿ì¸®´Â Çì´õÆÄÀÏ ³»¿¡¼­ ¼¼°¡Áö Ç¥ÁØÀûÀÎ ¸ÅÅ©·Î¸¦
¼±¾ðÇÑ´Ù.  Áï TICTACTOE(obj), TICTACTOE_CLASS(klass), IS_TICTACTOE(obj)ÀÌ´Ù.
À̵éÀº ¾î¶² ÇÑ Æ÷ÀÎÅ͸¦ object ȤÀº class structure¿¡ ´ëÇÑ Æ÷ÀÎÅͷΠij½ºÆ®
ÇÏ°í, ¾î¶² object°¡ Tictactoe widgetÀÎÁö¸¦ üũÇÏ´Â ¿ªÇÒÀ» ÇÑ´Ù.

 ÀÌ°ÍÀÌ ÃÖÁ¾ÀûÀÎ Çì´õÆÄÀÏÀÌ´Ù.

 #ifndef __TICTACTOE_H__
 #define __TICTACTOE_H__

 #include <gdk/gdk.h>
 #include <gtk/gtkvbox.h>

 #ifdef __cplusplus
 extern "C" {
 #endif /* __cplusplus */

 #define TICTACTOE(obj)          GTK_CHECK_CAST (obj, tictactoe_get_type (), Tictactoe)
 #define TICTACTOE_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, tictactoe_get_type (), TictactoeClass)
 #define IS_TICTACTOE(obj)       GTK_CHECK_TYPE (obj, tictactoe_get_type ())

 typedef struct _Tictactoe       Tictactoe;
 typedef struct _TictactoeClass  TictactoeClass;

 struct _Tictactoe
 {
   GtkVBox vbox;

   GtkWidget *buttons[3][3];
 };

 struct _TictactoeClass
 {
   GtkVBoxClass parent_class;

   void (* tictactoe) (Tictactoe *ttt);
 };

 guint          tictactoe_get_type        (void);
 GtkWidget*     tictactoe_new             (void);
 void           tictactoe_clear           (Tictactoe *ttt);

 #ifdef __cplusplus
 }
 #endif /* __cplusplus */

 #endif /* __TICTACTOE_H__ */

***
*** 19-3.4. _get_type() ÇÔ¼ö
***
 ÀÌÁ¦ ¿ì¸®ÀÇ widgetÀ» °è¼Ó ´Ùµë¾î º¸ÀÚ.  ¸ðµç widgetµé¿¡ ´ëÇÑ ÇÙ½É(core)
ÇÔ¼ö´Â WIDGETNAME_get_type()ÀÌ´Ù.  ÀÌ ÇÔ¼ö´Â óÀ½ È£ÃâµÇ¾úÀ» ¶§, GTK¿¡°Ô
widget class¿¡ ´ëÇØ ¾Ë·ÁÁØ´Ù.  ±×¸®°í widget class¸¦ ¸íÈ®È÷ ½Äº°ÇÏ´Â ID¸¦
ÃëÇÑ´Ù.  °è¼Ó È£ÃâÇÏ¸é ¹Ù·Î ±× ID¸¦ ¸®ÅÏÇÑ´Ù.

 guint
 tictactoe_get_type ()
 {
   static guint ttt_type = 0;

   if (!ttt_type)
     {
       GtkTypeInfo ttt_info =
       {
         "Tictactoe",
         sizeof (Tictactoe),
         sizeof (TictactoeClass),
         (GtkClassInitFunc) tictactoe_class_init,
         (GtkObjectInitFunc) tictactoe_init,
         (GtkArgFunc) NULL,
       };

       ttt_type = gtk_type_unique (gtk_vbox_get_type (), &ttt_info);
     }

   return ttt_type;
 }

 ±¸Á¶Ã¼ GtkTypeInfo´Â ´ÙÀ½°ú °°ÀÌ Á¤ÀǵǾú´Ù.

      struct _GtkTypeInfo
      {
        gchar *type_name;
        guint object_size;
        guint class_size;
        GtkClassInitFunc class_init_func;
        GtkObjectInitFunc object_init_func;
        GtkArgFunc arg_func;
      };

 ÀÌ ±¸Á¶Ã¼ÀÇ °¢ Çʵå´Â ¿ª½Ã º¸ÀÌ´Â ±×´ë·Î´Ù.  ¿ì¸®´Â ¿©±â¼­ arg_func Çʵå
¸¦ ¹«½ÃÇÒ °ÍÀÌ´Ù.  ÀÌ°ÍÀº ÀÎÅÍÇÁ¸®ÅÍ ¾ð¾î¿¡¼­ ºñ·ÔµÇ¾î widget ¿É¼ÇµéÀ»
Æí¸®ÇÏ°Ô ¼¼ÆÃÇÒ ¼ö ÀÖµµ·Ï ÇÏ´Â Áß¿äÇÑ ¿ªÇÒÀ» ÇÒ ¼ö ÀÖÁö¸¸, ¾ÆÁ÷Àº ´ë°³
°®Ãß¾îÁöÁö ¾Ê¾Ò´Ù.  ÀÏ´Ü GTK°¡ ÀÌ ±¸Á¶Ã¼ÀÇ Á¦´ë·Î µÈ º¹»çº»À» °¡Áö°Ô µÇ¸é,
±×°ÍÀº Ưº°ÇÑ widget typeÀÇ object¸¦ ¸¸µå´Â ¹æ¹ýÀ» ¾Ë°Ô µÈ´Ù.

***
*** 19-3.5. _class_init() ÇÔ¼ö
***
 WIDGETNAME_class_init() ÇÔ¼ö´Â widgetÀÇ class structure¿¡ ÀÖ´Â ÇʵåµéÀ»
ÃʱâÈ­ÇÏ°í, ±× Ŭ·¡½º¿¡ ´ëÇÑ ½Ã±×³Îµéµµ ¼Â¾÷ÇØ ÁØ´Ù.  ¿ì¸®ÀÇ Tictactoe
widget¿¡ ´ëÇؼ­ ÀÌ°ÍÀº ÀÌ·¸°Ô º¸¿©Áø´Ù.

 enum {
   TICTACTOE_SIGNAL,
   LAST_SIGNAL
 };

 static gint tictactoe_signals[LAST_SIGNAL] = { 0 };

 static void
 tictactoe_class_init (TictactoeClass *class)
 {
   GtkObjectClass *object_class;

   object_class = (GtkObjectClass*) class;

   tictactoe_signals[TICTACTOE_SIGNAL] = gtk_signal_new ("tictactoe",
                                          GTK_RUN_FIRST,
                                          object_class->type,
                                          GTK_SIGNAL_OFFSET (TictactoeClass, tictactoe),
                                          gtk_signal_default_marshaller, GTK_ARG_NONE, 0);

   gtk_object_class_add_signals (object_class, tictactoe_signals, LAST_SIGNAL);

   class->tictactoe = NULL;
 }

 ¿ì¸® widgetÀÌ °¡Áø À¯ÀÏÇÑ ½Ã±×³ÎÀº 'tictactoe' ½Ã±×³Î·Î, ÀÌ°ÍÀº ÇÑ Çà,
¿­, ȤÀº ´ë°¢ ¼ººÐÀÌ ¿ÏÀüÈ÷ ä¿öÁö¸é ¿ä±¸µÈ´Ù.  ¸ðµç ÇÕ¼º widgetµéÀÌ ½Ã±×³Î
À» ÇÊ¿ä·Î ÇÏ´Â °ÍÀº ¾Æ´Ï¸ç, µû¶ó¼­ ¿©·¯ºÐÀÌ ÀÌ ºÎºÐÀ» óÀ½ Àаí ÀÖ´Â »óÅÂ
¶ó¸é ´ÙÀ½ ¼½¼Ç(section)À¸·Î ³Ñ¾î°¡µµ ÁÁ´Ù.  ÀÌ ºÎºÐÀº ´Ù¼Ò º¹ÀâÇÒ °ÍÀ̱â
¶§¹®ÀÌ´Ù.

 ÀÌ ÇÔ¼ö¸¦ º¸ÀÚ.

      gint   gtk_signal_new (gchar               *name,
                             GtkSignalRunType     run_type,
                             gint                 object_type,
                             gint                 function_offset,
                             GtkSignalMarshaller  marshaller,
                             GtkArgType           return_val,
                             gint                 nparams,
                             ...);

 »õ·Î¿î ½Ã±×³ÎÀ» ¸¸µç´Ù.  ¿©±â¿¡ ¾²ÀÎ ÀÎÀÚµéÀ» »ìÆ캸ÀÚ.

 o name: ½Ã±×³ÎÀÇ À̸§

 o run_type: µðÆúÆ® Çڵ鷯°¡ »ç¿ëÀÚ Çڵ鷯º¸´Ù ¾Õ¼­¼­ ȤÀº
   µÚµû¶ó ÀÛµ¿ÇÏ´ÂÁö °áÁ¤ÇÑ´Ù.  ´Ù¸¥ °¡´É¼ºµéµµ ÀÖÁö¸¸, º¸Åë
   ÀÌ°ÍÀº GTK_RUN_FIRST ¶Ç´Â GTK_RUN_LAST°¡ µÈ´Ù.

 o object_type: ÀÌ ½Ã±×³ÎÀÌ Àû¿ëµÉ objectÀÇ ID. (ÀÌ objectÀÇ
   descendents¿¡µµ Àû¿ëµÊ)

 o function_offset: µðÆúÆ® Çڵ鷯¸¦ °¡¸®Å°´Â Æ÷ÀÎÅÍÀÇ
   class structure ³»¿¡¼­ÀÇ ¿É¼Â.

 o marshaller: ½Ã±×³Î Çڵ鷯¸¦ ºÒ·¯³»±â À§ÇØ ¾²ÀÌ´Â ÇÔ¼ö.
   ½Ã±×³Î°ú »ç¿ëÀÚ µ¥ÀÌÅ͸¦ ¹ß»ýÇÑ object¸¸À» ÀÎÀÚ·Î °¡Áö´Â
   ½Ã±×³Î Çڵ鷯ÀÏ °æ¿ì, ¿ì¸®´Â ÀÌ¹Ì Á¦°øµÇ´Â marshaller ÇÔ¼öÀÎ
   gtk_signal_default_marshaller¸¦ ÀÌ¿ëÇÒ ¼ö ÀÖ´Ù.

 o return_val: ¸®ÅÏ°ªÀÇ Å¸ÀÔ.

 o nparams: ½Ã±×³Î Çڵ鷯ÀÇ ÀÎÀÚ °¹¼ö. (À§¿¡¼­ ¾ð±ÞµÈ µÎ µðÆúÆ®
   ÀÎÀÚ ÀÌ¿ÜÀÇ ´Ù¸¥ °Íµé)

 Å¸ÀÔÀ» ¼³Á¤Çϱâ À§ÇØ, GtkArgTypeÀ̶ó´Â enumerationÀÌ ¾²ÀδÙ.

      typedef enum
      {
        GTK_ARG_INVALID,
        GTK_ARG_NONE,
        GTK_ARG_CHAR,
        GTK_ARG_SHORT,
        GTK_ARG_INT,
        GTK_ARG_LONG,
        GTK_ARG_POINTER,
        GTK_ARG_OBJECT,
        GTK_ARG_FUNCTION,
        GTK_ARG_SIGNAL
      } GtkArgType;

 gtk_signal_new()´Â ½Ã±×³Î¿¡ ´ëÇØ °íÀ¯ÇÑ Á¤¼ö ½Äº°ÀÚ¸¦ ¸®ÅÏÇÑ´Ù.  ¿ì¸®´Â
À̵éÀ» tictactoe_signals ¹è¿­¿¡ ÀúÀåÇÏ°í, enumeration·Î ÀÌ¿ëÇؼ­ À妽º¸¦
ÁØ´Ù. (°ü½ÀÀûÀ¸·Î enumerationÀÇ ¿ø¼ÒµéÀº ´ë¹®ÀÚ·Î ½Ã±×³ÎÀÇ À̸§À» ³ªÅ¸³»
Áö¸¸, ¿©±â¼­ TICTACTOE() ¸ÅÅ©·Î¿Í Ãæµ¹ÇÒ ¼ö Àֱ⠶§¹®¿¡, ¿ì¸®´Â À̵éÀ»
TICTACTOE_SIGNALÀ̶ó°í ºÎ¸¥´Ù.)

 ½Ã±×³ÎÀ» ¸¸µé¾ú´Ù¸é, ÀÌÁ¦ GTK°¡ ÀÌ ½Ã±×³ÎµéÀ» Tictactoe Ŭ·¡½º¿¡ ¿¬°á½ÃÅ°
µµ·Ï ÇØ¾ß ÇÑ´Ù.  ÀÌ ÀÛ¾÷Àº gtk_object_class_add_signals()·Î ÇØÁØ´Ù.  ±×¸®°í
¾Æ¹«·± µðÆúÆ® µ¿ÀÛÀÌ ¾ø´Ù´Â °É ³ªÅ¸³»±â À§ÇØ, tictactoe ½Ã±×³ÎÀ» À§ÇÑ µðÆúÆ®
Çڵ鷯¸¦ °¡¸®Å°°í ÀÖ´Â Æ÷ÀÎÅ͸¦ NULL·Î ¼¼ÆÃÇÑ´Ù.

***
*** 19-3.6. _init() ÇÔ¼ö
***
 °¢ widget Ŭ·¡½º´Â ¶ÇÇÑ object structure¸¦ ÃʱâÈ­ÇØ ÁÙ ÇÔ¼ö¸¦ ÇÊ¿ä·Î ÇÑ´Ù.
º¸Åë, ÀÌ ÇÔ¼ö´Â ±¸Á¶Ã¼ÀÇ ÇʵåµéÀ» µðÆúÆ® °ªÀ¸·Î ¼¼ÆÃÇÏ´Â ³ª¸§´ë·Î Á¦ÇѵÈ
¿ªÇÒÀ» °¡Áö°í ÀÖ´Ù.  ±×·¯³ª ÇÕ¼º widgetµéÀÇ °æ¿ì, ÀÌ ÇÔ¼öµéÀÌ ÀûÇÕÇÑ ¶Ç´Ù¸¥
widgetµéÀ» ¸¸µé¾î Áֱ⵵ ÇÑ´Ù.

 static void
 tictactoe_init (Tictactoe *ttt)
 {
   GtkWidget *table;
   gint i,j;

   table = gtk_table_new (3, 3, TRUE);
   gtk_container_add (GTK_CONTAINER(ttt), table);
   gtk_widget_show (table);

   for (i=0;i<3; i++)
     for (j=0;j<3; j++)
       {
         ttt->buttons[i][j] = gtk_toggle_button_new ();
         gtk_table_attach_defaults (GTK_TABLE(table), ttt->buttons[i][j],
                                    i, i+1, j, j+1);
         gtk_signal_connect (GTK_OBJECT (ttt->buttons[i][j]), "toggled",
                             GTK_SIGNAL_FUNC (tictactoe_toggle), ttt);
         gtk_widget_set_usize (ttt->buttons[i][j], 20, 20);
         gtk_widget_show (ttt->buttons[i][j]);
       }
 }

***
*** 19-3.7. ±×¸®°í ³ª¸ÓÁöµé...
***
 ¸ðµç widgetµé(GtkBinó·³ ´Þ¸® ¼³¸íµÉ ¼ö ¾ø´Â base widgetµéÀº Á¦¿Ü)ÀÌ
°¡Áö°í ÀÖ¾î¾ß ÇÒ ÇÔ¼ö°¡ Çϳª ´õ ÀÖ´Ù.  ¹Ù·Î ±× ÇØ´çÇϴ ŸÀÔÀÇ object¸¦
¸¸µé±â À§ÇÑ ÇÔ¼ö´Ù.  ÀÌ°ÍÀº °ü·Ê»ó WIDGETNAME_new()°¡ µÈ´Ù.  Tictactoe
widget¿¡´Â ÇØ´çÇÏÁö ¾ÊÁö¸¸, ÀϺΠwidgetµéÀº ÀÌ ÇÔ¼öµéÀÌ ÀÎÀÚ¸¦ °¡Áö°í,
±×¸®°í ±× ÀÎÀÚ¸¦ Âü°íÇؼ­ ¾î¶² ¼Â¾÷À» ÇàÇϱ⵵ ÇÑ´Ù.  ´Ù¸¥ µÎ ÇÔ¼ö´Â ¿ì¸®ÀÇ
Tictactoe widget¿¡ ´ëÇÑ Æ¯º°ÇÑ °ÍµéÀÌ´Ù.

 tictactoe_clear()´Â widget¿¡ ÀÖ´Â ¸ðµç ¹öÆ°À» up »óÅ·Π¸®¼ÂÇØ ÁØ´Ù.  ¹öÆ°
Åä±ÛÀ» À§ÇÑ ¿ì¸® ½Ã±×³Î Çڵ鷯°¡ ºÒÇÊ¿äÇÏ°Ô Á¶ÁصǴ °ÍÀ» ¸·¾ÆÁÖ±â À§ÇØ
gtk_signal_handler_block_by_data()¸¦ ÀÌ¿ëÇÏ´Â °ÍÀ» ¸í½ÉÇÏÀÚ.

 tictactoe_toggle()Àº »ç¿ëÀÚ°¡ ¾î¶² ¹öÆ°À» Ŭ¸¯ÇßÀ» ¶§ ¿äûµÇ´Â ½Ã±×³Î
Çڵ鷯´Ù.  ÀÌ°ÍÀº Åä±ÛµÈ ¹öÆ°À» Æ÷ÇÔÇØ ¾î¶² ¸Å·ÂÀûÀÎ ÄÞºñ(combination)°¡
ÀÌ·ç¾îÁö´ÂÁö üũÇÏ°í, ¸¸¾à ±×·¸´Ù¸é "tictactoe" ½Ã±×³ÎÀ» ¹ß»ý½ÃŲ´Ù.

 GtkWidget*
 tictactoe_new ()
 {
   return GTK_WIDGET ( gtk_type_new (tictactoe_get_type ()));
 }

 void
 tictactoe_clear (Tictactoe *ttt)
 {
   int i,j;

   for (i=0;i<3;i++)
     for (j=0;j<3;j++)
       {
         gtk_signal_handler_block_by_data (GTK_OBJECT(ttt->buttons[i][j]), ttt);
         gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (ttt->buttons[i][j]),
                                      FALSE);
         gtk_signal_handler_unblock_by_data (GTK_OBJECT(ttt->buttons[i][j]), ttt);
       }
 }

 static void
 tictactoe_toggle (GtkWidget *widget, Tictactoe *ttt)
 {
   int i,k;

   static int rwins[8][3] = { { 0, 0, 0 }, { 1, 1, 1 }, { 2, 2, 2 },
                              { 0, 1, 2 }, { 0, 1, 2 }, { 0, 1, 2 },
                              { 0, 1, 2 }, { 0, 1, 2 } };
   static int cwins[8][3] = { { 0, 1, 2 }, { 0, 1, 2 }, { 0, 1, 2 },
                              { 0, 0, 0 }, { 1, 1, 1 }, { 2, 2, 2 },
                              { 0, 1, 2 }, { 2, 1, 0 } };

   int success, found;

   for (k=0; k<8; k++)
     {
       success = TRUE;
       found = FALSE;

       for (i=0;i<3;i++)
         {
           success = success &&
             GTK_TOGGLE_BUTTON(ttt->buttons[rwins[k][i]][cwins[k][i]])->active;
           found = found ||
             ttt->buttons[rwins[k][i]][cwins[k][i]] == widget;
         }

       if (success && found)
         {
           gtk_signal_emit (GTK_OBJECT (ttt),
                            tictactoe_signals[TICTACTOE_SIGNAL]);
           break;
         }
     }
 }

 ±×¸®°í ¿ì¸®ÀÇ Tictactoe widgetÀ» ÀÌ¿ëÇÑ ¿¹Á¦ ÇÁ·Î±×·¥Àº ÃÖÁ¾ÀûÀ¸·Î
ÀÌ°ÍÀÌ´Ù.

 #include <gtk/gtk.h>
 #include "tictactoe.h"

 /* ¾î¶² Çà, ¿­, ȤÀº ´ë°¢¼ººÐÀÌ ´Ù Â÷°Ô µÇ¸é ¿äûµÈ´Ù. */
 void
 win (GtkWidget *widget, gpointer data)
 {
   g_print ("Yay!\n");
   tictactoe_clear (TICTACTOE (widget));
 }

 int
 main (int argc, char *argv[])
 {
   GtkWidget *window;
   GtkWidget *ttt;

   gtk_init (&argc, &argv);

   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);

   gtk_window_set_title (GTK_WINDOW (window), "Aspect Frame");

   gtk_signal_connect (GTK_OBJECT (window), "destroy",
                       GTK_SIGNAL_FUNC (gtk_exit), NULL);

   gtk_container_border_width (GTK_CONTAINER (window), 10);

   /* Tictactoe widgetÀ» Çϳª ¸¸µç´Ù. */
   ttt = tictactoe_new ();
   gtk_container_add (GTK_CONTAINER (window), ttt);
   gtk_widget_show (ttt);

   /* ±×¸®°í ÀÌ°ÍÀÇ "tictactoe" ½Ã±×³Î¿¡ °áÇÕ½ÃÄÑ µÐ´Ù. */
   gtk_signal_connect (GTK_OBJECT (ttt), "tictactoe",
                       GTK_SIGNAL_FUNC (win), NULL);

   gtk_widget_show (window);

   gtk_main ();

   return 0;
 }

***
*** 19-4. ¹«¿¡¼­(from scratch) widget ¸¸µé±â
***

***
*** 19-4.1. ¼Ò°³
***
 À̹ø ¼½¼Ç¿¡¼­´Â widgetµéÀÌ ±× ÀڽŵéÀ» ¾î¶»°Ô ½ºÅ©¸°¿¡ º¸ÀÌ°Ô ÇÏ´ÂÁö,
±×¸®°í À̺¥Æ®¿Í »óÈ£ÀÛ¿ë ÇÏ´ÂÁö¸¦ ´õ °øºÎÇÒ °ÍÀÌ´Ù.  ÀÌ¿¡ ´ëÇÑ ¿¹Á¦·Î ¿ì¸®´Â
Æ÷ÀÎÅÍ°¡ ´Þ·ÁÀÖ´Â ¾Æ³¯·Î±× ´ÙÀ̾ó(analog dial) widgetÀ» ¸¸µé¾î¼­, »ç¿ëÀÚ°¡
±×°É ²ø¾î¼­ °ªÀ» ¼¼ÆÃÇϵµ·Ï ÇÒ °ÍÀÌ´Ù.

***
*** 19-4.2. ½ºÅ©¸°¿¡ widgetÀ» º¸À̱â
***
 ½ºÅ©¸°¿¡ º¸¿©ÁÖ±â À§Çؼ­ ¸î°¡Áö ´Ü°è°¡ ÀÖ´Ù.  WidgetÀÌ WIDGETNAME_new()
·Î½á ¸¸µé¾îÁö°í ³ª¼­, ¸î°³ÀÇ ÇÔ¼ö°¡ ´õ ÇÊ¿äÇÏ´Ù.

 o ÇØ´çÇÏ´Â widget¿¡ ´ëÇØ WIDGETNAEME_realize()°¡ XÀ©µµ¸¦ ¸¸µé¾îÁØ´Ù.

 o WIDGETNAME_map()Àº »ç¿ëÀÚ°¡ gtk_widget_show()¸¦ È£ÃâÇÑ ÀÌÈÄ¿¡ ¿äûµÈ´Ù.
   ÀÌ´Â widgetÀÌ ½ÇÁ¦·Î ½ºÅ©¸° À§¿¡ ±×·ÁÁö´Â(mapped) °ÍÀ» È®ÀÎÇÑ´Ù.
   ÄÁÅ×ÀÌ³Ê Å¬·¡½ºÀÇ °æ¿ì, ÀÏüÀÇ child widgetµéÀ» ¸ÅÇÎÇϱâ À§ÇÑ È£Ãâ ¶ÇÇÑ
   ÇÊ¿äÇÏ´Ù.

 o WIDGETNAME_draw()´Â widget ȤÀº ±×°ÍÀÇ ancestor¿¡ ´ëÇØ gtk_widget_draw()
   °¡ È£ÃâµÇ¾úÀ» ¶§ ¿äûµÇ´Â °ÍÀÌ´Ù.  ÀÌ°ÍÀº widgetÀ» ½ºÅ©¸°¿¡ ±×¸®±â À§ÇØ
   ½ÇÁ¦ ±×¸®´Â ÇÔ¼ö¸¦ È£ÃâÇØ ÁØ´Ù.  ÄÁÅ×ÀÌ³Ê widgetÀÇ °æ¿ì¿£ ±×°ÍÀÇ child
   widgetµéÀ» À§ÇØ gtk_widget_draw()µµ È£ÃâÇØ Áà¾ß ÇÑ´Ù.

 o  WIDGETNAME_expose()´Â expose À̺¥Æ®¸¦ À§ÇÑ Çڵ鷯´Ù.  ÀÌ°ÍÀº ½ºÅ©¸°¿¡
    exposeµÈ ¿µ¿ªÀ» ±×·ÁÁÖ±â À§ÇØ ÇÊ¿äÇÑ ÇÔ¼ö¸¦ È£ÃâÇÑ´Ù.  ÄÁÅ×ÀÌ³Ê widget
    ÀÇ °æ¿ì, ÀÌ ÇÔ¼ö´Â ÀڽŸ¸ÀÇ À©µµ¸¦ °¡ÁöÁö ¾Ê´Â child widgetµé¿¡ ´ëÇØ
    expose À̺¥Æ®¸¦ ¹ß»ý½ÃÄÑÁØ´Ù. (¸¸¾à ±×µéÀÌ À©µµ¸¦ °¡Áø´Ù¸é, ÇÊ¿äÇÑ
    expose À̺¥Æ®¸¦ X°¡ ¹ß»ý½ÃŲ´Ù.)

 »ó´çÈ÷ À¯»çÇÑ ¸¶Áö¸·ÀÇ µÎ ÇÔ¼ö¿¡ ÁÖÀÇÇØ¾ß ÇÒ °ÍÀÌ´Ù.  »ç½Ç ¸¹Àº ŸÀÔÀÇ
widgetµéÀº µÎ °æ¿ìÀÇ Â÷ÀÌÁ¡À» ±×´ÙÁö ±¸º°ÇÏÁö ¾Ê´Â´Ù.  Widget Ŭ·¡½ºÀÇ
µðÆúÆ® draw() ÇÔ¼ö´Â ´ÜÁö ´Ù½Ã ±×·ÁÁø ¿µ¿ª¿¡ ´ëÇØ Á¾ÇÕÀûÀÎ expose À̺¥Æ®¸¦
¹ß»ý½Ãų »ÓÀÌ´Ù.  ±×·¯³ª ¾î¶² ŸÀÔÀÇ widgetÀº µÎ ÇÔ¼ö¸¦ ±¸º°ÇÔÀ¸·Î½á ÀÛ¾÷À»
ÃÖ¼ÒÈ­Çϱ⵵ ÇÑ´Ù.  ¿¹¸¦µé¾î ¿©·¯ °³ÀÇ XÀ©µµ¸¦ °¡Áø widgetÀº ¿µÇâÀ» ¹ÞÀº
(affected) À©µµ¸¸À» ´Ù½Ã ±×·ÁÁÙ ¼ö Àִµ¥, ÀÌ°ÍÀº ´Ü¼øÈ÷ draw()À» È£ÃâÇÏ´Â
°ÍÀ¸·Î´Â ºÒ°¡´ÉÇÑ ÀÏÀÌ´Ù.

 ÄÁÅ×ÀÌ³Ê widgetµéÀº ¼­·ÎÀÇ Â÷ÀÌÁ¡¿¡ ´ëÇØ ÀÚ±â ÀÚ½ÅÀº »ó°üÇÏÁö ¾ÊÁö¸¸,
±×µéÀÇ child widgetµéÀº ¼­·Î¸¦ ºÐ¸íÈ÷ ±¸º°ÇØ¾ß ÇϹǷÎ, °£´ÜÈ÷ µðÆúÆ® draw()
ÇÔ¼ö¸¦ °¡Áú ¼ö ¾ø´Ù.  ÇÏÁö¸¸, µÎ ÇÔ¼ö »çÀÌ¿¡¼­ ±×¸®´Â Äڵ带 Áߺ¹ÇÏ´Â °ÍÀº
³¶ºñ´Ù.  ÀÌ·± widgetµéÀº °ü½À»ó WIDGETNAME_paint() ¶ó°í ºÒ¸®´Â ÇÔ¼ö¸¦
°¡Áø´Ù.  ÀÌ ÇÔ¼öµéÀº widgetÀ» ½ÇÁ¦·Î ±×¸®´Â ¿ªÇÒÀ» Çϸç, draw() ¹× expose()
ÇÔ¼ö¿¡ ÀÇÇØ ºÒ¸®¾îÁö°Ô µÈ´Ù.

 ¿ì¸®ÀÇ ¿¹Á¦¿¡¼­´Â dial widgetÀÌ ÄÁÅ×À̳ʰ¡ ¾Æ´Ï¸ç ¿ÀÁ÷ ÇϳªÀÇ À©µµ¸¸ °¡Áö
±â ¶§¹®¿¡, ¿ì¸®´Â °£´ÜÇÏ°Ô ¹®Á¦¸¦ ÇØ°áÇÒ ¼ö ÀÖ´Ù.  Áï µðÆúÆ® draw()¸¦ ÀÌ¿ë
ÇÏ°í ¶Ç expose() ÇÔ¼ö¸¸À» °®Ãá´Ù.


HomePage Backward Forward Post Reply List
1998 by swindler