spek

Acoustic spectrum analyser
git clone http://git.hanabi.in/repos/spek.git
Log | Files | Refs | README

commit f41b33fbac5143b0af4c357539c9a2460f1b76df
parent 95d5c87fd26ac007581e594ebb4ec46fcf9b7078
Author: Alexander Kojevnikov <alexander@kojevnikov.com>
Date:   Wed, 15 Aug 2012 22:43:28 -0700

spek-ruler.cc

Diffstat:
Msrc/Makefile.am | 2++
Asrc/spek-ruler.cc | 85+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/spek-ruler.hh | 54++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dsrc/spek-ruler.vala | 124-------------------------------------------------------------------------------
Msrc/spek-spectrogram.vala | 12------------
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;