~asac/clutk/gles-support

« back to all changes in this revision

Viewing changes to clutk/ctk-menu.c

  • Committer: Jay Taoko
  • Date: 2010-07-22 16:33:53 UTC
  • mfrom: (237.1.2 clutk.menu-expandable)
  • Revision ID: jay.taoko@canonical.com-20100722163353-jospaxvda2ih8b4p
CtkMenuExpandable: Added an Expandable Menu. Compute correct size
and position with regard to the anchor and the special item inside the menu.

[modified]
  clutk/Makefile.am
  clutk/clutk.h
  clutk/ctk-arb-asm-private.c
  clutk/ctk-arb-asm-private.h
  clutk/ctk-layer-actor.c
  clutk/ctk-main.c
  clutk/ctk-menu.c
  clutk/ctk-menu.h
  data/shaders/Makefile.am
  data/shaders/shaders.h
  gtk-doc.make
  tests/Makefile.am
  tests/test-clutk.c
  vapi/clutk-0.3.gi
  vapi/clutk-0.3.vapi

[added]
  clutk/ctk-menu-expandable.c
  clutk/ctk-menu-expandable.h
  data/shaders/TextureColorMask.fparb
  tests/test-ctk-menu-expandable.c
  tests/test-menu-expandable.c

Show diffs side-by-side

added added

removed removed

Lines of Context:
70
70
  guint    close_on_leave_timeout;
71
71
  ClutterStage  *attached_stage;
72
72
 
 
73
  gfloat special_item_y;
 
74
  gfloat special_item_height;
 
75
  gint special_item_index;
 
76
  gboolean is_expandable_menu;
 
77
  
73
78
  /* background */
74
79
  guint blurred_background_texture;
75
80
  gboolean refresh_background_texture;
197
202
  priv->close_on_leave = FALSE;
198
203
  priv->close_on_leave_timeout = 0;
199
204
 
 
205
  priv->special_item_height = 0.0f;
 
206
  priv->special_item_index = 0;
 
207
  priv->special_item_y = 0.0f;
 
208
  priv->is_expandable_menu = FALSE;
 
209
  
200
210
  g_signal_connect (CLUTTER_ACTOR (menu),
201
211
                    "realize",
202
212
                    G_CALLBACK(ctk_menu_on_realize),
738
748
 
739
749
}
740
750
 
741
 
 
742
751
static void
743
752
ctk_menu_allocate (ClutterActor          *actor,
744
753
                  const ClutterActorBox *box,
758
767
  gfloat             attached_actor_height;
759
768
  gfloat            delta_width, delta_height;
760
769
  gfloat            delta_y1, delta_y2;
761
 
 
 
770
  
762
771
  special_y = special_height = 0;
763
772
  actor_box = clutter_actor_box_copy (box);
764
773
  ctk_actor_get_padding (CTK_ACTOR (actor), &padding);
775
784
  /* Work out the size of the children first */
776
785
  gfloat x, y;
777
786
  y = padding.top;
778
 
  for (c = priv->children; c; c = c->next)
 
787
  int item_index = 0;
 
788
  for (c = priv->children, item_index = 0; c; c = c->next, item_index++)
779
789
    {
780
790
      ClutterActor *child = c->data;
781
791
      gfloat min_width;
798
808
        {
799
809
          special_y = y;
800
810
          special_height = child_height;
 
811
          priv->special_item_y = y;
 
812
          priv->special_item_height = child_height;
 
813
          priv->special_item_index = item_index;
801
814
        }
802
815
 
803
816
      y += child_height + spacing;
804
817
    }
805
818
 
 
819
  if (special_y == 0)
 
820
    {
 
821
      // elect the first item to be the special widget
 
822
      if (priv->children)
 
823
      {
 
824
        ClutterActor *child = priv->children->data;
 
825
        priv->special_item_height = clutter_actor_get_height (child);
 
826
        priv->special_item_y = padding.top;
 
827
        priv->special_item_index = 0;
 
828
      }
 
829
    }
 
830
 
806
831
  /* Now we do the positioning */
807
832
 
808
833
  // modify the position of the menu so that the special child is aligned
814
839
                                          CLUTTER_ACTOR (priv->attached_actor));
