Commit dd8153b2 authored by Andy Hertzfeld's avatar Andy Hertzfeld
Browse files

made fonts scale according to zoom level enabled/disabled zoom items in


     	made fonts scale according to zoom level
	enabled/disabled zoom items in context menu as necessary
parent 3abb791e
2000-01-30 Andy Hertzfeld <andy@eazel.com>
made fonts scale according to the zoom level:
* libnautilus/gnome-icon-container-private.h:
replaced label font with array of fonts
* libnautilus/gnome-icon-container.c:
load a font for each zoom level
* libnautilus/nautilus_icons_view_icon_item:c
use a font selected by the zoom level
enabled/disabled zoom items as necessary in context menu:
* src/file-manager/fm-directory-view-icons.c:
made bump_zoom_level return a boolean indicating if it can zoom further
* src/file-manager/fm-directory-view-list.c:
made bump_zoom_level return a boolean indicating if it can zoom further
* src/file-manager/fm-directory-view-list.c:
enable/disable items in zoom level according to the passed-back booleans
2000-01-28 Andy Hertzfeld <andy@eazel.com>
* libnautilus/gnome-icon-container-dnd.c:
......
......@@ -165,8 +165,8 @@ struct _GnomeIconContainerDetails {
/* zoom level */
gint zoom_level;
/* default font used to draw labels */
GdkFont *label_font;
/* default fonts used to draw labels */
GdkFont *label_font[NAUTILUS_ZOOM_LEVEL_LARGEST + 1];
};
/* Layout and icon size constants.
......
......@@ -1636,7 +1636,7 @@ static void
destroy (GtkObject *object)
{
GnomeIconContainer *container;
gint index;
container = GNOME_ICON_CONTAINER (object);
gnome_icon_container_dnd_fini (container);
......@@ -1649,8 +1649,9 @@ destroy (GtkObject *object)
gtk_idle_remove (container->details->idle_id);
if (container->details->linger_selection_mode_timer_tag != -1)
gtk_timeout_remove (container->details->linger_selection_mode_timer_tag);
if (container->details->label_font)
gdk_font_unref(container->details->label_font);
for (index = 0; index < 3; index++)
if (container->details->label_font[index])
gdk_font_unref(container->details->label_font[index]);
g_free (container->details);
......@@ -2033,8 +2034,16 @@ gnome_icon_container_initialize (GnomeIconContainer *container)
details->linger_selection_mode_timer_tag = -1;
details->zoom_level = NAUTILUS_ZOOM_LEVEL_STANDARD;
/* FIXME: soon we'll need fonts at multiple sizes */
details->label_font = gdk_font_load("-bitstream-charter-medium-r-normal-*-12-*-*-*-*-*-*-*");
/* font table - this isnt exactly proportional, but it looks better than computed */
/* FIXME: read font from metadata */
details->label_font[NAUTILUS_ZOOM_LEVEL_SMALLEST] = gdk_font_load("-bitstream-charter-medium-r-normal-*-8-*-*-*-*-*-*-*");
details->label_font[NAUTILUS_ZOOM_LEVEL_SMALLER] = gdk_font_load("-bitstream-charter-medium-r-normal-*-8-*-*-*-*-*-*-*");
details->label_font[NAUTILUS_ZOOM_LEVEL_SMALL] = gdk_font_load("-bitstream-charter-medium-r-normal-*-10-*-*-*-*-*-*-*");
details->label_font[NAUTILUS_ZOOM_LEVEL_STANDARD] = gdk_font_load("-bitstream-charter-medium-r-normal-*-12-*-*-*-*-*-*-*");
details->label_font[NAUTILUS_ZOOM_LEVEL_LARGE] = gdk_font_load("-bitstream-charter-medium-r-normal-*-14-*-*-*-*-*-*-*");
details->label_font[NAUTILUS_ZOOM_LEVEL_LARGER] = gdk_font_load("-bitstream-charter-medium-r-normal-*-16-*-*-*-*-*-*-*");
details->label_font[NAUTILUS_ZOOM_LEVEL_LARGEST] = gdk_font_load("-bitstream-charter-medium-r-normal-*-18-*-*-*-*-*-*-*");
/* FIXME: Read these from preferences. */
details->linger_selection_mode = FALSE;
......
......@@ -110,6 +110,7 @@ static void nautilus_icons_view_icon_item_bounds (GnomeCanvasItem *item, double
static void nautilus_icons_view_draw_text_box (GnomeCanvasItem* item, GdkDrawable *drawable, GdkFont *title_font, gchar* label,
gint icon_left, gint icon_bottom, gboolean is_selected, gboolean real_draw);
static GdkFont* get_font_for_item(GnomeCanvasItem *item);
static GnomeCanvasItemClass *parent_class;
......@@ -491,8 +492,15 @@ compute_render_affine (NautilusIconsViewIconItem *icon_view_item, double *render
art_affine_multiply (render_affine, viewport_affine, i2c);
}
/* Recomputes the bounding box of a icon canvas item.
*/
/* utility to return the proper font for a given item, factoring in the current zoom level */
static GdkFont*
get_font_for_item(GnomeCanvasItem *item)
{
GnomeIconContainer* container = GNOME_ICON_CONTAINER(item->canvas);
return container->details->label_font[container->details->zoom_level];
}
/* Recomputes the bounding box of a icon canvas item. */
static void
recompute_bounding_box (NautilusIconsViewIconItem *icon_view_item)
{
......@@ -537,8 +545,7 @@ nautilus_icons_view_icon_item_update (GnomeCanvasItem *item, double *affine, Art
{
NautilusIconsViewIconItem *icon_view_item = NAUTILUS_ICONS_VIEW_ICON_ITEM (item);
IconItemPrivate *priv = icon_view_item->priv;
GnomeIconContainer *container = GNOME_ICON_CONTAINER(item->canvas);
GdkFont *title_font = container->details->label_font;
GdkFont *title_font = get_font_for_item(item);
/* make sure the text box measurements are set up before recalculating the bounding box */
nautilus_icons_view_draw_text_box(item, NULL, title_font, priv->label, 0, 0, priv->is_selected, FALSE);
......@@ -686,7 +693,7 @@ nautilus_icons_view_icon_item_draw (GnomeCanvasItem *item, GdkDrawable *drawable
gint w, h, icon_height;
gint center_offset = 0;
GnomeIconContainer *container = GNOME_ICON_CONTAINER(item->canvas);
GdkFont *title_font = container->details->label_font;
GdkFont *title_font = get_font_for_item(item);
icon_view_item = NAUTILUS_ICONS_VIEW_ICON_ITEM (item);
priv = icon_view_item->priv;
......
......@@ -165,8 +165,8 @@ struct _GnomeIconContainerDetails {
/* zoom level */
gint zoom_level;
/* default font used to draw labels */
GdkFont *label_font;
/* default fonts used to draw labels */
GdkFont *label_font[NAUTILUS_ZOOM_LEVEL_LARGEST + 1];
};
/* Layout and icon size constants.
......
......@@ -1636,7 +1636,7 @@ static void
destroy (GtkObject *object)
{
GnomeIconContainer *container;
gint index;
container = GNOME_ICON_CONTAINER (object);
gnome_icon_container_dnd_fini (container);
......@@ -1649,8 +1649,9 @@ destroy (GtkObject *object)
gtk_idle_remove (container->details->idle_id);
if (container->details->linger_selection_mode_timer_tag != -1)
gtk_timeout_remove (container->details->linger_selection_mode_timer_tag);
if (container->details->label_font)
gdk_font_unref(container->details->label_font);
for (index = 0; index < 3; index++)
if (container->details->label_font[index])
gdk_font_unref(container->details->label_font[index]);
g_free (container->details);
......@@ -2033,8 +2034,16 @@ gnome_icon_container_initialize (GnomeIconContainer *container)
details->linger_selection_mode_timer_tag = -1;
details->zoom_level = NAUTILUS_ZOOM_LEVEL_STANDARD;
/* FIXME: soon we'll need fonts at multiple sizes */
details->label_font = gdk_font_load("-bitstream-charter-medium-r-normal-*-12-*-*-*-*-*-*-*");
/* font table - this isnt exactly proportional, but it looks better than computed */
/* FIXME: read font from metadata */
details->label_font[NAUTILUS_ZOOM_LEVEL_SMALLEST] = gdk_font_load("-bitstream-charter-medium-r-normal-*-8-*-*-*-*-*-*-*");
details->label_font[NAUTILUS_ZOOM_LEVEL_SMALLER] = gdk_font_load("-bitstream-charter-medium-r-normal-*-8-*-*-*-*-*-*-*");
details->label_font[NAUTILUS_ZOOM_LEVEL_SMALL] = gdk_font_load("-bitstream-charter-medium-r-normal-*-10-*-*-*-*-*-*-*");
details->label_font[NAUTILUS_ZOOM_LEVEL_STANDARD] = gdk_font_load("-bitstream-charter-medium-r-normal-*-12-*-*-*-*-*-*-*");
details->label_font[NAUTILUS_ZOOM_LEVEL_LARGE] = gdk_font_load("-bitstream-charter-medium-r-normal-*-14-*-*-*-*-*-*-*");
details->label_font[NAUTILUS_ZOOM_LEVEL_LARGER] = gdk_font_load("-bitstream-charter-medium-r-normal-*-16-*-*-*-*-*-*-*");
details->label_font[NAUTILUS_ZOOM_LEVEL_LARGEST] = gdk_font_load("-bitstream-charter-medium-r-normal-*-18-*-*-*-*-*-*-*");
/* FIXME: Read these from preferences. */
details->linger_selection_mode = FALSE;
......
......@@ -110,6 +110,7 @@ static void nautilus_icons_view_icon_item_bounds (GnomeCanvasItem *item, double
static void nautilus_icons_view_draw_text_box (GnomeCanvasItem* item, GdkDrawable *drawable, GdkFont *title_font, gchar* label,
gint icon_left, gint icon_bottom, gboolean is_selected, gboolean real_draw);
static GdkFont* get_font_for_item(GnomeCanvasItem *item);
static GnomeCanvasItemClass *parent_class;
......@@ -491,8 +492,15 @@ compute_render_affine (NautilusIconsViewIconItem *icon_view_item, double *render
art_affine_multiply (render_affine, viewport_affine, i2c);
}
/* Recomputes the bounding box of a icon canvas item.
*/
/* utility to return the proper font for a given item, factoring in the current zoom level */
static GdkFont*
get_font_for_item(GnomeCanvasItem *item)
{
GnomeIconContainer* container = GNOME_ICON_CONTAINER(item->canvas);
return container->details->label_font[container->details->zoom_level];
}
/* Recomputes the bounding box of a icon canvas item. */
static void
recompute_bounding_box (NautilusIconsViewIconItem *icon_view_item)
{
......@@ -537,8 +545,7 @@ nautilus_icons_view_icon_item_update (GnomeCanvasItem *item, double *affine, Art
{
NautilusIconsViewIconItem *icon_view_item = NAUTILUS_ICONS_VIEW_ICON_ITEM (item);
IconItemPrivate *priv = icon_view_item->priv;
GnomeIconContainer *container = GNOME_ICON_CONTAINER(item->canvas);
GdkFont *title_font = container->details->label_font;
GdkFont *title_font = get_font_for_item(item);
/* make sure the text box measurements are set up before recalculating the bounding box */
nautilus_icons_view_draw_text_box(item, NULL, title_font, priv->label, 0, 0, priv->is_selected, FALSE);
......@@ -686,7 +693,7 @@ nautilus_icons_view_icon_item_draw (GnomeCanvasItem *item, GdkDrawable *drawable
gint w, h, icon_height;
gint center_offset = 0;
GnomeIconContainer *container = GNOME_ICON_CONTAINER(item->canvas);
GdkFont *title_font = container->details->label_font;
GdkFont *title_font = get_font_for_item(item);
icon_view_item = NAUTILUS_ICONS_VIEW_ICON_ITEM (item);
priv = icon_view_item->priv;
......
......@@ -165,8 +165,8 @@ struct _GnomeIconContainerDetails {
/* zoom level */
gint zoom_level;
/* default font used to draw labels */
GdkFont *label_font;
/* default fonts used to draw labels */
GdkFont *label_font[NAUTILUS_ZOOM_LEVEL_LARGEST + 1];
};
/* Layout and icon size constants.
......
......@@ -1636,7 +1636,7 @@ static void
destroy (GtkObject *object)
{
GnomeIconContainer *container;
gint index;
container = GNOME_ICON_CONTAINER (object);
gnome_icon_container_dnd_fini (container);
......@@ -1649,8 +1649,9 @@ destroy (GtkObject *object)
gtk_idle_remove (container->details->idle_id);
if (container->details->linger_selection_mode_timer_tag != -1)
gtk_timeout_remove (container->details->linger_selection_mode_timer_tag);
if (container->details->label_font)
gdk_font_unref(container->details->label_font);
for (index = 0; index < 3; index++)
if (container->details->label_font[index])
gdk_font_unref(container->details->label_font[index]);
g_free (container->details);
......@@ -2033,8 +2034,16 @@ gnome_icon_container_initialize (GnomeIconContainer *container)
details->linger_selection_mode_timer_tag = -1;
details->zoom_level = NAUTILUS_ZOOM_LEVEL_STANDARD;
/* FIXME: soon we'll need fonts at multiple sizes */
details->label_font = gdk_font_load("-bitstream-charter-medium-r-normal-*-12-*-*-*-*-*-*-*");
/* font table - this isnt exactly proportional, but it looks better than computed */
/* FIXME: read font from metadata */
details->label_font[NAUTILUS_ZOOM_LEVEL_SMALLEST] = gdk_font_load("-bitstream-charter-medium-r-normal-*-8-*-*-*-*-*-*-*");
details->label_font[NAUTILUS_ZOOM_LEVEL_SMALLER] = gdk_font_load("-bitstream-charter-medium-r-normal-*-8-*-*-*-*-*-*-*");
details->label_font[NAUTILUS_ZOOM_LEVEL_SMALL] = gdk_font_load("-bitstream-charter-medium-r-normal-*-10-*-*-*-*-*-*-*");
details->label_font[NAUTILUS_ZOOM_LEVEL_STANDARD] = gdk_font_load("-bitstream-charter-medium-r-normal-*-12-*-*-*-*-*-*-*");
details->label_font[NAUTILUS_ZOOM_LEVEL_LARGE] = gdk_font_load("-bitstream-charter-medium-r-normal-*-14-*-*-*-*-*-*-*");
details->label_font[NAUTILUS_ZOOM_LEVEL_LARGER] = gdk_font_load("-bitstream-charter-medium-r-normal-*-16-*-*-*-*-*-*-*");
details->label_font[NAUTILUS_ZOOM_LEVEL_LARGEST] = gdk_font_load("-bitstream-charter-medium-r-normal-*-18-*-*-*-*-*-*-*");
/* FIXME: Read these from preferences. */
details->linger_selection_mode = FALSE;
......
......@@ -110,6 +110,7 @@ static void nautilus_icons_view_icon_item_bounds (GnomeCanvasItem *item, double
static void nautilus_icons_view_draw_text_box (GnomeCanvasItem* item, GdkDrawable *drawable, GdkFont *title_font, gchar* label,
gint icon_left, gint icon_bottom, gboolean is_selected, gboolean real_draw);
static GdkFont* get_font_for_item(GnomeCanvasItem *item);
static GnomeCanvasItemClass *parent_class;
......@@ -491,8 +492,15 @@ compute_render_affine (NautilusIconsViewIconItem *icon_view_item, double *render
art_affine_multiply (render_affine, viewport_affine, i2c);
}
/* Recomputes the bounding box of a icon canvas item.
*/
/* utility to return the proper font for a given item, factoring in the current zoom level */
static GdkFont*
get_font_for_item(GnomeCanvasItem *item)
{
GnomeIconContainer* container = GNOME_ICON_CONTAINER(item->canvas);
return container->details->label_font[container->details->zoom_level];
}
/* Recomputes the bounding box of a icon canvas item. */
static void
recompute_bounding_box (NautilusIconsViewIconItem *icon_view_item)
{
......@@ -537,8 +545,7 @@ nautilus_icons_view_icon_item_update (GnomeCanvasItem *item, double *affine, Art
{
NautilusIconsViewIconItem *icon_view_item = NAUTILUS_ICONS_VIEW_ICON_ITEM (item);
IconItemPrivate *priv = icon_view_item->priv;
GnomeIconContainer *container = GNOME_ICON_CONTAINER(item->canvas);
GdkFont *title_font = container->details->label_font;
GdkFont *title_font = get_font_for_item(item);
/* make sure the text box measurements are set up before recalculating the bounding box */
nautilus_icons_view_draw_text_box(item, NULL, title_font, priv->label, 0, 0, priv->is_selected, FALSE);
......@@ -686,7 +693,7 @@ nautilus_icons_view_icon_item_draw (GnomeCanvasItem *item, GdkDrawable *drawable
gint w, h, icon_height;
gint center_offset = 0;
GnomeIconContainer *container = GNOME_ICON_CONTAINER(item->canvas);
GdkFont *title_font = container->details->label_font;
GdkFont *title_font = get_font_for_item(item);
icon_view_item = NAUTILUS_ICONS_VIEW_ICON_ITEM (item);
priv = icon_view_item->priv;
......
......@@ -39,6 +39,7 @@
#include <libnautilus/nautilus-string.h>
#include <libnautilus/nautilus-background.h>
#include <libnautilus/nautilus-directory.h>
#include <libnautilus/nautilus-icon-factory.h>
#define DEFAULT_BACKGROUND_COLOR "rgb:FFFF/FFFF/FFFF"
......@@ -60,7 +61,7 @@ static void fm_directory_view_icons_background_changed_cb (NautilusBackground *b
FMDirectoryViewIcons *icon_view);
static void fm_directory_view_icons_begin_loading
(FMDirectoryView *view);
static void fm_directory_view_icons_bump_zoom_level
static gboolean fm_directory_view_icons_bump_zoom_level
(FMDirectoryView *view, gint zoom_increment);
static void fm_directory_view_icons_clear (FMDirectoryView *view);
static void fm_directory_view_icons_destroy (GtkObject *view);
......@@ -294,13 +295,17 @@ fm_directory_view_icons_begin_loading (FMDirectoryView *view)
{
}
static void
static gboolean
fm_directory_view_icons_bump_zoom_level (FMDirectoryView *view, gint zoom_increment)
{
GnomeIconContainer *icon_container = get_icon_container(FM_DIRECTORY_VIEW_ICONS (view));
gint current_zoom_level = gnome_icon_container_get_zoom_level(icon_container);
gnome_icon_container_set_zoom_level(icon_container, current_zoom_level + zoom_increment);
gint new_zoom_level = current_zoom_level + zoom_increment;
gnome_icon_container_set_zoom_level(icon_container, new_zoom_level);
if (zoom_increment > 0)
return new_zoom_level < NAUTILUS_ZOOM_LEVEL_LARGEST;
else
return new_zoom_level > NAUTILUS_ZOOM_LEVEL_SMALLEST;
}
static GList *
......
......@@ -91,7 +91,7 @@ static void fm_directory_view_list_background_changed_cb
FMDirectoryViewList *list_view);
static void fm_directory_view_list_begin_adding_entries
(FMDirectoryView *view);
static void fm_directory_view_list_bump_zoom_level (FMDirectoryView *view,
static gboolean fm_directory_view_list_bump_zoom_level (FMDirectoryView *view,
gint zoom_increment);
static void fm_directory_view_list_clear (FMDirectoryView *view);
static guint fm_directory_view_list_get_icon_size (FMDirectoryViewList *list_view);
......@@ -490,13 +490,13 @@ get_flist (FMDirectoryViewList *list_view)
return GTK_FLIST (GTK_BIN (list_view)->child);
}
static void
static gboolean
fm_directory_view_list_bump_zoom_level (FMDirectoryView *view, gint zoom_increment)
{
FMDirectoryViewList *list_view;
NautilusZoomLevel new_level;
g_return_if_fail (FM_IS_DIRECTORY_VIEW (view));
g_return_val_if_fail (FM_IS_DIRECTORY_VIEW (view), FALSE);
list_view = FM_DIRECTORY_VIEW_LIST (view);
......@@ -511,6 +511,12 @@ fm_directory_view_list_bump_zoom_level (FMDirectoryView *view, gint zoom_increme
}
fm_directory_view_list_set_zoom_level (list_view, new_level);
if (zoom_increment > 0)
return new_level < NAUTILUS_ZOOM_LEVEL_LARGEST;
else
return new_level > NAUTILUS_ZOOM_LEVEL_SMALLEST;
}
static void
......
......@@ -76,6 +76,9 @@ struct _FMDirectoryViewDetails
NautilusDirectory *model;
GtkMenu *background_context_menu;
GtkWidget *zoom_in_item;
GtkWidget *zoom_out_item;
};
/* forward declarations */
......@@ -157,7 +160,7 @@ static void
fm_directory_view_initialize (FMDirectoryView *directory_view)
{
directory_view->details = g_new0 (FMDirectoryViewDetails, 1);
#if 0
gtk_scroll_frame_set_policy (GTK_SCROLL_FRAME (directory_view),
GTK_POLICY_AUTOMATIC,
......@@ -369,13 +372,19 @@ stop_load (FMDirectoryView *view, gboolean error)
static void
zoom_in_cb(GtkMenuItem *item, FMDirectoryView *directory_view)
{
fm_directory_view_bump_zoom_level (directory_view, 1);
gboolean can_zoom_in = fm_directory_view_bump_zoom_level (directory_view, 1);
gtk_widget_set_sensitive(directory_view->details->zoom_in_item, can_zoom_in);
gtk_widget_set_sensitive(directory_view->details->zoom_out_item, TRUE);
}
static void
zoom_out_cb(GtkMenuItem *item, FMDirectoryView *directory_view)
{
fm_directory_view_bump_zoom_level (directory_view, -1);
gboolean can_zoom_out = fm_directory_view_bump_zoom_level (directory_view, -1);
gtk_widget_set_sensitive(directory_view->details->zoom_out_item, can_zoom_out);
gtk_widget_set_sensitive(directory_view->details->zoom_in_item, TRUE);
}
static void
......@@ -569,12 +578,12 @@ fm_directory_view_begin_loading (FMDirectoryView *view)
* bump the current zoom level by invoking the relevant subclass through the slot
*
**/
void
gboolean
fm_directory_view_bump_zoom_level (FMDirectoryView *view, gint zoom_increment)
{
g_return_if_fail (FM_IS_DIRECTORY_VIEW (view));
g_return_val_if_fail (FM_IS_DIRECTORY_VIEW (view), FALSE);
(* FM_DIRECTORY_VIEW_CLASS (GTK_OBJECT (view)->klass)->bump_zoom_level) (view, zoom_increment);
return (* FM_DIRECTORY_VIEW_CLASS (GTK_OBJECT (view)->klass)->bump_zoom_level) (view, zoom_increment);
}
/**
......@@ -660,19 +669,24 @@ append_background_items (FMDirectoryView *view, GtkMenu *menu)
gtk_widget_show (menu_item);
gtk_menu_append (menu, menu_item);
menu_item = gtk_menu_item_new_with_label ("Zoom in");
menu_item = gtk_menu_item_new_with_label ("Zoom in");
gtk_signal_connect(GTK_OBJECT (menu_item), "activate",
GTK_SIGNAL_FUNC (zoom_in_cb), view);
gtk_widget_show (menu_item);
gtk_menu_append (menu, menu_item);
view->details->zoom_in_item = menu_item;
menu_item = gtk_menu_item_new_with_label ("Zoom out");
gtk_signal_connect(GTK_OBJECT (menu_item), "activate",
GTK_SIGNAL_FUNC (zoom_out_cb), view);
gtk_widget_show (menu_item);
gtk_menu_append (menu, menu_item);
view->details->zoom_out_item = menu_item;
}
/* FIXME - need better architecture for setting these. */
......
......@@ -89,8 +89,9 @@ struct _FMDirectoryViewClass {
(* get_selection) (FMDirectoryView *view);
/* bump_zoom_level is a function pointer that subclasses override to
* change the zoom level of an object */
void (* bump_zoom_level) (FMDirectoryView *view, gint zoom_increment);
* change the zoom level of an object. It returns FALSE if it's now zoomed as
far as it can go */
gboolean (* bump_zoom_level) (FMDirectoryView *view, gint zoom_increment);
};
......@@ -124,7 +125,7 @@ void fm_directory_view_begin_loading (FMDirector
*/
void fm_directory_view_activate_entry (FMDirectoryView *view,
NautilusFile *file);
void fm_directory_view_bump_zoom_level (FMDirectoryView *view, gint zoom_increment);
gboolean fm_directory_view_bump_zoom_level (FMDirectoryView *view, gint zoom_increment);
void fm_directory_view_notify_selection_changed (FMDirectoryView *view);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment