366 lines
11 KiB
C++
366 lines
11 KiB
C++
#pragma once
|
|
|
|
#include <gtkmm.h>
|
|
|
|
#if !defined(GLIBMM_DEFAULT_SIGNAL_HANDLERS_ENABLED)
|
|
#error GLIBMM_DEFAULT_SIGNAL_HANDLERS_ENABLED must be set.
|
|
#endif
|
|
|
|
#include "model.hpp"
|
|
|
|
namespace Jacker {
|
|
|
|
class PatternCursor;
|
|
class PatternView;
|
|
|
|
//=============================================================================
|
|
|
|
class CellRenderer {
|
|
public:
|
|
CellRenderer();
|
|
virtual ~CellRenderer() {}
|
|
virtual void render_background(PatternCursor &cursor,
|
|
bool selected);
|
|
virtual void render_cell(PatternCursor &cursor,
|
|
Pattern::Event *event, bool draw_cursor,
|
|
bool selected);
|
|
virtual int get_width();
|
|
virtual int get_item(int x);
|
|
virtual int get_item_count();
|
|
|
|
virtual bool on_key_press_event(GdkEventKey* event_key,
|
|
Pattern::Event &event, int item);
|
|
|
|
void set_view(PatternView &view);
|
|
PatternView *get_view() const;
|
|
protected:
|
|
PatternView *view;
|
|
};
|
|
|
|
//=============================================================================
|
|
|
|
class CellRendererNote : public CellRenderer {
|
|
public:
|
|
enum {
|
|
ItemNote = 0,
|
|
ItemOctave,
|
|
|
|
ItemCount
|
|
};
|
|
|
|
virtual void render_cell(PatternCursor &cursor,
|
|
Pattern::Event *event, bool draw_cursor,
|
|
bool selected);
|
|
virtual int get_width();
|
|
virtual int get_item(int x);
|
|
virtual int get_item_count();
|
|
|
|
virtual bool on_key_press_event(GdkEventKey* event_key,
|
|
Pattern::Event &event, int item);
|
|
};
|
|
|
|
//=============================================================================
|
|
|
|
class CellRendererHex : public CellRenderer {
|
|
public:
|
|
CellRendererHex(int value_length);
|
|
|
|
int value_length;
|
|
|
|
virtual void render_cell(PatternCursor &cursor,
|
|
Pattern::Event *event, bool draw_cursor,
|
|
bool selected);
|
|
virtual int get_width();
|
|
virtual int get_item(int x);
|
|
virtual int get_item_count();
|
|
|
|
virtual bool on_key_press_event(GdkEventKey* event_key,
|
|
Pattern::Event &event, int item);
|
|
};
|
|
|
|
//=============================================================================
|
|
|
|
class CellRendererCommand : public CellRenderer {
|
|
public:
|
|
CellRendererCommand();
|
|
|
|
virtual void render_cell(PatternCursor &cursor,
|
|
Pattern::Event *event, bool draw_cursor,
|
|
bool selected);
|
|
virtual int get_width();
|
|
virtual int get_item(int x);
|
|
virtual int get_item_count();
|
|
virtual bool on_key_press_event(GdkEventKey* event_key,
|
|
Pattern::Event &event, int item);
|
|
};
|
|
|
|
//=============================================================================
|
|
|
|
class PatternCursor {
|
|
friend class PatternSelection;
|
|
public:
|
|
PatternCursor();
|
|
void origin();
|
|
void next_row();
|
|
void next_channel();
|
|
void prev_channel();
|
|
void next_param();
|
|
|
|
// moves to the first param, then to the first channel,
|
|
// then to the first row
|
|
void home();
|
|
// moves to the last param, then to the last channel,
|
|
// then to the last row
|
|
void end();
|
|
|
|
int get_row() const;
|
|
int get_channel() const;
|
|
int get_param() const;
|
|
int get_item() const;
|
|
int get_column() const;
|
|
|
|
void set_row(int row);
|
|
void set_channel(int channel);
|
|
void set_param(int param);
|
|
void set_item(int item);
|
|
|
|
void set_last_item();
|
|
bool is_last_item() const;
|
|
void navigate_row(int delta);
|
|
void navigate_column(int delta);
|
|
|
|
// true if param is the last param in a channel
|
|
bool is_last_param() const;
|
|
void set_last_param();
|
|
bool is_last_channel() const;
|
|
void set_last_channel();
|
|
bool is_last_row() const;
|
|
void set_last_row();
|
|
|
|
void get_pos(int &x, int &y) const;
|
|
void set_pos(int x, int y);
|
|
void get_cell_size(int &w, int &h, bool include_margin=false) const;
|
|
|
|
PatternView *get_view() const;
|
|
void set_view(PatternView &view);
|
|
|
|
// true if cursor shares row/channel/param with other cursor
|
|
bool is_at(const PatternCursor &other) const;
|
|
|
|
std::string debug_string() const;
|
|
|
|
const PatternCursor &operator =(const Pattern::Event &event);
|
|
|
|
protected:
|
|
PatternView *view;
|
|
// index of current row
|
|
int row;
|
|
// index of current channel
|
|
int channel;
|
|
// index of current parameter
|
|
int param;
|
|
// index of parameter item
|
|
int item;
|
|
};
|
|
|
|
//=============================================================================
|
|
|
|
class PatternSelection {
|
|
public:
|
|
PatternSelection();
|
|
bool in_range(const PatternCursor &cursor) const;
|
|
|
|
void set_active(bool active);
|
|
bool get_active() const;
|
|
|
|
void set_view(PatternView &view);
|
|
|
|
bool get_rect(int &x, int &y, int &width, int &height) const;
|
|
|
|
void sort();
|
|
|
|
PatternCursor p0;
|
|
PatternCursor p1;
|
|
|
|
std::string debug_string() const;
|
|
protected:
|
|
|
|
bool active;
|
|
PatternView *view;
|
|
|
|
};
|
|
|
|
//=============================================================================
|
|
|
|
class PatternView : public Gtk::Widget {
|
|
public:
|
|
enum {
|
|
CharBegin = 32,
|
|
CharEnd = 128,
|
|
};
|
|
|
|
enum InteractMode {
|
|
InteractNone = 0,
|
|
InteractSelect,
|
|
};
|
|
|
|
typedef sigc::signal<void, int, const Pattern::Event &> type_play_event_request;
|
|
typedef sigc::signal<void> type_return_request;
|
|
typedef sigc::signal<void, int> type_play_request;
|
|
typedef sigc::signal<void, const std::string &,
|
|
const std::string &, const std::string &> type_navigation_status_request;
|
|
|
|
PatternView(BaseObjectType* cobject,
|
|
const Glib::RefPtr<Gtk::Builder>& builder);
|
|
|
|
void set_model(class Model &model);
|
|
void set_song_event(Song::iterator event);
|
|
Song::iterator get_song_event();
|
|
Pattern *get_pattern() const;
|
|
|
|
virtual void on_realize();
|
|
virtual bool on_expose_event(GdkEventExpose* event);
|
|
virtual bool on_motion_notify_event(GdkEventMotion *event);
|
|
virtual bool on_button_press_event(GdkEventButton* event);
|
|
virtual bool on_button_release_event(GdkEventButton* event);
|
|
virtual bool on_key_press_event(GdkEventKey* event);
|
|
virtual bool on_key_release_event(GdkEventKey* event);
|
|
virtual void on_size_allocate(Gtk::Allocation& allocation);
|
|
|
|
void set_cursor(const PatternCursor &cursor, bool select=false);
|
|
void set_cursor(int x, int y);
|
|
|
|
Glib::RefPtr<Gdk::GC> gc;
|
|
Glib::RefPtr<Gdk::GC> xor_gc;
|
|
Glib::RefPtr<Gdk::Colormap> cm;
|
|
Glib::RefPtr<Pango::Layout> pango_layout;
|
|
Glib::RefPtr<Gdk::Window> window;
|
|
std::vector< Glib::RefPtr<Gdk::Pixmap> > chars;
|
|
|
|
std::vector<Gdk::Color> colors;
|
|
|
|
CellRendererNote note_renderer;
|
|
CellRendererHex byte_renderer;
|
|
CellRendererCommand command_renderer;
|
|
|
|
int cursor_x, cursor_y;
|
|
//CellRendererHex word_renderer;
|
|
class Model *model;
|
|
|
|
void set_scroll_adjustments(Gtk::Adjustment *hadjustment,
|
|
Gtk::Adjustment *vadjustment);
|
|
|
|
void on_adjustment_value_changed();
|
|
void draw_text(int x, int y, const char *text);
|
|
void navigate(int delta_x, int delta_y, bool select=false);
|
|
|
|
|
|
void show_cursor();
|
|
void show_cursor(const PatternCursor &cur, bool page_jump=false);
|
|
|
|
int get_page_scroll_size() const;
|
|
int get_page_step_size() const;
|
|
int get_frames_per_bar() const;
|
|
void set_row_height(int height);
|
|
int get_row_height() const;
|
|
void set_cell_renderer(int param, CellRenderer *renderer);
|
|
CellRenderer *get_cell_renderer(int param) const;
|
|
int get_cell_count() const;
|
|
void set_origin(int x, int y);
|
|
void get_origin(int &x, int &y);
|
|
void set_cell_margin(int margin);
|
|
int get_cell_margin() const;
|
|
void set_channel_margin(int margin);
|
|
int get_channel_margin() const;
|
|
void get_cell_size(int param, int &w, int &h, bool include_margin=false) const;
|
|
void get_cell_pos(int row, int channel, int param,
|
|
int &x, int &y) const;
|
|
bool get_cell_location(int x, int y, int &row, int &channel,
|
|
int ¶m, int &item) const;
|
|
int get_channel_width() const;
|
|
int get_param_offset(int param) const;
|
|
void set_font_size(int width, int height);
|
|
void get_font_size(int &width, int &height) const;
|
|
|
|
void set_octave(int octave);
|
|
int get_octave() const;
|
|
|
|
void set_play_position(int pos);
|
|
void invalidate();
|
|
|
|
Pattern::iterator get_event(PatternCursor &cur);
|
|
|
|
void play_event(const Pattern::Event &event);
|
|
void play_from_cursor();
|
|
void play_from_mouse_cursor();
|
|
void play_pattern();
|
|
|
|
void cut_block();
|
|
void copy_block();
|
|
void paste_block();
|
|
void clear_block();
|
|
void on_clipboard_get(Gtk::SelectionData &data, guint info);
|
|
void on_clipboard_clear();
|
|
void on_clipboard_received(const Gtk::SelectionData &data);
|
|
void begin_block();
|
|
void end_block();
|
|
void cycle_block_selection();
|
|
void transpose(int step);
|
|
void interpolate();
|
|
|
|
void move_frames(int step, bool all_channels=false);
|
|
void reset();
|
|
|
|
type_play_event_request signal_play_event_request();
|
|
type_return_request signal_return_request();
|
|
type_play_request signal_play_request();
|
|
type_navigation_status_request signal_navigation_status_request();
|
|
protected:
|
|
void invalidate_play_position();
|
|
void invalidate_cursor();
|
|
void invalidate_selection();
|
|
void invalidate_range(const PatternSelection &range);
|
|
void clip_cursor(PatternCursor &c);
|
|
void update_adjustments();
|
|
void update_navigation_status();
|
|
|
|
InteractMode interact_mode;
|
|
|
|
Song::iterator song_event;
|
|
Gtk::Adjustment *hadjustment;
|
|
Gtk::Adjustment *vadjustment;
|
|
PatternCursor cursor;
|
|
PatternSelection selection;
|
|
std::string clipboard_jsong;
|
|
|
|
typedef std::vector<CellRenderer *> CellRendererArray;
|
|
|
|
// height of active row
|
|
int row_height;
|
|
// cell renderers indexed by param
|
|
CellRendererArray renderers;
|
|
// start x and y position
|
|
int origin_x, origin_y;
|
|
// margin between cells
|
|
int cell_margin;
|
|
// margin between channels
|
|
int channel_margin;
|
|
// how wide is a pattern character
|
|
int font_width;
|
|
// how high is a pattern character
|
|
int font_height;
|
|
// current base octave
|
|
int octave;
|
|
|
|
int play_position;
|
|
bool select_at_cursor;
|
|
|
|
type_play_event_request _play_event_request;
|
|
type_return_request _return_request;
|
|
type_play_request _play_request;
|
|
type_navigation_status_request _navigation_status_request;
|
|
};
|
|
|
|
//=============================================================================
|
|
|
|
} // namespace Jacker
|