815
840
      pad = (attached_actor_height - special_height) * 0.5;
816
841
    }
817
 
  actor_box->y1 = actor_box->y1 - special_y + pad;
818
 
  actor_box->y2 = actor_box->y2 - special_y + pad;
 
842
 
 
843
  if(!ctk_menu_is_expandable (CTK_MENU (actor)))
 
844
    {
 
845
      actor_box->y1 = actor_box->y1 - special_y + pad;
 
846
      actor_box->y2 = actor_box->y2 - special_y + pad;
 
847
    }
819
848
 
820
849
  // its only at this point that we know if we are too big to fit on the screen
821
850
  // if we are, we need to move
837
866
    }
838
867
 
839
868
  CLUTTER_ACTOR_CLASS (ctk_menu_parent_class)->allocate (actor, actor_box, flags);
840
 
 
 
869
  
841
870
  // if is_transforming is true, we need to calculate a new width/height
842
871
  delta_y1 = 0;
843
872
  delta_y2 = clutter_actor_box_get_height (actor_box);
1127
1156
 
1128
1157
 }
1129
1158
 
 
1159
 
1130
1160
static void
1131
1161
ctk_menu_stick_to_actor (CtkMenu *menu, CtkActor *actor)
1132
1162
{
1139
1169
  ctk_actor_get_stored_allocation (actor, &box);
1140
1170
  w = clutter_actor_box_get_width (&box);
1141
1171
  h = clutter_actor_box_get_height (&box);
1142
 
  clutter_actor_get_position (CLUTTER_ACTOR (actor), &x, &y);
 
1172
  clutter_actor_get_transformed_position (CLUTTER_ACTOR (actor), &x, &y);
1143
1173
 
1144
1174
  clutter_actor_set_position (CLUTTER_ACTOR (menu),
1145
 
                              x + w, y + (h/2.0f));
 
1175
                              x + w , y + (h/2.0f));
1146
1176
}
1147
1177
 
1148
1178
static void
1335
1365
  }
1336
1366
 
1337
1367
  menu->priv->attached_actor = actor;
 
1368
  
 
1369
  // Deactivate the tracking of actors attached to the menu
1338
1370
  menu->priv->attached_actor_handle_id = g_signal_connect (
1339
1371
                            actor, "notify::allocation",
1340
1372
                            G_CALLBACK (ctk_menu_notify_on_attached_allocation),
1341
1373
                            menu);
1342
1374
 
1343
1375
  ctk_menu_stick_to_actor (menu, actor);
 
1376
 
1344
1377
}
1345
1378
 
1346
1379
CtkActor *
1461
1494
  g_return_val_if_fail (CTK_IS_MENU (menu), NULL);
1462
1495
  return menu->priv->children;
1463
1496
}
 
1497
 
 
1498
gfloat
 
1499
ctk_menu_get_special_item_height (CtkMenu *self)
 
1500
{
 
1501
  g_return_val_if_fail (CTK_IS_MENU (self), 0.0f);
 
1502
  return self->priv->special_item_height;  
 
1503
}
 
1504
 
 
1505
gfloat
 
1506
ctk_menu_get_special_item_y (CtkMenu *self)
 
1507
{
 
1508
  g_return_val_if_fail (CTK_IS_MENU (self), 0.0f);
 
1509
  return self->priv->special_item_y;
 
1510
}
 
1511
 
 
1512
gint
 
1513
ctk_menu_get_special_item_index (CtkMenu *self)
 
1514
{
 
1515
  g_return_val_if_fail (CTK_IS_MENU (self), 0);
 
1516
  return self->priv->special_item_index;  
 
1517
}
 
1518
 
 
1519
gboolean
 
1520
ctk_menu_is_expandable (CtkMenu *self)
 
1521
{
 
1522
  g_return_val_if_fail (CTK_IS_MENU (self), FALSE);
 
1523
  return self->priv->is_expandable_menu;
 
1524
}
 
1525
 
 
1526
void
 
1527
ctk_menu_set_is_expandable (CtkMenu *self, gboolean b)
 
1528
{
 
1529
  g_return_if_fail (CTK_IS_MENU (self));
 
1530
  self->priv->is_expandable_menu = b;
 
1531
}
 
1532