[glabels/vala] Initial implementation of LabelObjectText.
- From: Jim Evins <jimevins src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glabels/vala] Initial implementation of LabelObjectText.
- Date: Mon, 23 Jul 2012 01:39:10 +0000 (UTC)
commit e05f32d7e382617c64f181f064ebe390f57cbe1b
Author: Jim Evins <evins snaught com>
Date: Sun Jul 22 21:38:11 2012 -0400
Initial implementation of LabelObjectText.
Still needs a lot of work.
data/ui/object_editor.ui | 635 ++++++++++++++++++++++++++++++++++++---
glabels/Makefile.am | 7 +-
glabels/color_swatch.vala | 2 +-
glabels/font_sample.vala | 2 +-
glabels/handle.vala | 2 +-
glabels/label_object.vala | 35 +++
glabels/label_object_text.vala | 293 ++++++++++++++++++
glabels/mini_preview.vala | 2 +-
glabels/object_editor.vala | 158 +++++++---
glabels/outline.vala | 85 ++++++
glabels/text_line.vala | 80 +++++
glabels/text_lines.vala | 60 ++++
glabels/text_node.vala | 264 +++++++++++++++++
glabels/ui.vala | 7 +-
glabels/valign_type.vala | 28 ++
glabels/view.vala | 28 ++-
glabels/xml_label.vala | 56 ++++-
17 files changed, 1637 insertions(+), 107 deletions(-)
---
diff --git a/data/ui/object_editor.ui b/data/ui/object_editor.ui
index a9731f5..11ef3bb 100644
--- a/data/ui/object_editor.ui
+++ b/data/ui/object_editor.ui
@@ -1,27 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
- <requires lib="gtk+" version="2.20"/>
- <object class="GtkSizeGroup" id="color_box_sizegroup">
- <widgets>
- <widget name="shadow_color_box"/>
- <widget name="line_color_box"/>
- <widget name="fill_color_box"/>
- </widgets>
+ <!-- interface-requires gtk+ 3.0 -->
+ <object class="GtkAdjustment" id="font_size_adjustment">
+ <property name="lower">1</property>
+ <property name="upper">100</property>
+ <property name="value">12</property>
+ <property name="step_increment">0.5</property>
+ <property name="page_increment">10</property>
</object>
- <object class="GtkSizeGroup" id="label_sizegroup">
- <widgets>
- <widget name="line_w_label"/>
- <widget name="line_color_label"/>
- <widget name="fill_color_label"/>
- <widget name="pos_x_label"/>
- <widget name="pos_y_label"/>
- <widget name="size_w_label"/>
- <widget name="size_h_label"/>
- <widget name="label40"/>
- <widget name="label41"/>
- <widget name="label45"/>
- <widget name="label46"/>
- </widgets>
+ <object class="GtkAdjustment" id="line_spacing_adjustment">
+ <property name="lower">1</property>
+ <property name="upper">5</property>
+ <property name="value">1</property>
+ <property name="step_increment">0.10000000000000001</property>
+ <property name="page_increment">10</property>
</object>
<object class="GtkAdjustment" id="line_width_adjustment">
<property name="lower">0.25</property>
@@ -30,16 +22,6 @@
<property name="step_increment">0.25</property>
<property name="page_increment">1</property>
</object>
- <object class="GtkAdjustment" id="pos_x_adjustment">
- <property name="upper">100</property>
- <property name="step_increment">0.01</property>
- <property name="page_increment">1</property>
- </object>
- <object class="GtkAdjustment" id="pos_y_adjustment">
- <property name="upper">100</property>
- <property name="step_increment">0.01</property>
- <property name="page_increment">1</property>
- </object>
<object class="GtkAdjustment" id="shadow_opacity_adjustment">
<property name="upper">100</property>
<property name="value">1</property>
@@ -119,6 +101,536 @@
<property name="can_focus">True</property>
<property name="enable_popup">True</property>
<child>
+ <object class="GtkBox" id="text_page_box">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">start</property>
+ <property name="hexpand">True</property>
+ <property name="border_width">6</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="frame9">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkAlignment" id="alignment10">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="left_padding">12</property>
+ <child>
+ <object class="GtkBox" id="box2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkBox" id="box3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">3</property>
+ <child>
+ <object class="GtkBox" id="text_font_family_box">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="text_font_size_spin">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="has_tooltip">True</property>
+ <property name="tooltip_markup" translatable="yes">Font size</property>
+ <property name="tooltip_text" translatable="yes">Font size</property>
+ <property name="invisible_char">â</property>
+ <property name="invisible_char_set">True</property>
+ <property name="progress_pulse_step">0.5</property>
+ <property name="adjustment">font_size_adjustment</property>
+ <property name="digits">1</property>
+ <property name="numeric">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box9">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">3</property>
+ <child>
+ <object class="GtkToggleButton" id="text_font_bold_toggle">
+ <property name="use_action_appearance">False</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="has_tooltip">True</property>
+ <property name="tooltip_markup" translatable="yes">Bold</property>
+ <property name="tooltip_text" translatable="yes">Bold</property>
+ <property name="use_action_appearance">False</property>
+ <child>
+ <object class="GtkImage" id="image1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="stock">gtk-bold</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToggleButton" id="togglebutton1">
+ <property name="use_action_appearance">False</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="has_tooltip">True</property>
+ <property name="tooltip_markup" translatable="yes">Italic</property>
+ <property name="tooltip_text" translatable="yes">Italic</property>
+ <property name="use_action_appearance">False</property>
+ <child>
+ <object class="GtkImage" id="image2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="stock">gtk-italic</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToggleButton" id="togglebutton2">
+ <property name="use_action_appearance">False</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="has_tooltip">True</property>
+ <property name="tooltip_markup" translatable="yes">Underline</property>
+ <property name="tooltip_text" translatable="yes">Underline</property>
+ <property name="use_action_appearance">False</property>
+ <child>
+ <object class="GtkImage" id="image3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="stock">gtk-underline</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="text_color_box">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label13">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes"><b>Font/Appearance</b></property>
+ <property name="use_markup">True</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame6">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkAlignment" id="alignment7">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="left_padding">12</property>
+ <child>
+ <object class="GtkBox" id="box4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkBox" id="box5">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">3</property>
+ <child>
+ <object class="GtkToggleButton" id="text_align_left_toggle">
+ <property name="use_action_appearance">False</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_action_appearance">False</property>
+ <child>
+ <object class="GtkImage" id="image4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="stock">gtk-justify-left</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToggleButton" id="text_align_center_toggle">
+ <property name="use_action_appearance">False</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_action_appearance">False</property>
+ <child>
+ <object class="GtkImage" id="image5">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="stock">gtk-justify-center</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToggleButton" id="text_align_right_toggle">
+ <property name="use_action_appearance">False</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_action_appearance">False</property>
+ <child>
+ <object class="GtkImage" id="image6">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="stock">gtk-justify-right</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box6">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">3</property>
+ <child>
+ <object class="GtkToggleButton" id="text_align_top_toggle">
+ <property name="use_action_appearance">False</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_action_appearance">False</property>
+ <child>
+ <object class="GtkImage" id="image7">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="icon_name">glabels-align-text-top</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToggleButton" id="text_align_middle_toggle">
+ <property name="use_action_appearance">False</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_action_appearance">False</property>
+ <child>
+ <object class="GtkImage" id="image8">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="icon_name">glabels-align-text-middle</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToggleButton" id="text_align_bottom_toggle">
+ <property name="use_action_appearance">False</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_action_appearance">False</property>
+ <child>
+ <object class="GtkImage" id="image9">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="icon_name">glabels-align-text-bottom</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label10">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes"><b>Alignment</b></property>
+ <property name="use_markup">True</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame7">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkAlignment" id="alignment8">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="left_padding">12</property>
+ <child>
+ <object class="GtkBox" id="box7">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkSpinButton" id="text_line_spacing_spin">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="has_tooltip">True</property>
+ <property name="tooltip_markup" translatable="yes">Font size</property>
+ <property name="tooltip_text" translatable="yes">Line spacing</property>
+ <property name="invisible_char">â</property>
+ <property name="invisible_char_set">True</property>
+ <property name="progress_pulse_step">0.10000000149011612</property>
+ <property name="adjustment">line_spacing_adjustment</property>
+ <property name="digits">1</property>
+ <property name="numeric">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label11">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes"><b>Line spacing</b></property>
+ <property name="use_markup">True</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame8">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="vexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkAlignment" id="alignment9">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="left_padding">12</property>
+ <child>
+ <object class="GtkBox" id="box8">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkScrolledWindow" id="scrolledwindow1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTextView" id="text_text_view">
+ <property name="width_request">232</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="vexpand">True</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">center</property>
+ <property name="valign">start</property>
+ <property name="hexpand">True</property>
+ <child>
+ <object class="GtkBox" id="text_insert_field_box">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">start</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label12">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes"><b>Editor</b></property>
+ <property name="use_markup">True</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="label8">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Text</property>
+ </object>
+ <packing>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
<object class="GtkBox" id="line_fill_page_box">
<property name="visible">True</property>
<property name="can_focus">False</property>
@@ -145,7 +657,6 @@
<property name="hexpand">True</property>
<property name="row_spacing">6</property>
<property name="column_spacing">12</property>
- <property name="n_rows">2</property>
<child>
<object class="GtkLabel" id="line_w_label">
<property name="visible">True</property>
@@ -221,9 +732,6 @@
<property name="height">1</property>
</packing>
</child>
- <child>
- <placeholder/>
- </child>
</object>
</child>
</object>
@@ -261,7 +769,6 @@
<property name="hexpand">True</property>
<property name="row_spacing">6</property>
<property name="column_spacing">12</property>
- <property name="n_rows">1</property>
<child>
<object class="GtkLabel" id="fill_color_label">
<property name="visible">True</property>
@@ -291,9 +798,6 @@
<property name="height">1</property>
</packing>
</child>
- <child>
- <placeholder/>
- </child>
</object>
</child>
</object>
@@ -314,6 +818,9 @@
</packing>
</child>
</object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
</child>
<child type="tab">
<object class="GtkLabel" id="label3">
@@ -323,6 +830,7 @@
<property name="label" translatable="yes">Line/Fill</property>
</object>
<packing>
+ <property name="position">1</property>
<property name="tab_fill">False</property>
</packing>
</child>
@@ -352,7 +860,6 @@
<property name="can_focus">False</property>
<property name="row_spacing">6</property>
<property name="column_spacing">12</property>
- <property name="n_rows">2</property>
<child>
<object class="GtkLabel" id="pos_x_label">
<property name="width_request">50</property>
@@ -484,7 +991,6 @@
<property name="can_focus">False</property>
<property name="row_spacing">6</property>
<property name="column_spacing">12</property>
- <property name="n_rows">4</property>
<child>
<object class="GtkLabel" id="size_w_label">
<property name="visible">True</property>
@@ -580,6 +1086,7 @@
<child>
<object class="GtkCheckButton" id="size_aspect_check">
<property name="label" translatable="yes">Lock aspect ratio</property>
+ <property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
@@ -597,6 +1104,7 @@
<child>
<object class="GtkButton" id="size_reset_image_button">
<property name="label" translatable="yes">Reset image size</property>
+ <property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
@@ -638,7 +1146,7 @@
</child>
</object>
<packing>
- <property name="position">1</property>
+ <property name="position">2</property>
</packing>
</child>
<child type="tab">
@@ -649,7 +1157,7 @@
<property name="label" translatable="yes">Position/Size</property>
</object>
<packing>
- <property name="position">1</property>
+ <property name="position">2</property>
<property name="tab_fill">False</property>
</packing>
</child>
@@ -665,6 +1173,7 @@
<child>
<object class="GtkCheckButton" id="shadow_enable_check">
<property name="label" translatable="yes">Enable shadow</property>
+ <property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
@@ -691,7 +1200,6 @@
<property name="hexpand">True</property>
<property name="row_spacing">6</property>
<property name="column_spacing">12</property>
- <property name="n_rows">4</property>
<child>
<object class="GtkLabel" id="label40">
<property name="visible">True</property>
@@ -859,9 +1367,6 @@
<property name="height">1</property>
</packing>
</child>
- <child>
- <placeholder/>
- </child>
</object>
</child>
</object>
@@ -873,7 +1378,7 @@
</child>
</object>
<packing>
- <property name="position">2</property>
+ <property name="position">3</property>
<property name="tab_fill">False</property>
</packing>
</child>
@@ -885,7 +1390,7 @@
<property name="label" translatable="yes">Shadow</property>
</object>
<packing>
- <property name="position">2</property>
+ <property name="position">3</property>
<property name="tab_fill">False</property>
</packing>
</child>
@@ -899,6 +1404,28 @@
</object>
</child>
</object>
+ <object class="GtkSizeGroup" id="color_box_sizegroup">
+ <widgets>
+ <widget name="shadow_color_box"/>
+ <widget name="line_color_box"/>
+ <widget name="fill_color_box"/>
+ </widgets>
+ </object>
+ <object class="GtkSizeGroup" id="label_sizegroup">
+ <widgets>
+ <widget name="line_w_label"/>
+ <widget name="line_color_label"/>
+ <widget name="fill_color_label"/>
+ <widget name="pos_x_label"/>
+ <widget name="pos_y_label"/>
+ <widget name="size_w_label"/>
+ <widget name="size_h_label"/>
+ <widget name="label40"/>
+ <widget name="label41"/>
+ <widget name="label45"/>
+ <widget name="label46"/>
+ </widgets>
+ </object>
<object class="GtkSizeGroup" id="page_sizegroup">
<property name="mode">both</property>
<widgets>
@@ -907,6 +1434,16 @@
<widget name="shadow_page_box"/>
</widgets>
</object>
+ <object class="GtkAdjustment" id="pos_x_adjustment">
+ <property name="upper">100</property>
+ <property name="step_increment">0.01</property>
+ <property name="page_increment">1</property>
+ </object>
+ <object class="GtkAdjustment" id="pos_y_adjustment">
+ <property name="upper">100</property>
+ <property name="step_increment">0.01</property>
+ <property name="page_increment">1</property>
+ </object>
<object class="GtkSizeGroup" id="width_sizegroup">
<widgets>
<widget name="notebook"/>
diff --git a/glabels/Makefile.am b/glabels/Makefile.am
index da71fea..c0ff975 100644
--- a/glabels/Makefile.am
+++ b/glabels/Makefile.am
@@ -8,7 +8,6 @@ bin_PROGRAMS = glabels-4
glabels_4_SOURCES = \
glabels.vala \
- TMP_gdk_key.vala \
color.vala \
color_button.vala \
color_history.vala \
@@ -34,6 +33,7 @@ glabels_4_SOURCES = \
label.vala \
label_object.vala \
label_object_box.vala \
+ label_object_text.vala \
label_region.vala \
label_state.vala \
merge.vala \
@@ -50,13 +50,18 @@ glabels_4_SOURCES = \
mini_preview.vala \
new_label_dialog.vala \
object_editor.vala \
+ outline.vala \
prefs.vala \
print_op.vala \
print_op_dialog.vala \
property_editor.vala \
template_history.vala \
+ text_line.vala \
+ text_lines.vala \
+ text_node.vala \
ui.vala \
units_util.vala \
+ valign_type.vala \
view.vala \
window.vala \
xml_label.vala \
diff --git a/glabels/color_swatch.vala b/glabels/color_swatch.vala
index bc3387c..f53de14 100644
--- a/glabels/color_swatch.vala
+++ b/glabels/color_swatch.vala
@@ -101,7 +101,7 @@ namespace glabels
return;
}
- unowned Cairo.Region region = window.get_clip_region();
+ Cairo.Region region = window.get_clip_region();
// redraw the cairo canvas completely by exposing it
window.invalidate_region(region, true);
window.process_updates(true);
diff --git a/glabels/font_sample.vala b/glabels/font_sample.vala
index 508e338..e989c91 100644
--- a/glabels/font_sample.vala
+++ b/glabels/font_sample.vala
@@ -128,7 +128,7 @@ namespace glabels
return;
}
- unowned Cairo.Region region = window.get_clip_region ();
+ Cairo.Region region = window.get_clip_region ();
// redraw the cairo canvas completely by exposing it
window.invalidate_region (region, true);
window.process_updates (true);
diff --git a/glabels/handle.vala b/glabels/handle.vala
index 7c8b060..e65b421 100644
--- a/glabels/handle.vala
+++ b/glabels/handle.vala
@@ -1,4 +1,4 @@
-/* label_object_box.vala
+/* handle.vala
*
* Copyright (C) 2011 Jim Evins <evins snaught com>
*
diff --git a/glabels/label_object.vala b/glabels/label_object.vala
index 79fd089..687fba1 100644
--- a/glabels/label_object.vala
+++ b/glabels/label_object.vala
@@ -32,10 +32,12 @@ namespace glabels
private bool selected;
protected List<Handle> handles;
+ protected Outline? outline;
private double aspect_ratio;
+
/**
* Parent label
*/
@@ -254,6 +256,25 @@ namespace glabels
/**
+ * Text vertical alignment
+ */
+ public ValignType text_valignment
+ {
+ get { return _text_valignment; }
+
+ set
+ {
+ if ( _text_valignment != value )
+ {
+ _text_valignment = value;
+ changed();
+ }
+ }
+ }
+ private ValignType _text_valignment;
+
+
+ /**
* Text line spacing
*/
public double text_line_spacing
@@ -452,6 +473,7 @@ namespace glabels
_font_italic_flag = prefs.default_font_italic_flag;
_text_color_node = ColorNode.from_color( prefs.default_text_color );
_text_alignment = prefs.default_text_alignment;
+ _text_valignment = ValignType.TOP;
_text_line_spacing = prefs.default_text_line_spacing;
_line_width = prefs.default_line_width;
@@ -700,6 +722,11 @@ namespace glabels
cr.translate( x0, y0 );
cr.transform( matrix );
+ if ( outline != null )
+ {
+ outline.draw( cr );
+ }
+
foreach( Handle handle in handles )
{
handle.draw( cr );
@@ -723,6 +750,14 @@ namespace glabels
bool ret_val = is_object_located_at( cr, x, y );
+ if ( (outline != null) && is_selected() )
+ {
+ if ( outline.in_stroke( cr, x, y ) )
+ {
+ ret_val = true;
+ }
+ }
+
cr.restore();
return ret_val;
diff --git a/glabels/label_object_text.vala b/glabels/label_object_text.vala
new file mode 100644
index 0000000..4cb0146
--- /dev/null
+++ b/glabels/label_object_text.vala
@@ -0,0 +1,293 @@
+/* label_object_text.vala
+ *
+ * Copyright (C) 2012 Jim Evins <evins snaught com>
+ *
+ * This file is part of gLabels.
+ *
+ * gLabels is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * gLabels is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with gLabels. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+using GLib;
+
+namespace glabels
+{
+
+ public class LabelObjectText : LabelObject
+ {
+ public Gtk.TextBuffer buffer;
+
+ private Gtk.TextTagTable tag_table;
+ private bool size_changed;
+
+ private const double FONT_SCALE = (72.0/96.0);
+ private const double SELECTION_SLOP_PIXELS = 4.0;
+ private const double TEXT_MARGIN = 3.0;
+
+ public bool auto_shrink { get; set; default = false; }
+
+
+ public LabelObjectText()
+ {
+ handles.append( new HandleSouthEast( this ) );
+ handles.append( new HandleSouthWest( this ) );
+ handles.append( new HandleNorthEast( this ) );
+ handles.append( new HandleNorthWest( this ) );
+ handles.append( new HandleEast( this ) );
+ handles.append( new HandleSouth( this ) );
+ handles.append( new HandleWest( this ) );
+ handles.append( new HandleNorth( this ) );
+
+ outline = new Outline( this );
+
+ tag_table = new Gtk.TextTagTable();
+ buffer = new Gtk.TextBuffer( tag_table );
+ size_changed = true;
+
+ buffer.begin_user_action.connect( on_buffer_begin_user_action );
+ buffer.changed.connect( on_buffer_changed );
+ }
+
+
+ public override bool can_text()
+ {
+ return true;
+ }
+
+
+ public override LabelObject dup()
+ {
+ LabelObjectText copy = new LabelObjectText();
+
+ copy.set_common_properties_from_object( this );
+
+ return copy;
+ }
+
+
+ public override void draw_object( Cairo.Context cr, bool in_editor, MergeRecord? record )
+ {
+ Color text_color = text_color_node.expand( record );
+
+ if ( in_editor && text_color_node.field_flag )
+ {
+ text_color = Color.from_rgba( 0, 0, 0, 0.5 );
+ }
+
+ draw_text_real( cr, in_editor, record, text_color );
+ }
+
+
+ public override void draw_shadow( Cairo.Context cr, bool in_editor, MergeRecord? record )
+ {
+ Color shadow_color = shadow_color_node.expand( record );
+
+ if ( in_editor && shadow_color_node.field_flag )
+ {
+ shadow_color = Color.black();
+ }
+
+ shadow_color.set_opacity( shadow_opacity );
+
+ draw_text_real( cr, in_editor, record, shadow_color );
+ }
+
+
+ private void draw_text_real( Cairo.Context cr, bool in_editor, MergeRecord? record, Color color )
+ {
+ set_text_path( cr, in_editor, record);
+
+ cr.set_source_rgba( color.r, color.g, color.b, color.a );
+ cr.fill();
+ }
+
+
+ public override bool is_object_located_at( Cairo.Context cr, double x, double y )
+ {
+ if ( (x >= 0) && (x <= w) && (y >=0) && (y <= h) )
+ {
+ cr.new_path();
+ set_text_path( cr, true, null);
+ if ( cr.in_fill( x, y ) )
+ {
+ return true;
+ }
+
+ double scale_x = 1.0;
+ double scale_y = 1.0;
+ cr.device_to_user_distance( ref scale_x, ref scale_y );
+ cr.set_line_width( 2*SELECTION_SLOP_PIXELS*scale_x );
+ if (cr.in_stroke( x, y ))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+
+ private void set_text_path( Cairo.Context cr, bool in_editor, MergeRecord? record )
+ {
+ cr.save();
+
+ TextLines lines = get_lines();
+ string text = lines.expand( record );
+
+ Pango.Style style = font_italic_flag ? Pango.Style.ITALIC : Pango.Style.NORMAL;
+
+ double scaled_font_size = font_size * FONT_SCALE;
+
+ if (!in_editor && (record != null) && auto_shrink)
+ {
+ scaled_font_size = auto_shrink_font_size( cr,
+ font_family, scaled_font_size, font_weight, style,
+ text, w, h );
+ }
+
+
+ Pango.Layout layout = Pango.cairo_create_layout( cr );
+
+ Cairo.FontOptions font_options = new Cairo.FontOptions();
+ font_options.set_hint_metrics( Cairo.HintMetrics.OFF );
+ Pango.Context context = layout.get_context();
+ Pango.cairo_context_set_font_options( context, font_options );
+
+ Pango.FontDescription desc = new Pango.FontDescription();
+ desc.set_family( font_family );
+ desc.set_weight( font_weight );
+ desc.set_size( (int)(scaled_font_size * Pango.SCALE + 0.5) );
+ desc.set_style( style );
+ layout.set_font_description( desc );
+
+ layout.set_text( text, -1 );
+ layout.set_spacing( (int)(scaled_font_size * (text_line_spacing-1) * Pango.SCALE + 0.5) );
+ layout.set_width( (int)(w * Pango.SCALE + 0.5) );
+ layout.set_wrap( Pango.WrapMode.WORD );
+ layout.set_alignment( text_alignment );
+
+ int iw, ih;
+ layout.get_pixel_size( out iw, out ih );
+
+ double y;
+ switch (text_valignment)
+ {
+ case ValignType.CENTER:
+ y = (h - ih) / 2;
+ break;
+ case ValignType.BOTTOM:
+ y = h - ih;
+ break;
+ default:
+ y = 0;
+ break;
+ }
+
+ cr.move_to( TEXT_MARGIN, y );
+ Pango.cairo_layout_path( cr, layout );
+
+ cr.restore();
+ }
+
+
+ private double auto_shrink_font_size( Cairo.Context cr,
+ string family,
+ double size,
+ Pango.Weight weight,
+ Pango.Style style,
+ string text,
+ double width,
+ double height )
+ {
+ Pango.Layout layout = Pango.cairo_create_layout( cr );
+
+ Pango.FontDescription desc = new Pango.FontDescription();
+ desc.set_family( family );
+ desc.set_weight( weight );
+ desc.set_style( style );
+ desc.set_size( (int)(size * Pango.SCALE + 0.5) );
+ layout.set_font_description( desc );
+
+ layout.set_text( text, -1 );
+ layout.set_spacing( (int)(size * (text_line_spacing-1) * Pango.SCALE + 0.5) );
+ layout.set_width( -1 );
+
+ int iw, ih;
+ layout.get_size( out iw, out ih );
+ double layout_width = iw / (double)Pango.SCALE;
+ double layout_height = ih / (double)Pango.SCALE;
+
+ double new_wsize = size;
+ double new_hsize = size;
+ if ( layout_width > width )
+ {
+ /* Scale down. */
+ new_wsize = size * (width-2*TEXT_MARGIN) / layout_width;
+
+ /* Round down to nearest 1/2 point */
+ new_wsize = (int)(new_wsize*2.0) / 2.0;
+
+ /* don't get ridiculously small. */
+ if (new_wsize < 1.0)
+ {
+ new_wsize = 1.0;
+ }
+ }
+
+ if ( layout_height > height )
+ {
+ /* Scale down. */
+ new_hsize = size * height / layout_height;
+
+ /* Round down to nearest 1/2 point */
+ new_hsize = (int)(new_hsize*2.0) / 2.0;
+
+ /* don't get ridiculously small. */
+ if (new_hsize < 1.0)
+ {
+ new_hsize = 1.0;
+ }
+ }
+
+ return (new_wsize < new_hsize ? new_wsize : new_hsize);
+ }
+
+
+ private void on_buffer_begin_user_action()
+ {
+ }
+
+
+ private void on_buffer_changed()
+ {
+ size_changed = true;
+
+ changed();
+ }
+
+
+ private TextLines get_lines()
+ {
+ Gtk.TextIter start, end;
+
+ buffer.get_bounds( out start, out end );
+ string text = buffer.get_text( start, end, false );
+ TextLines lines = new TextLines( text );
+
+ return lines;
+ }
+
+ }
+
+}
diff --git a/glabels/mini_preview.vala b/glabels/mini_preview.vala
index 154b2d1..d5d51dd 100644
--- a/glabels/mini_preview.vala
+++ b/glabels/mini_preview.vala
@@ -232,7 +232,7 @@ namespace glabels
{
update_scheduled_flag = true;
- unowned Cairo.Region region = window.get_clip_region ();
+ Cairo.Region region = window.get_clip_region ();
// redraw the cairo canvas completely by exposing it
window.invalidate_region (region, true);
}
diff --git a/glabels/object_editor.vala b/glabels/object_editor.vala
index 7236c3c..7efcadb 100644
--- a/glabels/object_editor.vala
+++ b/glabels/object_editor.vala
@@ -27,49 +27,69 @@ namespace glabels
class ObjectEditor : Gtk.Box
{
- private Prefs prefs;
- private Units units;
-
- private Model model;
- private LabelObject? object;
-
-
- private Gtk.Image title_image;
- private Gtk.Label title_label;
- private Gtk.Notebook notebook;
-
- private Gtk.Box line_fill_page_box;
- private Gtk.Box pos_size_page_box;
- private Gtk.Box shadow_page_box;
-
- private Gtk.SpinButton line_width_spin;
- private Gtk.Box line_color_box;
- private ColorButton line_color_button;
-
- private Gtk.Box fill_color_box;
- private ColorButton fill_color_button;
-
- private Gtk.SpinButton pos_x_spin;
- private Gtk.SpinButton pos_y_spin;
- private Gtk.Label pos_x_units_label;
- private Gtk.Label pos_y_units_label;
-
- private Gtk.SpinButton size_w_spin;
- private Gtk.SpinButton size_h_spin;
- private Gtk.Label size_w_units_label;
- private Gtk.Label size_h_units_label;
- private Gtk.CheckButton size_aspect_check;
- private Gtk.Button size_reset_image_button;
-
- private Gtk.CheckButton shadow_enable_check;
- private Gtk.Grid shadow_controls_grid;
- private Gtk.SpinButton shadow_x_spin;
- private Gtk.SpinButton shadow_y_spin;
- private Gtk.Label shadow_x_units_label;
- private Gtk.Label shadow_y_units_label;
- private Gtk.Box shadow_color_box;
- private ColorButton shadow_color_button;
- private Gtk.SpinButton shadow_opacity_spin;
+ private Prefs prefs;
+ private Units units;
+
+ private Model model;
+ private LabelObject? object;
+
+
+ private Gtk.Image title_image;
+ private Gtk.Label title_label;
+ private Gtk.Notebook notebook;
+
+ private Gtk.Box text_page_box;
+ private Gtk.Box line_fill_page_box;
+ private Gtk.Box pos_size_page_box;
+ private Gtk.Box shadow_page_box;
+
+ private Gtk.Box text_font_family_box;
+ private FontButton text_font_family_button;
+ private Gtk.SpinButton text_font_size_spin;
+ private Gtk.ToggleButton text_font_bold_toggle;
+ private Gtk.ToggleButton text_font_italic_toggle;
+ private Gtk.ToggleButton text_font_underline_toggle;
+ private Gtk.Box text_color_box;
+ private ColorButton text_color_button;
+ private Gtk.ToggleButton text_align_left_toggle;
+ private Gtk.ToggleButton text_align_center_toggle;
+ private Gtk.ToggleButton text_align_right_toggle;
+ private Gtk.ToggleButton text_align_top_toggle;
+ private Gtk.ToggleButton text_align_middle_toggle;
+ private Gtk.ToggleButton text_align_bottom_toggle;
+ private Gtk.SpinButton text_line_spacing_spin;
+ private Gtk.TextView text_text_view;
+ private Gtk.Box text_insert_field_box;
+ private FieldButton text_insert_field_button;
+
+ private Gtk.SpinButton line_width_spin;
+ private Gtk.Box line_color_box;
+ private ColorButton line_color_button;
+
+ private Gtk.Box fill_color_box;
+ private ColorButton fill_color_button;
+
+ private Gtk.SpinButton pos_x_spin;
+ private Gtk.SpinButton pos_y_spin;
+ private Gtk.Label pos_x_units_label;
+ private Gtk.Label pos_y_units_label;
+
+ private Gtk.SpinButton size_w_spin;
+ private Gtk.SpinButton size_h_spin;
+ private Gtk.Label size_w_units_label;
+ private Gtk.Label size_h_units_label;
+ private Gtk.CheckButton size_aspect_check;
+ private Gtk.Button size_reset_image_button;
+
+ private Gtk.CheckButton shadow_enable_check;
+ private Gtk.Grid shadow_controls_grid;
+ private Gtk.SpinButton shadow_x_spin;
+ private Gtk.SpinButton shadow_y_spin;
+ private Gtk.Label shadow_x_units_label;
+ private Gtk.Label shadow_y_units_label;
+ private Gtk.Box shadow_color_box;
+ private ColorButton shadow_color_button;
+ private Gtk.SpinButton shadow_opacity_spin;
public ObjectEditor()
@@ -108,11 +128,44 @@ namespace glabels
title_label.set_sensitive( false );
/* Notebook pages. */
+ text_page_box = builder.get_object( "text_page_box" ) as Gtk.Box;
line_fill_page_box = builder.get_object( "line_fill_page_box" ) as Gtk.Box;
pos_size_page_box = builder.get_object( "pos_size_page_box" ) as Gtk.Box;
shadow_page_box = builder.get_object( "shadow_page_box" ) as Gtk.Box;
+ /* Text widgets. */
+ text_font_family_box = builder.get_object( "text_font_family_box" ) as Gtk.Box;
+ text_font_size_spin = builder.get_object( "text_font_size_spin" ) as Gtk.SpinButton;
+ text_font_bold_toggle = builder.get_object( "text_font_bold_toggle" ) as Gtk.ToggleButton;
+ text_font_italic_toggle = builder.get_object( "text_font_italic_toggle" ) as Gtk.ToggleButton;
+ text_font_underline_toggle = builder.get_object( "text_font_underline_toggle" ) as Gtk.ToggleButton;
+ text_color_box = builder.get_object( "text_color_box" ) as Gtk.Box;
+ text_align_left_toggle = builder.get_object( "text_align_left_toggle" ) as Gtk.ToggleButton;
+ text_align_center_toggle = builder.get_object( "text_align_center_toggle" ) as Gtk.ToggleButton;
+ text_align_right_toggle = builder.get_object( "text_align_right_toggle" ) as Gtk.ToggleButton;
+ text_align_top_toggle = builder.get_object( "text_align_top_toggle" ) as Gtk.ToggleButton;
+ text_align_middle_toggle = builder.get_object( "text_align_middle_toggle" ) as Gtk.ToggleButton;
+ text_align_bottom_toggle = builder.get_object( "text_align_bottom_toggle" ) as Gtk.ToggleButton;
+ text_line_spacing_spin = builder.get_object( "text_line_spacing_spin" ) as Gtk.SpinButton;
+ text_text_view = builder.get_object( "text_text_view" ) as Gtk.TextView;
+ text_insert_field_box = builder.get_object( "text_insert_field_box" ) as Gtk.Box;
+
+ text_font_family_button = new FontButton( null );
+ text_font_family_box.pack_start( text_font_family_button, false, false, 0 );
+
+ text_color_button = new ColorButton( _("Default"), Color.black(), Color.black() );
+ text_color_box.pack_start( text_color_button, true, true, 0 );
+
+ text_insert_field_button = new FieldButton( null );
+ text_insert_field_box.pack_start( text_insert_field_button, true, true, 0 );
+/*
+ text_font_family_button.changed.connect( on_text_font_family_button_changed );
+ text_font_size_spin.value_changed.connect( on_text_font_size_spin_changed );
+ text_color_button.color_changed.connect( on_text_color_button_changed );
+ text_insert_field_button.changed.connect( on_text_field_button_changed );
+*/
+
/* Line widgets. */
line_width_spin = builder.get_object( "line_width_spin" ) as Gtk.SpinButton;
line_color_box = builder.get_object( "line_color_box" ) as Gtk.Box;
@@ -248,11 +301,28 @@ namespace glabels
{
object = model.label.get_1st_selected_object();
- if ( object is LabelObjectBox )
+ if ( object is LabelObjectText )
+ {
+ LabelObjectText tobject = object as LabelObjectText;
+
+ title_image.set_from_icon_name( "glabels-box", Gtk.IconSize.LARGE_TOOLBAR );
+ title_label.set_text( "<b>%s</b>".printf( _("Text object properties") ) );
+
+ text_text_view.set_buffer( tobject.buffer );
+
+ text_page_box.show_all();
+ line_fill_page_box.hide();
+ pos_size_page_box.show_all();
+ shadow_page_box.show_all();
+
+ size_reset_image_button.hide();
+ }
+ else if ( object is LabelObjectBox )
{
title_image.set_from_icon_name( "glabels-box", Gtk.IconSize.LARGE_TOOLBAR );
title_label.set_text( "<b>%s</b>".printf( _("Box object properties") ) );
+ text_page_box.hide();
line_fill_page_box.show_all();
pos_size_page_box.show_all();
shadow_page_box.show_all();
diff --git a/glabels/outline.vala b/glabels/outline.vala
new file mode 100644
index 0000000..c640b0a
--- /dev/null
+++ b/glabels/outline.vala
@@ -0,0 +1,85 @@
+/* outline.vala
+ *
+ * Copyright (C) 2011 Jim Evins <evins snaught com>
+ *
+ * This file is part of gLabels.
+ *
+ * gLabels is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * gLabels is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with gLabels. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+using GLib;
+
+namespace glabels
+{
+
+ private const double OUTLINE_WIDTH_PIXELS = 2;
+ private const double SELECTION_SLOP_PIXELS = 4;
+
+ private const Color OUTLINE_COLOR = { 0.0, 0.0, 0.0, 0.8 };
+
+
+ public class Outline
+ {
+ public weak LabelObject owner { get; protected set; }
+
+
+ public Outline( LabelObject owner )
+ {
+ this.owner = owner;
+ }
+
+
+ public void draw( Cairo.Context cr )
+ {
+ double dashes[2] = { 2, 2 };
+
+ cr.save();
+
+ cr.rectangle( 0, 0, owner.w, owner.h );
+
+ double scale_x = 1.0;
+ double scale_y = 1.0;
+ cr.device_to_user_distance( ref scale_x, ref scale_y );
+ cr.scale( scale_x, scale_y );
+
+ cr.set_dash( dashes, 0 );
+ cr.set_line_width( OUTLINE_WIDTH_PIXELS );
+ cr.set_source_rgba( OUTLINE_COLOR.r, OUTLINE_COLOR.g, OUTLINE_COLOR.b,
+ OUTLINE_COLOR.a );
+ cr.stroke();
+
+ cr.restore();
+ }
+
+
+ public bool in_stroke( Cairo.Context cr, double x, double y )
+ {
+ cr.rectangle( 0, 0, owner.w, owner.h );
+
+ double scale_x = 1.0;
+ double scale_y = 1.0;
+ cr.device_to_user_distance( ref scale_x, ref scale_y );
+
+ cr.set_line_width( 2*SELECTION_SLOP_PIXELS*scale_x );
+
+ return cr.in_stroke( x, y );
+ }
+
+
+ }
+
+
+}
+
diff --git a/glabels/text_line.vala b/glabels/text_line.vala
new file mode 100644
index 0000000..8eb057d
--- /dev/null
+++ b/glabels/text_line.vala
@@ -0,0 +1,80 @@
+/* text_line.vala
+ *
+ * Copyright (C) 2012 Jim Evins <evins snaught com>
+ *
+ * This file is part of gLabels.
+ *
+ * gLabels is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * gLabels is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with gLabels. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+using GLib;
+
+namespace glabels
+{
+
+ public class TextLine
+ {
+ public unowned List<TextNode> nodes { get; private set; }
+
+
+ public TextLine( string text, int i_start, out int i_next )
+ {
+ i_next = i_start;
+
+ for ( int i = i_start; text[i] != 0; i = i_next )
+ {
+ if ( text[i] != '\n' )
+ {
+ TextNode node = new TextNode.parse( text, i, out i_next );
+ nodes.append( node );
+ }
+ else
+ {
+ i_next++;
+ break;
+ }
+ }
+ }
+
+
+ public void expand( MergeRecord? record, ref StringBuilder builder )
+ {
+ /* special case: something like ${ADDRESS2} = "" on line by itself. */
+ /* in such circumstances ignore the line completely. */
+ if ( nodes.first().next == null )
+ {
+ if ( nodes.first().data.is_empty_field( record ) )
+ {
+ return;
+ }
+ }
+
+ /* prepend newline unless this is the first line. */
+ if ( builder.len > 0 )
+ {
+ builder.append_c( '\n' );
+ }
+
+ /* expand each node */
+ foreach (TextNode node in nodes)
+ {
+ builder.append( node.expand( record ) );
+ }
+ }
+
+
+ }
+
+}
diff --git a/glabels/text_lines.vala b/glabels/text_lines.vala
new file mode 100644
index 0000000..18149ed
--- /dev/null
+++ b/glabels/text_lines.vala
@@ -0,0 +1,60 @@
+/* text_lines.vala
+ *
+ * Copyright (C) 2012 Jim Evins <evins snaught com>
+ *
+ * This file is part of gLabels.
+ *
+ * gLabels is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * gLabels is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with gLabels. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+using GLib;
+
+namespace glabels
+{
+
+ public class TextLines
+ {
+ public unowned List<TextLine> lines { get; private set; }
+
+
+ public TextLines( string text )
+ {
+ int i_next = 0;
+
+ for ( int i = 0; text[i] != 0; i = i_next )
+ {
+ stderr.printf( "Text[%d] = %c, ", i, text[i] );
+ lines.append( new TextLine( text, i, out i_next ) );
+ stderr.printf( "i_next =%d\n", i_next );
+ }
+ }
+
+
+ public string expand( MergeRecord? record )
+ {
+ StringBuilder builder = new StringBuilder();
+
+ foreach ( TextLine line in lines )
+ {
+ line.expand( record, ref builder );
+ }
+
+ return builder.str;
+ }
+
+
+ }
+
+}
diff --git a/glabels/text_node.vala b/glabels/text_node.vala
new file mode 100644
index 0000000..a7d2ca5
--- /dev/null
+++ b/glabels/text_node.vala
@@ -0,0 +1,264 @@
+/* text_node.vala
+ *
+ * Copyright (C) 2012 Jim Evins <evins snaught com>
+ *
+ * This file is part of gLabels.
+ *
+ * gLabels is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * gLabels is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with gLabels. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+using GLib;
+
+namespace glabels
+{
+
+ public class TextNode
+ {
+ public bool field_flag { get; private set; }
+ public string data { get; private set; }
+
+
+ public TextNode( bool field_flag, string data )
+ {
+ this.field_flag = field_flag;
+ this.data = data;
+ }
+
+
+ public TextNode.dup( TextNode node )
+ {
+ this( node.field_flag, node.data );
+ }
+
+
+ private enum State { START,
+ LITERAL, LITERAL_DOLLAR,
+ START_DOLLAR, FIELD,
+ DONE }
+
+
+ public TextNode.parse( string text, int i_start, out int i_next )
+ {
+ State state = State.START;
+ StringBuilder literal_text = new StringBuilder();
+ StringBuilder field_name = new StringBuilder();
+ bool field_flag = false;
+
+ int i = i_start;
+
+ while ( state != State.DONE )
+ {
+ char c = text[i];
+
+ switch (state) {
+
+ case State.START:
+ switch (c) {
+ case '$':
+ /* May be start of a field node. */
+ i++;
+ state = State.START_DOLLAR;
+ break;
+ case '\n':
+ state = State.DONE;
+ break;
+ case 0:
+ state = State.DONE;
+ break;
+ default:
+ /* Start a literal text node. */
+ literal_text.append_c( c );
+ i++;
+ state = State.LITERAL;
+ break;
+ }
+ break;
+
+ case State.LITERAL:
+ switch (c) {
+ case '$':
+ /* May be the beginning of a field node. */
+ i++;
+ state = State.LITERAL_DOLLAR;
+ break;
+ case '\n':
+ state = State.DONE;
+ break;
+ case 0:
+ state = State.DONE;
+ break;
+ default:
+ literal_text.append_c( c );
+ i++;
+ state = State.LITERAL;
+ break;
+ }
+ break;
+
+ case State.LITERAL_DOLLAR:
+ switch (c) {
+ case '{':
+ /* "${" indicates the start of a new field node, gather for literal too. */
+ literal_text.append_c( '$' );
+ i++;
+ state = State.DONE;
+ break;
+ case '\n':
+ /* Append "$" to literal text, don't gather newline. */
+ literal_text.append_c( '$' );
+ i++;
+ state = State.DONE;
+ break;
+ case 0:
+ /* Append "$" to literal text, don't gather null. */
+ literal_text.append_c( '$' );
+ i++;
+ state = State.DONE;
+ break;
+ default:
+ /* Append "$" to literal text, gather this character too. */
+ literal_text.append_c( '$' );
+ literal_text.append_c( c );
+ i+=2;
+ state = State.LITERAL;
+ break;
+ }
+ break;
+
+ case State.START_DOLLAR:
+ switch (c) {
+ case '{':
+ /* This is probably the begging of a field node, gather for literal too. */
+ literal_text.append_c( c );
+ i++;
+ state = State.FIELD;
+ break;
+ case '\n':
+ state = State.DONE;
+ break;
+ case 0:
+ state = State.DONE;
+ break;
+ default:
+ /* The "$" was literal. */
+ literal_text.append_c( c );
+ i++;
+ state = State.LITERAL;
+ break;
+ }
+ break;
+
+ case State.FIELD:
+ switch (c) {
+ case '}':
+ /* We now finally know that this node is really field node. */
+ field_flag = true;
+ i++;
+ state = State.DONE;
+ break;
+ case '\n':
+ state = State.DONE;
+ break;
+ case 0:
+ state = State.DONE;
+ break;
+ default:
+ /* Gather for field name and literal, just in case. */
+ field_name.append_unichar( c );
+ literal_text.append_c( c );
+ i++;
+ state = State.FIELD;
+ break;
+ }
+ break;
+
+ }
+
+ }
+
+ string data;
+ if ( field_flag )
+ {
+ data = field_name.str;
+ }
+ else
+ {
+ data = literal_text.str;
+ }
+
+ this( field_flag, data );
+
+ i_next = i;
+ }
+
+
+ public bool equal( TextNode node2 )
+ {
+ if ( this.field_flag != node2.field_flag )
+ {
+ return false;
+ }
+
+ return ( this.data == node2.data );
+ }
+
+
+ public string expand( MergeRecord? record )
+ {
+ if ( field_flag )
+ {
+
+ if ( record == null )
+ {
+ return "${%s}".printf( data );
+ }
+ else
+ {
+ string? text = record.eval_key( data );
+ if ( text != null )
+ {
+ return text;
+ }
+ else
+ {
+ return "";
+ }
+ }
+
+ }
+ else
+ {
+ return data;
+ }
+ }
+
+
+ public bool is_empty_field( MergeRecord? record )
+ {
+ if ( (record !=null) && field_flag )
+ {
+ string? text = record.eval_key( data );
+ return ( (text == null) || (text == "") );
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+
+ }
+
+}
diff --git a/glabels/ui.vala b/glabels/ui.vala
index ffa31fd..d2037a2 100644
--- a/glabels/ui.vala
+++ b/glabels/ui.vala
@@ -1152,12 +1152,7 @@ namespace glabels
private void on_objects_create_text( Gtk.Action action )
{
- /*
- if (window->view != NULL) {
- gl_view_object_create_mode (GL_VIEW(window->view),
- GL_LABEL_OBJECT_TEXT);
- }
- */
+ window.view.create_text_mode();
}
diff --git a/glabels/valign_type.vala b/glabels/valign_type.vala
new file mode 100644
index 0000000..d260f8c
--- /dev/null
+++ b/glabels/valign_type.vala
@@ -0,0 +1,28 @@
+/* valign_type.vala
+ *
+ * Copyright (C) 2012 Jim Evins <evins snaught com>
+ *
+ * This file is part of gLabels.
+ *
+ * gLabels is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * gLabels is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with gLabels. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+using GLib;
+
+namespace glabels
+{
+ public enum ValignType { TOP, CENTER, BOTTOM }
+}
+
diff --git a/glabels/view.vala b/glabels/view.vala
index 8dc2b96..c4505ef 100644
--- a/glabels/view.vala
+++ b/glabels/view.vala
@@ -385,6 +385,28 @@ namespace glabels
}
+ public void create_text_mode()
+ {
+ Gdk.Window window = canvas.get_window();
+
+ try
+ {
+ Gdk.Pixbuf pixbuf = Gdk.Pixbuf.from_pixdata( Cursor.text_pixdata, false );
+ Gdk.Cursor cursor = new Gdk.Cursor.from_pixbuf( Gdk.Display.get_default(),
+ pixbuf, CURSOR_X_HOTSPOT, CURSOR_Y_HOTSPOT );
+ window.set_cursor( cursor );
+ }
+ catch ( Error err )
+ {
+ error( "%s\n", err.message );
+ }
+
+ in_object_create_mode = true;
+ create_object_type = CreateType.TEXT;
+ state = State.IDLE;
+ }
+
+
private void on_prefs_changed()
{
grid_spacing = UnitsUtil.get_grid_size( prefs.units );
@@ -844,7 +866,9 @@ namespace glabels
/* TODO */
break;
case CreateType.TEXT:
- /* TODO */
+ create_object.set_position( double.min( x, create_x0 ), double.min( y, create_y0 ) );
+ create_object.set_size( double.max( x, create_x0 ) - double.min( x, create_x0 ),
+ double.max( y, create_y0 ) - double.min( y, create_y0 ) );
break;
case CreateType.BARCODE:
/* TODO */
@@ -970,7 +994,7 @@ namespace glabels
/* TODO */
break;
case CreateType.TEXT:
- /* TODO */
+ create_object = new LabelObjectText() as LabelObject;
break;
case CreateType.BARCODE:
/* TODO */
diff --git a/glabels/xml_label.vala b/glabels/xml_label.vala
index 19d7dac..fee45ab 100644
--- a/glabels/xml_label.vala
+++ b/glabels/xml_label.vala
@@ -186,7 +186,7 @@ namespace glabels
{
case "Object-text":
- /* TODO. */
+ parse_object_text_node( child, label );
break;
case "Object-box":
@@ -263,6 +263,32 @@ namespace glabels
}
+ private void parse_object_text_node( Xml.Node node,
+ Label label )
+ {
+ LabelObjectText object = new LabelObjectText();
+
+
+ /* position attrs */
+ object.x0 = XmlUtil.get_prop_length( node, "x", 0.0 );
+ object.y0 = XmlUtil.get_prop_length( node, "y", 0.0 );
+
+ /* size attrs */
+ object.w = XmlUtil.get_prop_length( node, "w", 0 );
+ object.h = XmlUtil.get_prop_length( node, "h", 0 );
+
+ /* affine attrs */
+ parse_affine_attrs( node, object );
+
+ /* shadow attrs */
+ parse_shadow_attrs( node, object );
+
+ // TODO: parse contents.
+
+ label.add_object( object );
+ }
+
+
private void parse_affine_attrs( Xml.Node node,
LabelObject object )
{
@@ -389,6 +415,10 @@ namespace glabels
{
create_object_box_node( node, ns, (LabelObjectBox)object );
}
+ else if ( object is LabelObjectText )
+ {
+ create_object_text_node( node, ns, (LabelObjectText)object );
+ }
else /* TODO: other object types. */
{
message( "Unknown label object." );
@@ -440,6 +470,30 @@ namespace glabels
}
+ private void create_object_text_node( Xml.Node parent,
+ Xml.Ns ns,
+ LabelObjectText object )
+ {
+ unowned Xml.Node *node = parent.new_child( ns, "Object-text" );
+
+ /* position attrs */
+ XmlUtil.set_prop_length( node, "x", object.x0 );
+ XmlUtil.set_prop_length( node, "y", object.y0 );
+
+ /* size attrs */
+ XmlUtil.set_prop_length( node, "w", object.w );
+ XmlUtil.set_prop_length( node, "h", object.h );
+
+ /* affine attrs */
+ create_affine_attrs( node, object );
+
+ /* shadow attrs */
+ create_shadow_attrs( node, object );
+
+ // TODO: create contents.
+ }
+
+
private void create_affine_attrs( Xml.Node node,
LabelObject object )
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]