commit f41b33fbac5143b0af4c357539c9a2460f1b76df
parent 95d5c87fd26ac007581e594ebb4ec46fcf9b7078
Author: Alexander Kojevnikov <alexander@kojevnikov.com>
Date: Wed, 15 Aug 2012 22:43:28 -0700
spek-ruler.cc
Diffstat:
5 files changed, 141 insertions(+), 136 deletions(-)
diff --git a/src/Makefile.am b/src/Makefile.am
@@ -14,6 +14,8 @@ spek_SOURCES = \
spek-platform.hh \
spek-preferences.cc \
spek-preferences.hh \
+ spek-ruler.cc \
+ spek-ruler.hh \
spek-spectrogram.cc \
spek-spectrogram.hh \
spek-window.cc \
diff --git a/src/spek-ruler.cc b/src/spek-ruler.cc
@@ -0,0 +1,85 @@
+/* spek-ruler.cc
+ *
+ * Copyright (C) 2010-2012 Alexander Kojevnikov <alexander@kojevnikov.com>
+ *
+ * Spek 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.
+ *
+ * Spek 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 Spek. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "spek-ruler.hh"
+
+SpekRuler::SpekRuler(Position pos, wxString sample_label, int *factors, int units, double spacing) :
+ pos(pos), sample_label(sample_label), factors(factors), units(units), spacing(spacing)
+{
+}
+
+void SpekRuler::draw(wxDC& dc)
+{
+ // Mesure the sample label.
+ wxSize size = dc.GetTextExtent(sample_label);
+ int len = this->pos == TOP || this->pos == BOTTOM ? size.GetWidth() : size.GetHeight();
+
+ // Select the factor to use, we want some space between the labels.
+ int factor = 0;
+ for (int i = 0; factors[i]; ++i) {
+ if (this->measure(factors[i]) >= this->spacing * len) {
+ factor = factors[i];
+ break;
+ }
+ }
+
+ // Draw the ticks.
+ this->draw_tick(dc, 0);
+ this->draw_tick(dc, units);
+
+ if (factor > 0) {
+ for (int tick = factor; tick < units; tick += factor) {
+ if (this->measure(units - tick) < len * 1.2) {
+ break;
+ }
+ this->draw_tick(dc, tick);
+ }
+ }
+}
+
+void SpekRuler::draw_tick(wxDC& dc, int tick)
+{
+ double GAP = 10;
+ double TICK_LEN = 4;
+
+ wxString label = format(tick);
+ double p = place(measure(this->pos == TOP || this->pos == BOTTOM ? tick : this->units - tick));
+ wxSize size = dc.GetTextExtent(label);
+ int w = size.GetWidth();
+ int h = size.GetHeight();
+
+ if (this->pos == TOP) {
+ dc.DrawText(label, p - w / 2, -GAP - h);
+ } else if (this->pos == RIGHT){
+ dc.DrawText(label, GAP, p + h / 4);
+ } else if (this->pos == BOTTOM) {
+ dc.DrawText(label, p - w / 2, GAP + h);
+ } else if (this->pos == LEFT){
+ dc.DrawText(label, -w - GAP, p + h / 4);
+ }
+
+ if (this->pos == TOP) {
+ dc.DrawLine(p, 0, p, -TICK_LEN);
+ } else if (this->pos == RIGHT) {
+ dc.DrawLine(0, p, TICK_LEN, p);
+ } else if (this->pos == BOTTOM) {
+ dc.DrawLine(p, 0, p, TICK_LEN);
+ } else if (this->pos == LEFT) {
+ dc.DrawLine(0, p, -TICK_LEN, p);
+ }
+}
diff --git a/src/spek-ruler.hh b/src/spek-ruler.hh
@@ -0,0 +1,54 @@
+/* spek-ruler.hh
+ *
+ * Copyright (C) 2010-2012 Alexander Kojevnikov <alexander@kojevnikov.com>
+ *
+ * Spek 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.
+ *
+ * Spek 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 Spek. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef SPEK_RULER_HH_
+#define SPEK_RULER_HH_
+
+#include <wx/dc.h>
+#include <wx/string.h>
+
+class SpekRuler
+{
+public:
+ enum Position
+ {
+ TOP,
+ RIGHT,
+ BOTTOM,
+ LEFT
+ };
+
+ SpekRuler(Position pos, wxString sample_label, int *factors, int units, double spacing);
+
+ void draw(wxDC& dc);
+
+protected:
+ virtual double measure(int unit) = 0;
+ virtual double place(double p) = 0;
+ virtual wxString format(int unit) = 0;
+
+ void draw_tick(wxDC& dc, int tick);
+
+ Position pos;
+ wxString sample_label;
+ int *factors;
+ int units;
+ double spacing;
+};
+
+#endif
diff --git a/src/spek-ruler.vala b/src/spek-ruler.vala
@@ -1,123 +0,0 @@
-/* spek-ruler.vala
- *
- * Copyright (C) 2010,2011 Alexander Kojevnikov <alexander@kojevnikov.com>
- *
- * Spek 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.
- *
- * Spek 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 Spek. If not, see <http://www.gnu.org/licenses/>.
- */
-
-using Cairo;
-using Pango;
-
-namespace Spek {
- class Ruler : GLib.Object {
- public enum Position {
- TOP,
- RIGHT,
- BOTTOM,
- LEFT
- }
-
- private Position pos;
- private string sample_label;
- private int[] factors;
- private int units;
- private double spacing;
- private Measure measure;
- private Place place;
- private FormatTick format_tick;
-
- public delegate double Measure (int unit);
- public delegate double Place (double p);
- public delegate string FormatTick (int unit);
-
- public Ruler (
- Position pos, string sample_label,
- int[] factors, int units, double spacing,
- Measure measure, Place place, FormatTick format_tick) {
- this.pos = pos;
- this.sample_label = sample_label;
- this.factors = factors;
- this.units = units;
- this.spacing = spacing;
- this.measure = measure;
- this.place = place;
- this.format_tick = format_tick;
- }
-
- public void draw (Cairo.Context cr, Pango.Layout layout) {
- // Mesure the sample label.
- int w, h;
- layout.set_text (sample_label, -1);
- layout.get_pixel_size (out w, out h);
- var size = pos == Position.TOP || pos == Position.BOTTOM ? w : h;
-
- // Select the factor to use, we want some space between the labels.
- int factor = 0;
- foreach (var f in factors) {
- if (measure (f) >= spacing * size) {
- factor = f;
- break;
- }
- }
-
- // Add the ticks.
- int[] ticks = { 0, units };
- if (factor > 0) {
- for (var tick = factor; tick < units; tick += factor) {
- if (measure (units - tick) < size * 1.2) {
- break;
- }
- ticks += tick;
- }
- // TODO: `ticks = ticks[0:-1]` crashes, file a bug.
- }
-
- // Draw the ticks.
- double GAP = 10;
- double TICK_LEN = 4;
- foreach (var tick in ticks) {
- var label = format_tick (tick);
- var p = place (measure (
- pos == Position.TOP || pos == Position.BOTTOM
- ? tick : units - tick));
- layout.set_text (label, -1);
- layout.get_pixel_size (out w, out h);
- if (pos == Position.TOP) {
- cr.move_to (p - w / 2, -GAP - h);
- } else if (pos == Position.RIGHT){
- cr.move_to (GAP, p + h / 4);
- } else if (pos == Position.BOTTOM) {
- cr.move_to (p - w / 2, GAP + h);
- } else if (pos == Position.LEFT){
- cr.move_to (-w - GAP, p + h / 4);
- }
- cairo_show_layout_line (cr, layout.get_line (0));
- if (pos == Position.TOP) {
- cr.move_to (p, 0);
- cr.rel_line_to (0, -TICK_LEN);
- } else if (pos == Position.RIGHT) {
- cr.move_to (0, p);
- cr.rel_line_to (TICK_LEN, 0);
- } else if (pos == Position.BOTTOM) {
- cr.move_to (p, 0);
- cr.rel_line_to (0, TICK_LEN);
- } else if (pos == Position.LEFT) {
- cr.move_to (0, p);
- cr.rel_line_to (-TICK_LEN, 0);
- }
- cr.stroke ();
- }
- }
- }
-}
-\ No newline at end of file
diff --git a/src/spek-spectrogram.vala b/src/spek-spectrogram.vala
@@ -36,18 +36,6 @@ namespace Spek {
surface.write_to_png (file_name);
}
- protected override bool expose_event (EventExpose event) {
- var window = get_window ();
- var cr = cairo_create (window);
-
- // Clip to the exposed area.
- cr.rectangle (event.area.x, event.area.y, event.area.width, event.area.height);
- cr.clip ();
-
- draw (cr);
- return true;
- }
-
private void draw (Cairo.Context cr) {
int text_width, text_height;