diff --git a/ChangeLog b/ChangeLog index 22036224a8..e6ec98c655 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,51 @@ +Mon Dec 3 16:39:17 2001 Owen Taylor + + Patch from Bill Haneman (with many modifications) to make + the focus color work on dark themes and to make the + focus line width configurable. (#61079, #63074) + + * gtk/gtkwidget.c: Add style properties, + ::focus-widget, ::focus-line-width, and ::focus-padding. + + * gtk/gtkstyle.[ch]: Make gtk_paint_focus() take a + state argument as well so we can use fg[STATE] to + draw instead of always drawing with black. + Cange paint_focus() to respect GtkWidget::focus-width + and GtkWidget::focus-line-pattern. Fix continuity + problem where the default 1-1 stipple had a blob + in one corner and a gap in the other. Change the + interpretation of x/y/width/height to be the bounding + box of the focus rect instead of the rectangle + passed to gdk_draw_rectangle. + + * gtk/gtkcheckbutton.c gtk/gtklistitem.c gtk/gtknotebook.c + gtk/gtkoptionmenu.c gtk/gtkradiobutton.c gtk/gtkspinbutton.c + gtk/gtktextview.c gtk/gtktreeview.c: Handle ::focus-width + and ::focus-line-padding. + + * gtk/gtkentry.c: Handle :;focus-width property; cleanup + and remove duplicated code; fix drawing of focus rectangle + when interior-focus = FALSE. (#63072, #63073) + + * gtk/gtkrange.c gtk/gtktext.c gtk/gtktreeitem.c + gtk/gtktreeviewcolumn.c: Basic fixups to make compile; + Range and TreeViewColumn will need more extensive fixing. + + * gtk/gtkcolorsel.c: Honor focus line attributes when + drawing the focus on the color swatches. (#63071) + + * gtk/gtkhsv.c: Honor focus line attributes when + drawing the focus for the ring and triangle. + + * docs/widget_geometry.txt: Start at documenting how + various widgets are drawn. + + * gtk/gtkbutton.c (_gtk_button_paint): Export + _gtk_button_paint() librarywide, so we don't have + duplicate a bunch of code in gtktogglebutton.c. + + * gtk/gtktogglebutton.c: Use _gtk_button_paint(). + Mon Dec 3 21:04:13 2001 Jonathan Blandford * gtk/gtkmarshalers.list: remove VOID:BOXED,POINTER and diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0 index 22036224a8..e6ec98c655 100644 --- a/ChangeLog.pre-2-0 +++ b/ChangeLog.pre-2-0 @@ -1,3 +1,51 @@ +Mon Dec 3 16:39:17 2001 Owen Taylor + + Patch from Bill Haneman (with many modifications) to make + the focus color work on dark themes and to make the + focus line width configurable. (#61079, #63074) + + * gtk/gtkwidget.c: Add style properties, + ::focus-widget, ::focus-line-width, and ::focus-padding. + + * gtk/gtkstyle.[ch]: Make gtk_paint_focus() take a + state argument as well so we can use fg[STATE] to + draw instead of always drawing with black. + Cange paint_focus() to respect GtkWidget::focus-width + and GtkWidget::focus-line-pattern. Fix continuity + problem where the default 1-1 stipple had a blob + in one corner and a gap in the other. Change the + interpretation of x/y/width/height to be the bounding + box of the focus rect instead of the rectangle + passed to gdk_draw_rectangle. + + * gtk/gtkcheckbutton.c gtk/gtklistitem.c gtk/gtknotebook.c + gtk/gtkoptionmenu.c gtk/gtkradiobutton.c gtk/gtkspinbutton.c + gtk/gtktextview.c gtk/gtktreeview.c: Handle ::focus-width + and ::focus-line-padding. + + * gtk/gtkentry.c: Handle :;focus-width property; cleanup + and remove duplicated code; fix drawing of focus rectangle + when interior-focus = FALSE. (#63072, #63073) + + * gtk/gtkrange.c gtk/gtktext.c gtk/gtktreeitem.c + gtk/gtktreeviewcolumn.c: Basic fixups to make compile; + Range and TreeViewColumn will need more extensive fixing. + + * gtk/gtkcolorsel.c: Honor focus line attributes when + drawing the focus on the color swatches. (#63071) + + * gtk/gtkhsv.c: Honor focus line attributes when + drawing the focus for the ring and triangle. + + * docs/widget_geometry.txt: Start at documenting how + various widgets are drawn. + + * gtk/gtkbutton.c (_gtk_button_paint): Export + _gtk_button_paint() librarywide, so we don't have + duplicate a bunch of code in gtktogglebutton.c. + + * gtk/gtktogglebutton.c: Use _gtk_button_paint(). + Mon Dec 3 21:04:13 2001 Jonathan Blandford * gtk/gtkmarshalers.list: remove VOID:BOXED,POINTER and diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 22036224a8..e6ec98c655 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,51 @@ +Mon Dec 3 16:39:17 2001 Owen Taylor + + Patch from Bill Haneman (with many modifications) to make + the focus color work on dark themes and to make the + focus line width configurable. (#61079, #63074) + + * gtk/gtkwidget.c: Add style properties, + ::focus-widget, ::focus-line-width, and ::focus-padding. + + * gtk/gtkstyle.[ch]: Make gtk_paint_focus() take a + state argument as well so we can use fg[STATE] to + draw instead of always drawing with black. + Cange paint_focus() to respect GtkWidget::focus-width + and GtkWidget::focus-line-pattern. Fix continuity + problem where the default 1-1 stipple had a blob + in one corner and a gap in the other. Change the + interpretation of x/y/width/height to be the bounding + box of the focus rect instead of the rectangle + passed to gdk_draw_rectangle. + + * gtk/gtkcheckbutton.c gtk/gtklistitem.c gtk/gtknotebook.c + gtk/gtkoptionmenu.c gtk/gtkradiobutton.c gtk/gtkspinbutton.c + gtk/gtktextview.c gtk/gtktreeview.c: Handle ::focus-width + and ::focus-line-padding. + + * gtk/gtkentry.c: Handle :;focus-width property; cleanup + and remove duplicated code; fix drawing of focus rectangle + when interior-focus = FALSE. (#63072, #63073) + + * gtk/gtkrange.c gtk/gtktext.c gtk/gtktreeitem.c + gtk/gtktreeviewcolumn.c: Basic fixups to make compile; + Range and TreeViewColumn will need more extensive fixing. + + * gtk/gtkcolorsel.c: Honor focus line attributes when + drawing the focus on the color swatches. (#63071) + + * gtk/gtkhsv.c: Honor focus line attributes when + drawing the focus for the ring and triangle. + + * docs/widget_geometry.txt: Start at documenting how + various widgets are drawn. + + * gtk/gtkbutton.c (_gtk_button_paint): Export + _gtk_button_paint() librarywide, so we don't have + duplicate a bunch of code in gtktogglebutton.c. + + * gtk/gtktogglebutton.c: Use _gtk_button_paint(). + Mon Dec 3 21:04:13 2001 Jonathan Blandford * gtk/gtkmarshalers.list: remove VOID:BOXED,POINTER and diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2 index 22036224a8..e6ec98c655 100644 --- a/ChangeLog.pre-2-2 +++ b/ChangeLog.pre-2-2 @@ -1,3 +1,51 @@ +Mon Dec 3 16:39:17 2001 Owen Taylor + + Patch from Bill Haneman (with many modifications) to make + the focus color work on dark themes and to make the + focus line width configurable. (#61079, #63074) + + * gtk/gtkwidget.c: Add style properties, + ::focus-widget, ::focus-line-width, and ::focus-padding. + + * gtk/gtkstyle.[ch]: Make gtk_paint_focus() take a + state argument as well so we can use fg[STATE] to + draw instead of always drawing with black. + Cange paint_focus() to respect GtkWidget::focus-width + and GtkWidget::focus-line-pattern. Fix continuity + problem where the default 1-1 stipple had a blob + in one corner and a gap in the other. Change the + interpretation of x/y/width/height to be the bounding + box of the focus rect instead of the rectangle + passed to gdk_draw_rectangle. + + * gtk/gtkcheckbutton.c gtk/gtklistitem.c gtk/gtknotebook.c + gtk/gtkoptionmenu.c gtk/gtkradiobutton.c gtk/gtkspinbutton.c + gtk/gtktextview.c gtk/gtktreeview.c: Handle ::focus-width + and ::focus-line-padding. + + * gtk/gtkentry.c: Handle :;focus-width property; cleanup + and remove duplicated code; fix drawing of focus rectangle + when interior-focus = FALSE. (#63072, #63073) + + * gtk/gtkrange.c gtk/gtktext.c gtk/gtktreeitem.c + gtk/gtktreeviewcolumn.c: Basic fixups to make compile; + Range and TreeViewColumn will need more extensive fixing. + + * gtk/gtkcolorsel.c: Honor focus line attributes when + drawing the focus on the color swatches. (#63071) + + * gtk/gtkhsv.c: Honor focus line attributes when + drawing the focus for the ring and triangle. + + * docs/widget_geometry.txt: Start at documenting how + various widgets are drawn. + + * gtk/gtkbutton.c (_gtk_button_paint): Export + _gtk_button_paint() librarywide, so we don't have + duplicate a bunch of code in gtktogglebutton.c. + + * gtk/gtktogglebutton.c: Use _gtk_button_paint(). + Mon Dec 3 21:04:13 2001 Jonathan Blandford * gtk/gtkmarshalers.list: remove VOID:BOXED,POINTER and diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index 22036224a8..e6ec98c655 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,51 @@ +Mon Dec 3 16:39:17 2001 Owen Taylor + + Patch from Bill Haneman (with many modifications) to make + the focus color work on dark themes and to make the + focus line width configurable. (#61079, #63074) + + * gtk/gtkwidget.c: Add style properties, + ::focus-widget, ::focus-line-width, and ::focus-padding. + + * gtk/gtkstyle.[ch]: Make gtk_paint_focus() take a + state argument as well so we can use fg[STATE] to + draw instead of always drawing with black. + Cange paint_focus() to respect GtkWidget::focus-width + and GtkWidget::focus-line-pattern. Fix continuity + problem where the default 1-1 stipple had a blob + in one corner and a gap in the other. Change the + interpretation of x/y/width/height to be the bounding + box of the focus rect instead of the rectangle + passed to gdk_draw_rectangle. + + * gtk/gtkcheckbutton.c gtk/gtklistitem.c gtk/gtknotebook.c + gtk/gtkoptionmenu.c gtk/gtkradiobutton.c gtk/gtkspinbutton.c + gtk/gtktextview.c gtk/gtktreeview.c: Handle ::focus-width + and ::focus-line-padding. + + * gtk/gtkentry.c: Handle :;focus-width property; cleanup + and remove duplicated code; fix drawing of focus rectangle + when interior-focus = FALSE. (#63072, #63073) + + * gtk/gtkrange.c gtk/gtktext.c gtk/gtktreeitem.c + gtk/gtktreeviewcolumn.c: Basic fixups to make compile; + Range and TreeViewColumn will need more extensive fixing. + + * gtk/gtkcolorsel.c: Honor focus line attributes when + drawing the focus on the color swatches. (#63071) + + * gtk/gtkhsv.c: Honor focus line attributes when + drawing the focus for the ring and triangle. + + * docs/widget_geometry.txt: Start at documenting how + various widgets are drawn. + + * gtk/gtkbutton.c (_gtk_button_paint): Export + _gtk_button_paint() librarywide, so we don't have + duplicate a bunch of code in gtktogglebutton.c. + + * gtk/gtktogglebutton.c: Use _gtk_button_paint(). + Mon Dec 3 21:04:13 2001 Jonathan Blandford * gtk/gtkmarshalers.list: remove VOID:BOXED,POINTER and diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index 22036224a8..e6ec98c655 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,51 @@ +Mon Dec 3 16:39:17 2001 Owen Taylor + + Patch from Bill Haneman (with many modifications) to make + the focus color work on dark themes and to make the + focus line width configurable. (#61079, #63074) + + * gtk/gtkwidget.c: Add style properties, + ::focus-widget, ::focus-line-width, and ::focus-padding. + + * gtk/gtkstyle.[ch]: Make gtk_paint_focus() take a + state argument as well so we can use fg[STATE] to + draw instead of always drawing with black. + Cange paint_focus() to respect GtkWidget::focus-width + and GtkWidget::focus-line-pattern. Fix continuity + problem where the default 1-1 stipple had a blob + in one corner and a gap in the other. Change the + interpretation of x/y/width/height to be the bounding + box of the focus rect instead of the rectangle + passed to gdk_draw_rectangle. + + * gtk/gtkcheckbutton.c gtk/gtklistitem.c gtk/gtknotebook.c + gtk/gtkoptionmenu.c gtk/gtkradiobutton.c gtk/gtkspinbutton.c + gtk/gtktextview.c gtk/gtktreeview.c: Handle ::focus-width + and ::focus-line-padding. + + * gtk/gtkentry.c: Handle :;focus-width property; cleanup + and remove duplicated code; fix drawing of focus rectangle + when interior-focus = FALSE. (#63072, #63073) + + * gtk/gtkrange.c gtk/gtktext.c gtk/gtktreeitem.c + gtk/gtktreeviewcolumn.c: Basic fixups to make compile; + Range and TreeViewColumn will need more extensive fixing. + + * gtk/gtkcolorsel.c: Honor focus line attributes when + drawing the focus on the color swatches. (#63071) + + * gtk/gtkhsv.c: Honor focus line attributes when + drawing the focus for the ring and triangle. + + * docs/widget_geometry.txt: Start at documenting how + various widgets are drawn. + + * gtk/gtkbutton.c (_gtk_button_paint): Export + _gtk_button_paint() librarywide, so we don't have + duplicate a bunch of code in gtktogglebutton.c. + + * gtk/gtktogglebutton.c: Use _gtk_button_paint(). + Mon Dec 3 21:04:13 2001 Jonathan Blandford * gtk/gtkmarshalers.list: remove VOID:BOXED,POINTER and diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index 22036224a8..e6ec98c655 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,51 @@ +Mon Dec 3 16:39:17 2001 Owen Taylor + + Patch from Bill Haneman (with many modifications) to make + the focus color work on dark themes and to make the + focus line width configurable. (#61079, #63074) + + * gtk/gtkwidget.c: Add style properties, + ::focus-widget, ::focus-line-width, and ::focus-padding. + + * gtk/gtkstyle.[ch]: Make gtk_paint_focus() take a + state argument as well so we can use fg[STATE] to + draw instead of always drawing with black. + Cange paint_focus() to respect GtkWidget::focus-width + and GtkWidget::focus-line-pattern. Fix continuity + problem where the default 1-1 stipple had a blob + in one corner and a gap in the other. Change the + interpretation of x/y/width/height to be the bounding + box of the focus rect instead of the rectangle + passed to gdk_draw_rectangle. + + * gtk/gtkcheckbutton.c gtk/gtklistitem.c gtk/gtknotebook.c + gtk/gtkoptionmenu.c gtk/gtkradiobutton.c gtk/gtkspinbutton.c + gtk/gtktextview.c gtk/gtktreeview.c: Handle ::focus-width + and ::focus-line-padding. + + * gtk/gtkentry.c: Handle :;focus-width property; cleanup + and remove duplicated code; fix drawing of focus rectangle + when interior-focus = FALSE. (#63072, #63073) + + * gtk/gtkrange.c gtk/gtktext.c gtk/gtktreeitem.c + gtk/gtktreeviewcolumn.c: Basic fixups to make compile; + Range and TreeViewColumn will need more extensive fixing. + + * gtk/gtkcolorsel.c: Honor focus line attributes when + drawing the focus on the color swatches. (#63071) + + * gtk/gtkhsv.c: Honor focus line attributes when + drawing the focus for the ring and triangle. + + * docs/widget_geometry.txt: Start at documenting how + various widgets are drawn. + + * gtk/gtkbutton.c (_gtk_button_paint): Export + _gtk_button_paint() librarywide, so we don't have + duplicate a bunch of code in gtktogglebutton.c. + + * gtk/gtktogglebutton.c: Use _gtk_button_paint(). + Mon Dec 3 21:04:13 2001 Jonathan Blandford * gtk/gtkmarshalers.list: remove VOID:BOXED,POINTER and diff --git a/docs/Changes-2.0.txt b/docs/Changes-2.0.txt index da9e9a37c5..c2dd2fbacc 100644 --- a/docs/Changes-2.0.txt +++ b/docs/Changes-2.0.txt @@ -546,3 +546,14 @@ Incompatible Changes from GTK+-1.2 to GTK+-2.0: to store the difference between world and window coordinates for layout->bin_window. These coordinate systems are now always the same. + +* gtk_paint_focus(), gtk_draw_focus() and GtkStyle::draw_focus() + have been changed a bit: + + - A GtkStateType argument has been added to gtk_paint_focus() + - The default implementation of GtkStyle::draw_focus virtual + function now draws a focus rectangle whose width is + determinted by the GtkWidget::focus-width style property. + - The rectangle passed in is the bounding box, instead of + the rectangle used in the gdk_draw_rectangle() call, so it is + no longer necessary to subtract 1 from the width and height. diff --git a/docs/widget_geometry.txt b/docs/widget_geometry.txt new file mode 100644 index 0000000000..d6627f44f6 --- /dev/null +++ b/docs/widget_geometry.txt @@ -0,0 +1,594 @@ +This file is some notes about how different widgets are drawn. + +============= + +GtkOptionMenu: + +============= + +Geometry parameters + + Style properties + + GtkWidget::interior_focus = TRUE + GtkWidget::focus_width = 1 + GtkWidget::focus_padding = 0 + GtkOptionMenu::indicator_size = { 7, 13 } + GtkOptionMenu::indicator_spacing = { 7, 5, 2, 2 } + + Properties + + GtkContainer::border_width = 0 + + #defines + + CHILD_LEFT_SPACING = 5 + CHILD_RIGHT_SPACING = 1 + CHILD_TOP_SPACING = 1 + CHILD_BOTTOM_SPACING = 1 + + +I) interior_focus = TRUE + ++--------------------------------------------------+ ++ A | +| +----------------------------------------------+ | +| |\\\\\\\\\\\\\\\\\\\\ H ///////////////////////| | +| |\+------------------------------------------+/| | +| |\| C |/| | +| |\| +------------------------------+ |/| | +| |\| |################ D ###########| L |/| | +| |\| |#+--------------------------+#| |/| | +| |\| |#| K |#| |/| | +| |\| |#| +----------------------+ |#| +-----+ |/| | +| |\| |#| | | |#| | /#\ | |/| | +| |\| |#| | | |#| | === | |/| | +|A|B|C|D|E| Child |F|D|G| IxJ |O|B|A| +| |/| |#| | | |#| | === | |\| | +| |/| |#| | | |#| | \#/ | |\| | +| |/| |#| +----------------------+ |#| +-----+ |\| | +| |/| |#| M |#| |\| | +| |/| |#+---------------------------#| |\| | +| |/| |################ D ###########| N |\| | +| |/| +------------------------------+ |\| | +| |/| C |\| | +| |/+------------------------------------------+\| | +| |//////////////////// H \\\\\\\\\\\\\\\\\\\\\\\| | +| +----------------------------------------------+ | +| A | ++--------------------------------------------------+ + + A: GtkContainer::border_width + B: xthickness + C: GtkWidget::focus_pad + D: GtkWidget::focus_width + E: CHILD_LEFT_SPACING + F: CHILD_RIGHT_SPACING + G: GtkOptionMenu::indicator_spacing::left + H: ythickness + I: GtkOptionMenu::indicator_size::width + J: GtkOptionMenu::indicator_size::height + K: CHILD_TOP_SPACING + L: GtkOptionMenu::indicator_spacing::top + GtkWidget::focus_width + GtkWidget::focus_pad + CHILD_TOP_SPACING + M: CHILD_BOTTOM_SPACING + N: GtkOptionMenu::indicator_spacing::bottom + GtkWidget::focus_width + GtkWidget::focus_pad + CHILD_BOTTOM_SPACING + O: GtkOptionMenu::indicator_spacing::right + + +II) interior_focus = FALSE + ++--------------------------------------------------+ ++ A | +| +----------------------------------------------+ | +| |#################### B #######################| | +| |#+------------------------------------------+#| | +| |#| C |#| | +| |#| +--------------------------------------+ |#| | +| |#| |\\\\\\\\\\\\\\\\ H ///////////////////| |#| | +| |#| |\+----------------------------------+/| |#| | +| |#| |\| K L |/| |#| | +| |#| |\| +----------------------+ +-----+ |/| |#| | +| |#| |\| | | | /#\ | |/| |#| | +| |#| |\| | | | === | |/| |#| | +|A|B|C|D|E| Child |F| IxJ |G|D|C|B|A| +| |#| |/| | | | === | |\| |#| | +| |#| |/| | | | \#/ | |\| |#| | +| |#| |/| +----------------------+ +-----+ |\| |#| | +| |#| |/| M N |\| |#| | +| |#| |/+----------------------------------+\| |#| | +| |#| |//////////////// H \\\\\\\\\\\\\\\\\\\| |#| | +| |#| +--------------------------------------+ |#| | +| |#| C |#| | +| |#+------------------------------------------+#| | +| |#################### B #######################| | +| +----------------------------------------------+ | +| A | ++--------------------------------------------------+ + + + A: GtkContainer::border_width + B: GtkWidget::focus_width + C: GtkWidget::focus_padding + D: xthickness + E: CHILD_LEFT_SPACING + F: CHILD_RIGHT_SPACING + GtkOptionMenu::indicator_spacing::left + G: GtkOptionMenu::indicator_spacing::right + H: ythickness + I: GtkOptionMenu::indicator_size::width + J: GtkOptionMenu::indicator_size::height + K: CHILD_TOP_SPACING + L: CHILD_TOP_SPACING + GtkOptionMenu::indicator_spacing::top + M: CHILD_BOTTOM_SPACING + N: CHILD_BOTTOM_SPACING + GtkOptionMenu::indicator_spacing::bottom + + +III) interior_focus = FALSE, !HAVE_FOCUS + ++--------------------------------------------------+ ++ A | +| +----------------------------------------------+ | +| |\\\\\\\\\\\\\\\\\\\\ H ///////////////////////| | +| |\+------------------------------------------+/| | +| |\| |/| | +| |\| |/| | +| |\| |/| | +| |\| |/| | +| |\| K L |/| | +| |\| +----------------------+ +-----+ |/| | +| |\| | | | /#\ | |/| | +| |\| | | | === | |/| | +|A|D| E| Child |F| IxJ |G |D|A| +| |/| | | | === | |\| | +| |/| | | | \#/ | |\| | +| |/| +----------------------+ +-----+ |\| | +| |/| M N |\| | +| |/| |\| | +| |/| |\| | +| |/| |\| | +| |/| |\| | +| |/+------------------------------------------+\| | +| |//////////////////// H \\\\\\\\\\\\\\\\\\\\\\\| | +| +----------------------------------------------+ | +| A | ++--------------------------------------------------+ + + + A: GtkContainer::border_width + B: GtkWidget::focus_width + C: GtkWidget::focus_padding + D: xthickness + E: CHILD_LEFT_SPACING + GtkWidget::focus_width + GtkWidget::focus_padding + F: CHILD_RIGHT_SPACING + GtkOptionMenu::in+icator_spacing::left + G: GtkOptionMenu::indicator_spacing::right + GtkWidget::focus_width + GtkWidget::focus_padding + H: ythickness + I: GtkOptionMenu::indicator_size::width + J: GtkOptionMenu::indicator_size::height + K: CHILD_TOP_SPACING + GtkWidget::focus_width + GtkWidget::focus_padding + L: CHILD_TOP_SPACING + GtkOptionMenu::indicator_spacing::top + GtkWidget::focus_width + GtkWidget::focus_padding + M: CHILD_BOTTOM_SPACING + GtkWidget::focus_width + GtkWidget::focus_padding + N: CHILD_BOTTOM_SPACING + GtkOptionMenu::indicator_spacing::bottom + GtkWidget::focus_width + GtkWidget::focus_padding + + + +===================== + +GtkButton + +===================== + + Style properties + + GtkWidget::interior_focus = TRUE + GtkWidget::focus_width = 1 + GtkWidget::focus_padding = 0 + GtkButton::default_border = { 1, 1, 1, 1 }; + GtkButton::default_outside_border = { 0, 0, 0, 0 }; + GtkButton::child_displacement_x = 0; + GtkButton::child_displacement_y = 0; + + Properties + + GtkContainer::border_width = 0 + + #defines + + CHILD_SPACING 1 + +I) HAS_DEFAULT && (!GtkWidget::interior-focus || !HAVE_FOCUS) + ++----------------------------------------------+ +| A | +| +------------------------------------------+ | +| |@@@@@@@@@@@@@@@@@@@ I @@@@@@@@@@@@@@@@@@@@| | +| |@+--------------------------------------+@| | +| |@|\\\\\\\\\\\\\\\\\ J //////////////////|@| | +| |@|\+----------------------------------+/|@| | +| |@|\| E |/|@| | +| |@|\| +------------------------------+ |/|@| | +| |@|\| |############# F ##############| |/|@| | +| |@|\| |#+--------------------------+#| |/|@| | +| |@|\| |#| L |#| |/|@| | +| |@|\| |#| +----------------------+ |#| |/|@| | +| |@|\| |#| | | |#| |/|@| | +| |@|\| |#| | | |#| |/|@| | +|A|B|D|E|F|G| Child |M|F|E|D|C|A| +| |@|/| |#| | | |#| |\|@| | +| |@|/| |#| | | |#| |\|@| | +| |@|/| |#| +----------------------+ |#| |\|@| | +| |@|/| |#| N |#| |\|@| | +| |@|/| |#+--------------------------+#| |\|@| | +| |@|/| |############# F ##############| |\|@| | +| |@|/| +------------------------------+ |\|@| | +| |@|/| E |\|@| | +| |@|/+----------------------------------+\|@| | +| |@|///////////////// J \\\\\\\\\\\\\\\\\\|@| | +| |@+--------------------------------------+@| | +| |@@@@@@@@@@@@@@@@@@@ K @@@@@@@@@@@@@@@@@@@@| | +| +------------------------------------------+ | +| A | ++----------------------------------------------+ + +A: GtkContainer::border-width +B: GtkButton::default-border::left +C: GtkButton::default-border::right +D: xthickness +E: GtkWidget::focus-padding +F: GtkWidget::focus-line-width +G: CHILD_SPACING + (depressed ? GtkButton::child-displacement-x : 0) +I: GtkButton::default-border::top +J: ythickness +K: GtkButton::default-border::bottom +L: CHILD_SPACING + (depressed ? GtkButton::child-displacement-y : 0) +M: CHILD_SPACING - (depressed ? GtkButton::child-displacement-x : 0) +N: CHILD_SPACING - (depressed ? GtkButton::child-displacement-y : 0) + + +II) !HAS_DEFAULT && (!GtkWidget::interior-focus || !HAVE_FOCUS) + ++----------------------------------------------+ +| | +| I | +| | +| +--------------------------------------+ | +| |\\\\\\\\\\\\\\\\\ J //////////////////| | +| |\+----------------------------------+/| | +| |\| E |/| | +| |\| +------------------------------+ |/| | +| |\| |############# F ##############| |/| | +| |\| |#+--------------------------+#| |/| | +| |\| |#| L |#| |/| | +| |\| |#| +----------------------+ |#| |/| | +| |\| |#| | | |#| |/| | +| |\| |#| | | |#| |/| | +| B |D|E|F|G| Child |M|F|E|D| C | +| |/| |#| | | |#| |\| | +| |/| |#| | | |#| |\| | +| |/| |#| +----------------------+ |#| |\| | +| |/| |#| N |#| |\| | +| |/| |#+--------------------------+#| |\| | +| |/| |############# F ##############| |\| | +| |/| +------------------------------+ |\| | +| |/| E |\| | +| |/+----------------------------------+\| | +| |///////////////// J \\\\\\\\\\\\\\\\\\| | +| +--------------------------------------+ | +| | +| K | +| | ++----------------------------------------------+ + + +a) CAN_DEFAULT + +B: GtkContainer::border-width + GtkButton::default-outside-border::left +C: GtkContainer::border-width + GtkButton::default-outside-border::right +D: xthickness +E: GtkWidget::focus-padding +F: GtkWidget::focus-line-width +G: CHILD_SPACING + (depressed ? GtkButton::child-displacement-x : 0) + + (GtkButton::default-outside-border - GtkButton::default-outside-border)::left +I: GtkContainer::border-width + GtkButton::default-outside-border::top +J: ythickness +K: GtkContainer::border-width + GtkButton::default-outside-border::bottom +L: CHILD_SPACING + (depressed ? GtkButton::child-displacement-y : 0) + + (GtkButton::default-outside-border - GtkButton::default-outside-border)::top +M: CHILD_SPACING - (depressed ? GtkButton::child-displacement-x : 0) + + (GtkButton::default-outside-border - GtkButton::default-outside-border)::right +N: CHILD_SPACING - (depressed ? GtkButton::child-displacement-y : 0) + + (GtkButton::default-outside-border - GtkButton::default-outside-border)::bottom + + +b) !CAN_DEFAULT + +B: GtkContainer::border-width +C: GtkContainer::border-width +D: xthickness +E: GtkWidget::focus-padding +F: GtkWidget::focus-line-width +G: CHILD_SPACING + (depressed ? GtkButton::child-displacement-x : 0) +I: GtkContainer::border-width +J: ythickness +K: GtkContainer::border-width +L: CHILD_SPACING + (depressed ? GtkButton::child-displacement-y : 0) +M: CHILD_SPACING - (depressed ? GtkButton::child-displacement-x : 0) +N: CHILD_SPACING - (depressed ? GtkButton::child-displacement-y : 0) + + + + +III) HAS_DEFAULT && (GtkWidget::interior-focus && HAVE_FOCUS) + ++----------------------------------------------+ +| A | +| +------------------------------------------+ | +| |@@@@@@@@@@@@@@@@@@@ I @@@@@@@@@@@@@@@@@@@@| | +| |@+--------------------------------------+@| | +| |@|################# F ##################|@| | +| |@|#+----------------------------------+#|@| | +| |@|#| E |#|@| | +| |@|#| +------------------------------+ |#|@| | +| |@|#| |\\\\\\\\\\\\\ J //////////////| |#|@| | +| |@|#| |\+--------------------------+/| |#|@| | +| |@|#| |\| L |/| |#|@| | +| |@|#| |\| +----------------------+ |/| |#|@| | +| |@|#| |\| | | |/| |#|@| | +| |@|#| |\| | | |/| |#|@| | +|A|B|F|E|D|G| Child |M|D|E|F|C|A| +| |@|#| |/| | | |\| |#|@| | +| |@|#| |/| | | |\| |#|@| | +| |@|#| |/| +----------------------+ |\| |#|@| | +| |@|#| |/| N |\| |#|@| | +| |@|#| |/+--------------------------+\| |#|@| | +| |@|#| |///////////// J \\\\\\\\\\\\\\| |#|@| | +| |@|#| +------------------------------+ |#|@| | +| |@|#| E |#|@| | +| |@|#+----------------------------------+#|@| | +| |@|################# F ##################|@| | +| |@+--------------------------------------+@| | +| |@@@@@@@@@@@@@@@@@@@ K @@@@@@@@@@@@@@@@@@@@| | +| +------------------------------------------+ | +| A | ++----------------------------------------------+ + +A: GtkContainer::border-width +B: GtkButton::default-border::left +C: GtkButton::default-border::right +D: xthickness +E: GtkWidget::focus-padding +F: GtkWidget::focus-line-width +G: CHILD_SPACING + (depressed ? GtkButton::child-displacement-x : 0) +I: GtkButton::default-border::top +J: ythickness +K: GtkButton::default-border::bottom +L: CHILD_SPACING + (depressed ? GtkButton::child-displacement-y : 0) +M: CHILD_SPACING - (depressed ? GtkButton::child-displacement-x : 0) +N: CHILD_SPACING - (depressed ? GtkButton::child-displacement-y : 0) + + +IV) !HAS_DEFAULT && (GtkWidget::interior-focus && HAVE_FOCUS) + ++----------------------------------------------+ +| | +| I | +| | +| +--------------------------------------+ | +| |################# J ##################| | +| |#+----------------------------------+#| | +| |#| E |#| | +| |#| +------------------------------+ |#| | +| |#| |\\\\\\\\\\\\\ F //////////////| |#| | +| |#| |\+--------------------------+/| |#| | +| |#| |\| L |/| |#| | +| |#| |\| +----------------------+ |/| |#| | +| |#| |\| | | |/| |#| | +| |#| |\| | | |/| |#| | +| B |D|E|F|G| Child |M|F|E|D| C | +| |#| |/| | | |\| |#| | +| |#| |/| | | |\| |#| | +| |#| |/| +----------------------+ |\| |#| | +| |#| |/| N |\| |#| | +| |#| |/+--------------------------+\| |#| | +| |#| |///////////// F \\\\\\\\\\\\\\| |#| | +| |#| +------------------------------+ |#| | +| |#| E |#| | +| |#+----------------------------------+#| | +| |################# J ##################| | +| +--------------------------------------+ | +| | +| K | +| | ++----------------------------------------------+ + + +a) CAN_DEFAULT + +B: GtkContainer::border-width + GtkButton::default-outside-border::left +C: GtkContainer::border-width + GtkButton::default-outside-border::right +D: xthickness +E: GtkWidget::focus-padding +F: GtkWidget::focus-line-width +G: CHILD_SPACING + (depressed ? GtkButton::child-displacement-x : 0) + + (GtkButton::default-outside-border - GtkButton::default-outside-border)::left +I: GtkContainer::border-width + GtkButton::default-outside-border::top +J: ythickness +K: GtkContainer::border-width + GtkButton::default-outside-border::bottom +L: CHILD_SPACING + (depressed ? GtkButton::child-displacement-y : 0) + + (GtkButton::default-outside-border - GtkButton::default-outside-border)::top +M: CHILD_SPACING - (depressed ? GtkButton::child-displacement-x : 0) + + (GtkButton::default-outside-border - GtkButton::default-outside-border)::right +N: CHILD_SPACING - (depressed ? GtkButton::child-displacement-y : 0) + + (GtkButton::default-outside-border - GtkButton::default-outside-border)::bottom + + +b) !CAN_DEFAULT + +B: GtkContainer::border-width +C: GtkContainer::border-width +D: xthickness +E: GtkWidget::focus-padding +F: GtkWidget::focus-line-width +G: CHILD_SPACING + (depressed ? GtkButton::child-displacement-x : 0) +I: GtkContainer::border-width +J: ythickness +K: GtkContainer::border-width +L: CHILD_SPACING + (depressed ? GtkButton::child-displacement-y : 0) +M: CHILD_SPACING - (depressed ? GtkButton::child-displacement-x : 0) +N: CHILD_SPACING - (depressed ? GtkButton::child-displacement-y : 0) + + +====================== + +GtkCheckButton + +====================== + +Note: This is the draw_indicator=TRUE case; draw_indicator=FALSE + is like GtkButton) + + Style properties + + GtkWidget::interior_focus = TRUE + GtkWidget::focus_width = 1 + GtkWidget::focus_padding = 0 + GtkButton::indicator-size = 13 + GtkButton::indicator-spacing = 2 + + Properties + + GtkContainer::border_width = 0 + + #defines + + CHILD_SPACING 1 + +interior_focus + + +-------------------------------------------+ + | F | + | G +------------------------+ | + | |########### D ##########| | + | +------------+ |#+--------------------+#| | + | | | |#| E |#| | + | | | |#| +----------------+ |#| | + | | | |#| | | |#| | + |A| BxB |C|D|E| Child |E|#|F| + | | | |#| | | |#| | + | | | |#| +----------------+ |#| | + | | | |#| E |#| | + | +------------+ |#+--------------------+#| | + | |########### D ##########| | + | G +------------------------+ | + | F | + +-------------------------------------------+ + +A: GtkContainer::border-width + GtkCheckButton::indicator-spacing +B: GtkCheckButton::indicator-size +C: 2 * GtkCheckButton::indicator-spacing +D: GtkWidget::focus-line-width +E: GtkWidget::focus-padding +F: GtkContainer::border-width +G: GtkConainer::border-width + GtkCheckButton::indicator-spacing + +!interior_focus + + +-------------------------------------------+ + | A | + | +---------------------------------------+ | + | |################ D ####################| | + | |#+-----------------------------------+#| | + | |#| G E |#| | + | |#| +------------+ +---------------+ |#| | + | |#| | | | | |#| | + | |#| | | | | |#| | + |A|D|F| BxB |C | Child |E|D|A| + | |#| | | | | |#| | + | |#| | | | | |#| | + | |#| +------------+ +---------------+ |#| | + | |#| G E |#| | + | |#+-----------------------------------+#| | + | |################ D ####################| | + | +---------------------------------------+ | + | A | + +-------------------------------------------+ + +A: GtkContainer::border-width +B: GtkCheckButton::indicator-size +C: 2 * GtkCheckButton::indicator-spacing +D: GtkWidget::focus-line-width +E: GtkWidget::focus-padding +F: GtkWidget::focus-padding + GtkCheckButton::indicator-spacing +G: GtkWidget::focus-padding + GtkCheckButton::indicator-spacing + +=============== + +GtkEntry + +=============== + + Style properties + + GtkWidget::interior_focus = TRUE + GtkWidget::focus_width = 1 + GtkWidget::focus_padding = 0 + + Properties + + GtkContainer::border_width = 0 + + #defines + + INNER_BORDER 2 + + + +interior_focus + ++--------------------------------------+ +|\\\\\\\\\\\\\\\\\ B //////////////////| +|\+----------------------------------+/| +|\| D |/| +|\| +------------------------------+ |/| +|\| | | |/| +|\| | | |/| +|A|D| |D|A| +|\| | | |/| +|\| | | |/| +|\| +------------------------------+ |/| +|\| D |/| +|\+----------------------------------+/| +|///////////////// B \\\\\\\\\\\\\\\\\/| ++--------------------------------------+ + +A: xthickness +B: ythickness +D: INNER_BORDER + +!interior_focus + ++------------------------------------------+ +|####################C#####################| +|#+--------------------------------------+#| +|#|\\\\\\\\\\\\\\\\\ B //////////////////|#| +|#|\+----------------------------------+/|#| +|#|\| D |/|#| +|#|\| +------------------------------+ |/|#| +|#|\| | | |/|#| +|#|\| | | |/|#| +|C|A|D| |D|A|C| +|#|\| | | |/|#| +|#|\| | | |/|#| +|#|\| +------------------------------+ |/|#| +|#|\| D |/|#| +|#|\+----------------------------------+/|#| +|#|///////////////// B \\\\\\\\\\\\\\\\\/|#| +|#+--------------------------------------+#| +|####################C#####################| ++------------------------------------------+ + +A: xthickness +B: ythickness +C: GtkWidget::focus-line-width +D: INNER_BORDER + (HAVE_FOCUS ? 0 : GtkWidget::focus-line-width + +Note - effect here for !interior_focus is that bevel moves in +by focus-line-width when entry gains focus diff --git a/gtk/gtkbutton.c b/gtk/gtkbutton.c index e504d32f7f..c8958ed6cb 100644 --- a/gtk/gtkbutton.c +++ b/gtk/gtkbutton.c @@ -84,8 +84,6 @@ static void gtk_button_size_request (GtkWidget *widget, GtkRequisition *requisition); static void gtk_button_size_allocate (GtkWidget *widget, GtkAllocation *allocation); -static void gtk_button_paint (GtkWidget *widget, - GdkRectangle *area); static gint gtk_button_expose (GtkWidget *widget, GdkEventExpose *event); static gint gtk_button_button_press (GtkWidget *widget, @@ -714,9 +712,15 @@ gtk_button_size_request (GtkWidget *widget, GtkButton *button = GTK_BUTTON (widget); GtkBorder default_border; gboolean interior_focus; + gint focus_width; + gint focus_pad; gtk_button_get_props (button, &default_border, NULL, &interior_focus); - + gtk_widget_style_get (GTK_WIDGET (widget), + "focus-line-width", &focus_width, + "focus-padding", &focus_pad, + NULL); + requisition->width = (GTK_CONTAINER (widget)->border_width + CHILD_SPACING + GTK_WIDGET (widget)->style->xthickness) * 2; requisition->height = (GTK_CONTAINER (widget)->border_width + CHILD_SPACING + @@ -737,12 +741,9 @@ gtk_button_size_request (GtkWidget *widget, requisition->width += child_requisition.width; requisition->height += child_requisition.height; } - - if (interior_focus) - { - requisition->width += 2; - requisition->height += 2; - } + + requisition->width += 2 * (focus_width + focus_pad); + requisition->height += 2 * (focus_width + focus_pad); } static void @@ -758,7 +759,7 @@ gtk_button_size_allocate (GtkWidget *widget, GtkBorder default_border; gtk_button_get_props (button, &default_border, NULL, NULL); - + widget->allocation = *allocation; if (GTK_WIDGET_REALIZED (widget)) @@ -770,13 +771,13 @@ gtk_button_size_allocate (GtkWidget *widget, if (GTK_BIN (button)->child && GTK_WIDGET_VISIBLE (GTK_BIN (button)->child)) { - child_allocation.x = widget->allocation.x + border_width + (CHILD_SPACING + xthickness); - child_allocation.y = widget->allocation.y + border_width + (CHILD_SPACING + ythickness); - - child_allocation.width = MAX (1, (gint)widget->allocation.width - (CHILD_SPACING + xthickness) * 2 - - border_width * 2); - child_allocation.height = MAX (1, (gint)widget->allocation.height - (CHILD_SPACING + ythickness) * 2 - - border_width * 2); + child_allocation.x = widget->allocation.x + border_width + CHILD_SPACING + xthickness; + child_allocation.y = widget->allocation.y + border_width + CHILD_SPACING + ythickness; + + child_allocation.width = MAX (1, widget->allocation.width - (CHILD_SPACING + xthickness) * 2 - + border_width * 2); + child_allocation.height = MAX (1, widget->allocation.height - (CHILD_SPACING + ythickness) * 2 - + border_width * 2); if (GTK_WIDGET_CAN_DEFAULT (button)) { @@ -803,51 +804,34 @@ gtk_button_size_allocate (GtkWidget *widget, } } -/* - * +------------------------------------------------+ - * | BORDER | - * | +------------------------------------------+ | - * | |\\\\\\\\\\\\\\\\DEFAULT\\\\\\\\\\\\\\\\\ | | - * | |\\+------------------------------------+ | | - * | |\\| | SPACING 3 | | | | - * | |\\| +--------------------------------+ | | | - * | |\\| |########## FOCUS ###############| | | | - * | |\\| |#+----------------------------+#| | | | - * | |\\| |#| RELIEF \|#| | | | - * | |\\| |#| +-----------------------+\|#| | | | - * | |\\|1|#| + THE TEXT +\|#|2| | | - * | |\\| |#| +-----------------------+\|#| | | | - * | |\\| |#| \\\\\ ythickness \\\\\\\\\\|#| | | | - * | |\\| |#+----------------------------+#| | | | - * | |\\| |########### 1 ##################| | | | - * | |\\| +--------------------------------+ | | | - * | |\\| | default spacing 4 | | | | - * | |\\+------------------------------------+ | | - * | |\ ythickness | | - * | +------------------------------------------+ | - * | border_width | - * +------------------------------------------------+ - */ - -static void -gtk_button_paint (GtkWidget *widget, - GdkRectangle *area) +void +_gtk_button_paint (GtkButton *button, + GdkRectangle *area, + GtkStateType state_type, + GtkShadowType shadow_type, + const gchar *main_detail, + const gchar *default_detail) { - GtkButton *button; - GtkShadowType shadow_type; + GtkWidget *widget; gint width, height; gint x, y; gint border_width; GtkBorder default_border; GtkBorder default_outside_border; gboolean interior_focus; + gint focus_width; + gint focus_pad; - if (GTK_WIDGET_DRAWABLE (widget)) + if (GTK_WIDGET_DRAWABLE (button)) { + widget = GTK_WIDGET (button); border_width = GTK_CONTAINER (widget)->border_width; - button = GTK_BUTTON (widget); gtk_button_get_props (button, &default_border, &default_outside_border, &interior_focus); + gtk_widget_style_get (GTK_WIDGET (widget), + "focus-line-width", &focus_width, + "focus-padding", &focus_pad, + NULL); x = widget->allocation.x + border_width; y = widget->allocation.y + border_width; @@ -877,19 +861,17 @@ gtk_button_paint (GtkWidget *widget, if (!interior_focus && GTK_WIDGET_HAS_FOCUS (widget)) { - x += 1; - y += 1; - width -= 2; - height -= 2; + x += focus_width + focus_pad; + y += focus_width + focus_pad; + width -= 2 * (focus_width + focus_pad); + height -= 2 * (focus_width + focus_pad); } - shadow_type = button->depressed ? GTK_SHADOW_IN : GTK_SHADOW_OUT; - if ((button->relief != GTK_RELIEF_NONE) || ((GTK_WIDGET_STATE(widget) != GTK_STATE_NORMAL) && (GTK_WIDGET_STATE(widget) != GTK_STATE_INSENSITIVE))) gtk_paint_box (widget->style, widget->window, - GTK_WIDGET_STATE (widget), + state_type, shadow_type, area, widget, "button", x, y, width, height); @@ -897,22 +879,22 @@ gtk_button_paint (GtkWidget *widget, { if (interior_focus) { - x += widget->style->xthickness + 1; - y += widget->style->ythickness + 1; - width -= 2 * (widget->style->xthickness + 1); - height -= 2 * (widget->style->xthickness + 1); + x += widget->style->xthickness + focus_pad; + y += widget->style->ythickness + focus_pad; + width -= 2 * (widget->style->xthickness + focus_pad); + height -= 2 * (widget->style->xthickness + focus_pad); } else { - x -= 1; - y -= 1; - width += 2; - height += 2; + x -= focus_width + focus_pad; + y -= focus_width + focus_pad; + width += 2 * (focus_width + focus_pad); + height += 2 * (focus_width + focus_pad); } - gtk_paint_focus (widget->style, widget->window, + gtk_paint_focus (widget->style, widget->window, GTK_WIDGET_STATE (widget), area, widget, "button", - x, y, width - 1, height - 1); + x, y, width, height); } } } @@ -921,17 +903,18 @@ static gboolean gtk_button_expose (GtkWidget *widget, GdkEventExpose *event) { - GtkBin *bin; - g_return_val_if_fail (widget != NULL, FALSE); g_return_val_if_fail (GTK_IS_BUTTON (widget), FALSE); g_return_val_if_fail (event != NULL, FALSE); if (GTK_WIDGET_DRAWABLE (widget)) { - bin = GTK_BIN (widget); + GtkButton *button = GTK_BUTTON (widget); - gtk_button_paint (widget, &event->area); + _gtk_button_paint (button, &event->area, + GTK_WIDGET_STATE (widget), + button->depressed ? GTK_SHADOW_IN : GTK_SHADOW_OUT, + "button", "buttondefault"); (* GTK_WIDGET_CLASS (parent_class)->expose_event) (widget, event); } diff --git a/gtk/gtkbutton.h b/gtk/gtkbutton.h index c0caa19e2e..ccc227aef4 100644 --- a/gtk/gtkbutton.h +++ b/gtk/gtkbutton.h @@ -103,8 +103,15 @@ gboolean gtk_button_get_use_underline (GtkButton *button); void gtk_button_set_use_stock (GtkButton *button, gboolean use_stock); gboolean gtk_button_get_use_stock (GtkButton *button); -void _gtk_button_set_depressed (GtkButton *button, - gboolean depressed); + +void _gtk_button_set_depressed (GtkButton *button, + gboolean depressed); +void _gtk_button_paint (GtkButton *button, + GdkRectangle *area, + GtkStateType state_type, + GtkShadowType shadow_type, + const gchar *main_detail, + const gchar *default_detail); #ifdef __cplusplus } diff --git a/gtk/gtkcheckbutton.c b/gtk/gtkcheckbutton.c index 3d2fff01ad..d124836328 100644 --- a/gtk/gtkcheckbutton.c +++ b/gtk/gtkcheckbutton.c @@ -159,8 +159,14 @@ gtk_check_button_paint (GtkWidget *widget, { gint border_width; gint interior_focus; + gint focus_width; + gint focus_pad; - gtk_widget_style_get (widget, "interior_focus", &interior_focus, NULL); + gtk_widget_style_get (widget, + "interior-focus", &interior_focus, + "focus-line-width", &focus_width, + "focus-padding", &focus_pad, + NULL); gtk_check_button_draw_indicator (check_button, area); @@ -170,22 +176,22 @@ gtk_check_button_paint (GtkWidget *widget, if (interior_focus) { GtkWidget *child = GTK_BIN (widget)->child; - + if (child && GTK_WIDGET_VISIBLE (child)) - gtk_paint_focus (widget->style, widget->window, + gtk_paint_focus (widget->style, widget->window, GTK_WIDGET_STATE (widget), NULL, widget, "checkbutton", - child->allocation.x - 1, - child->allocation.y - 1, - child->allocation.width + 1, - child->allocation.height + 1); + child->allocation.x - focus_width - focus_pad, + child->allocation.y - focus_width - focus_pad, + child->allocation.width + 2 * (focus_width + focus_pad), + child->allocation.height + 2 * (focus_width + focus_pad)); } else - gtk_paint_focus (widget->style, widget->window, + gtk_paint_focus (widget->style, widget->window, GTK_WIDGET_STATE (widget), NULL, widget, "checkbutton", border_width + widget->allocation.x, border_width + widget->allocation.y, - widget->allocation.width - 2 * border_width - 1, - widget->allocation.height - 2 * border_width - 1); + widget->allocation.width - 2 * border_width, + widget->allocation.height - 2 * border_width); } } } @@ -222,9 +228,16 @@ gtk_check_button_size_request (GtkWidget *widget, gint indicator_size; gint indicator_spacing; gint border_width = GTK_CONTAINER (widget)->border_width; - - requisition->width = border_width * 2 + 2; - requisition->height = border_width * 2 + 2; + gint focus_width; + gint focus_pad; + + gtk_widget_style_get (GTK_WIDGET (widget), + "focus-line-width", &focus_width, + "focus-padding", &focus_pad, + NULL); + + requisition->width = border_width * 2; + requisition->height = border_width * 2; child = GTK_BIN (widget)->child; if (child && GTK_WIDGET_VISIBLE (child)) @@ -240,10 +253,10 @@ gtk_check_button_size_request (GtkWidget *widget, _gtk_check_button_get_props (GTK_CHECK_BUTTON (widget), &indicator_size, &indicator_spacing); - requisition->width += (indicator_size + indicator_spacing * 3 + 2); + requisition->width += (indicator_size + indicator_spacing * 3 + 2 * (focus_width + focus_pad)); - temp = (indicator_size + indicator_spacing * 2); - requisition->height = MAX (requisition->height, temp) + 2; + temp = indicator_size + indicator_spacing * 2; + requisition->height = MAX (requisition->height, temp) + 2 * (focus_width + focus_pad); } else (* GTK_WIDGET_CLASS (parent_class)->size_request) (widget, requisition); @@ -257,7 +270,7 @@ gtk_check_button_size_allocate (GtkWidget *widget, GtkToggleButton *toggle_button; GtkButton *button; GtkAllocation child_allocation; - + g_return_if_fail (GTK_IS_CHECK_BUTTON (widget)); g_return_if_fail (allocation != NULL); @@ -269,8 +282,14 @@ gtk_check_button_size_allocate (GtkWidget *widget, { gint indicator_size; gint indicator_spacing; + gint focus_width; + gint focus_pad; _gtk_check_button_get_props (check_button, &indicator_size, &indicator_spacing); + gtk_widget_style_get (widget, + "focus-line-width", &focus_width, + "focus-padding", &focus_pad, + NULL); widget->allocation = *allocation; if (GTK_WIDGET_REALIZED (widget)) @@ -284,15 +303,16 @@ gtk_check_button_size_allocate (GtkWidget *widget, child_allocation.width = MIN (GTK_BIN (button)->child->requisition.width, allocation->width - - ((border_width + 1) * 2 + indicator_size + indicator_spacing * 3)); - child_allocation.height = MIN (GTK_BIN (button)->child->requisition.height, - allocation->height - (border_width + 1) * 2); - child_allocation.x = (border_width + indicator_size + indicator_spacing * 3 + 1 + - widget->allocation.x); - child_allocation.y = widget->allocation.y + - (allocation->height - child_allocation.height) / 2; + ((border_width + focus_width + focus_pad) * 2 + + indicator_size + indicator_spacing * 3)); + + child_allocation.height = MIN (GTK_BIN (button)->child->requisition.height, + allocation->height - (border_width + focus_width + focus_pad) * 2); + child_allocation.x = (border_width + indicator_size + indicator_spacing * 3 + + widget->allocation.x + focus_width + focus_pad); + child_allocation.y = widget->allocation.y + + (allocation->height - child_allocation.height) / 2; - if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) child_allocation.x = allocation->x + allocation->width - (child_allocation.x - allocation->x + child_allocation.width); @@ -367,6 +387,9 @@ gtk_real_check_button_draw_indicator (GtkCheckButton *check_button, gint x, y; gint indicator_size; gint indicator_spacing; + gint focus_width; + gint focus_pad; + gboolean interior_focus; GdkWindow *window; g_return_if_fail (GTK_IS_CHECK_BUTTON (check_button)); @@ -377,7 +400,11 @@ gtk_real_check_button_draw_indicator (GtkCheckButton *check_button, if (GTK_WIDGET_DRAWABLE (check_button)) { window = widget->window; - + + gtk_widget_style_get (widget, "interior_focus", &interior_focus, + "focus-line-width", &focus_width, + "focus-padding", &focus_pad, NULL); + _gtk_check_button_get_props (check_button, &indicator_size, &indicator_spacing); state_type = GTK_WIDGET_STATE (widget); @@ -405,6 +432,9 @@ gtk_real_check_button_draw_indicator (GtkCheckButton *check_button, width = indicator_size; height = indicator_size; + if (!interior_focus) + x += focus_width + focus_pad; + state_type = GTK_WIDGET_STATE (widget) == GTK_STATE_ACTIVE ? GTK_STATE_NORMAL : GTK_WIDGET_STATE (widget); if (GTK_TOGGLE_BUTTON (widget)->inconsistent) shadow_type = GTK_SHADOW_ETCHED_IN; diff --git a/gtk/gtkcolorsel.c b/gtk/gtkcolorsel.c index 55484ce1dd..14843ec4f9 100644 --- a/gtk/gtkcolorsel.c +++ b/gtk/gtkcolorsel.c @@ -164,6 +164,8 @@ static void gtk_color_selection_set_palette_color (GtkColorSelection *colo GdkColor *color); static void gtk_color_selection_unset_palette_color (GtkColorSelection *colorsel, gint index); +static GdkGC *get_focus_gc (GtkWidget *drawing_area, + gint *focus_width); static void default_change_palette_func (const GdkColor *colors, gint n_colors); @@ -637,23 +639,45 @@ palette_paint (GtkWidget *drawing_area, if (GTK_WIDGET_HAS_FOCUS (drawing_area)) { - GdkGC *gc; - gdouble color[4]; - - palette_get_color (drawing_area, color); - - if (INTENSITY (color[0], color[1], color[2]) > 0.5) - gc = drawing_area->style->black_gc; - else - gc = drawing_area->style->white_gc; - + gint focus_width; + GdkGC *gc = get_focus_gc (drawing_area, &focus_width); gdk_draw_rectangle (drawing_area->window, - gc, FALSE, 0, 0, - drawing_area->allocation.width - 1, - drawing_area->allocation.height - 1); + gc, FALSE, focus_width / 2, focus_width / 2, + drawing_area->allocation.width - focus_width, + drawing_area->allocation.height - focus_width); + g_object_unref (gc); } } +static GdkGC * +get_focus_gc (GtkWidget *drawing_area, + gint *focus_width) +{ + GdkGC *gc = gdk_gc_new (drawing_area->window); + gdouble color[4]; + gint8 *dash_list; + + gtk_widget_style_get (drawing_area, + "focus-line-width", focus_width, + "focus-line-pattern", (gchar *)&dash_list, + NULL); + + palette_get_color (drawing_area, color); + + if (INTENSITY (color[0], color[1], color[2]) > 0.5) + gdk_gc_copy (gc, drawing_area->style->black_gc); + else + gdk_gc_copy (gc, drawing_area->style->white_gc); + + gdk_gc_set_line_attributes (gc, *focus_width, + dash_list[0] ? GDK_LINE_ON_OFF_DASH : GDK_LINE_SOLID, + GDK_CAP_BUTT, GDK_JOIN_MITER); + + if (dash_list[0]) + gdk_gc_set_dashes (gc, 0, dash_list, strlen (dash_list)); + + return gc; +} static void palette_drag_begin (GtkWidget *widget, @@ -2738,6 +2762,3 @@ gtk_color_selection_set_change_palette_hook (GtkColorSelectionChangePaletteFunc return old; } - - - diff --git a/gtk/gtkentry.c b/gtk/gtkentry.c index 88ad409bf3..3dfeb3ff20 100644 --- a/gtk/gtkentry.c +++ b/gtk/gtkentry.c @@ -125,7 +125,7 @@ static void gtk_entry_size_request (GtkWidget *widget, GtkRequisition *requisition); static void gtk_entry_size_allocate (GtkWidget *widget, GtkAllocation *allocation); -static void gtk_entry_draw_focus (GtkWidget *widget); +static void gtk_entry_draw_frame (GtkWidget *widget); static gint gtk_entry_expose (GtkWidget *widget, GdkEventExpose *event); static gint gtk_entry_button_press (GtkWidget *widget, @@ -290,6 +290,16 @@ static gboolean gtk_entry_mnemonic_activate (GtkWidget *widget, gboolean group_cycling); static void gtk_entry_check_cursor_blink (GtkEntry *entry); static void gtk_entry_pend_cursor_blink (GtkEntry *entry); +static void get_text_area_size (GtkEntry *entry, + gint *x, + gint *y, + gint *width, + gint *height); +static void get_widget_window_size (GtkEntry *entry, + gint *x, + gint *y, + gint *width, + gint *height); static GtkWidgetClass *parent_class = NULL; @@ -985,7 +995,6 @@ gtk_entry_realize (GtkWidget *widget) { GtkEntry *entry; GtkEditable *editable; - GtkRequisition requisition; GdkWindowAttr attributes; gint attributes_mask; @@ -995,14 +1004,10 @@ gtk_entry_realize (GtkWidget *widget) entry = GTK_ENTRY (widget); editable = GTK_EDITABLE (widget); - gtk_widget_get_child_requisition (widget, &requisition); - attributes.window_type = GDK_WINDOW_CHILD; - attributes.x = widget->allocation.x; - attributes.y = widget->allocation.y + (widget->allocation.height - - requisition.height) / 2; - attributes.width = widget->allocation.width; - attributes.height = requisition.height; + + get_widget_window_size (entry, &attributes.x, &attributes.y, &attributes.width, &attributes.height); + attributes.wclass = GDK_INPUT_OUTPUT; attributes.visual = gtk_widget_get_visual (widget); attributes.colormap = gtk_widget_get_colormap (widget); @@ -1020,19 +1025,8 @@ gtk_entry_realize (GtkWidget *widget) widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask); gdk_window_set_user_data (widget->window, entry); - if (entry->has_frame) - { - attributes.x = widget->style->xthickness; - attributes.y = widget->style->ythickness; - } - else - { - attributes.x = 0; - attributes.y = 0; - } - - attributes.width = widget->allocation.width - attributes.x * 2; - attributes.height = requisition.height - attributes.y * 2; + get_text_area_size (entry, &attributes.x, &attributes.y, &attributes.width, &attributes.height); + attributes.cursor = gdk_cursor_new (GDK_XTERM); attributes_mask |= GDK_WA_CURSOR; @@ -1089,6 +1083,40 @@ gtk_entry_unrealize (GtkWidget *widget) (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget); } +static void +get_borders (GtkEntry *entry, + gint *xborder, + gint *yborder) +{ + GtkWidget *widget; + gint focus_width; + gboolean interior_focus; + + widget = GTK_WIDGET (entry); + + gtk_widget_style_get (widget, + "interior-focus", &interior_focus, + "focus-line-width", &focus_width, + NULL); + + if (entry->has_frame) + { + *xborder = widget->style->xthickness; + *yborder = widget->style->ythickness; + } + else + { + *xborder = 0; + *yborder = 0; + } + + if (!interior_focus) + { + *xborder += focus_width; + *yborder += focus_width; + } +} + static void gtk_entry_size_request (GtkWidget *widget, GtkRequisition *requisition) @@ -1102,7 +1130,7 @@ gtk_entry_size_request (GtkWidget *widget, g_return_if_fail (requisition != NULL); entry = GTK_ENTRY (widget); - + context = gtk_widget_get_pango_context (widget); metrics = pango_context_get_metrics (context, widget->style->font_desc, @@ -1111,21 +1139,11 @@ gtk_entry_size_request (GtkWidget *widget, entry->ascent = pango_font_metrics_get_ascent (metrics); entry->descent = pango_font_metrics_get_descent (metrics); - xborder = INNER_BORDER; - yborder = INNER_BORDER; + get_borders (entry, &xborder, &yborder); + + xborder += INNER_BORDER; + yborder += INNER_BORDER; - if (entry->has_frame) - { - xborder += widget->style->xthickness; - yborder += widget->style->ythickness; - } - else - { - /* add 1 pixel to draw focus rect in widget->window */ - xborder += 1; - yborder += 1; - } - if (entry->width_chars < 0) requisition->width = MIN_ENTRY_WIDTH + xborder * 2; else @@ -1139,32 +1157,6 @@ gtk_entry_size_request (GtkWidget *widget, pango_font_metrics_unref (metrics); } -static void -get_borders (GtkEntry *entry, - gint *xborder, - gint *yborder) -{ - GtkWidget *widget; - - widget = GTK_WIDGET (entry); - - if (entry->has_frame) - { - if (xborder) - *xborder = widget->style->xthickness; - if (yborder) - *yborder = widget->style->ythickness; - } - else - { - /* 1 pixel for focus rect */ - if (xborder) - *xborder = 1; - if (yborder) - *yborder = 1; - } -} - static void get_text_area_size (GtkEntry *entry, gint *x, @@ -1177,7 +1169,7 @@ get_text_area_size (GtkEntry *entry, GtkWidget *widget; widget = GTK_WIDGET (entry); - + gtk_widget_get_child_requisition (widget, &requisition); get_borders (entry, &xborder, &yborder); @@ -1269,65 +1261,46 @@ gtk_entry_size_allocate (GtkWidget *widget, } static void -gtk_entry_draw_focus (GtkWidget *widget) +gtk_entry_draw_frame (GtkWidget *widget) { + gint x = 0, y = 0; gint width, height; - GtkEntry *entry; gboolean interior_focus; + gint focus_width; - g_return_if_fail (GTK_IS_ENTRY (widget)); - - gtk_widget_style_get (widget, "interior_focus", &interior_focus, NULL); - - entry = GTK_ENTRY (widget); + gtk_widget_style_get (widget, + "interior-focus", &interior_focus, + "focus-line-width", &focus_width, + NULL); - if (GTK_WIDGET_DRAWABLE (widget)) - { - if (entry->has_frame) - { - gint x = 0, y = 0; - - gdk_window_get_size (widget->window, &width, &height); - - if (GTK_WIDGET_HAS_FOCUS (widget) && !interior_focus) - { - x += 1; - y += 1; - width -= 2; - height -= 2; - } - - gtk_paint_shadow (widget->style, widget->window, - GTK_STATE_NORMAL, GTK_SHADOW_IN, - NULL, widget, "entry", - x, y, width, height); - } - else - gdk_window_clear (widget->window); - - if (GTK_WIDGET_HAS_FOCUS (widget) && !interior_focus) - { - gdk_window_get_size (widget->window, &width, &height); - gtk_paint_focus (widget->style, widget->window, - NULL, widget, "entry", - 0, 0, width - 1, height - 1); - } + gdk_window_get_size (widget->window, &width, &height); + + if (GTK_WIDGET_HAS_FOCUS (widget) && !interior_focus) + { + gtk_paint_focus (widget->style, widget->window, GTK_WIDGET_STATE (widget), + NULL, widget, "entry", + 0, 0, width, height); + + x += focus_width; + y += focus_width; + width -= 2 * focus_width; + height -= 2 * focus_width; } + + gtk_paint_shadow (widget->style, widget->window, + GTK_STATE_NORMAL, GTK_SHADOW_IN, + NULL, widget, "entry", + x, y, width, height); } static gint gtk_entry_expose (GtkWidget *widget, GdkEventExpose *event) { - GtkEntry *entry; - - g_return_val_if_fail (GTK_IS_ENTRY (widget), FALSE); - g_return_val_if_fail (event != NULL, FALSE); - - entry = GTK_ENTRY (widget); + GtkEntry *entry = GTK_ENTRY (widget); if (widget->window == event->window) - gtk_entry_draw_focus (widget); + gtk_entry_draw_frame (widget); else if (entry->text_area == event->window) { gtk_entry_draw_text (GTK_ENTRY (widget)); @@ -1598,7 +1571,7 @@ gtk_entry_focus_in (GtkWidget *widget, GtkEntry *entry = GTK_ENTRY (widget); GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_FOCUS); - gtk_entry_queue_draw (entry); + gtk_widget_queue_draw (widget); entry->need_im_reset = TRUE; gtk_im_context_focus_in (entry->im_context); @@ -1608,7 +1581,7 @@ gtk_entry_focus_in (GtkWidget *widget, G_CALLBACK (gtk_entry_keymap_direction_changed), entry); gtk_entry_check_cursor_blink (entry); - + return FALSE; } @@ -1619,7 +1592,7 @@ gtk_entry_focus_out (GtkWidget *widget, GtkEntry *entry = GTK_ENTRY (widget); GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_FOCUS); - gtk_entry_queue_draw (entry); + gtk_widget_queue_draw (widget); entry->need_im_reset = TRUE; gtk_im_context_focus_out (entry->im_context); @@ -1629,7 +1602,7 @@ gtk_entry_focus_out (GtkWidget *widget, g_signal_handlers_disconnect_by_func (gdk_keymap_get_default (), gtk_entry_keymap_direction_changed, entry); - + return FALSE; } diff --git a/gtk/gtkhsv.c b/gtk/gtkhsv.c index db030e63b3..cc041c589d 100644 --- a/gtk/gtkhsv.c +++ b/gtk/gtkhsv.c @@ -23,6 +23,7 @@ */ #include +#include #include "gtksignal.h" #include "gtkhsv.h" #include "gdk/gdkkeysyms.h" @@ -85,30 +86,31 @@ enum { LAST_SIGNAL }; -static void gtk_hsv_class_init (GtkHSVClass *class); -static void gtk_hsv_init (GtkHSV *hsv); -static void gtk_hsv_destroy (GtkObject *object); -static void gtk_hsv_map (GtkWidget *widget); -static void gtk_hsv_unmap (GtkWidget *widget); -static void gtk_hsv_realize (GtkWidget *widget); -static void gtk_hsv_unrealize (GtkWidget *widget); -static void gtk_hsv_size_request (GtkWidget *widget, - GtkRequisition *requisition); -static void gtk_hsv_size_allocate (GtkWidget *widget, - GtkAllocation *allocation); -static gint gtk_hsv_button_press (GtkWidget *widget, - GdkEventButton *event); -static gint gtk_hsv_button_release (GtkWidget *widget, - GdkEventButton *event); -static gint gtk_hsv_motion (GtkWidget *widget, - GdkEventMotion *event); -static gint gtk_hsv_expose (GtkWidget *widget, - GdkEventExpose *event); -static gboolean gtk_hsv_focus (GtkWidget *widget, - GtkDirectionType direction); - -static void gtk_hsv_move (GtkHSV *hsv, - GtkDirectionType dir); +static void gtk_hsv_class_init (GtkHSVClass *class); +static void gtk_hsv_init (GtkHSV *hsv); +static void gtk_hsv_destroy (GtkObject *object); +static void gtk_hsv_map (GtkWidget *widget); +static void gtk_hsv_unmap (GtkWidget *widget); +static void gtk_hsv_realize (GtkWidget *widget); +static void gtk_hsv_unrealize (GtkWidget *widget); +static void gtk_hsv_size_request (GtkWidget *widget, + GtkRequisition *requisition); +static void gtk_hsv_size_allocate (GtkWidget *widget, + GtkAllocation *allocation); +static gint gtk_hsv_button_press (GtkWidget *widget, + GdkEventButton *event); +static gint gtk_hsv_button_release (GtkWidget *widget, + GdkEventButton *event); +static gint gtk_hsv_motion (GtkWidget *widget, + GdkEventMotion *event); +static gint gtk_hsv_expose (GtkWidget *widget, + GdkEventExpose *event); +static gboolean gtk_hsv_focus (GtkWidget *widget, + GtkDirectionType direction); +static void gtk_hsv_move (GtkHSV *hsv, + GtkDirectionType dir); +static GdkGC * gtk_hsv_get_focus_gc (GtkHSV *hsv, + gint *line_width); static guint hsv_signals[LAST_SIGNAL]; static GtkWidgetClass *parent_class; @@ -1040,16 +1042,22 @@ paint_ring (GtkHSV *hsv, if (GTK_WIDGET_HAS_FOCUS (hsv) && priv->focus_on_ring) { - gdk_rgb_gc_set_foreground (priv->gc, 0x000000); + gint focus_width; + gint focus_halfwidth; + GdkGC *gc = gtk_hsv_get_focus_gc (hsv, &focus_width); + focus_halfwidth = (focus_width + 1) / 2; - gdk_draw_arc (drawable, priv->gc, FALSE, - -x, -y, - priv->size - 1, priv->size - 1, + gdk_draw_arc (drawable, gc, FALSE, + -x + focus_width/2, -y + focus_width/2, + priv->size - focus_width, priv->size - focus_width, 0, 360 * 64); - gdk_draw_arc (drawable, priv->gc, FALSE, - -x + priv->ring_width - 1, -y + priv->ring_width - 1, - priv->size - 2 * priv->ring_width + 1, priv->size - 2 * priv->ring_width + 1, + gdk_draw_arc (drawable, gc, FALSE, + -x + priv->ring_width - focus_halfwidth, -y + priv->ring_width - focus_halfwidth, + priv->size - 2 * priv->ring_width + focus_width, + priv->size - 2 * priv->ring_width + focus_width, 0, 360 * 64); + + g_object_unref (gc); } } @@ -1253,9 +1261,11 @@ paint_triangle (GtkHSV *hsv, if (GTK_WIDGET_HAS_FOCUS (hsv) && !priv->focus_on_ring) { - gdk_rgb_gc_set_foreground (priv->gc, 0x000000); + gint focus_width = 1; + GdkGC *gc = gtk_hsv_get_focus_gc (hsv, &focus_width); - gdk_draw_polygon (drawable, priv->gc, FALSE, points, 3); + gdk_draw_polygon (drawable, gc, FALSE, points, 3); + g_object_unref (gc); } /* Draw value marker */ @@ -1723,3 +1733,27 @@ gtk_hsv_move (GtkHSV *hsv, gtk_hsv_set_color (hsv, hue, sat, val); } +static GdkGC * +gtk_hsv_get_focus_gc (GtkHSV *hsv, + gint *line_width) +{ + GdkGC *focus_gc; + GtkWidget *widget = GTK_WIDGET (hsv); + gint8 *dash_list; + + focus_gc = gdk_gc_new (widget->window); + gdk_gc_copy (focus_gc, widget->style->fg_gc[GTK_WIDGET_STATE (widget)]); + + gtk_widget_style_get (widget, + "focus-line-width", line_width, + "focus-line-pattern", (gchar *)&dash_list, + NULL); + + gdk_gc_set_line_attributes (focus_gc, *line_width, + dash_list[0] ? GDK_LINE_ON_OFF_DASH : GDK_LINE_SOLID, + GDK_CAP_BUTT, GDK_JOIN_MITER); + if (dash_list[0]) + gdk_gc_set_dashes (focus_gc, 0, dash_list, strlen (dash_list)); + + return focus_gc; +} diff --git a/gtk/gtklistitem.c b/gtk/gtklistitem.c index 996fb618e6..952649f9fe 100644 --- a/gtk/gtklistitem.c +++ b/gtk/gtklistitem.c @@ -458,15 +458,22 @@ gtk_list_item_size_request (GtkWidget *widget, { GtkBin *bin; GtkRequisition child_requisition; + gint focus_width; + gint focus_pad; g_return_if_fail (GTK_IS_LIST_ITEM (widget)); g_return_if_fail (requisition != NULL); bin = GTK_BIN (widget); + gtk_widget_style_get (widget, + "focus-line-width", &focus_width, + "focus-padding", &focus_pad, + NULL); - requisition->width = (GTK_CONTAINER (widget)->border_width + - widget->style->xthickness) * 2; - requisition->height = GTK_CONTAINER (widget)->border_width * 2; + requisition->width = 2 * (GTK_CONTAINER (widget)->border_width + + widget->style->xthickness + focus_width + focus_pad - 1); + requisition->height = 2 * (GTK_CONTAINER (widget)->border_width + + focus_width + focus_pad - 1); if (bin->child && GTK_WIDGET_VISIBLE (bin->child)) { @@ -532,6 +539,7 @@ gtk_list_item_expose (GtkWidget *widget, GdkEventExpose *event) { GtkBin *bin; + gint focus_width; g_return_val_if_fail (widget != NULL, FALSE); @@ -558,17 +566,13 @@ gtk_list_item_expose (GtkWidget *widget, if (GTK_WIDGET_HAS_FOCUS (widget)) { if (GTK_IS_LIST (widget->parent) && GTK_LIST (widget->parent)->add_mode) - gtk_paint_focus (widget->style, widget->window, + gtk_paint_focus (widget->style, widget->window, GTK_WIDGET_STATE (widget), NULL, widget, "add-mode", - 0, 0, - widget->allocation.width - 1, - widget->allocation.height - 1); + 0, 0, widget->allocation.width, widget->allocation.height); else - gtk_paint_focus (widget->style, widget->window, + gtk_paint_focus (widget->style, widget->window, GTK_WIDGET_STATE (widget), NULL, widget, NULL, - 0, 0, - widget->allocation.width - 1, - widget->allocation.height - 1); + 0, 0, widget->allocation.width, widget->allocation.height); } } diff --git a/gtk/gtkmenuitem.c b/gtk/gtkmenuitem.c index a656f8edac..8902476410 100644 --- a/gtk/gtkmenuitem.c +++ b/gtk/gtkmenuitem.c @@ -186,9 +186,9 @@ gtk_menu_item_class_init (GtkMenuItemClass *klass) GTK_RUN_FIRST, GTK_CLASS_TYPE (object_class), GTK_SIGNAL_OFFSET (GtkMenuItemClass, toggle_size_request), - _gtk_marshal_NONE__POINTER, + _gtk_marshal_VOID__BOXED, GTK_TYPE_NONE, 1, - GTK_TYPE_POINTER); + GTK_TYPE_REQUISITION); menu_item_signals[TOGGLE_SIZE_ALLOCATE] = gtk_signal_new ("toggle_size_allocate", diff --git a/gtk/gtknotebook.c b/gtk/gtknotebook.c index 45796a0a7d..962dc26bf5 100644 --- a/gtk/gtknotebook.c +++ b/gtk/gtknotebook.c @@ -41,7 +41,6 @@ #define TAB_CURVATURE 1 #define ARROW_SIZE 12 #define ARROW_SPACING 0 -#define FOCUS_WIDTH 1 #define NOTEBOOK_INIT_SCROLL_DELAY (200) #define NOTEBOOK_SCROLL_DELAY (100) @@ -612,12 +611,8 @@ gtk_notebook_new (void) static void gtk_notebook_destroy (GtkObject *object) { - GtkNotebook *notebook; + GtkNotebook *notebook = GTK_NOTEBOOK (object); - g_return_if_fail (GTK_IS_NOTEBOOK (object)); - - notebook = GTK_NOTEBOOK (object); - if (notebook->menu) gtk_notebook_popup_disable (notebook); @@ -896,17 +891,16 @@ static void gtk_notebook_size_request (GtkWidget *widget, GtkRequisition *requisition) { - GtkNotebook *notebook; + GtkNotebook *notebook = GTK_NOTEBOOK (widget); GtkNotebookPage *page; GList *children; GtkRequisition child_requisition; gboolean switch_page = FALSE; gint vis_pages; + gint focus_width; - g_return_if_fail (GTK_IS_NOTEBOOK (widget)); - g_return_if_fail (requisition != NULL); - - notebook = GTK_NOTEBOOK (widget); + gtk_widget_style_get (widget, "focus-line-width", &focus_width, NULL); + widget->requisition.width = 0; widget->requisition.height = 0; @@ -976,14 +970,14 @@ gtk_notebook_size_request (GtkWidget *widget, case GTK_POS_TOP: case GTK_POS_BOTTOM: page->requisition.height += 2 * (notebook->tab_vborder + - FOCUS_WIDTH); + focus_width); tab_height = MAX (tab_height, page->requisition.height); tab_max = MAX (tab_max, page->requisition.width); break; case GTK_POS_LEFT: case GTK_POS_RIGHT: page->requisition.width += 2 * (notebook->tab_hborder + - FOCUS_WIDTH); + focus_width); tab_width = MAX (tab_width, page->requisition.width); tab_max = MAX (tab_max, page->requisition.height); break; @@ -1008,7 +1002,7 @@ gtk_notebook_size_request (GtkWidget *widget, widget->requisition.width < tab_width) tab_height = MAX (tab_height, ARROW_SIZE); - padding = 2 * (TAB_CURVATURE + FOCUS_WIDTH + + padding = 2 * (TAB_CURVATURE + focus_width + notebook->tab_hborder) - TAB_OVERLAP; tab_max += padding; while (children) @@ -1051,7 +1045,7 @@ gtk_notebook_size_request (GtkWidget *widget, widget->requisition.height < tab_height) tab_width = MAX (tab_width, ARROW_SPACING +2 * ARROW_SIZE); - padding = 2 * (TAB_CURVATURE + FOCUS_WIDTH + + padding = 2 * (TAB_CURVATURE + focus_width + notebook->tab_vborder) - TAB_OVERLAP; tab_max += padding; @@ -1615,13 +1609,16 @@ gtk_notebook_draw_focus (GtkWidget *widget) { GtkNotebookPage *page; GdkRectangle area; + gint focus_width; + + gtk_widget_style_get (widget, "focus-line-width", &focus_width, NULL); page = notebook->focus_tab->data; - area.x = page->tab_label->allocation.x - 1; - area.y = page->tab_label->allocation.y - 1; - area.width = page->tab_label->allocation.width + 2; - area.height = page->tab_label->allocation.height + 2; + area.x = page->tab_label->allocation.x - focus_width; + area.y = page->tab_label->allocation.y - focus_width; + area.width = page->tab_label->allocation.width + 2 * focus_width; + area.height = page->tab_label->allocation.height + 2 * focus_width; gtk_notebook_draw_tab (GTK_NOTEBOOK (widget), page, &area); } @@ -2107,6 +2104,9 @@ gtk_notebook_focus_changed (GtkNotebook *notebook, if (GTK_WIDGET_DRAWABLE (notebook) && notebook->show_tabs) { GdkRectangle area; + gint focus_width; + + gtk_widget_style_get (GTK_WIDGET (notebook), "focus-line-width", &focus_width, NULL); if (notebook->focus_tab) { @@ -2114,20 +2114,20 @@ gtk_notebook_focus_changed (GtkNotebook *notebook, page = notebook->focus_tab->data; - area.x = page->tab_label->allocation.x - 1; - area.y = page->tab_label->allocation.y - 1; - area.width = page->tab_label->allocation.width + 2; - area.height = page->tab_label->allocation.height + 2; + area.x = page->tab_label->allocation.x - focus_width; + area.y = page->tab_label->allocation.y - focus_width; + area.width = page->tab_label->allocation.width + 2 * focus_width; + area.height = page->tab_label->allocation.height + 2 * focus_width; gtk_notebook_draw_tab (notebook, page, &area); } if (old_page) { - area.x = old_page->tab_label->allocation.x - 1; - area.y = old_page->tab_label->allocation.y - 1; - area.width = old_page->tab_label->allocation.width + 2; - area.height = old_page->tab_label->allocation.height + 2; + area.x = old_page->tab_label->allocation.x - focus_width; + area.y = old_page->tab_label->allocation.y - focus_width; + area.width = old_page->tab_label->allocation.width + 2 * focus_width; + area.height = old_page->tab_label->allocation.height + 2 * focus_width; gtk_notebook_draw_tab (notebook, old_page, &area); } @@ -2586,12 +2586,16 @@ gtk_notebook_draw_tab (GtkNotebook *notebook, if ((GTK_WIDGET_HAS_FOCUS (widget)) && notebook->focus_tab && (notebook->focus_tab->data == page)) { - gtk_paint_focus (widget->style, widget->window, + gint focus_width; + + gtk_widget_style_get (widget, "focus-line-width", &focus_width, NULL); + + gtk_paint_focus (widget->style, widget->window, GTK_WIDGET_STATE (widget), area, widget, "tab", - page->tab_label->allocation.x - 1, - page->tab_label->allocation.y - 1, - page->tab_label->allocation.width + 1, - page->tab_label->allocation.height + 1); + page->tab_label->allocation.x - focus_width, + page->tab_label->allocation.y - focus_width, + page->tab_label->allocation.width + 2 * focus_width, + page->tab_label->allocation.height + 2 * focus_width); } if (gtk_widget_intersect (page->tab_label, area, &child_area) && GTK_WIDGET_DRAWABLE (page->tab_label)) @@ -3126,19 +3130,16 @@ gtk_notebook_page_allocate (GtkNotebook *notebook, GtkNotebookPage *page, GtkAllocation *allocation) { - GtkWidget *widget; + GtkWidget *widget = GTK_WIDGET (notebook); GtkAllocation child_allocation; GtkRequisition tab_requisition; gint xthickness; gint ythickness; gint padding; + gint focus_width; - g_return_if_fail (notebook != NULL); - g_return_if_fail (page != NULL); - g_return_if_fail (allocation != NULL); - - widget = GTK_WIDGET (notebook); - + gtk_widget_style_get (widget, "focus-line-width", &focus_width, NULL); + xthickness = widget->style->xthickness; ythickness = widget->style->ythickness; @@ -3213,10 +3214,10 @@ gtk_notebook_page_allocate (GtkNotebook *notebook, { case GTK_POS_TOP: case GTK_POS_BOTTOM: - padding = TAB_CURVATURE + FOCUS_WIDTH + notebook->tab_hborder; + padding = TAB_CURVATURE + focus_width + notebook->tab_hborder; if (page->fill) { - child_allocation.x = (xthickness + FOCUS_WIDTH + + child_allocation.x = (xthickness + focus_width + notebook->tab_hborder); child_allocation.width = MAX (1, (page->allocation.width - 2 * child_allocation.x)); @@ -3229,16 +3230,16 @@ gtk_notebook_page_allocate (GtkNotebook *notebook, tab_requisition.width) / 2); child_allocation.width = tab_requisition.width; } - child_allocation.y = (notebook->tab_vborder + FOCUS_WIDTH + + child_allocation.y = (notebook->tab_vborder + focus_width + page->allocation.y); if (notebook->tab_pos == GTK_POS_TOP) child_allocation.y += ythickness; - child_allocation.height = MAX (1, (page->allocation.height - ythickness - - 2 * (notebook->tab_vborder + FOCUS_WIDTH))); + child_allocation.height = MAX (1, (((gint) page->allocation.height) - ythickness - + 2 * (notebook->tab_vborder + focus_width))); break; case GTK_POS_LEFT: case GTK_POS_RIGHT: - padding = TAB_CURVATURE + FOCUS_WIDTH + notebook->tab_vborder; + padding = TAB_CURVATURE + focus_width + notebook->tab_vborder; if (page->fill) { child_allocation.y = ythickness + padding; @@ -3252,11 +3253,11 @@ gtk_notebook_page_allocate (GtkNotebook *notebook, tab_requisition.height) / 2); child_allocation.height = tab_requisition.height; } - child_allocation.x = page->allocation.x + notebook->tab_hborder + FOCUS_WIDTH; + child_allocation.x = page->allocation.x + notebook->tab_hborder + focus_width; if (notebook->tab_pos == GTK_POS_LEFT) child_allocation.x += xthickness; - child_allocation.width = MAX (1, (page->allocation.width - xthickness - - 2 * (notebook->tab_hborder + FOCUS_WIDTH))); + child_allocation.width = MAX (1, (((gint) page->allocation.width) - xthickness - + 2 * (notebook->tab_hborder + focus_width))); break; } diff --git a/gtk/gtkoptionmenu.c b/gtk/gtkoptionmenu.c index 458a8fe431..283a09a7ec 100644 --- a/gtk/gtkoptionmenu.c +++ b/gtk/gtkoptionmenu.c @@ -33,7 +33,7 @@ #include "gdk/gdkkeysyms.h" -#define CHILD_LEFT_SPACING 5 +#define CHILD_LEFT_SPACING 4 #define CHILD_RIGHT_SPACING 1 #define CHILD_TOP_SPACING 1 #define CHILD_BOTTOM_SPACING 1 @@ -45,12 +45,16 @@ struct _GtkOptionMenuProps gboolean interior_focus; GtkRequisition indicator_size; GtkBorder indicator_spacing; + gint focus_width; + gint focus_pad; }; static GtkOptionMenuProps default_props = { - FALSE, + TRUE, { 7, 13 }, - { 7, 5, 2, 2 } /* Left, right, top, bottom */ + { 7, 5, 2, 2 }, /* Left, right, top, bottom */ + 1, + 0 }; static void gtk_option_menu_class_init (GtkOptionMenuClass *klass); @@ -409,6 +413,8 @@ gtk_option_menu_get_props (GtkOptionMenu *option_menu, "indicator_size", &indicator_size, "indicator_spacing", &indicator_spacing, "interior_focus", &props->interior_focus, + "focus_line_width", &props->focus_width, + "focus_padding", &props->focus_pad, NULL); if (indicator_size) @@ -445,15 +451,15 @@ gtk_option_menu_size_request (GtkWidget *widget, } requisition->width = ((GTK_CONTAINER (widget)->border_width + - GTK_WIDGET (widget)->style->xthickness) * 2 + + GTK_WIDGET (widget)->style->xthickness + props.focus_pad) * 2 + MAX (child_requisition.width, option_menu->width) + props.indicator_size.width + props.indicator_spacing.left + props.indicator_spacing.right + - CHILD_LEFT_SPACING + CHILD_RIGHT_SPACING + 2); + CHILD_LEFT_SPACING + CHILD_RIGHT_SPACING + props.focus_width * 2); requisition->height = ((GTK_CONTAINER (widget)->border_width + - GTK_WIDGET (widget)->style->ythickness) * 2 + + GTK_WIDGET (widget)->style->ythickness + props.focus_pad) * 2 + MAX (child_requisition.height, option_menu->height) + - CHILD_TOP_SPACING + CHILD_BOTTOM_SPACING + 2); + CHILD_TOP_SPACING + CHILD_BOTTOM_SPACING + props.focus_width * 2); tmp = (requisition->height - option_menu->height + props.indicator_size.height + props.indicator_spacing.top + props.indicator_spacing.bottom); @@ -483,16 +489,15 @@ gtk_option_menu_size_allocate (GtkWidget *widget, if (child && GTK_WIDGET_VISIBLE (child)) { gint xthickness = GTK_WIDGET (widget)->style->xthickness; + gint ythickness = GTK_WIDGET (widget)->style->ythickness; - child_allocation.x = widget->allocation.x + border_width + xthickness + 1; - child_allocation.y = widget->allocation.y + 2 * border_width + 1; - child_allocation.width = MAX (1, (gint)allocation->width - (xthickness + 1) * 2 - border_width * 2 - + child_allocation.x = widget->allocation.x + border_width + xthickness + props.focus_width + props.focus_pad + CHILD_LEFT_SPACING; + child_allocation.y = widget->allocation.y + border_width + ythickness + props.focus_width + props.focus_pad + CHILD_TOP_SPACING; + child_allocation.width = MAX (1, allocation->width - (border_width + xthickness + props.focus_width + props.focus_pad) * 2 - props.indicator_size.width - props.indicator_spacing.left - props.indicator_spacing.right - - CHILD_LEFT_SPACING - CHILD_RIGHT_SPACING - 2); - child_allocation.height = MAX (1, (gint)allocation->height - (border_width + 1) * 2 - border_width * 2 - - CHILD_TOP_SPACING - CHILD_BOTTOM_SPACING - 2); - child_allocation.x += CHILD_LEFT_SPACING; - child_allocation.y += CHILD_TOP_SPACING; + CHILD_LEFT_SPACING - CHILD_RIGHT_SPACING); + child_allocation.height = MAX (1, allocation->height - (border_width + ythickness + props.focus_width + props.focus_pad) * 2 - + CHILD_TOP_SPACING - CHILD_BOTTOM_SPACING); gtk_widget_size_allocate (child, &child_allocation); } @@ -519,14 +524,14 @@ gtk_option_menu_paint (GtkWidget *widget, button_area.width = widget->allocation.width - 2 * border_width; button_area.height = widget->allocation.height - 2 * border_width; - if (!props.interior_focus) + if (!props.interior_focus && GTK_WIDGET_HAS_FOCUS (widget)) { - button_area.x += 1; - button_area.y += 1; - button_area.width -= 2; - button_area.height -= 2; + button_area.x += props.focus_width + props.focus_pad; + button_area.y += props.focus_width + props.focus_pad; + button_area.width -= 2 * (props.focus_width + props.focus_pad); + button_area.height -= 2 * (props.focus_width + props.focus_pad); } - + gtk_paint_box (widget->style, widget->window, GTK_WIDGET_STATE (widget), GTK_SHADOW_OUT, area, widget, "optionmenu", @@ -546,26 +551,28 @@ gtk_option_menu_paint (GtkWidget *widget, { if (props.interior_focus) { - button_area.x += widget->style->xthickness + 1; - button_area.y += widget->style->ythickness + 1; - button_area.width -= 2 * (widget->style->xthickness + 1) - + props.indicator_spacing.left + props.indicator_spacing.right + props.indicator_size.width; - button_area.height -= 2 * (widget->style->ythickness + 1); + button_area.x += widget->style->xthickness + props.focus_pad; + button_area.y += widget->style->ythickness + props.focus_pad; + button_area.width -= 2 * (widget->style->xthickness + props.focus_pad) + + props.indicator_spacing.left + + props.indicator_spacing.right + + props.indicator_size.width; + button_area.height -= 2 * (widget->style->ythickness + props.focus_pad); } else { - button_area.x -= 1; - button_area.y -= 1; - button_area.width += 2; - button_area.height += 2; + button_area.x -= props.focus_width + props.focus_pad; + button_area.y -= props.focus_width + props.focus_pad; + button_area.width += 2 * (props.focus_width + props.focus_pad); + button_area.height += 2 * (props.focus_width + props.focus_pad); } - gtk_paint_focus (widget->style, widget->window, + gtk_paint_focus (widget->style, widget->window, GTK_WIDGET_STATE (widget), area, widget, "button", button_area.x, button_area.y, - button_area.width - 1, - button_area.height - 1); + button_area.width, + button_area.height); } } } diff --git a/gtk/gtkradiobutton.c b/gtk/gtkradiobutton.c index b1ce1e2eef..ea4b8d5567 100644 --- a/gtk/gtkradiobutton.c +++ b/gtk/gtkradiobutton.c @@ -587,6 +587,9 @@ gtk_radio_button_draw_indicator (GtkCheckButton *check_button, GdkRectangle new_area; gint x, y; gint indicator_size, indicator_spacing; + gint focus_width; + gint focus_pad; + gboolean interior_focus; g_return_if_fail (GTK_IS_RADIO_BUTTON (check_button)); @@ -596,6 +599,12 @@ gtk_radio_button_draw_indicator (GtkCheckButton *check_button, button = GTK_BUTTON (check_button); toggle_button = GTK_TOGGLE_BUTTON (check_button); + gtk_widget_style_get (widget, + "interior_focus", &interior_focus, + "focus-line-width", &focus_width, + "focus-padding", &focus_pad, + NULL); + state_type = GTK_WIDGET_STATE (widget); if ((state_type != GTK_STATE_NORMAL) && (state_type != GTK_STATE_PRELIGHT)) @@ -620,6 +629,9 @@ gtk_radio_button_draw_indicator (GtkCheckButton *check_button, x = widget->allocation.x + indicator_spacing + GTK_CONTAINER (widget)->border_width; y = widget->allocation.y + (widget->allocation.height - indicator_size) / 2; + + if (!interior_focus) + x += focus_width + focus_pad; state_type = GTK_WIDGET_STATE (widget) == GTK_STATE_ACTIVE ? GTK_STATE_NORMAL : GTK_WIDGET_STATE (widget); if (GTK_TOGGLE_BUTTON (widget)->active) diff --git a/gtk/gtkrange.c b/gtk/gtkrange.c index d2ead16d1f..5184177db8 100644 --- a/gtk/gtkrange.c +++ b/gtk/gtkrange.c @@ -918,8 +918,7 @@ gtk_range_expose (GtkWidget *widget, if (sensitive && GTK_WIDGET_HAS_FOCUS (range)) - gtk_paint_focus (widget->style, - widget->window, + gtk_paint_focus (widget->style, widget->window, GTK_WIDGET_STATE (widget), &area, widget, "trough", widget->allocation.x + range->range_rect.x, widget->allocation.y + range->range_rect.y, diff --git a/gtk/gtkspinbutton.c b/gtk/gtkspinbutton.c index 172120234b..9fc7f99e74 100644 --- a/gtk/gtkspinbutton.c +++ b/gtk/gtkspinbutton.c @@ -591,6 +591,13 @@ gtk_spin_button_size_request (GtkWidget *widget, gint string_len; gint max_string_len; gint digit_width; + gboolean interior_focus; + gint focus_width; + + gtk_widget_style_get (widget, + "interior-focus", &interior_focus, + "focus-line-width", &focus_width, + NULL); context = gtk_widget_get_pango_context (widget); metrics = pango_context_get_metrics (context, @@ -617,11 +624,14 @@ gtk_spin_button_size_request (GtkWidget *widget, w = MIN (string_len, max_string_len) * digit_width; width = MAX (width, w); - requisition->width = (width + arrow_size + - 2 * widget->style->xthickness); + requisition->width = width + arrow_size + 2 * widget->style->xthickness; + if (interior_focus) + requisition->width += 2 * focus_width; } else - requisition->width += arrow_size + 2 * widget->style->xthickness; + { + requisition->width += arrow_size + 2 * widget->style->xthickness; + } } static void diff --git a/gtk/gtkstyle.c b/gtk/gtkstyle.c index b9cb750952..dfdd6fea23 100644 --- a/gtk/gtkstyle.c +++ b/gtk/gtkstyle.c @@ -239,6 +239,7 @@ static void gtk_default_draw_extension (GtkStyle *style, GtkPositionType gap_side); static void gtk_default_draw_focus (GtkStyle *style, GdkWindow *window, + GtkStateType state_type, GdkRectangle *area, GtkWidget *widget, const gchar *detail, @@ -1061,7 +1062,7 @@ gtk_draw_focus (GtkStyle *style, g_return_if_fail (GTK_IS_STYLE (style)); g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_focus != NULL); - GTK_STYLE_GET_CLASS (style)->draw_focus (style, window, NULL, NULL, NULL, x, y, width, height); + GTK_STYLE_GET_CLASS (style)->draw_focus (style, window, GTK_STATE_NORMAL, NULL, NULL, NULL, x, y, width, height); } void @@ -3778,6 +3779,7 @@ gtk_default_draw_extension (GtkStyle *style, static void gtk_default_draw_focus (GtkStyle *style, GdkWindow *window, + GtkStateType state_type, GdkRectangle *area, GtkWidget *widget, const gchar *detail, @@ -3787,34 +3789,114 @@ gtk_default_draw_focus (GtkStyle *style, gint height) { GdkPoint points[5]; + GdkGC *gc; + gint line_width = 1; + gchar *dash_list = "\1\1"; + gint dash_len; + + gc = style->fg_gc[state_type]; + + if (widget) + gtk_widget_style_get (widget, + "focus-line-width", &line_width, + "focus-line-pattern", (gchar *)&dash_list, + NULL); sanitize_size (window, &width, &height); if (area) - gdk_gc_set_clip_rectangle (style->black_gc, area); + gdk_gc_set_clip_rectangle (gc, area); + + gdk_gc_set_line_attributes (gc, line_width, + dash_list[0] ? GDK_LINE_ON_OFF_DASH : GDK_LINE_SOLID, + GDK_CAP_BUTT, GDK_JOIN_MITER); - gdk_gc_set_line_attributes (style->black_gc, 1, GDK_LINE_ON_OFF_DASH, 0, 0); if (detail && !strcmp (detail, "add-mode")) - gdk_gc_set_dashes (style->black_gc, 0, "\4\4", 2); - else - gdk_gc_set_dashes (style->black_gc, 0, "\1\1", 2); + dash_list = "\4\4"; - points[0].x = x; - points[0].y = y; - points[1].x = x + width; - points[1].y = y; - points[2].x = x + width; - points[2].y = y + height; - points[3].x = x; - points[3].y = y + height; + points[0].x = x + line_width / 2; + points[0].y = y + line_width / 2; + points[1].x = x + width - line_width + line_width / 2; + points[1].y = y + line_width / 2; + points[2].x = x + width - line_width + line_width / 2; + points[2].y = y + height - line_width + line_width / 2; + points[3].x = x + line_width / 2; + points[3].y = y + height - line_width + line_width / 2; points[4] = points[0]; - - gdk_draw_polygon (window, style->black_gc, FALSE, points, 4); - gdk_gc_set_line_attributes (style->black_gc, 0, GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_MITER); + + if (!dash_list[0]) + { + gdk_draw_lines (window, gc, points, 5); + } + else + { + /* We go through all the pain below because the X rasterization + * rules don't really work right for dashed lines if you + * want continuity in segments that go between top/right + * and left/bottom. For instance, a top left corner + * with a 1-1 dash is drawn as: + * + * X X X + * X + * + * X + * + * This is because pixels on the top and left boundaries + * of polygons are drawn, but not on the bottom and right. + * So, if you have a line going up that turns the corner + * and goes right, there is a one pixel shift in the pattern. + * + * So, to fix this, we drawn the top and right in one call, + * then the left and bottom in another call, fixing up + * the dash offset for the second call ourselves to get + * continuity at the upper left. + * + * It's not perfect since we really should have a join at + * the upper left and lower right instead of two intersecting + * lines but that's only really apparent for no-dashes, + * which (for this reason) are done as one polygon and + * don't to through this code path. + */ + + dash_len = strlen (dash_list); + + if (dash_list[0]) + gdk_gc_set_dashes (gc, 0, dash_list, dash_len); + + gdk_draw_lines (window, gc, points, 3); + + /* We draw this line one farther over than it is "supposed" to + * because of another rasterization problem ... if two 1 pixel + * unjoined lines meet at the lower right, there will be a missing + * pixel. + */ + points[2].x += 1; + + if (dash_list[0]) + { + gint dash_pixels = 0; + gint i; + + /* Adjust the dash offset for the bottom and left so we + * match up at the upper left. + */ + for (i = 0; i < dash_len; i++) + dash_pixels += dash_list[i]; + + if (dash_len % 2 == 1) + dash_pixels *= 2; + + gdk_gc_set_dashes (gc, dash_pixels - (width + height - 2 * line_width) % dash_pixels, dash_list, dash_len); + } + + gdk_draw_lines (window, gc, points + 2, 3); + } + + gdk_gc_set_line_attributes (gc, 0, GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_MITER); if (area) - gdk_gc_set_clip_rectangle (style->black_gc, NULL); + gdk_gc_set_clip_rectangle (gc, NULL); } static void @@ -4847,6 +4929,7 @@ gtk_paint_extension (GtkStyle *style, void gtk_paint_focus (GtkStyle *style, GdkWindow *window, + GtkStateType state_type, GdkRectangle *area, GtkWidget *widget, const gchar *detail, @@ -4858,7 +4941,7 @@ gtk_paint_focus (GtkStyle *style, g_return_if_fail (GTK_IS_STYLE (style)); g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_focus != NULL); - GTK_STYLE_GET_CLASS (style)->draw_focus (style, window, area, widget, detail, x, y, width, height); + GTK_STYLE_GET_CLASS (style)->draw_focus (style, window, state_type, area, widget, detail, x, y, width, height); } void @@ -5114,4 +5197,3 @@ _gtk_draw_insertion_cursor (GdkDrawable *drawable, } } } - diff --git a/gtk/gtkstyle.h b/gtk/gtkstyle.h index 3e7332b9f3..32d1c121a7 100644 --- a/gtk/gtkstyle.h +++ b/gtk/gtkstyle.h @@ -340,6 +340,7 @@ struct _GtkStyleClass GtkPositionType gap_side); void (*draw_focus) (GtkStyle *style, GdkWindow *window, + GtkStateType state_type, GdkRectangle *area, GtkWidget *widget, const gchar *detail, @@ -775,6 +776,7 @@ void gtk_paint_extension (GtkStyle *style, GtkPositionType gap_side); void gtk_paint_focus (GtkStyle *style, GdkWindow *window, + GtkStateType state_type, GdkRectangle *area, GtkWidget *widget, const gchar *detail, diff --git a/gtk/gtktext.c b/gtk/gtktext.c index 4e5c551dd6..335c4fb07a 100644 --- a/gtk/gtktext.c +++ b/gtk/gtktext.c @@ -1526,11 +1526,11 @@ gtk_text_draw_focus (GtkWidget *widget) xextra -= 1; yextra -= 1; - gtk_paint_focus (widget->style, widget->window, + gtk_paint_focus (widget->style, widget->window, GTK_WIDGET_STATE (widget), NULL, widget, "text", 0, 0, - widget->allocation.width - 1, - widget->allocation.height - 1); + widget->allocation.width, + widget->allocation.height); } gtk_paint_shadow (widget->style, widget->window, diff --git a/gtk/gtktextview.c b/gtk/gtktextview.c index 59a8e845a1..ce99a63f0d 100644 --- a/gtk/gtktextview.c +++ b/gtk/gtktextview.c @@ -2377,16 +2377,20 @@ gtk_text_view_size_request (GtkWidget *widget, GtkTextView *text_view; GSList *tmp_list; gint focus_edge_width; + gint focus_width; gboolean interior_focus; text_view = GTK_TEXT_VIEW (widget); - gtk_widget_style_get (widget, "interior_focus", &interior_focus, NULL); + gtk_widget_style_get (widget, + "interior_focus", &interior_focus, + "focus_line_width", &focus_width, + NULL); if (interior_focus) focus_edge_width = 0; else - focus_edge_width = 1; + focus_edge_width = focus_width; if (text_view->layout) { @@ -2588,6 +2592,7 @@ gtk_text_view_size_allocate (GtkWidget *widget, GdkRectangle top_rect; GdkRectangle bottom_rect; gint focus_edge_width; + gint focus_width; gboolean interior_focus; gboolean size_changed; @@ -2612,12 +2617,15 @@ gtk_text_view_size_allocate (GtkWidget *widget, * windows get at least a 1x1 allocation. */ - gtk_widget_style_get (widget, "interior_focus", &interior_focus, NULL); - + gtk_widget_style_get (widget, + "interior_focus", &interior_focus, + "focus_line_width", &focus_width, + NULL); + if (interior_focus) focus_edge_width = 0; else - focus_edge_width = 1; + focus_edge_width = focus_width; width = allocation->width - focus_edge_width * 2 - GTK_CONTAINER (text_view)->border_width * 2; @@ -3779,17 +3787,19 @@ gtk_text_view_draw_focus (GtkWidget *widget) gboolean interior_focus; /* We clear the focus if we are in interior focus mode. */ - gtk_widget_style_get (widget, "interior_focus", &interior_focus, NULL); + gtk_widget_style_get (widget, + "interior_focus", &interior_focus, + NULL); if (GTK_WIDGET_DRAWABLE (widget)) { if (GTK_WIDGET_HAS_FOCUS (widget) && !interior_focus) { - gtk_paint_focus (widget->style, widget->window, + gtk_paint_focus (widget->style, widget->window, GTK_WIDGET_STATE (widget), NULL, widget, "textview", 0, 0, - widget->allocation.width - 1, - widget->allocation.height - 1); + widget->allocation.width, + widget->allocation.height); } else { @@ -6140,13 +6150,17 @@ buffer_to_widget (GtkTextView *text_view, { gint focus_edge_width; gboolean interior_focus; + gint focus_width; - gtk_widget_style_get (GTK_WIDGET (text_view), "interior_focus", &interior_focus, NULL); + gtk_widget_style_get (GTK_WIDGET (text_view), + "interior_focus", &interior_focus, + "focus_line_width", &focus_width, + NULL); if (interior_focus) focus_edge_width = 0; else - focus_edge_width = 1; + focus_edge_width = focus_width; if (window_x) { @@ -6287,13 +6301,17 @@ widget_to_buffer (GtkTextView *text_view, { gint focus_edge_width; gboolean interior_focus; + gint focus_width; - gtk_widget_style_get (GTK_WIDGET (text_view), "interior_focus", &interior_focus, NULL); + gtk_widget_style_get (GTK_WIDGET (text_view), + "interior_focus", &interior_focus, + "focus_line_width", &focus_width, + NULL); if (interior_focus) focus_edge_width = 0; else - focus_edge_width = 1; + focus_edge_width = focus_width; if (buffer_x) { diff --git a/gtk/gtktogglebutton.c b/gtk/gtktogglebutton.c index a275b55fbf..0b159e5a02 100644 --- a/gtk/gtktogglebutton.c +++ b/gtk/gtktogglebutton.c @@ -50,8 +50,6 @@ enum { static void gtk_toggle_button_class_init (GtkToggleButtonClass *klass); static void gtk_toggle_button_init (GtkToggleButton *toggle_button); -static void gtk_toggle_button_paint (GtkWidget *widget, - GdkRectangle *area); static gint gtk_toggle_button_expose (GtkWidget *widget, GdkEventExpose *event); static void gtk_toggle_button_pressed (GtkButton *button); @@ -369,63 +367,20 @@ gtk_toggle_button_get_inconsistent (GtkToggleButton *toggle_button) return toggle_button->inconsistent; } -static void -gtk_toggle_button_paint (GtkWidget *widget, - GdkRectangle *area) +static gint +gtk_toggle_button_expose (GtkWidget *widget, + GdkEventExpose *event) { - GtkButton *button; - GtkToggleButton *toggle_button; - GtkShadowType shadow_type; - GtkStateType state_type; - gint width, height; - gboolean interior_focus; - gint border_width; - gint x, y; - - button = GTK_BUTTON (widget); - toggle_button = GTK_TOGGLE_BUTTON (widget); - if (GTK_WIDGET_DRAWABLE (widget)) { - border_width = GTK_CONTAINER (widget)->border_width; - - gtk_widget_style_get (widget, "interior_focus", &interior_focus, NULL); - - x = widget->allocation.x + border_width; - y = widget->allocation.y + border_width; - width = widget->allocation.width - border_width * 2; - height = widget->allocation.height - border_width * 2; - - if (GTK_WIDGET_HAS_DEFAULT (widget) && - GTK_BUTTON (widget)->relief == GTK_RELIEF_NORMAL) - { - gtk_paint_box (widget->style, widget->window, - GTK_STATE_NORMAL, GTK_SHADOW_IN, - area, widget, "togglebuttondefault", - x, y, width, height); - } - - if (GTK_WIDGET_CAN_DEFAULT (widget)) - { - x += widget->style->xthickness; - y += widget->style->ythickness; - width -= 2 * x + DEFAULT_SPACING; - height -= 2 * y + DEFAULT_SPACING; - x += DEFAULT_LEFT_POS; - y += DEFAULT_TOP_POS; - } - - if (GTK_WIDGET_HAS_FOCUS (widget) && !interior_focus) - { - x += 1; - y += 1; - width -= 2; - height -= 2; - } + GtkWidget *child = GTK_BIN (widget)->child; + GtkButton *button = GTK_BUTTON (widget); + GtkStateType state_type; + GtkShadowType shadow_type; state_type = GTK_WIDGET_STATE (widget); - if (toggle_button->inconsistent) + if (GTK_TOGGLE_BUTTON (widget)->inconsistent) { if (state_type == GTK_STATE_ACTIVE) state_type = GTK_STATE_NORMAL; @@ -434,47 +389,8 @@ gtk_toggle_button_paint (GtkWidget *widget, else shadow_type = button->depressed ? GTK_SHADOW_IN : GTK_SHADOW_OUT; - if (button->relief != GTK_RELIEF_NONE || - (GTK_WIDGET_STATE(widget) != GTK_STATE_NORMAL && - GTK_WIDGET_STATE(widget) != GTK_STATE_INSENSITIVE)) - gtk_paint_box (widget->style, widget->window, - state_type, - shadow_type, area, widget, "togglebutton", - x, y, width, height); - - if (GTK_WIDGET_HAS_FOCUS (widget)) - { - if (interior_focus) - { - x += widget->style->xthickness + 1; - y += widget->style->xthickness + 1; - width -= 2 * (widget->style->xthickness + 1); - height -= 2 * (widget->style->ythickness + 1); - } - else - { - x -= 1; - y -= 1; - width += 2; - height += 2; - } - - gtk_paint_focus (widget->style, widget->window, - area, widget, "togglebutton", - x, y, width - 1, height - 1); - } - } -} - -static gint -gtk_toggle_button_expose (GtkWidget *widget, - GdkEventExpose *event) -{ - if (GTK_WIDGET_DRAWABLE (widget)) - { - GtkWidget *child = GTK_BIN (widget)->child; - - gtk_toggle_button_paint (widget, &event->area); + _gtk_button_paint (button, &event->area, state_type, shadow_type, + "togglebutton", "togglebuttondefault"); if (child) gtk_container_propagate_expose (GTK_CONTAINER (widget), child, event); diff --git a/gtk/gtktreeitem.c b/gtk/gtktreeitem.c index a6ca337e49..ba1fe88a07 100644 --- a/gtk/gtktreeitem.c +++ b/gtk/gtktreeitem.c @@ -664,11 +664,11 @@ gtk_tree_item_paint (GtkWidget *widget, } if (GTK_WIDGET_HAS_FOCUS (widget)) - gtk_paint_focus (widget->style, widget->window, + gtk_paint_focus (widget->style, widget->window, GTK_WIDGET_STATE (widget), NULL, widget, "treeitem", 0, 0, - widget->allocation.width - 1, - widget->allocation.height - 1); + widget->allocation.width, + widget->allocation.height); } } diff --git a/gtk/gtktreeview.c b/gtk/gtktreeview.c index db8adb09ab..fdccdab76f 100644 --- a/gtk/gtktreeview.c +++ b/gtk/gtktreeview.c @@ -2766,11 +2766,12 @@ gtk_tree_view_bin_expose (GtkWidget *widget, &width, NULL); gtk_paint_focus (widget->style, tree_view->priv->bin_window, + GTK_WIDGET_STATE (widget), NULL, widget, "treeview-drop-indicator", 0, BACKGROUND_FIRST_PIXEL (tree_view, tree, node), - width - 1, BACKGROUND_HEIGHT (node) - 1); + width, BACKGROUND_HEIGHT (node)); break; } diff --git a/gtk/gtktreeviewcolumn.c b/gtk/gtktreeviewcolumn.c index ecbd58c741..849a14d9c7 100644 --- a/gtk/gtktreeviewcolumn.c +++ b/gtk/gtktreeviewcolumn.c @@ -2419,13 +2419,14 @@ gtk_tree_view_column_cell_draw_focus (GtkTreeViewColumn *tree_column, gtk_paint_focus (tree_column->tree_view->style, window, + GTK_WIDGET_STATE (tree_column->tree_view), NULL, tree_column->tree_view, "treeview", cell_area->x - 1, cell_area->y - 1, - cell_area->width + 2 - 1, - cell_area->height + 2 - 1); + cell_area->width + 2, + cell_area->height + 2); } else @@ -2442,13 +2443,14 @@ gtk_tree_view_column_cell_draw_focus (GtkTreeViewColumn *tree_column, gtk_paint_focus (tree_column->tree_view->style, window, + GTK_WIDGET_STATE (tree_column->tree_view), NULL, tree_column->tree_view, "treeview", focus_rectangle.x, focus_rectangle.y, - focus_rectangle.width - 1, - focus_rectangle.height - 1); + focus_rectangle.width, + focus_rectangle.height); } } diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c index dbfef6090f..6e0e0d631c 100644 --- a/gtk/gtkwidget.c +++ b/gtk/gtkwidget.c @@ -1054,6 +1054,27 @@ gtk_widget_class_init (GtkWidgetClass *klass) _("Whether to draw the focus indicator inside widgets."), TRUE, G_PARAM_READABLE)); + + gtk_widget_class_install_style_property (klass, + g_param_spec_int ("focus-line-width", + _("Focus linewidth"), + _("Width, in pixels, of the focus indicator line."), + 0, G_MAXINT, 1, + G_PARAM_READWRITE)); + + gtk_widget_class_install_style_property (klass, + g_param_spec_string ("focus-line-pattern", + _("Focus line dash pattern"), + _("Dash pattern used to draw the focus indicator."), + "\1\1", + G_PARAM_READWRITE)); + gtk_widget_class_install_style_property (klass, + g_param_spec_int ("focus-padding", + _("Focus padding"), + _("Width, in pixels, between focus indicator and the widget 'box'."), + 0, G_MAXINT, 1, + G_PARAM_READWRITE)); + } static void